@portabletext/react
Advanced tools
Comparing version 1.0.6 to 2.0.0
@@ -1,1 +0,329 @@ | ||
export * from "../src/index" | ||
/// <reference types="react" /> | ||
import type {ArbitraryTypedObject} from '@portabletext/types' | ||
import type {ComponentType} from 'react' | ||
import {ToolkitListNestMode as ListNestMode} from '@portabletext/toolkit' | ||
import type {PortableTextBlock} from '@portabletext/types' | ||
import type {PortableTextBlockStyle} from '@portabletext/types' | ||
import type {PortableTextListItemBlock} from '@portabletext/types' | ||
import type {PortableTextListItemType} from '@portabletext/types' | ||
import type {ReactNode} from 'react' | ||
import type {ToolkitPortableTextList} from '@portabletext/toolkit' | ||
import type {ToolkitPortableTextListItem} from '@portabletext/toolkit' | ||
import {toPlainText} from '@portabletext/toolkit' | ||
import type {TypedObject} from '@portabletext/types' | ||
export declare const defaultComponents: PortableTextReactComponents | ||
export {ListNestMode} | ||
export declare function mergeComponents( | ||
parent: PortableTextReactComponents, | ||
overrides: PortableTextComponents | ||
): PortableTextReactComponents | ||
export declare type MissingComponentHandler = ( | ||
message: string, | ||
options: { | ||
type: string | ||
nodeType: NodeType | ||
} | ||
) => void | ||
/** | ||
* Function that renders any node that might appear in a portable text array or block, | ||
* including virtual "toolkit"-nodes like lists and nested spans | ||
*/ | ||
export declare type NodeRenderer = <T extends TypedObject>(options: Serializable<T>) => ReactNode | ||
export declare type NodeType = 'block' | 'mark' | 'blockStyle' | 'listStyle' | 'listItemStyle' | ||
export declare function PortableText<B extends TypedObject = PortableTextBlock>({ | ||
value: input, | ||
components: componentOverrides, | ||
listNestingMode, | ||
onMissingComponent: missingComponentHandler, | ||
}: PortableTextProps<B>): JSX.Element | ||
/** | ||
* React component type for rendering portable text blocks (paragraphs, headings, blockquotes etc) | ||
*/ | ||
export declare type PortableTextBlockComponent = PortableTextComponent<PortableTextBlock> | ||
/** | ||
* Generic type for portable text rendering components that takes blocks/inline blocks | ||
* | ||
* @template N Node types we expect to be rendering (`PortableTextBlock` should usually be part of this) | ||
*/ | ||
export declare type PortableTextComponent<N> = ComponentType<PortableTextComponentProps<N>> | ||
/** | ||
* Props received by most Portable Text components | ||
* | ||
* @template T Type of data this component will receive in its `value` property | ||
*/ | ||
export declare interface PortableTextComponentProps<T> { | ||
/** | ||
* Data associated with this portable text node, eg the raw JSON value of a block/type | ||
*/ | ||
value: T | ||
/** | ||
* Index within its parent | ||
*/ | ||
index: number | ||
/** | ||
* Whether or not this node is "inline" - ie as a child of a text block, | ||
* alongside text spans, or a block in and of itself. | ||
*/ | ||
isInline: boolean | ||
/** | ||
* React child nodes of this block/component | ||
*/ | ||
children?: ReactNode | ||
/** | ||
* Function used to render any node that might appear in a portable text array or block, | ||
* including virtual "toolkit"-nodes like lists and nested spans. You will rarely need | ||
* to use this. | ||
*/ | ||
renderNode: NodeRenderer | ||
} | ||
/** | ||
* Object defining the different React components to use for rendering various aspects | ||
* of Portable Text and user-provided types, where only the overrides needs to be provided. | ||
*/ | ||
export declare type PortableTextComponents = Partial<PortableTextReactComponents> | ||
/** | ||
* React component type for rendering (virtual, not part of the spec) portable text lists | ||
*/ | ||
export declare type PortableTextListComponent = PortableTextComponent<ReactPortableTextList> | ||
/** | ||
* React component type for rendering portable text list items | ||
*/ | ||
export declare type PortableTextListItemComponent = PortableTextComponent<PortableTextListItemBlock> | ||
/** | ||
* React component type for rendering portable text marks and/or decorators | ||
* | ||
* @template M The mark type we expect | ||
*/ | ||
export declare type PortableTextMarkComponent<M extends TypedObject = any> = ComponentType< | ||
PortableTextMarkComponentProps<M> | ||
> | ||
/** | ||
* Props received by Portable Text mark rendering components | ||
* | ||
* @template M Shape describing the data associated with this mark, if it is an annotation | ||
*/ | ||
export declare interface PortableTextMarkComponentProps< | ||
M extends TypedObject = ArbitraryTypedObject | ||
> { | ||
/** | ||
* Mark definition, eg the actual data of the annotation. If the mark is a simple decorator, this will be `undefined` | ||
*/ | ||
value?: M | ||
/** | ||
* Text content of this mark | ||
*/ | ||
text: string | ||
/** | ||
* Key for this mark. The same key can be used amongst multiple text spans within the same block, so don't rely on this for React keys. | ||
*/ | ||
markKey?: string | ||
/** | ||
* Type of mark - ie value of `_type` in the case of annotations, or the name of the decorator otherwise - eg `em`, `italic`. | ||
*/ | ||
markType: string | ||
/** | ||
* React child nodes of this mark | ||
*/ | ||
children: ReactNode | ||
/** | ||
* Function used to render any node that might appear in a portable text array or block, | ||
* including virtual "toolkit"-nodes like lists and nested spans. You will rarely need | ||
* to use this. | ||
*/ | ||
renderNode: NodeRenderer | ||
} | ||
/** | ||
* Properties for the Portable Text react component | ||
* | ||
* @template B Types that can appear in the array of blocks | ||
*/ | ||
export declare interface PortableTextProps< | ||
B extends TypedObject = PortableTextBlock | ArbitraryTypedObject | ||
> { | ||
/** | ||
* One or more blocks to render | ||
*/ | ||
value: B | B[] | ||
/** | ||
* React components to use for rendering | ||
*/ | ||
components?: Partial<PortableTextReactComponents> | ||
/** | ||
* Function to call when encountering unknown unknown types, eg blocks, marks, | ||
* block style, list styles without an associated React component. | ||
* | ||
* Will print a warning message to the console by default. | ||
* Pass `false` to disable. | ||
*/ | ||
onMissingComponent?: MissingComponentHandler | false | ||
/** | ||
* Determines whether or not lists are nested inside of list items (`html`) | ||
* or as a direct child of another list (`direct` - for React Native) | ||
* | ||
* You rarely (if ever) need/want to customize this | ||
*/ | ||
listNestingMode?: ListNestMode | ||
} | ||
/** | ||
* Object definining the different React components to use for rendering various aspects | ||
* of Portable Text and user-provided types. | ||
*/ | ||
export declare interface PortableTextReactComponents { | ||
/** | ||
* Object of React components that renders different types of objects that might appear | ||
* both as part of the blocks array, or as inline objects _inside_ of a block, | ||
* alongside text spans. | ||
* | ||
* Use the `isInline` property to check whether or not this is an inline object or a block | ||
* | ||
* The object has the shape `{typeName: ReactComponent}`, where `typeName` is the value set | ||
* in individual `_type` attributes. | ||
*/ | ||
types: Record<string, PortableTextTypeComponent | undefined> | ||
/** | ||
* Object of React components that renders different types of marks that might appear in spans. | ||
* | ||
* The object has the shape `{markName: ReactComponent}`, where `markName` is the value set | ||
* in individual `_type` attributes, values being stored in the parent blocks `markDefs`. | ||
*/ | ||
marks: Record<string, PortableTextMarkComponent | undefined> | ||
/** | ||
* Object of React components that renders blocks with different `style` properties. | ||
* | ||
* The object has the shape `{styleName: ReactComponent}`, where `styleName` is the value set | ||
* in individual `style` attributes on blocks. | ||
* | ||
* Can also be set to a single React component, which would handle block styles of _any_ type. | ||
*/ | ||
block: | ||
| Record<PortableTextBlockStyle, PortableTextBlockComponent | undefined> | ||
| PortableTextBlockComponent | ||
/** | ||
* Object of React components used to render lists of different types (bulleted vs numbered, | ||
* for instance, which by default is `<ul>` and `<ol>`, respectively) | ||
* | ||
* There is no actual "list" node type in the Portable Text specification, but a series of | ||
* list item blocks with the same `level` and `listItem` properties will be grouped into a | ||
* virtual one inside of this library. | ||
* | ||
* Can also be set to a single React component, which would handle lists of _any_ type. | ||
*/ | ||
list: | ||
| Record<PortableTextListItemType, PortableTextListComponent | undefined> | ||
| PortableTextListComponent | ||
/** | ||
* Object of React components used to render different list item styles. | ||
* | ||
* The object has the shape `{listItemType: ReactComponent}`, where `listItemType` is the value | ||
* set in individual `listItem` attributes on blocks. | ||
* | ||
* Can also be set to a single React component, which would handle list items of _any_ type. | ||
*/ | ||
listItem: | ||
| Record<PortableTextListItemType, PortableTextListItemComponent | undefined> | ||
| PortableTextListItemComponent | ||
/** | ||
* Component to use for rendering "hard breaks", eg `\n` inside of text spans | ||
* Will by default render a `<br />`. Pass `false` to render as-is (`\n`) | ||
*/ | ||
hardBreak: ComponentType<{}> | false | ||
/** | ||
* React component used when encountering a mark type there is no registered component for | ||
* in the `components.marks` prop. | ||
*/ | ||
unknownMark: PortableTextMarkComponent | ||
/** | ||
* React component used when encountering an object type there is no registered component for | ||
* in the `components.types` prop. | ||
*/ | ||
unknownType: PortableTextComponent<UnknownNodeType> | ||
/** | ||
* React component used when encountering a block style there is no registered component for | ||
* in the `components.block` prop. Only used if `components.block` is an object. | ||
*/ | ||
unknownBlockStyle: PortableTextComponent<PortableTextBlock> | ||
/** | ||
* React component used when encountering a list style there is no registered component for | ||
* in the `components.list` prop. Only used if `components.list` is an object. | ||
*/ | ||
unknownList: PortableTextComponent<ReactPortableTextList> | ||
/** | ||
* React component used when encountering a list item style there is no registered component for | ||
* in the `components.listItem` prop. Only used if `components.listItem` is an object. | ||
*/ | ||
unknownListItem: PortableTextComponent<PortableTextListItemBlock> | ||
} | ||
export declare type PortableTextTypeComponent<V extends TypedObject = any> = ComponentType< | ||
PortableTextTypeComponentProps<V> | ||
> | ||
/** | ||
* Props received by any user-defined type in the input array that is not a text block | ||
* | ||
* @template T Type of data this component will receive in its `value` property | ||
*/ | ||
export declare type PortableTextTypeComponentProps<T> = Omit< | ||
PortableTextComponentProps<T>, | ||
'children' | ||
> | ||
/** | ||
* A virtual "list" node for Portable Text - not strictly part of Portable Text, | ||
* but generated by this library to ease the rendering of lists in HTML etc | ||
*/ | ||
export declare type ReactPortableTextList = ToolkitPortableTextList | ||
/** | ||
* A virtual "list item" node for Portable Text - not strictly any different from a | ||
* regular Portable Text Block, but we can guarantee that it has a `listItem` property. | ||
*/ | ||
export declare type ReactPortableTextListItem = ToolkitPortableTextListItem | ||
export declare interface Serializable<T> { | ||
node: T | ||
index: number | ||
isInline: boolean | ||
renderNode: NodeRenderer | ||
} | ||
export declare interface SerializedBlock { | ||
_key: string | ||
children: ReactNode | ||
index: number | ||
isInline: boolean | ||
node: PortableTextBlock | PortableTextListItemBlock | ||
} | ||
export {toPlainText} | ||
/** | ||
* Any node type that we can't identify - eg it has an `_type`, | ||
* but we don't know anything about its other properties | ||
*/ | ||
export declare type UnknownNodeType = | ||
| { | ||
[key: string]: unknown | ||
_type: string | ||
} | ||
| TypedObject | ||
export {} |
@@ -1,4 +0,497 @@ | ||
"use strict";var q=Object.defineProperty,j=Object.defineProperties;var H=Object.getOwnPropertyDescriptors;var L=Object.getOwnPropertySymbols;var $=Object.prototype.hasOwnProperty,C=Object.prototype.propertyIsEnumerable;var M=(e,t,n)=>t in e?q(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,E=(e,t)=>{for(var n in t||(t={}))$.call(t,n)&&M(e,n,t[n]);if(L)for(var n of L(t))C.call(t,n)&&M(e,n,t[n]);return e},P=(e,t)=>j(e,H(t));var S=(e,t)=>{var n={};for(var a in e)$.call(e,a)&&t.indexOf(a)<0&&(n[a]=e[a]);if(e!=null&&L)for(var a of L(e))t.indexOf(a)<0&&C.call(e,a)&&(n[a]=e[a]);return n};Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var y=require("@portabletext/toolkit"),w=require("react");function R(e){return e&&typeof e=="object"&&"default"in e?e:{default:e}}var l=R(w);function B(e,t){const d=t,{block:n,list:a,listItem:f,marks:h,types:I}=d,p=S(d,["block","list","listItem","marks","types"]);return E(P(E({},e),{block:_(e,t,"block"),list:_(e,t,"list"),listItem:_(e,t,"listItem"),marks:_(e,t,"marks"),types:_(e,t,"types")}),p)}function _(e,t,n){const a=t[n],f=e[n];return typeof a=="function"||a&&typeof f=="function"?a:a?E(E({},f),a):f}const A=({children:e,value:t})=>l.default.createElement("a",{href:t==null?void 0:t.href},e),z={textDecoration:"underline"},F={em:({children:e})=>l.default.createElement("em",null,e),strong:({children:e})=>l.default.createElement("strong",null,e),code:({children:e})=>l.default.createElement("code",null,e),underline:({children:e})=>l.default.createElement("span",{style:z},e),"strike-through":({children:e})=>l.default.createElement("del",null,e),link:A},K={number:({children:e})=>l.default.createElement("ol",null,e),bullet:({children:e})=>l.default.createElement("ul",null,e)},O=({children:e})=>l.default.createElement("li",null,e),x=(e,t)=>`Unknown ${e}, specify a component for it in the \`components.${t}\` prop`,U=e=>x(`block type "${e}"`,"types"),V=e=>x(`mark type "${e}"`,"marks"),G=e=>x(`block style "${e}"`,"block"),J=e=>x(`list style "${e}"`,"list"),Q=e=>x(`list item style "${e}"`,"listItem");function X(e){console.warn(e)}const N={display:"none"},Y=({value:e,isInline:t})=>{const n=U(e._type);return t?l.default.createElement("span",{style:N},n):l.default.createElement("div",{style:N},n)},Z=({markType:e,children:t})=>l.default.createElement("span",{className:`unknown__pt__mark__${e}`},t),ee=({children:e})=>l.default.createElement("p",null,e),te=({children:e})=>l.default.createElement("ul",null,e),ne=({children:e})=>l.default.createElement("li",null,e),le=()=>l.default.createElement("br",null),re={normal:({children:e})=>l.default.createElement("p",null,e),blockquote:({children:e})=>l.default.createElement("blockquote",null,e),h1:({children:e})=>l.default.createElement("h1",null,e),h2:({children:e})=>l.default.createElement("h2",null,e),h3:({children:e})=>l.default.createElement("h3",null,e),h4:({children:e})=>l.default.createElement("h4",null,e),h5:({children:e})=>l.default.createElement("h5",null,e),h6:({children:e})=>l.default.createElement("h6",null,e)},D={types:{},block:re,marks:F,list:K,listItem:O,hardBreak:le,unknownType:Y,unknownMark:Z,unknownList:te,unknownListItem:ne,unknownBlockStyle:ee},g=w.createContext(D),oe=({components:e,children:t})=>{const n=w.useMemo(()=>B(D,e),[e]);return l.default.createElement(g.Provider,{value:n},t)};function ae({value:e,components:t,listNestingMode:n,onMissingComponent:a=X}){const f=a||se,h=Array.isArray(e)?e:[e],I=y.nestLists(h,n||y.LIST_NEST_MODE_HTML),p=w.useContext(g),d=w.useMemo(()=>t?B(p,t):p,[p,t]),r=w.useMemo(()=>ue(d,f),[d,f]),o=I.map((s,c)=>r({node:s,index:c,isInline:!1,renderNode:r}));return t?l.default.createElement(g.Provider,{value:d},o):l.default.createElement(l.default.Fragment,null,o)}const ue=(e,t)=>{function n(r){const{node:o,index:s,isInline:c}=r,u=o._key||`node-${s}`;return y.isPortableTextToolkitList(o)?f(o,s,u):y.isPortableTextListItemBlock(o)?a(o,s,u):y.isPortableTextToolkitSpan(o)?h(o,s,u):y.isPortableTextBlock(o)?I(o,s,u,c):y.isPortableTextToolkitTextNode(o)?p(o,u):d(o,s,u,c)}function a(r,o,s){const c=v({node:r,index:o,isInline:!1,renderNode:n}),u=e.listItem,i=(typeof u=="function"?u:u[r.listItem])||e.unknownListItem;if(i===e.unknownListItem){const T=r.listItem||"bullet";t(Q(T),{type:T,nodeType:"listItemStyle"})}let k=c.children;if(r.style&&r.style!=="normal"){const b=r,{listItem:T}=b,W=S(b,["listItem"]);k=n({node:W,index:o,isInline:!1,renderNode:n})}return l.default.createElement(i,{key:s,value:r,index:o,isInline:!1,renderNode:n},k)}function f(r,o,s){const c=r.children.map((k,b)=>n({node:k._key?k:P(E({},k),{_key:`li-${o}-${b}`}),index:o,isInline:!1,renderNode:n})),u=e.list,i=(typeof u=="function"?u:u[r.listItem])||e.unknownList;if(i===e.unknownList){const k=r.listItem||"bullet";t(J(k),{nodeType:"listStyle",type:k})}return l.default.createElement(i,{key:s,value:r,index:o,isInline:!1,renderNode:n},c)}function h(r,o,s){const{markDef:c,markType:u,markKey:m}=r,i=e.marks[u]||e.unknownMark,k=r.children.map((b,T)=>n({node:b,index:T,isInline:!0,renderNode:n}));return i===e.unknownMark&&t(V(u),{nodeType:"mark",type:u}),l.default.createElement(i,{key:s,text:y.spanToPlainText(r),value:c,markType:u,markKey:m,renderNode:n},k)}function I(r,o,s,c){const T=v({node:r,index:o,isInline:c,renderNode:n}),{_key:u}=T,m=S(T,["_key"]),i=m.node.style||"normal",b=(typeof e.block=="function"?e.block:e.block[i])||e.unknownBlockStyle;return b===e.unknownBlockStyle&&t(G(i),{nodeType:"blockStyle",type:i}),l.default.createElement(b,P(E({key:s},m),{value:m.node,renderNode:n}))}function p(r,o){if(r.text===` | ||
`){const s=e.hardBreak;return s?l.default.createElement(s,{key:o}):` | ||
`}return r.text}function d(r,o,s,c){const u=e.types[r._type],m={value:r,isInline:c,index:o,renderNode:n};if(u)return l.default.createElement(u,E({key:s},m));t(U(r._type),{nodeType:"block",type:r._type});const i=e.unknownType;return l.default.createElement(i,E({key:s},m))}return n};function v(e){const{node:t,index:n,isInline:a,renderNode:f}=e,I=y.buildMarksTree(t).map((p,d)=>f({node:p,isInline:!0,index:d,renderNode:f}));return{_key:t._key||`block-${n}`,children:I,index:n,isInline:a,node:t}}function se(){}Object.defineProperty(exports,"toPlainText",{enumerable:!0,get:function(){return y.toPlainText}});exports.PortableText=ae;exports.PortableTextComponentsProvider=oe;exports.defaultComponents=D;exports.mergeComponents=B; | ||
'use strict'; | ||
const _excluded = ["block", "list", "listItem", "marks", "types"], | ||
_excluded2 = ["listItem"], | ||
_excluded3 = ["_key"]; | ||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } | ||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } | ||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } | ||
Object.defineProperty(exports, '__esModule', { | ||
value: true | ||
}); | ||
var toolkit = require('@portabletext/toolkit'); | ||
var jsxRuntime = require('react/jsx-runtime'); | ||
var react = require('react'); | ||
function mergeComponents(parent, overrides) { | ||
const { | ||
block, | ||
list, | ||
listItem, | ||
marks, | ||
types | ||
} = overrides, | ||
rest = _objectWithoutProperties(overrides, _excluded); | ||
return _objectSpread(_objectSpread({}, parent), {}, { | ||
block: mergeDeeply(parent, overrides, "block"), | ||
list: mergeDeeply(parent, overrides, "list"), | ||
listItem: mergeDeeply(parent, overrides, "listItem"), | ||
marks: mergeDeeply(parent, overrides, "marks"), | ||
types: mergeDeeply(parent, overrides, "types") | ||
}, rest); | ||
} | ||
function mergeDeeply(parent, overrides, key) { | ||
const override = overrides[key]; | ||
const parentVal = parent[key]; | ||
if (typeof override === "function") { | ||
return override; | ||
} | ||
if (override && typeof parentVal === "function") { | ||
return override; | ||
} | ||
if (override) { | ||
return _objectSpread(_objectSpread({}, parentVal), override); | ||
} | ||
return parentVal; | ||
} | ||
const link = _ref => { | ||
let { | ||
children, | ||
value | ||
} = _ref; | ||
return /* @__PURE__ */jsxRuntime.jsx("a", { | ||
href: value == null ? void 0 : value.href, | ||
children | ||
}); | ||
}; | ||
const underlineStyle = { | ||
textDecoration: "underline" | ||
}; | ||
const defaultMarks = { | ||
em: _ref2 => { | ||
let { | ||
children | ||
} = _ref2; | ||
return /* @__PURE__ */jsxRuntime.jsx("em", { | ||
children | ||
}); | ||
}, | ||
strong: _ref3 => { | ||
let { | ||
children | ||
} = _ref3; | ||
return /* @__PURE__ */jsxRuntime.jsx("strong", { | ||
children | ||
}); | ||
}, | ||
code: _ref4 => { | ||
let { | ||
children | ||
} = _ref4; | ||
return /* @__PURE__ */jsxRuntime.jsx("code", { | ||
children | ||
}); | ||
}, | ||
underline: _ref5 => { | ||
let { | ||
children | ||
} = _ref5; | ||
return /* @__PURE__ */jsxRuntime.jsx("span", { | ||
style: underlineStyle, | ||
children | ||
}); | ||
}, | ||
"strike-through": _ref6 => { | ||
let { | ||
children | ||
} = _ref6; | ||
return /* @__PURE__ */jsxRuntime.jsx("del", { | ||
children | ||
}); | ||
}, | ||
link | ||
}; | ||
const defaultLists = { | ||
number: _ref7 => { | ||
let { | ||
children | ||
} = _ref7; | ||
return /* @__PURE__ */jsxRuntime.jsx("ol", { | ||
children | ||
}); | ||
}, | ||
bullet: _ref8 => { | ||
let { | ||
children | ||
} = _ref8; | ||
return /* @__PURE__ */jsxRuntime.jsx("ul", { | ||
children | ||
}); | ||
} | ||
}; | ||
const DefaultListItem = _ref9 => { | ||
let { | ||
children | ||
} = _ref9; | ||
return /* @__PURE__ */jsxRuntime.jsx("li", { | ||
children | ||
}); | ||
}; | ||
const getTemplate = (type, prop) => "[@portabletext/react] Unknown ".concat(type, ", specify a component for it in the `components.").concat(prop, "` prop"); | ||
const unknownTypeWarning = typeName => getTemplate("block type \"".concat(typeName, "\""), "types"); | ||
const unknownMarkWarning = markType => getTemplate("mark type \"".concat(markType, "\""), "marks"); | ||
const unknownBlockStyleWarning = blockStyle => getTemplate("block style \"".concat(blockStyle, "\""), "block"); | ||
const unknownListStyleWarning = listStyle => getTemplate("list style \"".concat(listStyle, "\""), "list"); | ||
const unknownListItemStyleWarning = listStyle => getTemplate("list item style \"".concat(listStyle, "\""), "listItem"); | ||
function printWarning(message) { | ||
console.warn(message); | ||
} | ||
const hidden = { | ||
display: "none" | ||
}; | ||
const DefaultUnknownType = _ref10 => { | ||
let { | ||
value, | ||
isInline | ||
} = _ref10; | ||
const warning = unknownTypeWarning(value._type); | ||
return isInline ? /* @__PURE__ */jsxRuntime.jsx("span", { | ||
style: hidden, | ||
children: warning | ||
}) : /* @__PURE__ */jsxRuntime.jsx("div", { | ||
style: hidden, | ||
children: warning | ||
}); | ||
}; | ||
const DefaultUnknownMark = _ref11 => { | ||
let { | ||
markType, | ||
children | ||
} = _ref11; | ||
return /* @__PURE__ */jsxRuntime.jsx("span", { | ||
className: "unknown__pt__mark__".concat(markType), | ||
children | ||
}); | ||
}; | ||
const DefaultUnknownBlockStyle = _ref12 => { | ||
let { | ||
children | ||
} = _ref12; | ||
return /* @__PURE__ */jsxRuntime.jsx("p", { | ||
children | ||
}); | ||
}; | ||
const DefaultUnknownList = _ref13 => { | ||
let { | ||
children | ||
} = _ref13; | ||
return /* @__PURE__ */jsxRuntime.jsx("ul", { | ||
children | ||
}); | ||
}; | ||
const DefaultUnknownListItem = _ref14 => { | ||
let { | ||
children | ||
} = _ref14; | ||
return /* @__PURE__ */jsxRuntime.jsx("li", { | ||
children | ||
}); | ||
}; | ||
const DefaultHardBreak = () => /* @__PURE__ */jsxRuntime.jsx("br", {}); | ||
const defaultBlockStyles = { | ||
normal: _ref15 => { | ||
let { | ||
children | ||
} = _ref15; | ||
return /* @__PURE__ */jsxRuntime.jsx("p", { | ||
children | ||
}); | ||
}, | ||
blockquote: _ref16 => { | ||
let { | ||
children | ||
} = _ref16; | ||
return /* @__PURE__ */jsxRuntime.jsx("blockquote", { | ||
children | ||
}); | ||
}, | ||
h1: _ref17 => { | ||
let { | ||
children | ||
} = _ref17; | ||
return /* @__PURE__ */jsxRuntime.jsx("h1", { | ||
children | ||
}); | ||
}, | ||
h2: _ref18 => { | ||
let { | ||
children | ||
} = _ref18; | ||
return /* @__PURE__ */jsxRuntime.jsx("h2", { | ||
children | ||
}); | ||
}, | ||
h3: _ref19 => { | ||
let { | ||
children | ||
} = _ref19; | ||
return /* @__PURE__ */jsxRuntime.jsx("h3", { | ||
children | ||
}); | ||
}, | ||
h4: _ref20 => { | ||
let { | ||
children | ||
} = _ref20; | ||
return /* @__PURE__ */jsxRuntime.jsx("h4", { | ||
children | ||
}); | ||
}, | ||
h5: _ref21 => { | ||
let { | ||
children | ||
} = _ref21; | ||
return /* @__PURE__ */jsxRuntime.jsx("h5", { | ||
children | ||
}); | ||
}, | ||
h6: _ref22 => { | ||
let { | ||
children | ||
} = _ref22; | ||
return /* @__PURE__ */jsxRuntime.jsx("h6", { | ||
children | ||
}); | ||
} | ||
}; | ||
const defaultComponents = { | ||
types: {}, | ||
block: defaultBlockStyles, | ||
marks: defaultMarks, | ||
list: defaultLists, | ||
listItem: DefaultListItem, | ||
hardBreak: DefaultHardBreak, | ||
unknownType: DefaultUnknownType, | ||
unknownMark: DefaultUnknownMark, | ||
unknownList: DefaultUnknownList, | ||
unknownListItem: DefaultUnknownListItem, | ||
unknownBlockStyle: DefaultUnknownBlockStyle | ||
}; | ||
function PortableText(_ref23) { | ||
let { | ||
value: input, | ||
components: componentOverrides, | ||
listNestingMode, | ||
onMissingComponent: missingComponentHandler = printWarning | ||
} = _ref23; | ||
const handleMissingComponent = missingComponentHandler || noop; | ||
const blocks = Array.isArray(input) ? input : [input]; | ||
const nested = toolkit.nestLists(blocks, listNestingMode || toolkit.LIST_NEST_MODE_HTML); | ||
const components = react.useMemo(() => { | ||
return componentOverrides ? mergeComponents(defaultComponents, componentOverrides) : defaultComponents; | ||
}, [componentOverrides]); | ||
const renderNode = react.useMemo(() => getNodeRenderer(components, handleMissingComponent), [components, handleMissingComponent]); | ||
const rendered = nested.map((node, index) => renderNode({ | ||
node, | ||
index, | ||
isInline: false, | ||
renderNode | ||
})); | ||
return /* @__PURE__ */jsxRuntime.jsx(jsxRuntime.Fragment, { | ||
children: rendered | ||
}); | ||
} | ||
const getNodeRenderer = (components, handleMissingComponent) => { | ||
function renderNode(options) { | ||
const { | ||
node, | ||
index, | ||
isInline | ||
} = options; | ||
const key = node._key || "node-".concat(index); | ||
if (toolkit.isPortableTextToolkitList(node)) { | ||
return renderList(node, index, key); | ||
} | ||
if (toolkit.isPortableTextListItemBlock(node)) { | ||
return renderListItem(node, index, key); | ||
} | ||
if (toolkit.isPortableTextToolkitSpan(node)) { | ||
return renderSpan(node, index, key); | ||
} | ||
if (toolkit.isPortableTextBlock(node)) { | ||
return renderBlock(node, index, key, isInline); | ||
} | ||
if (toolkit.isPortableTextToolkitTextNode(node)) { | ||
return renderText(node, key); | ||
} | ||
return renderCustomBlock(node, index, key, isInline); | ||
} | ||
function renderListItem(node, index, key) { | ||
const tree = serializeBlock({ | ||
node, | ||
index, | ||
isInline: false, | ||
renderNode | ||
}); | ||
const renderer = components.listItem; | ||
const handler = typeof renderer === "function" ? renderer : renderer[node.listItem]; | ||
const Li = handler || components.unknownListItem; | ||
if (Li === components.unknownListItem) { | ||
const style = node.listItem || "bullet"; | ||
handleMissingComponent(unknownListItemStyleWarning(style), { | ||
type: style, | ||
nodeType: "listItemStyle" | ||
}); | ||
} | ||
let children = tree.children; | ||
if (node.style && node.style !== "normal") { | ||
const { | ||
listItem | ||
} = node, | ||
blockNode = _objectWithoutProperties(node, _excluded2); | ||
children = renderNode({ | ||
node: blockNode, | ||
index, | ||
isInline: false, | ||
renderNode | ||
}); | ||
} | ||
return /* @__PURE__ */jsxRuntime.jsx(Li, { | ||
value: node, | ||
index, | ||
isInline: false, | ||
renderNode, | ||
children | ||
}, key); | ||
} | ||
function renderList(node, index, key) { | ||
const children = node.children.map((child, childIndex) => renderNode({ | ||
node: child._key ? child : _objectSpread(_objectSpread({}, child), {}, { | ||
_key: "li-".concat(index, "-").concat(childIndex) | ||
}), | ||
index, | ||
isInline: false, | ||
renderNode | ||
})); | ||
const component = components.list; | ||
const handler = typeof component === "function" ? component : component[node.listItem]; | ||
const List = handler || components.unknownList; | ||
if (List === components.unknownList) { | ||
const style = node.listItem || "bullet"; | ||
handleMissingComponent(unknownListStyleWarning(style), { | ||
nodeType: "listStyle", | ||
type: style | ||
}); | ||
} | ||
return /* @__PURE__ */jsxRuntime.jsx(List, { | ||
value: node, | ||
index, | ||
isInline: false, | ||
renderNode, | ||
children | ||
}, key); | ||
} | ||
function renderSpan(node, _index, key) { | ||
const { | ||
markDef, | ||
markType, | ||
markKey | ||
} = node; | ||
const Span = components.marks[markType] || components.unknownMark; | ||
const children = node.children.map((child, childIndex) => renderNode({ | ||
node: child, | ||
index: childIndex, | ||
isInline: true, | ||
renderNode | ||
})); | ||
if (Span === components.unknownMark) { | ||
handleMissingComponent(unknownMarkWarning(markType), { | ||
nodeType: "mark", | ||
type: markType | ||
}); | ||
} | ||
return /* @__PURE__ */jsxRuntime.jsx(Span, { | ||
text: toolkit.spanToPlainText(node), | ||
value: markDef, | ||
markType, | ||
markKey, | ||
renderNode, | ||
children | ||
}, key); | ||
} | ||
function renderBlock(node, index, key, isInline) { | ||
const _serializeBlock = serializeBlock({ | ||
node, | ||
index, | ||
isInline, | ||
renderNode | ||
}), | ||
{ | ||
_key | ||
} = _serializeBlock, | ||
props = _objectWithoutProperties(_serializeBlock, _excluded3); | ||
const style = props.node.style || "normal"; | ||
const handler = typeof components.block === "function" ? components.block : components.block[style]; | ||
const Block = handler || components.unknownBlockStyle; | ||
if (Block === components.unknownBlockStyle) { | ||
handleMissingComponent(unknownBlockStyleWarning(style), { | ||
nodeType: "blockStyle", | ||
type: style | ||
}); | ||
} | ||
return /* @__PURE__ */jsxRuntime.jsx(Block, _objectSpread(_objectSpread({}, props), {}, { | ||
value: props.node, | ||
renderNode | ||
}), key); | ||
} | ||
function renderText(node, key) { | ||
if (node.text === "\n") { | ||
const HardBreak = components.hardBreak; | ||
return HardBreak ? /* @__PURE__ */jsxRuntime.jsx(HardBreak, {}, key) : "\n"; | ||
} | ||
return node.text; | ||
} | ||
function renderCustomBlock(node, index, key, isInline) { | ||
const Node = components.types[node._type]; | ||
const nodeOptions = { | ||
value: node, | ||
isInline, | ||
index, | ||
renderNode | ||
}; | ||
if (Node) { | ||
return /* @__PURE__ */jsxRuntime.jsx(Node, _objectSpread({}, nodeOptions), key); | ||
} | ||
handleMissingComponent(unknownTypeWarning(node._type), { | ||
nodeType: "block", | ||
type: node._type | ||
}); | ||
const UnknownType = components.unknownType; | ||
return /* @__PURE__ */jsxRuntime.jsx(UnknownType, _objectSpread({}, nodeOptions), key); | ||
} | ||
return renderNode; | ||
}; | ||
function serializeBlock(options) { | ||
const { | ||
node, | ||
index, | ||
isInline, | ||
renderNode | ||
} = options; | ||
const tree = toolkit.buildMarksTree(node); | ||
const children = tree.map((child, i) => renderNode({ | ||
node: child, | ||
isInline: true, | ||
index: i, | ||
renderNode | ||
})); | ||
return { | ||
_key: node._key || "block-".concat(index), | ||
children, | ||
index, | ||
isInline, | ||
node | ||
}; | ||
} | ||
function noop() {} | ||
Object.defineProperty(exports, 'toPlainText', { | ||
enumerable: true, | ||
get: function () { | ||
return toolkit.toPlainText; | ||
} | ||
}); | ||
exports.PortableText = PortableText; | ||
exports.defaultComponents = defaultComponents; | ||
exports.mergeComponents = mergeComponents; | ||
//# sourceMappingURL=react-portable-text.js.map |
{ | ||
"name": "@portabletext/react", | ||
"version": "1.0.6", | ||
"version": "2.0.0", | ||
"description": "Render Portable Text with React", | ||
"types": "./dist/react-portable-text.d.ts", | ||
"source": "./src/index.ts", | ||
"module": "./dist/react-portable-text.esm.js", | ||
"main": "./dist/react-portable-text.js", | ||
"module": "./dist/react-portable-text.mjs", | ||
"exports": { | ||
".": { | ||
"import": "./dist/react-portable-text.mjs", | ||
"require": "./dist/react-portable-text.js" | ||
"types": "./dist/react-portable-text.d.ts", | ||
"source": "./src/index.ts", | ||
"import": "./dist/react-portable-text.esm.js", | ||
"require": "./dist/react-portable-text.js", | ||
"default": "./dist/react-portable-text.esm.js" | ||
} | ||
}, | ||
"sideEffects": false, | ||
"engines": { | ||
"node": "^14.13.1 || >=16.0.0" | ||
}, | ||
"files": [ | ||
"dist", | ||
"!dist/stats.html", | ||
"src", | ||
"README.md" | ||
"src" | ||
], | ||
@@ -24,3 +31,4 @@ "scripts": { | ||
"build:demo": "vite build demo --config=./vite.config.demo.ts --base=/react-portabletext/", | ||
"build": "vite build", | ||
"build": "rimraf dist && pkg-utils build && pkg-utils --strict", | ||
"dev": "vite demo", | ||
"start": "vite demo", | ||
@@ -41,34 +49,35 @@ "test": "tap test/*.test.*", | ||
"dependencies": { | ||
"@portabletext/toolkit": "^1.0.5", | ||
"@portabletext/types": "^1.0.3" | ||
"@portabletext/toolkit": "^2.0.0", | ||
"@portabletext/types": "^2.0.0" | ||
}, | ||
"devDependencies": { | ||
"@rexxars/vite-dts": "^1.0.4", | ||
"@sanity/ui": "^0.37.7", | ||
"@types/leaflet": "^1.7.9", | ||
"@types/react": "^17.0.44", | ||
"@types/react-dom": "^17.0.15", | ||
"@sanity/pkg-utils": "^1.15.0", | ||
"@sanity/ui": "1.0.0-beta.32", | ||
"@types/leaflet": "^1.9.0", | ||
"@types/react": "^18.0.24", | ||
"@types/react-dom": "^18.0.8", | ||
"@types/refractor": "^3.0.2", | ||
"@types/styled-components": "^5.1.25", | ||
"@types/tap": "^15.0.6", | ||
"@types/styled-components": "^5.1.26", | ||
"@types/tap": "^15.0.7", | ||
"@types/ws": "^8.5.3", | ||
"@typescript-eslint/eslint-plugin": "^5.18.0", | ||
"@typescript-eslint/parser": "^5.18.0", | ||
"@typescript-eslint/eslint-plugin": "^5.42.0", | ||
"@typescript-eslint/parser": "^5.42.0", | ||
"esbuild-register": "^3.3.2", | ||
"eslint": "^8.13.0", | ||
"eslint": "^8.26.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint-config-sanity": "^6.0.0", | ||
"eslint-plugin-react": "^7.29.4", | ||
"leaflet": "^1.7.1", | ||
"eslint-plugin-react": "^7.31.10", | ||
"leaflet": "^1.9.2", | ||
"prettier": "^2.6.2", | ||
"react": "^17.0.0", | ||
"react-dom": "^17.0.0", | ||
"react-leaflet": "^3.2.5", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"react-leaflet": "^4.1.0", | ||
"react-refractor": "^2.1.7", | ||
"refractor": "^3.6.0", | ||
"rollup-plugin-visualizer": "^5.6.0", | ||
"styled-components": "^5.3.5", | ||
"tap": "^16.0.1", | ||
"refractor": "^4.8.0", | ||
"rimraf": "^3.0.2", | ||
"rollup-plugin-visualizer": "^5.8.3", | ||
"styled-components": "^5.3.6", | ||
"tap": "^16.3.0", | ||
"typescript": "^4.6.3", | ||
"vite": "^2.9.1" | ||
"vite": "^3.2.2" | ||
}, | ||
@@ -75,0 +84,0 @@ "peerDependencies": { |
@@ -32,8 +32,6 @@ # @portabletext/react | ||
Default components are provided for all standard features of the Portable Text spec, with logical HTML defaults. You can pass an object of components to use, both to override the defaults and to provide components for your custom content types. This can be done in two ways: | ||
Default components are provided for all standard features of the Portable Text spec, with logical HTML defaults. You can pass an object of components to use, both to override the defaults and to provide components for your custom content types. | ||
### Passing a `components` prop | ||
Provided components will be merged with the defaults. In other words, you only need to provide the things you want to override. | ||
This overrides/provides components on a per-use basis, and will be merged with the defaults. In other words, you only need to provide the things you want to override. | ||
**Note**: Make sure the object does not change on every render - eg do not create the object within a React component, or if you do, use `useMemo` to ensure referential identity between renders for better performance. | ||
@@ -70,30 +68,2 @@ | ||
### Using a React context | ||
You can also use the `<PortableTextComponentsProvider>` to provide the same set of components to all `<PortableText>` instances below it in the tree. | ||
This is useful for recursive rendering as well as in cases where you have the same configuration for all/most uses. | ||
When using the context, the passed components gets merged with the defaults - you only need to provide overrides and components for custom types. | ||
**Note**: Make sure the object does not change on every render - eg do not create the object within a React component, or if you do, use `useMemo` to ensure referential identity between renders for better performance. | ||
```js | ||
import {PortableTextComponentsProvider, PortableText} from '@portabletext/react' | ||
const YourComponent = (props) => { | ||
return ( | ||
<PortableTextComponentsProvider components={myPortableTextComponents}> | ||
{/* The 2 PortableText instances below will receive the same custom components */} | ||
<div className="main-content"> | ||
<PortableText value={somePortableTextInput} /> | ||
</div> | ||
<div className="editor-notice"> | ||
<PortableText value={somePortableTextInput2} /> | ||
</div> | ||
</PortableTextComponentsProvider> | ||
) | ||
} | ||
``` | ||
## Available components | ||
@@ -198,3 +168,5 @@ | ||
// Ex. 2: rendering custom styles | ||
customHeading: ({children}) => <h2 className="text-lg text-primary text-purple-700">{children}</h2>, | ||
customHeading: ({children}) => ( | ||
<h2 className="text-lg text-primary text-purple-700">{children}</h2> | ||
), | ||
}, | ||
@@ -273,3 +245,3 @@ } | ||
When the library encounters a block, mark, list or list item with a type that is not known (eg it has no corresponding component in the `components` property or context), it will by default print a console warning. | ||
When the library encounters a block, mark, list or list item with a type that is not known (eg it has no corresponding component in the `components` property), it will by default print a console warning. | ||
@@ -276,0 +248,0 @@ To disable this behavior, you can either pass `false` to the `onMissingComponent` property, or give it a custom function you want to use to report the error. For instance: |
@@ -7,2 +7,1 @@ export * from './types' | ||
export {defaultComponents} from './components/defaults' | ||
export {PortableTextComponentsProvider} from './context' |
const getTemplate = (type: string, prop: string): string => | ||
`Unknown ${type}, specify a component for it in the \`components.${prop}\` prop` | ||
`[@portabletext/react] Unknown ${type}, specify a component for it in the \`components.${prop}\` prop` | ||
@@ -4,0 +4,0 @@ export const unknownTypeWarning = (typeName: string): string => |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
132500
1937
0
29
17
306
1
+ Added@portabletext/toolkit@2.0.16(transitive)
- Removed@portabletext/toolkit@1.0.8(transitive)
- Removed@portabletext/types@1.0.3(transitive)
Updated@portabletext/toolkit@^2.0.0
Updated@portabletext/types@^2.0.0