Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 100x 605x 144x 144x 1x 144x 144x 9x 144x 100x 100x 100x 100x | import { ContentBlock } from "draft-js";
// The block-data → rendered-class contract shared by the editor (HFRichInput)
// and the read-only viewer (DocumentViewer). Passing a custom blockStyleFn
// replaces react-draft-wysiwyg's default one, which is what maps the
// `text-align` block data (written by the toolbar's Alignment buttons) to an
// `rdw-{align}-aligned-block` class — mirror that mapping or aligned blocks
// stop aligning.
export const buildBlockStyleFn =
({ paragraphSmall = true }: { paragraphSmall?: boolean } = {}) =>
(block: ContentBlock): string => {
const classes: string[] = [];
if (paragraphSmall && block.getType() === "paragraph-small") {
classes.push("rdw-paragraph-small");
}
const alignment = block.getData().get("text-align");
if (alignment) {
classes.push(`rdw-${alignment}-aligned-block`);
}
return classes.join(" ");
};
// react-draft-wysiwyg's stylesheet embeds Draft.css, whose
// `.public-DraftStyleDefault-ltr { text-align: left }` sits directly on the
// inner block div — beating the `text-align: … !important` the
// `rdw-*-aligned-block` classes put on the wrapper (a direct rule wins over
// an inherited one). Its `> div { display: inline-block }` trick only visibly
// aligns single-line blocks, so align the inner div itself or wrapped
// paragraphs stay left-aligned.
export const alignmentInnerDivSx = {
"& .rdw-left-aligned-block > div": { textAlign: "left" },
"& .rdw-center-aligned-block > div": { textAlign: "center" },
"& .rdw-right-aligned-block > div": { textAlign: "right" },
} as const;
// Wrapper rules for surfaces that never load react-draft-wysiwyg's stylesheet
// (public ToS/Privacy, agreement panels), where the rdw-* alignment classes
// are otherwise unstyled.
export const alignmentWrapperSx = {
"& .rdw-left-aligned-block": { textAlign: "left" },
"& .rdw-center-aligned-block": { textAlign: "center" },
"& .rdw-right-aligned-block": { textAlign: "right" },
} as const;
// Heading scale for authored documents (legal documents), shared by the editor
// and the read-only viewer so an author sees what a merchant is served.
//
// Without it headings fall back to the browser defaults, where h4–h6 are the
// same size as body text or smaller — a pasted agreement's deeper headings then
// read as ordinary paragraphs. The editor additionally forces `font-weight: 400`
// on every block element (see HFRichInput's Container), which is why a heading
// there looked lighter than the same heading in the viewer.
//
// Declared as literals rather than pulled from `theme.typography` because the
// viewer also renders on public pages (ToS / Privacy) that mount neither MUI
// theme provider.
export const documentHeadingSx = {
"& h1": { fontSize: "32px", fontWeight: 600 },
"& h2": { fontSize: "26px", fontWeight: 600 },
"& h3": { fontSize: "22px", fontWeight: 600 },
"& h4": { fontSize: "19px", fontWeight: 600 },
"& h5": { fontSize: "17px", fontWeight: 600 },
"& h6": { fontSize: "16px", fontWeight: 600 },
} as const;
// List rendering for the read-only viewer. The rich editor renders list items
// as a custom `div::before` bullet with the NATIVE marker suppressed — split
// across two stylesheets: TextEditor.css (`.editorClassName ul/ol` → the "•"
// / counter bullet, `list-style-position: inside`) and HFRichInput's Container
// (`.editorClassName li { list-style-type: none }`, specificity 0,2,1, which
// beats Draft.css's `disc` on the `<li>` at 0,2,0).
//
// The viewer shares the editor's `.editorClassName` (ReadOnlyEditor renders it
// too) and the detail page statically imports the editor, so TextEditor.css
// leaks onto the viewer — the "•" bullet AND `list-style-position: inside`. But
// the Container's disc-suppression does NOT (it's on the editor's wrapper), so
// Draft.css's native `disc` survives and `inside` pushes it onto its own line:
// a stray extra bullet, mis-indented, above each item. Mirror BOTH halves here,
// scoped to `.editorClassName` so `& .editorClassName li` (0,2,1) beats
// Draft.css. Self-sufficient: also renders correctly on viewer surfaces that
// never load TextEditor.css (public ToS/Privacy, agreement panels).
export const listStyleSx = {
// Suppress Draft.css's native `<li>` disc marker — the missing half that the
// editor gets from its Container. This is what removes the extra bullet.
"& .editorClassName li": {
counterIncrement: "count 1",
listStyleType: "none",
marginLeft: 0,
"&::before": { display: "none" },
},
"& .editorClassName ul, & .editorClassName ol": {
listStylePosition: "inside",
paddingLeft: 0,
listStyleType: "none",
// `count` is incremented on every <li> (incl. <ul> items). Reset it at each
// list container so ordered-list numbers restart at 1 per <ol> instead of
// running continuously across lists / being offset by preceding <ul> items.
counterReset: "count",
},
"& .editorClassName ul li > div::before": {
content: '"•"',
unicodeBidi: "isolate",
textTransform: "none",
textIndent: "0px !important",
textAlign: "start !important",
textAlignLast: "start !important",
marginRight: "5px",
},
"& .editorClassName ol li > div::before": {
content: 'counter(count) ". "',
unicodeBidi: "isolate",
textTransform: "none",
textIndent: "0px !important",
textAlign: "start !important",
textAlignLast: "start !important",
},
} as const;
|