Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/prose/prose-example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ Now a nested list:

Do not bump wooden spoon or it will fall.

And here's a table, with column alignment:

| Item | Quantity | Price |
Comment thread
amix marked this conversation as resolved.
| ------- | :------: | ----: |
| Carrots | 3 | $1.20 |
| Celery | 1 | $0.95 |
| Lentils | 500g | $2.40 |

---

A horizontal rule follows.
Expand All @@ -82,3 +90,27 @@ A horizontal rule follows.

The End
`)

export const proseTableOverflowExample = marked(`
Tables whose content cannot wrap any further (e.g. long unbreakable links) scroll horizontally
instead of stretching the surrounding content:

| Resource | Reference |
| -------- | --------- |
| Prose styles | https://github.com/Doist/reactist/blob/main/src/prose/prose.module.css |
| Prose stories | https://github.com/Doist/reactist/blob/main/src/prose/prose.stories.tsx |
`)

export const proseTableColorsExample = marked(`
Consumers can give the header row and odd/even body rows their own background colors via the
\`--reactist-prose-table-header-fill\`, \`--reactist-prose-table-row-odd-fill\`, and
\`--reactist-prose-table-row-even-fill\` custom properties (all default to \`transparent\`):

| Item | Quantity | Price |
| ------- | :------: | ----: |
| Carrots | 3 | $1.20 |
| Celery | 1 | $0.95 |
| Lentils | 500g | $2.40 |
| Onions | 2 | $0.80 |
| Stock | 1L | $3.10 |
`)
69 changes: 69 additions & 0 deletions src/prose/prose.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
--reactist-prose-link-hover-underline: #006f85;

--reactist-prose-horizontal-rule-color: var(--reactist-divider-primary);

--reactist-prose-table-border: var(--reactist-divider-primary);

/* `transparent` (the initial value of `background-color`) rather than `initial`, which is
special-cased in custom property values to mean "guaranteed invalid", or `inherit`, which
backgrounds achieve through transparency rather than inheritance. */
--reactist-prose-table-header-fill: transparent;
--reactist-prose-table-row-odd-fill: transparent;
--reactist-prose-table-row-even-fill: transparent;
}

/* Internals for spacing. These are not considered public API. */
Expand Down Expand Up @@ -212,6 +221,66 @@
overflow: auto;
}

/* tables */

.prose table {
/* Let wide tables scroll horizontally instead of stretching the surrounding content. */
display: block;
width: max-content;
max-width: 100%;
overflow: auto;
Comment thread
amix marked this conversation as resolved.
margin-top: var(--reactist-prose-space-2);
border-collapse: collapse;

/* `.prose`'s `word-break: break-word` acts like `overflow-wrap: anywhere`, shrinking each
word's min-content width to a single character. That lets wide tables squeeze into
`max-width: 100%` by breaking words mid-word instead of overflowing into the scroll above. */
word-break: normal;
}

.prose th,
.prose td {
border: 1px solid var(--reactist-prose-table-border);
padding: calc(var(--reactist-prose-space-1) / 2) var(--reactist-prose-space-1);
}

/* The header fill goes on the row rather than `th` so that row headers in table bodies
(`<tbody><tr><th scope="row">…`) stripe with their row instead of picking up the header fill. */
.prose thead tr {
background-color: var(--reactist-prose-table-header-fill);
}

.prose tbody tr:nth-child(odd) {
background-color: var(--reactist-prose-table-row-odd-fill);
}

.prose tbody tr:nth-child(even) {
background-color: var(--reactist-prose-table-row-even-fill);
}

.prose th {
font-weight: 600;
}

/* Browsers center `th` by default; align with `td` instead. Markdown renderers express explicit
column alignment either as an inline `text-align` style (which wins over this rule) or as the
`align` attribute (which would lose to it, hence the `:not([align])` guard). */
.prose th:not([align]) {
text-align: start;
}

/* Markdown table cells hold inline content only, but raw HTML tables can nest block elements
(e.g. `<td><p>…</p></td>`), whose margins would add awkward vertical spacing. */
.prose th > :first-child,
.prose td > :first-child {
margin-top: 0;
}

.prose th > :last-child,
.prose td > :last-child {
margin-bottom: 0;
}

/* headings in relation to other tags */

.prose h1 + * {
Expand Down
51 changes: 50 additions & 1 deletion src/prose/prose.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as React from 'react'
import { Box } from '../box'

import { Prose } from './prose'
import { proseExample } from './prose-example'
import { proseExample, proseTableColorsExample, proseTableOverflowExample } from './prose-example'

import type { ProseProps } from './prose'

Expand Down Expand Up @@ -68,3 +68,52 @@ ProsePlaygroundStory.argTypes = {
dangerouslySetInnerHTML: { control: false },
exceptionallySetClassName: { control: false },
}

//
// Table overflow
//

export function ProseTableOverflowStory() {
// The narrow container guarantees the table overflows into a horizontal scroll at any
// viewport size, so the snapshot exercises the scrolling layout deterministically.
return (
<Box padding="xlarge" style={{ maxWidth: 400 }}>
<Prose
darkModeTypography={false}
dangerouslySetInnerHTML={{ __html: proseTableOverflowExample }}
/>
</Box>
)
}

ProseTableOverflowStory.storyName = 'Table overflow'
ProseTableOverflowStory.parameters = {
chromatic: { disableSnapshot: false },
}

//
// Table colors
//

export function ProseTableColorsStory() {
return (
<Box
padding="xlarge"
style={{
// @ts-expect-error
'--reactist-prose-table-header-fill': 'rgb(233, 239, 242)',
'--reactist-prose-table-row-even-fill': 'rgb(247, 250, 251)',
}}
>
<Prose
darkModeTypography={false}
dangerouslySetInnerHTML={{ __html: proseTableColorsExample }}
/>
</Box>
)
}

ProseTableColorsStory.storyName = 'Table colors'
ProseTableColorsStory.parameters = {
chromatic: { disableSnapshot: false },
}
Loading