oneslash-design-system 2.2.0 → 2.4.0
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 +19 -3
- package/dist/components/factsRow.d.ts +10 -0
- package/dist/components/factsRow.jsx +25 -0
- package/dist/components/figure.d.ts +14 -0
- package/dist/components/figure.jsx +12 -0
- package/dist/components/heading.d.ts +12 -0
- package/dist/components/heading.jsx +14 -0
- package/dist/components/layout.d.ts +23 -0
- package/dist/components/layout.jsx +33 -0
- package/dist/components/linkCard.d.ts +10 -0
- package/dist/components/linkCard.jsx +16 -0
- package/dist/components/list.d.ts +9 -0
- package/dist/components/list.jsx +10 -0
- package/dist/components/numberedRow.d.ts +14 -0
- package/dist/components/numberedRow.jsx +23 -0
- package/dist/components/pageHeader.d.ts +13 -0
- package/dist/components/pageHeader.jsx +18 -0
- package/dist/components/pageShell.d.ts +8 -0
- package/dist/components/pageShell.jsx +22 -0
- package/dist/components/paragraph.d.ts +13 -0
- package/dist/components/paragraph.jsx +16 -0
- package/dist/components/sectionIntro.d.ts +13 -0
- package/dist/components/sectionIntro.jsx +22 -0
- package/dist/components/surface.d.ts +14 -0
- package/dist/components/surface.jsx +19 -0
- package/dist/designTokens.d.ts +56 -4
- package/dist/designTokens.js +40 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/stories/PageComponents.stories.d.ts +6 -0
- package/dist/stories/PageComponents.stories.jsx +76 -0
- package/dist/tailwind-preset-auto.js +37 -5
- package/dist/tailwind-preset.js +37 -5
- package/dist/theme-auto.css +19 -0
- package/dist/theme.css +19 -0
- package/dist/themes/clay-auto.css +6 -0
- package/dist/themes/clay.css +4 -0
- package/dist/themes/default-auto.css +6 -0
- package/dist/themes/default.css +4 -0
- package/dist/themes/forest-auto.css +6 -0
- package/dist/themes/forest.css +4 -0
- package/dist/themes/indigo-auto.css +6 -0
- package/dist/themes/indigo.css +4 -0
- package/dist/themes/wine-auto.css +6 -0
- package/dist/themes/wine.css +4 -0
- package/dist/tokens.css +15 -0
- package/dist/typography.css +8 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,13 +15,13 @@ The package ships Tailwind class names, CSS variables and untranspiled `.jsx`. E
|
|
|
15
15
|
3. **Tailwind v4:** import `oneslash-design-system/theme.css` (toggle) or `theme-auto.css` (OS), plus `typography.css` if you want the type scale.
|
|
16
16
|
4. **Next.js:** `transpilePackages: ["oneslash-design-system"]` in `next.config`.
|
|
17
17
|
5. **Scan the components:** v3 `content` gets `./node_modules/oneslash-design-system/dist/**/*.{js,jsx}`; v4 CSS gets `@source "../node_modules/oneslash-design-system/dist/**/*.jsx";`.
|
|
18
|
-
6. **Load the fonts:** the package names Inter (`font-inter`) and
|
|
18
|
+
6. **Load the fonts:** the package names Inter (`font-inter`) and Fira Code (`font-mono`, for code, identifiers and type names; use it with `text-code`, the 14px weight-300 code style) but does not ship them. Load both under their real family names, for example with one Google Fonts link in `<head>`:
|
|
19
19
|
|
|
20
20
|
```html
|
|
21
|
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400&family=
|
|
21
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400&family=Fira+Code:wght@300;400&display=swap">
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
`next/font/google
|
|
24
|
+
Don't load Fira Code with `next/font/google`: it registers a generated family name, so `font-mono` would not find it. If your Content Security Policy blocks Google Fonts, self-host it with `@fontsource/fira-code` (import `latin-300.css` and `latin-400.css` in the root layout), which keeps the real family name.
|
|
25
25
|
|
|
26
26
|
```css
|
|
27
27
|
/* Tailwind v4, OS-driven dark mode */
|
|
@@ -34,6 +34,22 @@ The package ships Tailwind class names, CSS variables and untranspiled `.jsx`. E
|
|
|
34
34
|
|
|
35
35
|
Use class names that mean the same thing in Tailwind v3 and v4 inside components, since apps on both versions compile them.
|
|
36
36
|
|
|
37
|
+
## Building a page
|
|
38
|
+
|
|
39
|
+
2.4.0 adds what a page needs on top of the components, so a page can be written with no markup of its own: `PageShell` (the column and the space between sections), `PageHeader`, `SectionIntro`, `FactsRow`, `NumberedRow`, `Surface` (a panel, or a sheet of `paper`), `Figure`, `LinkCard`, `Heading`, `Paragraph`, `List`, and the layout helpers `Stack`, `Cluster`, `Grid` and `PageSection` in `components/layout`. Spacing has steps up to `page` (160px), text widths are `max-w-measure-*`, and the column is `max-w-page`. A Button in a `Stack` stretches to the full width, so put it in a `Cluster`.
|
|
40
|
+
|
|
41
|
+
```jsx
|
|
42
|
+
import PageShell from 'oneslash-design-system/components/pageShell';
|
|
43
|
+
import { PageSection } from 'oneslash-design-system/components/layout';
|
|
44
|
+
import SectionIntro from 'oneslash-design-system/components/sectionIntro';
|
|
45
|
+
|
|
46
|
+
<PageShell>
|
|
47
|
+
<PageSection>
|
|
48
|
+
<SectionIntro name="Origin" statement="Say the point of the section here." />
|
|
49
|
+
</PageSection>
|
|
50
|
+
</PageShell>
|
|
51
|
+
```
|
|
52
|
+
|
|
37
53
|
## Releasing
|
|
38
54
|
|
|
39
55
|
Bump `version` in `package.json`, run `npm run build`, and merge to `main`. The Release workflow runs the tests and `npm run check:contrast`, then publishes to npm, creates the tag and GitHub Release with notes from the merged PR titles, and updates the docs site.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Line from './line';
|
|
3
|
+
var columns = {
|
|
4
|
+
3: 'md:grid-cols-3',
|
|
5
|
+
4: 'md:grid-cols-4',
|
|
6
|
+
5: 'md:grid-cols-5',
|
|
7
|
+
};
|
|
8
|
+
// The few facts that sit under a title: small labels over small values,
|
|
9
|
+
// under a rule. Two across on a phone, one per fact from the medium breakpoint.
|
|
10
|
+
export default function FactsRow(_a) {
|
|
11
|
+
var items = _a.items;
|
|
12
|
+
var md = columns[Math.min(5, Math.max(3, items.length))];
|
|
13
|
+
return (<div className="flex flex-col gap-medium">
|
|
14
|
+
<Line />
|
|
15
|
+
<dl className={"grid grid-cols-2 gap-large text-body2 ".concat(md)}>
|
|
16
|
+
{items.map(function (_a) {
|
|
17
|
+
var label = _a.label, value = _a.value;
|
|
18
|
+
return (<div key={label}>
|
|
19
|
+
<dt className="text-fg-secondary">{label}</dt>
|
|
20
|
+
<dd className="text-fg-primary">{value}</dd>
|
|
21
|
+
</div>);
|
|
22
|
+
})}
|
|
23
|
+
</dl>
|
|
24
|
+
</div>);
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface FigureProps {
|
|
3
|
+
/** An image or a video. */
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
caption?: React.ReactNode;
|
|
6
|
+
/** Crop what is inside to this width over height, filling the frame. */
|
|
7
|
+
crop?: number;
|
|
8
|
+
/** Set it on a sheet of paper that stays light in dark mode, for scans and drawings in black. */
|
|
9
|
+
paper?: boolean;
|
|
10
|
+
radius?: 'control' | 'container';
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
export default function Figure({ children, caption, crop, paper, radius, className, }: FigureProps): React.JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
var radii = { control: 'rounded-control', container: 'rounded-container' };
|
|
3
|
+
export default function Figure(_a) {
|
|
4
|
+
var children = _a.children, caption = _a.caption, crop = _a.crop, _b = _a.paper, paper = _b === void 0 ? false : _b, _c = _a.radius, radius = _c === void 0 ? 'container' : _c, _d = _a.className, className = _d === void 0 ? '' : _d;
|
|
5
|
+
var frame = paper ? "bg-background-paper p-large md:p-xlarge ".concat(radii[radius]) : "overflow-hidden ".concat(radii[radius]);
|
|
6
|
+
return (<figure className={"flex flex-col gap-medium ".concat(className)}>
|
|
7
|
+
{crop ? (<div className={"relative overflow-hidden ".concat(radii[radius], " [&_img]:absolute [&_img]:inset-0 [&_img]:h-full [&_img]:w-full [&_img]:object-cover")} style={{ aspectRatio: crop }}>
|
|
8
|
+
{children}
|
|
9
|
+
</div>) : (<div className={frame}>{children}</div>)}
|
|
10
|
+
{caption && <figcaption className="text-body2 text-fg-secondary">{caption}</figcaption>}
|
|
11
|
+
</figure>);
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface HeadingProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
/** The element: h2 to h4. Pick the one that fits the page's outline, not the size. */
|
|
5
|
+
level?: 2 | 3 | 4;
|
|
6
|
+
/** How large it is set. */
|
|
7
|
+
size?: 'h4' | 'h5' | 'h6' | 'subtitle1';
|
|
8
|
+
id?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
export default function Heading({ children, level, size, id, className }: HeadingProps): React.JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
var sizes = {
|
|
3
|
+
h4: 'text-h4',
|
|
4
|
+
h5: 'text-h5',
|
|
5
|
+
h6: 'text-h6',
|
|
6
|
+
subtitle1: 'text-subtitle1',
|
|
7
|
+
};
|
|
8
|
+
export default function Heading(_a) {
|
|
9
|
+
var children = _a.children, _b = _a.level, level = _b === void 0 ? 3 : _b, _c = _a.size, size = _c === void 0 ? 'h6' : _c, id = _a.id, _d = _a.className, className = _d === void 0 ? '' : _d;
|
|
10
|
+
var Tag = "h".concat(level);
|
|
11
|
+
return (<Tag id={id} className={"".concat(sizes[size], " text-fg-primary ").concat(className)}>
|
|
12
|
+
{children}
|
|
13
|
+
</Tag>);
|
|
14
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type Gap = 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | 'huge' | 'giant';
|
|
3
|
+
interface LayoutProps {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
gap?: Gap;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
interface StackProps extends LayoutProps {
|
|
9
|
+
/** `stretch` gives every child the full width, which suits panels. `start` lets a child keep its own width, which a Button needs. */
|
|
10
|
+
align?: 'stretch' | 'start';
|
|
11
|
+
}
|
|
12
|
+
export declare function Stack({ children, gap, align, className }: StackProps): React.JSX.Element;
|
|
13
|
+
export declare function Cluster({ children, gap, className }: LayoutProps): React.JSX.Element;
|
|
14
|
+
interface GridProps extends LayoutProps {
|
|
15
|
+
/** How many columns from the medium breakpoint up. Below it: two for `compact`, otherwise one. */
|
|
16
|
+
columns?: 2 | 3 | 4;
|
|
17
|
+
compact?: boolean;
|
|
18
|
+
/** `stretch` makes the items in a row the same height; `start` lets each keep its own. */
|
|
19
|
+
align?: 'stretch' | 'start';
|
|
20
|
+
}
|
|
21
|
+
export declare function Grid({ children, columns, compact, align, gap, className }: GridProps): React.JSX.Element;
|
|
22
|
+
export declare function PageSection({ children, gap, className }: LayoutProps): React.JSX.Element;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
var gaps = {
|
|
3
|
+
small: 'gap-small',
|
|
4
|
+
medium: 'gap-medium',
|
|
5
|
+
large: 'gap-large',
|
|
6
|
+
xlarge: 'gap-xlarge',
|
|
7
|
+
xxlarge: 'gap-xxlarge',
|
|
8
|
+
huge: 'gap-huge',
|
|
9
|
+
giant: 'gap-giant',
|
|
10
|
+
};
|
|
11
|
+
// One column of things, a spacing token apart.
|
|
12
|
+
export function Stack(_a) {
|
|
13
|
+
var children = _a.children, _b = _a.gap, gap = _b === void 0 ? 'large' : _b, _c = _a.align, align = _c === void 0 ? 'stretch' : _c, _d = _a.className, className = _d === void 0 ? '' : _d;
|
|
14
|
+
return <div className={"flex flex-col ".concat(align === 'start' ? 'items-start' : '', " ").concat(gaps[gap], " ").concat(className)}>{children}</div>;
|
|
15
|
+
}
|
|
16
|
+
// Things that sit in a row and wrap, a spacing token apart.
|
|
17
|
+
export function Cluster(_a) {
|
|
18
|
+
var children = _a.children, _b = _a.gap, gap = _b === void 0 ? 'medium' : _b, _c = _a.className, className = _c === void 0 ? '' : _c;
|
|
19
|
+
return <div className={"flex flex-wrap items-center ".concat(gaps[gap], " ").concat(className)}>{children}</div>;
|
|
20
|
+
}
|
|
21
|
+
var mdColumns = { 2: 'md:grid-cols-2', 3: 'md:grid-cols-3', 4: 'md:grid-cols-4' };
|
|
22
|
+
export function Grid(_a) {
|
|
23
|
+
var children = _a.children, _b = _a.columns, columns = _b === void 0 ? 2 : _b, _c = _a.compact, compact = _c === void 0 ? false : _c, _d = _a.align, align = _d === void 0 ? 'stretch' : _d, _e = _a.gap, gap = _e === void 0 ? 'large' : _e, _f = _a.className, className = _f === void 0 ? '' : _f;
|
|
24
|
+
return (<div className={"grid ".concat(compact ? 'grid-cols-2' : 'grid-cols-1', " ").concat(mdColumns[columns], " ").concat(align === 'start' ? 'items-start' : '', " ").concat(gaps[gap], " ").concat(className)}>
|
|
25
|
+
{children}
|
|
26
|
+
</div>);
|
|
27
|
+
}
|
|
28
|
+
// A section of a page: a column of its parts. The first child is usually a SectionIntro.
|
|
29
|
+
// Children take the full width; put a Button in a Cluster so it keeps its own.
|
|
30
|
+
export function PageSection(_a) {
|
|
31
|
+
var children = _a.children, _b = _a.gap, gap = _b === void 0 ? 'huge' : _b, _c = _a.className, className = _c === void 0 ? '' : _c;
|
|
32
|
+
return <section className={"flex flex-col ".concat(gaps[gap], " ").concat(className)}>{children}</section>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface LinkCardProps {
|
|
3
|
+
href: string;
|
|
4
|
+
title: string;
|
|
5
|
+
/** A small line under the title, in the mono face. */
|
|
6
|
+
caption?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
export default function LinkCard({ href, title, caption, className }: LinkCardProps): React.JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import NextLink from 'next/link';
|
|
4
|
+
import Icon from './icon';
|
|
5
|
+
import { focusRing } from './sharedStyles';
|
|
6
|
+
// A link set as a card: the title, a caption, and an arrow that moves off the corner.
|
|
7
|
+
export default function LinkCard(_a) {
|
|
8
|
+
var href = _a.href, title = _a.title, caption = _a.caption, _b = _a.className, className = _b === void 0 ? '' : _b;
|
|
9
|
+
return (<NextLink href={href} className={"group flex items-center justify-between gap-xxlarge rounded-container bg-background-panel p-large transition-colors hover:bg-background-accent200 motion-reduce:transition-none ".concat(focusRing, " ").concat(className)}>
|
|
10
|
+
<span className="flex flex-col gap-small">
|
|
11
|
+
<span className="text-subtitle1 text-fg-primary">{title}</span>
|
|
12
|
+
{caption && <span className="font-mono text-caption text-fg-secondary">{caption}</span>}
|
|
13
|
+
</span>
|
|
14
|
+
<Icon name="ArrowUpRight" size="small" color="secondary" className="shrink-0 transition-transform group-hover:-translate-y-0.5 group-hover:translate-x-0.5 motion-reduce:transition-none"/>
|
|
15
|
+
</NextLink>);
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface ListProps {
|
|
3
|
+
items: React.ReactNode[];
|
|
4
|
+
size?: 'body1' | 'body2';
|
|
5
|
+
tone?: 'primary' | 'secondary';
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
export default function List({ items, size, tone, className }: ListProps): React.JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
var sizes = { body1: 'text-body1', body2: 'text-body2' };
|
|
3
|
+
var tones = { primary: 'text-fg-primary', secondary: 'text-fg-secondary' };
|
|
4
|
+
// A plain list, one line of text per item, a little apart.
|
|
5
|
+
export default function List(_a) {
|
|
6
|
+
var items = _a.items, _b = _a.size, size = _b === void 0 ? 'body2' : _b, _c = _a.tone, tone = _c === void 0 ? 'primary' : _c, _d = _a.className, className = _d === void 0 ? '' : _d;
|
|
7
|
+
return (<ul className={"flex flex-col gap-medium ".concat(sizes[size], " ").concat(tones[tone], " ").concat(className)}>
|
|
8
|
+
{items.map(function (item, i) { return (<li key={i}>{item}</li>); })}
|
|
9
|
+
</ul>);
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface NumberedRowProps {
|
|
3
|
+
/** Starts at 0; shown as 01, 02. */
|
|
4
|
+
index: number;
|
|
5
|
+
title: string;
|
|
6
|
+
/** What the row says: paragraphs, links. */
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
/** One line with a check, for what the row comes to. */
|
|
9
|
+
proof?: string;
|
|
10
|
+
/** What the row is about, shown beside it on wide windows and under it otherwise. */
|
|
11
|
+
visual?: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
export default function NumberedRow({ index, title, children, proof, visual }: NumberedRowProps): React.JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Icon from './icon';
|
|
3
|
+
import Surface from './surface';
|
|
4
|
+
// A numbered row with the thing it is about beside it. From the 2xl breakpoint
|
|
5
|
+
// the two sit side by side and swap sides each row; below it the visual sits
|
|
6
|
+
// under the text. A row with nothing to show is text alone.
|
|
7
|
+
export default function NumberedRow(_a) {
|
|
8
|
+
var index = _a.index, title = _a.title, children = _a.children, proof = _a.proof, visual = _a.visual;
|
|
9
|
+
return (<article className={"grid grid-cols-1 items-center gap-xxlarge ".concat(visual ? '2xl:grid-cols-2 2xl:gap-giant' : '')}>
|
|
10
|
+
<div className={"flex flex-col gap-large ".concat(visual && index % 2 === 1 ? '2xl:order-2' : '')}>
|
|
11
|
+
<span className="font-mono text-body2 text-fg-secondary">{String(index + 1).padStart(2, '0')}</span>
|
|
12
|
+
<h3 className="text-h5 text-fg-primary md:text-h4">{title}</h3>
|
|
13
|
+
{children && (<div className="flex max-w-measure-body flex-col gap-large text-body1 text-fg-secondary">{children}</div>)}
|
|
14
|
+
{proof && (<p className="flex items-start gap-medium text-body2 text-fg-primary">
|
|
15
|
+
<Icon name="Check" size="small" color="success" className="mt-0.5 shrink-0"/>
|
|
16
|
+
{proof}
|
|
17
|
+
</p>)}
|
|
18
|
+
</div>
|
|
19
|
+
{visual && (<Surface align="center" minHeight="tall" padding="medium">
|
|
20
|
+
{visual}
|
|
21
|
+
</Surface>)}
|
|
22
|
+
</article>);
|
|
23
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface PageHeaderProps {
|
|
3
|
+
/** A small line over the title: where this page sits. */
|
|
4
|
+
eyebrow?: string;
|
|
5
|
+
title: string;
|
|
6
|
+
lede?: React.ReactNode;
|
|
7
|
+
facts?: {
|
|
8
|
+
label: string;
|
|
9
|
+
value: React.ReactNode;
|
|
10
|
+
}[];
|
|
11
|
+
}
|
|
12
|
+
export default function PageHeader({ eyebrow, title, lede, facts }: PageHeaderProps): React.JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import FactsRow from './factsRow';
|
|
3
|
+
import Paragraph from './paragraph';
|
|
4
|
+
export default function PageHeader(_a) {
|
|
5
|
+
var eyebrow = _a.eyebrow, title = _a.title, lede = _a.lede, facts = _a.facts;
|
|
6
|
+
return (<div className="flex flex-col gap-huge">
|
|
7
|
+
<div className="flex flex-col gap-large">
|
|
8
|
+
{eyebrow && (<Paragraph tone="secondary" size="body2" measure="none">
|
|
9
|
+
{eyebrow}
|
|
10
|
+
</Paragraph>)}
|
|
11
|
+
<h1 className="text-h3 text-fg-primary md:text-h2">{title}</h1>
|
|
12
|
+
{lede && (<Paragraph tone="secondary" measure="lede">
|
|
13
|
+
{lede}
|
|
14
|
+
</Paragraph>)}
|
|
15
|
+
</div>
|
|
16
|
+
{facts && <FactsRow items={facts}/>}
|
|
17
|
+
</div>);
|
|
18
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface PageShellProps extends React.ComponentPropsWithoutRef<'main'> {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
/** Let the column grow from the 2xl breakpoint, for pages with wide figures. */
|
|
5
|
+
wide?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export default function PageShell({ children, wide, className, ...rest }: PageShellProps): React.JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import React from 'react';
|
|
13
|
+
// The frame of a page: the column, its side space, and the space between sections.
|
|
14
|
+
// Anything else given (data-* attributes, an id) goes to the <main>.
|
|
15
|
+
export default function PageShell(_a) {
|
|
16
|
+
var children = _a.children, _b = _a.wide, wide = _b === void 0 ? false : _b, _c = _a.className, className = _c === void 0 ? '' : _c, rest = __rest(_a, ["children", "wide", "className"]);
|
|
17
|
+
return (<main className={"min-h-screen ".concat(className)} {...rest}>
|
|
18
|
+
<div className={"mx-auto flex w-full max-w-page flex-col gap-section px-xlarge pb-page pt-giant md:px-xxlarge ".concat(wide ? '2xl:max-w-page-wide' : '')}>
|
|
19
|
+
{children}
|
|
20
|
+
</div>
|
|
21
|
+
</main>);
|
|
22
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface ParagraphProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
tone?: 'primary' | 'secondary';
|
|
5
|
+
size?: 'body1' | 'body2' | 'caption';
|
|
6
|
+
/** How wide a line may run, so a paragraph stays readable. `none` leaves it to the parent. */
|
|
7
|
+
measure?: 'narrow' | 'lede' | 'body' | 'wide' | 'none';
|
|
8
|
+
/** Set in the mono face, for labels, numbers and dates. */
|
|
9
|
+
mono?: boolean;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
export default function Paragraph({ children, tone, size, measure, mono, className, }: ParagraphProps): React.JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
var tones = { primary: 'text-fg-primary', secondary: 'text-fg-secondary' };
|
|
3
|
+
var sizes = { body1: 'text-body1', body2: 'text-body2', caption: 'text-caption' };
|
|
4
|
+
var measures = {
|
|
5
|
+
narrow: 'max-w-measure-narrow',
|
|
6
|
+
lede: 'max-w-measure-lede',
|
|
7
|
+
body: 'max-w-measure-body',
|
|
8
|
+
wide: 'max-w-measure-wide',
|
|
9
|
+
none: '',
|
|
10
|
+
};
|
|
11
|
+
export default function Paragraph(_a) {
|
|
12
|
+
var children = _a.children, _b = _a.tone, tone = _b === void 0 ? 'primary' : _b, _c = _a.size, size = _c === void 0 ? 'body1' : _c, _d = _a.measure, measure = _d === void 0 ? 'body' : _d, _e = _a.mono, mono = _e === void 0 ? false : _e, _f = _a.className, className = _f === void 0 ? '' : _f;
|
|
13
|
+
return (<p className={"".concat(sizes[size], " ").concat(tones[tone], " ").concat(measures[measure], " ").concat(mono ? 'font-mono' : '', " ").concat(className)}>
|
|
14
|
+
{children}
|
|
15
|
+
</p>);
|
|
16
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare function headingId(text: string): string | undefined;
|
|
3
|
+
interface SectionIntroProps {
|
|
4
|
+
/** The section's name. It is the heading, so a contents list shows it. */
|
|
5
|
+
name: string;
|
|
6
|
+
/** The point the section makes, set large under the name. */
|
|
7
|
+
statement?: string;
|
|
8
|
+
/** What carries on from the statement, usually paragraphs. */
|
|
9
|
+
children?: React.ReactNode;
|
|
10
|
+
id?: string;
|
|
11
|
+
}
|
|
12
|
+
export default function SectionIntro({ name, statement, children, id }: SectionIntroProps): React.JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
// The id a section heading carries, made from its own text, so every section
|
|
3
|
+
// has a link (/about#design-philosophy) without each page naming one.
|
|
4
|
+
// Built at run time: the tsconfig targets ES5, which has no \p{...} in a literal.
|
|
5
|
+
var NOT_A_LETTER_OR_NUMBER = new RegExp('[^\\p{L}\\p{N}]+', 'gu');
|
|
6
|
+
export function headingId(text) {
|
|
7
|
+
var id = text
|
|
8
|
+
.toLowerCase()
|
|
9
|
+
.replace(NOT_A_LETTER_OR_NUMBER, '-')
|
|
10
|
+
.replace(/^-|-$/g, '');
|
|
11
|
+
return id || undefined;
|
|
12
|
+
}
|
|
13
|
+
export default function SectionIntro(_a) {
|
|
14
|
+
var name = _a.name, statement = _a.statement, children = _a.children, id = _a.id;
|
|
15
|
+
return (<div className="flex max-w-measure-statement flex-col gap-large">
|
|
16
|
+
<h2 id={id !== null && id !== void 0 ? id : headingId(name)} className="scroll-mt-giant text-body2 font-normal text-fg-secondary">
|
|
17
|
+
{name}
|
|
18
|
+
</h2>
|
|
19
|
+
{statement && <p className="text-h4 text-fg-primary md:text-h3">{statement}</p>}
|
|
20
|
+
{children}
|
|
21
|
+
</div>);
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface SurfaceProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
/** `panel` is the quiet surface content sits on; `paper` stays light in dark mode, for scans and drawings in black. */
|
|
5
|
+
tone?: 'panel' | 'paper';
|
|
6
|
+
padding?: 'small' | 'medium' | 'large' | 'xlarge';
|
|
7
|
+
/** The least height it takes: `short` is 20rem, `tall` is 26rem from the medium breakpoint up. */
|
|
8
|
+
minHeight?: 'short' | 'tall';
|
|
9
|
+
/** `center` centers what is inside, both ways. `start` lays it out as it comes. */
|
|
10
|
+
align?: 'center' | 'start';
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
export default function Surface({ children, tone, padding, minHeight, align, className, }: SurfaceProps): React.JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
var tones = { panel: 'bg-background-panel', paper: 'bg-background-paper' };
|
|
3
|
+
var paddings = {
|
|
4
|
+
small: 'p-medium md:p-large',
|
|
5
|
+
medium: 'p-large md:p-xxlarge',
|
|
6
|
+
large: 'p-xlarge md:p-xxlarge',
|
|
7
|
+
xlarge: 'p-xlarge md:p-huge',
|
|
8
|
+
};
|
|
9
|
+
var heights = {
|
|
10
|
+
short: 'min-h-[var(--os-stage-short)]',
|
|
11
|
+
tall: 'min-h-[var(--os-stage-short)] md:min-h-[var(--os-stage-tall)]',
|
|
12
|
+
};
|
|
13
|
+
export default function Surface(_a) {
|
|
14
|
+
var children = _a.children, _b = _a.tone, tone = _b === void 0 ? 'panel' : _b, _c = _a.padding, padding = _c === void 0 ? 'large' : _c, minHeight = _a.minHeight, _d = _a.align, align = _d === void 0 ? 'start' : _d, _e = _a.className, className = _e === void 0 ? '' : _e;
|
|
15
|
+
var alignClasses = align === 'center' ? 'flex items-center justify-center overflow-hidden' : '';
|
|
16
|
+
return (<div className={"rounded-container ".concat(tones[tone], " ").concat(paddings[padding], " ").concat(minHeight ? heights[minHeight] : '', " ").concat(alignClasses, " ").concat(className)}>
|
|
17
|
+
{children}
|
|
18
|
+
</div>);
|
|
19
|
+
}
|
package/dist/designTokens.d.ts
CHANGED
|
@@ -97,6 +97,8 @@ declare const defaultSets: {
|
|
|
97
97
|
background: {
|
|
98
98
|
elevated: string;
|
|
99
99
|
overlay: string;
|
|
100
|
+
panel: string;
|
|
101
|
+
paper: string;
|
|
100
102
|
default: string;
|
|
101
103
|
accent100: string;
|
|
102
104
|
accent200: string;
|
|
@@ -249,6 +251,8 @@ declare const defaultSets: {
|
|
|
249
251
|
background: {
|
|
250
252
|
elevated: string;
|
|
251
253
|
overlay: string;
|
|
254
|
+
panel: string;
|
|
255
|
+
paper: string;
|
|
252
256
|
default: string;
|
|
253
257
|
accent100: string;
|
|
254
258
|
accent200: string;
|
|
@@ -403,6 +407,8 @@ declare const forestSets: {
|
|
|
403
407
|
background: {
|
|
404
408
|
elevated: string;
|
|
405
409
|
overlay: string;
|
|
410
|
+
panel: string;
|
|
411
|
+
paper: string;
|
|
406
412
|
default: string;
|
|
407
413
|
accent100: string;
|
|
408
414
|
accent200: string;
|
|
@@ -555,6 +561,8 @@ declare const forestSets: {
|
|
|
555
561
|
background: {
|
|
556
562
|
elevated: string;
|
|
557
563
|
overlay: string;
|
|
564
|
+
panel: string;
|
|
565
|
+
paper: string;
|
|
558
566
|
default: string;
|
|
559
567
|
accent100: string;
|
|
560
568
|
accent200: string;
|
|
@@ -712,6 +720,8 @@ export declare namespace themes {
|
|
|
712
720
|
background: {
|
|
713
721
|
elevated: string;
|
|
714
722
|
overlay: string;
|
|
723
|
+
panel: string;
|
|
724
|
+
paper: string;
|
|
715
725
|
default: string;
|
|
716
726
|
accent100: string;
|
|
717
727
|
accent200: string;
|
|
@@ -864,6 +874,8 @@ export declare namespace themes {
|
|
|
864
874
|
background: {
|
|
865
875
|
elevated: string;
|
|
866
876
|
overlay: string;
|
|
877
|
+
panel: string;
|
|
878
|
+
paper: string;
|
|
867
879
|
default: string;
|
|
868
880
|
accent100: string;
|
|
869
881
|
accent200: string;
|
|
@@ -1018,6 +1030,8 @@ export declare namespace themes {
|
|
|
1018
1030
|
background: {
|
|
1019
1031
|
elevated: string;
|
|
1020
1032
|
overlay: string;
|
|
1033
|
+
panel: string;
|
|
1034
|
+
paper: string;
|
|
1021
1035
|
default: string;
|
|
1022
1036
|
accent100: string;
|
|
1023
1037
|
accent200: string;
|
|
@@ -1170,6 +1184,8 @@ export declare namespace themes {
|
|
|
1170
1184
|
background: {
|
|
1171
1185
|
elevated: string;
|
|
1172
1186
|
overlay: string;
|
|
1187
|
+
panel: string;
|
|
1188
|
+
paper: string;
|
|
1173
1189
|
default: string;
|
|
1174
1190
|
accent100: string;
|
|
1175
1191
|
accent200: string;
|
|
@@ -1324,6 +1340,8 @@ export declare namespace themes {
|
|
|
1324
1340
|
background: {
|
|
1325
1341
|
elevated: string;
|
|
1326
1342
|
overlay: string;
|
|
1343
|
+
panel: string;
|
|
1344
|
+
paper: string;
|
|
1327
1345
|
default: string;
|
|
1328
1346
|
accent100: string;
|
|
1329
1347
|
accent200: string;
|
|
@@ -1476,6 +1494,8 @@ export declare namespace themes {
|
|
|
1476
1494
|
background: {
|
|
1477
1495
|
elevated: string;
|
|
1478
1496
|
overlay: string;
|
|
1497
|
+
panel: string;
|
|
1498
|
+
paper: string;
|
|
1479
1499
|
default: string;
|
|
1480
1500
|
accent100: string;
|
|
1481
1501
|
accent200: string;
|
|
@@ -1536,6 +1556,27 @@ export declare namespace spacing {
|
|
|
1536
1556
|
let small: string;
|
|
1537
1557
|
let medium: string;
|
|
1538
1558
|
let large: string;
|
|
1559
|
+
let xlarge: string;
|
|
1560
|
+
let xxlarge: string;
|
|
1561
|
+
let huge: string;
|
|
1562
|
+
let giant: string;
|
|
1563
|
+
let section: string;
|
|
1564
|
+
let page: string;
|
|
1565
|
+
}
|
|
1566
|
+
export declare namespace measure {
|
|
1567
|
+
let narrow: string;
|
|
1568
|
+
let lede: string;
|
|
1569
|
+
let statement: string;
|
|
1570
|
+
let body: string;
|
|
1571
|
+
let wide: string;
|
|
1572
|
+
}
|
|
1573
|
+
export declare let container: {
|
|
1574
|
+
page: string;
|
|
1575
|
+
'page-wide': string;
|
|
1576
|
+
};
|
|
1577
|
+
export declare namespace stage {
|
|
1578
|
+
let short: string;
|
|
1579
|
+
let tall: string;
|
|
1539
1580
|
}
|
|
1540
1581
|
export declare namespace typography {
|
|
1541
1582
|
let family: string;
|
|
@@ -1646,6 +1687,16 @@ export declare namespace typography {
|
|
|
1646
1687
|
let letterSpacing_10: string;
|
|
1647
1688
|
export { letterSpacing_10 as letterSpacing };
|
|
1648
1689
|
}
|
|
1690
|
+
namespace code {
|
|
1691
|
+
let weight_11: string;
|
|
1692
|
+
export { weight_11 as weight };
|
|
1693
|
+
let size_11: string;
|
|
1694
|
+
export { size_11 as size };
|
|
1695
|
+
let lineHeight_11: string;
|
|
1696
|
+
export { lineHeight_11 as lineHeight };
|
|
1697
|
+
let letterSpacing_11: string;
|
|
1698
|
+
export { letterSpacing_11 as letterSpacing };
|
|
1699
|
+
}
|
|
1649
1700
|
namespace alignments {
|
|
1650
1701
|
let left: string;
|
|
1651
1702
|
let center: string;
|
|
@@ -1654,10 +1705,11 @@ export declare namespace typography {
|
|
|
1654
1705
|
}
|
|
1655
1706
|
}
|
|
1656
1707
|
export declare namespace radius {
|
|
1657
|
-
let inline: string;
|
|
1658
|
-
let control: string;
|
|
1659
|
-
let
|
|
1660
|
-
|
|
1708
|
+
export let inline: string;
|
|
1709
|
+
export let control: string;
|
|
1710
|
+
let container_1: string;
|
|
1711
|
+
export { container_1 as container };
|
|
1712
|
+
export let full: string;
|
|
1661
1713
|
}
|
|
1662
1714
|
export declare namespace shadow {
|
|
1663
1715
|
let overlay: string;
|