@cloudflare/component-page 5.0.1 → 5.2.1
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/CHANGELOG.md +52 -0
- package/dist/Heading.d.ts +14 -0
- package/dist/Page.d.ts +7 -5
- package/dist/index.d.ts +2 -1
- package/es/Heading.js +81 -0
- package/es/Page.js +72 -55
- package/es/index.js +2 -1
- package/lib/Heading.js +101 -0
- package/lib/Page.js +89 -77
- package/lib/index.js +14 -0
- package/package.json +6 -6
- package/src/Heading.tsx +107 -0
- package/src/Page.tsx +106 -84
- package/src/index.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,58 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [5.2.1](http://stash.cfops.it:7999/fe/stratus/compare/@cloudflare/component-page@5.2.0...@cloudflare/component-page@5.2.1) (2021-12-03)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @cloudflare/component-page
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [5.2.0](http://stash.cfops.it:7999/fe/stratus/compare/@cloudflare/component-page@5.1.0...@cloudflare/component-page@5.2.0) (2021-11-25)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* **component-page:** A11Y-90 Update prop types ([7bd388f](http://stash.cfops.it:7999/fe/stratus/commits/7bd388f))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* **component-page:** A11Y-90 Add titleRef and subtitleRef properties ([3507385](http://stash.cfops.it:7999/fe/stratus/commits/3507385))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# [5.1.0](http://stash.cfops.it:7999/fe/stratus/compare/@cloudflare/component-page@5.0.2...@cloudflare/component-page@5.1.0) (2021-11-25)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
* **component-page:** A11Y-86 Bug fix ([9ab1079](http://stash.cfops.it:7999/fe/stratus/commits/9ab1079))
|
|
36
|
+
* **component-page:** A11Y-86 remove unused type ([8929fec](http://stash.cfops.it:7999/fe/stratus/commits/8929fec))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Features
|
|
40
|
+
|
|
41
|
+
* **component-page:** A11Y-86 Section and Heading tags ([5b91d18](http://stash.cfops.it:7999/fe/stratus/commits/5b91d18))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## [5.0.2](http://stash.cfops.it:7999/fe/stratus/compare/@cloudflare/component-page@5.0.1...@cloudflare/component-page@5.0.2) (2021-11-23)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Bug Fixes
|
|
51
|
+
|
|
52
|
+
* **component-page:** UI-4946 Fix mobile rendering ([dd60019](http://stash.cfops.it:7999/fe/stratus/commits/dd60019))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
6
58
|
## [5.0.1](http://stash.cfops.it:7999/fe/stratus/compare/@cloudflare/component-page@5.0.0...@cloudflare/component-page@5.0.1) (2021-11-23)
|
|
7
59
|
|
|
8
60
|
**Note:** Version bump only for package @cloudflare/component-page
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { H1 } from '@cloudflare/elements';
|
|
3
|
+
declare type SectionProps = {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
level?: number;
|
|
6
|
+
offset?: number;
|
|
7
|
+
};
|
|
8
|
+
declare type HeadingProps = React.ComponentProps<typeof H1> & {
|
|
9
|
+
level?: number;
|
|
10
|
+
offset?: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function Section(props: SectionProps): JSX.Element;
|
|
13
|
+
export declare function Heading({ level, offset, ...props }: HeadingProps): JSX.Element;
|
|
14
|
+
export {};
|
package/dist/Page.d.ts
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
declare type PageWidth = 'narrow' | 'wide' | 'unbounded';
|
|
3
3
|
declare const _default: React.ComponentType<{
|
|
4
|
-
type?: PageWidth | undefined;
|
|
5
|
-
className?: string | undefined;
|
|
6
|
-
testId?: string | undefined;
|
|
7
4
|
title?: React.ReactNode;
|
|
8
5
|
subtitle?: React.ReactNode;
|
|
9
6
|
description?: React.ReactNode;
|
|
10
7
|
control?: React.ReactNode;
|
|
8
|
+
children?: React.ReactNode;
|
|
11
9
|
centerHeader?: boolean | undefined;
|
|
10
|
+
beta?: boolean | undefined;
|
|
11
|
+
titleRef?: React.RefObject<HTMLHeadingElement> | undefined;
|
|
12
|
+
subtitleRef?: React.RefObject<HTMLHeadingElement> | undefined;
|
|
13
|
+
type?: PageWidth | undefined;
|
|
14
|
+
className?: string | undefined;
|
|
15
|
+
testId?: string | undefined;
|
|
12
16
|
sidebar?: React.ReactNode;
|
|
13
17
|
sidebarPosition?: "left" | "inside" | "outside" | undefined;
|
|
14
|
-
beta?: boolean | undefined;
|
|
15
|
-
children?: any;
|
|
16
18
|
autofocus?: boolean | undefined;
|
|
17
19
|
p?: import("csstype").PaddingProperty<string | number> | [import("csstype").PaddingProperty<string | number> | undefined, import("csstype").PaddingProperty<string | number> | undefined] | [import("csstype").PaddingProperty<string | number> | undefined, import("csstype").PaddingProperty<string | number> | undefined, import("csstype").PaddingProperty<string | number> | undefined] | undefined;
|
|
18
20
|
color?: string | [string | undefined, string | undefined] | [string | undefined, string | undefined, string | undefined] | undefined;
|
package/dist/index.d.ts
CHANGED
package/es/Heading.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
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; }
|
|
2
|
+
|
|
3
|
+
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; }
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { H1, H2, H3, H4, H5 } from '@cloudflare/elements';
|
|
7
|
+
import { createStyledComponent } from '@cloudflare/style-container';
|
|
8
|
+
const HeadingInfo = /*#__PURE__*/React.createContext({
|
|
9
|
+
level: 0,
|
|
10
|
+
offset: 0
|
|
11
|
+
});
|
|
12
|
+
const headerThemes = [({
|
|
13
|
+
theme
|
|
14
|
+
}) => ({
|
|
15
|
+
fontSize: theme.fontSizes[6],
|
|
16
|
+
lineHeight: 1.25,
|
|
17
|
+
color: theme.colors.gray[1],
|
|
18
|
+
fontWeight: 600
|
|
19
|
+
}), ({
|
|
20
|
+
theme
|
|
21
|
+
}) => ({
|
|
22
|
+
fontSize: theme.fontSizes[5],
|
|
23
|
+
lineHeight: 1.25,
|
|
24
|
+
color: theme.colors.gray[3],
|
|
25
|
+
fontWeight: 400
|
|
26
|
+
}), ({
|
|
27
|
+
theme
|
|
28
|
+
}) => ({
|
|
29
|
+
fontSize: theme.fontSizes[4],
|
|
30
|
+
fontWeight: 600
|
|
31
|
+
}), ({
|
|
32
|
+
theme
|
|
33
|
+
}) => ({
|
|
34
|
+
fontSize: theme.fontSizes[3],
|
|
35
|
+
lineHeight: 1.25,
|
|
36
|
+
fontWeight: 600
|
|
37
|
+
})];
|
|
38
|
+
const headings = [H1, H2, H3, H4, H5];
|
|
39
|
+
const maxHeadingLevel = headings.length - 1;
|
|
40
|
+
const maxOffset = 2;
|
|
41
|
+
const standardHeadings = headings.map((h, index) => {
|
|
42
|
+
const themeIndex = Math.min(index, headerThemes.length);
|
|
43
|
+
return createStyledComponent(headerThemes[themeIndex], h);
|
|
44
|
+
}); // Renders H1 with H2 style, H2 with H3 style etc.
|
|
45
|
+
|
|
46
|
+
const offsetOneHeadings = headings.map((h, index) => {
|
|
47
|
+
const themeIndex = Math.min(index + 1, headerThemes.length);
|
|
48
|
+
return createStyledComponent(headerThemes[themeIndex], h);
|
|
49
|
+
}); // Renders H1 with H3 style, H2 with H4 style etc.
|
|
50
|
+
|
|
51
|
+
const offsetTwoHeadings = headings.map((h, index) => {
|
|
52
|
+
const themeIndex = Math.min(index + 2, headerThemes.length);
|
|
53
|
+
return createStyledComponent(headerThemes[themeIndex], h);
|
|
54
|
+
});
|
|
55
|
+
export function Section(props) {
|
|
56
|
+
return /*#__PURE__*/React.createElement(HeadingInfo.Consumer, null, info => {
|
|
57
|
+
var _props$level, _props$offset;
|
|
58
|
+
|
|
59
|
+
return /*#__PURE__*/React.createElement(HeadingInfo.Provider, {
|
|
60
|
+
value: {
|
|
61
|
+
level: (_props$level = props.level) !== null && _props$level !== void 0 ? _props$level : info.level + 1,
|
|
62
|
+
offset: info.offset + ((_props$offset = props.offset) !== null && _props$offset !== void 0 ? _props$offset : 0)
|
|
63
|
+
}
|
|
64
|
+
}, props.children);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
export function Heading(_ref) {
|
|
68
|
+
let level = _ref.level,
|
|
69
|
+
_ref$offset = _ref.offset,
|
|
70
|
+
offset = _ref$offset === void 0 ? 0 : _ref$offset,
|
|
71
|
+
props = _objectWithoutProperties(_ref, ["level", "offset"]);
|
|
72
|
+
|
|
73
|
+
return /*#__PURE__*/React.createElement(HeadingInfo.Consumer, null, info => {
|
|
74
|
+
const headingOffset = Math.min(maxOffset, info.offset + offset);
|
|
75
|
+
const headings = headingOffset === 1 ? offsetOneHeadings : headingOffset === 2 ? offsetTwoHeadings : standardHeadings;
|
|
76
|
+
const headingLevel = Math.min(level !== undefined ? level - 1 : info.level, maxHeadingLevel);
|
|
77
|
+
const Heading = headings[Math.max(0, headingLevel)]; // @ts-ignore
|
|
78
|
+
|
|
79
|
+
return /*#__PURE__*/React.createElement(Heading, props);
|
|
80
|
+
});
|
|
81
|
+
}
|
package/es/Page.js
CHANGED
|
@@ -4,32 +4,12 @@ import { createStyledComponent, createComponent } from '@cloudflare/style-contai
|
|
|
4
4
|
import { Main, Header, Div } from '@cloudflare/elements';
|
|
5
5
|
import { Label } from '@cloudflare/component-label';
|
|
6
6
|
import { Trans } from '@cloudflare/intl-react';
|
|
7
|
+
import { Heading, Section } from './Heading';
|
|
7
8
|
const maxWidthByType = {
|
|
8
9
|
narrow: '64em',
|
|
9
10
|
wide: '79em',
|
|
10
11
|
unbounded: '100%'
|
|
11
12
|
};
|
|
12
|
-
const PageTitle = createComponent(({
|
|
13
|
-
theme
|
|
14
|
-
}) => ({
|
|
15
|
-
fontSize: theme.fontSizes[6],
|
|
16
|
-
marginTop: theme.space[0],
|
|
17
|
-
marginBottom: theme.space[0],
|
|
18
|
-
lineHeight: 1.25,
|
|
19
|
-
color: theme.colors.gray[1],
|
|
20
|
-
fontWeight: 600
|
|
21
|
-
}), 'h1');
|
|
22
|
-
PageTitle.displayName = 'Title';
|
|
23
|
-
const PageSubtitle = createComponent(({
|
|
24
|
-
theme
|
|
25
|
-
}) => ({
|
|
26
|
-
fontSize: theme.fontSizes[5],
|
|
27
|
-
marginBottom: theme.space[0],
|
|
28
|
-
lineHeight: 1.25,
|
|
29
|
-
color: theme.colors.gray[3],
|
|
30
|
-
fontWeight: 400
|
|
31
|
-
}), 'h2');
|
|
32
|
-
PageTitle.displayName = 'PageSubtitle';
|
|
33
13
|
const PageDescription = createComponent(({
|
|
34
14
|
theme
|
|
35
15
|
}) => ({
|
|
@@ -40,16 +20,61 @@ const PageDescription = createComponent(({
|
|
|
40
20
|
fontWeight: 400
|
|
41
21
|
}), 'p');
|
|
42
22
|
PageDescription.displayName = 'PageDescription';
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}),
|
|
52
|
-
|
|
23
|
+
|
|
24
|
+
const ControlWrapper = ({
|
|
25
|
+
control,
|
|
26
|
+
children
|
|
27
|
+
}) => {
|
|
28
|
+
return control ? /*#__PURE__*/React.createElement(Div, {
|
|
29
|
+
display: ['block', 'flex'],
|
|
30
|
+
justifyContent: "space-between"
|
|
31
|
+
}, children, control) : /*#__PURE__*/React.createElement(React.Fragment, null, children);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const maxPageTitles = 2;
|
|
35
|
+
|
|
36
|
+
const PageHeader = ({
|
|
37
|
+
title,
|
|
38
|
+
subtitle,
|
|
39
|
+
description,
|
|
40
|
+
centerHeader,
|
|
41
|
+
control,
|
|
42
|
+
children,
|
|
43
|
+
beta,
|
|
44
|
+
titleRef,
|
|
45
|
+
subtitleRef
|
|
46
|
+
}) => {
|
|
47
|
+
const headerVisible = !!(title || subtitle || description);
|
|
48
|
+
const titlesCount = Math.min([title, subtitle, description].filter(Boolean).length, 2);
|
|
49
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ControlWrapper, {
|
|
50
|
+
control: control
|
|
51
|
+
}, /*#__PURE__*/React.createElement(Header, {
|
|
52
|
+
mb: headerVisible ? 3 : 0,
|
|
53
|
+
textAlign: centerHeader ? 'center' : undefined
|
|
54
|
+
}, title && /*#__PURE__*/React.createElement(Heading, {
|
|
55
|
+
innerRef: titleRef
|
|
56
|
+
}, title, beta && /*#__PURE__*/React.createElement(Label, {
|
|
57
|
+
hue: "orange",
|
|
58
|
+
ml: 2,
|
|
59
|
+
verticalAlign: "middle"
|
|
60
|
+
}, /*#__PURE__*/React.createElement(Trans, {
|
|
61
|
+
_: "Beta",
|
|
62
|
+
id: "common.beta"
|
|
63
|
+
}))), subtitle && /*#__PURE__*/React.createElement(Heading, {
|
|
64
|
+
level: title ? 2 : 1,
|
|
65
|
+
offset: title ? 0 : 1,
|
|
66
|
+
innerRef: subtitleRef
|
|
67
|
+
}, subtitle), description && (subtitle ? /*#__PURE__*/React.createElement(PageDescription, null, description) : /*#__PURE__*/React.createElement(Heading, {
|
|
68
|
+
level: 2,
|
|
69
|
+
fontSize: 4,
|
|
70
|
+
color: "gray.3"
|
|
71
|
+
}, description)))), /*#__PURE__*/React.createElement(Section, {
|
|
72
|
+
level: titlesCount,
|
|
73
|
+
offset: maxPageTitles - titlesCount
|
|
74
|
+
}, children));
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
PageHeader.displayName = 'PageHeader'; // firstPage is used when dealing with focus. When navigating the dash, focus
|
|
53
78
|
// jumps to the page content, but not when the dash is initially loaded.
|
|
54
79
|
|
|
55
80
|
let firstPage = ''; // firstLoad is used to ensure focus is handled correctly if the user navigates
|
|
@@ -80,6 +105,8 @@ const Page = ({
|
|
|
80
105
|
sidebarPosition = 'inside',
|
|
81
106
|
autofocus = true,
|
|
82
107
|
control,
|
|
108
|
+
titleRef,
|
|
109
|
+
subtitleRef,
|
|
83
110
|
children
|
|
84
111
|
}) => {
|
|
85
112
|
var _history$location;
|
|
@@ -99,37 +126,17 @@ const Page = ({
|
|
|
99
126
|
}
|
|
100
127
|
}
|
|
101
128
|
}, [path]);
|
|
102
|
-
const headerVisible = !!(title || subtitle || description);
|
|
103
|
-
let header = /*#__PURE__*/React.createElement(Header, {
|
|
104
|
-
mb: headerVisible ? 3 : 0,
|
|
105
|
-
textAlign: centerHeader ? 'center' : undefined
|
|
106
|
-
}, title && /*#__PURE__*/React.createElement(PageTitle, null, title, beta && /*#__PURE__*/React.createElement(Label, {
|
|
107
|
-
hue: "orange",
|
|
108
|
-
ml: 2,
|
|
109
|
-
verticalAlign: "middle"
|
|
110
|
-
}, /*#__PURE__*/React.createElement(Trans, {
|
|
111
|
-
_: "Beta",
|
|
112
|
-
id: "common.beta"
|
|
113
|
-
}))), subtitle && /*#__PURE__*/React.createElement(PageSubtitle, null, subtitle), description && (subtitle ? /*#__PURE__*/React.createElement(PageDescription, null, description) : /*#__PURE__*/React.createElement(PageSubtitleDescription, null, description)));
|
|
114
|
-
|
|
115
|
-
if (control) {
|
|
116
|
-
header = /*#__PURE__*/React.createElement(Div, {
|
|
117
|
-
display: ['block', 'flex'],
|
|
118
|
-
justifyContent: "space-between"
|
|
119
|
-
}, header, control);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
129
|
const sidebarInside = sidebarPosition === 'inside';
|
|
123
|
-
const width = type === 'unbounded' ? '100%' : '90%';
|
|
124
130
|
return /*#__PURE__*/React.createElement(Main, {
|
|
125
131
|
"data-testid": testId,
|
|
126
132
|
className: className,
|
|
127
|
-
display: sidebar && sidebarInside ? undefined : 'flex'
|
|
133
|
+
display: sidebar && sidebarInside ? undefined : 'flex',
|
|
134
|
+
py: 4
|
|
128
135
|
}, /*#__PURE__*/React.createElement(Div, {
|
|
129
136
|
ml: "auto",
|
|
130
137
|
mr: sidebar && !sidebarInside ? 0 : 'auto',
|
|
131
138
|
display: sidebar ? ['block', 'block', 'flex'] : undefined,
|
|
132
|
-
width:
|
|
139
|
+
width: type === 'unbounded' ? '100%' : '90%',
|
|
133
140
|
maxWidth: maxWidthByType[type] || maxWidthByType.narrow
|
|
134
141
|
}, /*#__PURE__*/React.createElement(Div, {
|
|
135
142
|
width: sidebar && sidebarInside ? [1, 1, 2 / 3] : undefined,
|
|
@@ -139,7 +146,17 @@ const Page = ({
|
|
|
139
146
|
id: "skipTarget",
|
|
140
147
|
ref: skipTargetRef,
|
|
141
148
|
tabIndex: -1
|
|
142
|
-
}),
|
|
149
|
+
}), /*#__PURE__*/React.createElement(PageHeader, {
|
|
150
|
+
title: title,
|
|
151
|
+
subtitle: subtitle,
|
|
152
|
+
description: description,
|
|
153
|
+
centerHeader: centerHeader,
|
|
154
|
+
control: control,
|
|
155
|
+
children: children,
|
|
156
|
+
beta: beta,
|
|
157
|
+
titleRef: titleRef,
|
|
158
|
+
subtitleRef: subtitleRef
|
|
159
|
+
})), sidebar && sidebarInside && /*#__PURE__*/React.createElement(Div, {
|
|
143
160
|
width: [1, 1, 1 / 3],
|
|
144
161
|
pl: [0, 0, 3],
|
|
145
162
|
pt: [4, 4, 0]
|
package/es/index.js
CHANGED
package/lib/Heading.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Section = Section;
|
|
7
|
+
exports.Heading = Heading;
|
|
8
|
+
|
|
9
|
+
var _react = _interopRequireDefault(require("react"));
|
|
10
|
+
|
|
11
|
+
var _elements = require("@cloudflare/elements");
|
|
12
|
+
|
|
13
|
+
var _styleContainer = require("@cloudflare/style-container");
|
|
14
|
+
|
|
15
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
+
|
|
17
|
+
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; }
|
|
18
|
+
|
|
19
|
+
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; }
|
|
20
|
+
|
|
21
|
+
var HeadingInfo = /*#__PURE__*/_react.default.createContext({
|
|
22
|
+
level: 0,
|
|
23
|
+
offset: 0
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
var headerThemes = [function (_ref) {
|
|
27
|
+
var theme = _ref.theme;
|
|
28
|
+
return {
|
|
29
|
+
fontSize: theme.fontSizes[6],
|
|
30
|
+
lineHeight: 1.25,
|
|
31
|
+
color: theme.colors.gray[1],
|
|
32
|
+
fontWeight: 600
|
|
33
|
+
};
|
|
34
|
+
}, function (_ref2) {
|
|
35
|
+
var theme = _ref2.theme;
|
|
36
|
+
return {
|
|
37
|
+
fontSize: theme.fontSizes[5],
|
|
38
|
+
lineHeight: 1.25,
|
|
39
|
+
color: theme.colors.gray[3],
|
|
40
|
+
fontWeight: 400
|
|
41
|
+
};
|
|
42
|
+
}, function (_ref3) {
|
|
43
|
+
var theme = _ref3.theme;
|
|
44
|
+
return {
|
|
45
|
+
fontSize: theme.fontSizes[4],
|
|
46
|
+
fontWeight: 600
|
|
47
|
+
};
|
|
48
|
+
}, function (_ref4) {
|
|
49
|
+
var theme = _ref4.theme;
|
|
50
|
+
return {
|
|
51
|
+
fontSize: theme.fontSizes[3],
|
|
52
|
+
lineHeight: 1.25,
|
|
53
|
+
fontWeight: 600
|
|
54
|
+
};
|
|
55
|
+
}];
|
|
56
|
+
var headings = [_elements.H1, _elements.H2, _elements.H3, _elements.H4, _elements.H5];
|
|
57
|
+
var maxHeadingLevel = headings.length - 1;
|
|
58
|
+
var maxOffset = 2;
|
|
59
|
+
var standardHeadings = headings.map(function (h, index) {
|
|
60
|
+
var themeIndex = Math.min(index, headerThemes.length);
|
|
61
|
+
return (0, _styleContainer.createStyledComponent)(headerThemes[themeIndex], h);
|
|
62
|
+
}); // Renders H1 with H2 style, H2 with H3 style etc.
|
|
63
|
+
|
|
64
|
+
var offsetOneHeadings = headings.map(function (h, index) {
|
|
65
|
+
var themeIndex = Math.min(index + 1, headerThemes.length);
|
|
66
|
+
return (0, _styleContainer.createStyledComponent)(headerThemes[themeIndex], h);
|
|
67
|
+
}); // Renders H1 with H3 style, H2 with H4 style etc.
|
|
68
|
+
|
|
69
|
+
var offsetTwoHeadings = headings.map(function (h, index) {
|
|
70
|
+
var themeIndex = Math.min(index + 2, headerThemes.length);
|
|
71
|
+
return (0, _styleContainer.createStyledComponent)(headerThemes[themeIndex], h);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
function Section(props) {
|
|
75
|
+
return /*#__PURE__*/_react.default.createElement(HeadingInfo.Consumer, null, function (info) {
|
|
76
|
+
var _props$level, _props$offset;
|
|
77
|
+
|
|
78
|
+
return /*#__PURE__*/_react.default.createElement(HeadingInfo.Provider, {
|
|
79
|
+
value: {
|
|
80
|
+
level: (_props$level = props.level) !== null && _props$level !== void 0 ? _props$level : info.level + 1,
|
|
81
|
+
offset: info.offset + ((_props$offset = props.offset) !== null && _props$offset !== void 0 ? _props$offset : 0)
|
|
82
|
+
}
|
|
83
|
+
}, props.children);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function Heading(_ref5) {
|
|
88
|
+
var level = _ref5.level,
|
|
89
|
+
_ref5$offset = _ref5.offset,
|
|
90
|
+
offset = _ref5$offset === void 0 ? 0 : _ref5$offset,
|
|
91
|
+
props = _objectWithoutProperties(_ref5, ["level", "offset"]);
|
|
92
|
+
|
|
93
|
+
return /*#__PURE__*/_react.default.createElement(HeadingInfo.Consumer, null, function (info) {
|
|
94
|
+
var headingOffset = Math.min(maxOffset, info.offset + offset);
|
|
95
|
+
var headings = headingOffset === 1 ? offsetOneHeadings : headingOffset === 2 ? offsetTwoHeadings : standardHeadings;
|
|
96
|
+
var headingLevel = Math.min(level !== undefined ? level - 1 : info.level, maxHeadingLevel);
|
|
97
|
+
var Heading = headings[Math.max(0, headingLevel)]; // @ts-ignore
|
|
98
|
+
|
|
99
|
+
return /*#__PURE__*/_react.default.createElement(Heading, props);
|
|
100
|
+
});
|
|
101
|
+
}
|
package/lib/Page.js
CHANGED
|
@@ -19,6 +19,8 @@ var _componentLabel = require("@cloudflare/component-label");
|
|
|
19
19
|
|
|
20
20
|
var _intlReact = require("@cloudflare/intl-react");
|
|
21
21
|
|
|
22
|
+
var _Heading = require("./Heading");
|
|
23
|
+
|
|
22
24
|
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
|
|
23
25
|
|
|
24
26
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
@@ -28,31 +30,8 @@ var maxWidthByType = {
|
|
|
28
30
|
wide: '79em',
|
|
29
31
|
unbounded: '100%'
|
|
30
32
|
};
|
|
31
|
-
var
|
|
33
|
+
var PageDescription = (0, _styleContainer.createComponent)(function (_ref) {
|
|
32
34
|
var theme = _ref.theme;
|
|
33
|
-
return {
|
|
34
|
-
fontSize: theme.fontSizes[6],
|
|
35
|
-
marginTop: theme.space[0],
|
|
36
|
-
marginBottom: theme.space[0],
|
|
37
|
-
lineHeight: 1.25,
|
|
38
|
-
color: theme.colors.gray[1],
|
|
39
|
-
fontWeight: 600
|
|
40
|
-
};
|
|
41
|
-
}, 'h1');
|
|
42
|
-
PageTitle.displayName = 'Title';
|
|
43
|
-
var PageSubtitle = (0, _styleContainer.createComponent)(function (_ref2) {
|
|
44
|
-
var theme = _ref2.theme;
|
|
45
|
-
return {
|
|
46
|
-
fontSize: theme.fontSizes[5],
|
|
47
|
-
marginBottom: theme.space[0],
|
|
48
|
-
lineHeight: 1.25,
|
|
49
|
-
color: theme.colors.gray[3],
|
|
50
|
-
fontWeight: 400
|
|
51
|
-
};
|
|
52
|
-
}, 'h2');
|
|
53
|
-
PageTitle.displayName = 'PageSubtitle';
|
|
54
|
-
var PageDescription = (0, _styleContainer.createComponent)(function (_ref3) {
|
|
55
|
-
var theme = _ref3.theme;
|
|
56
35
|
return {
|
|
57
36
|
fontSize: theme.fontSizes[4],
|
|
58
37
|
marginBottom: theme.space[0],
|
|
@@ -62,17 +41,59 @@ var PageDescription = (0, _styleContainer.createComponent)(function (_ref3) {
|
|
|
62
41
|
};
|
|
63
42
|
}, 'p');
|
|
64
43
|
PageDescription.displayName = 'PageDescription';
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
44
|
+
|
|
45
|
+
var ControlWrapper = function ControlWrapper(_ref2) {
|
|
46
|
+
var control = _ref2.control,
|
|
47
|
+
children = _ref2.children;
|
|
48
|
+
return control ? /*#__PURE__*/_react.default.createElement(_elements.Div, {
|
|
49
|
+
display: ['block', 'flex'],
|
|
50
|
+
justifyContent: "space-between"
|
|
51
|
+
}, children, control) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
var maxPageTitles = 2;
|
|
55
|
+
|
|
56
|
+
var PageHeader = function PageHeader(_ref3) {
|
|
57
|
+
var title = _ref3.title,
|
|
58
|
+
subtitle = _ref3.subtitle,
|
|
59
|
+
description = _ref3.description,
|
|
60
|
+
centerHeader = _ref3.centerHeader,
|
|
61
|
+
control = _ref3.control,
|
|
62
|
+
children = _ref3.children,
|
|
63
|
+
beta = _ref3.beta,
|
|
64
|
+
titleRef = _ref3.titleRef,
|
|
65
|
+
subtitleRef = _ref3.subtitleRef;
|
|
66
|
+
var headerVisible = !!(title || subtitle || description);
|
|
67
|
+
var titlesCount = Math.min([title, subtitle, description].filter(Boolean).length, 2);
|
|
68
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(ControlWrapper, {
|
|
69
|
+
control: control
|
|
70
|
+
}, /*#__PURE__*/_react.default.createElement(_elements.Header, {
|
|
71
|
+
mb: headerVisible ? 3 : 0,
|
|
72
|
+
textAlign: centerHeader ? 'center' : undefined
|
|
73
|
+
}, title && /*#__PURE__*/_react.default.createElement(_Heading.Heading, {
|
|
74
|
+
innerRef: titleRef
|
|
75
|
+
}, title, beta && /*#__PURE__*/_react.default.createElement(_componentLabel.Label, {
|
|
76
|
+
hue: "orange",
|
|
77
|
+
ml: 2,
|
|
78
|
+
verticalAlign: "middle"
|
|
79
|
+
}, /*#__PURE__*/_react.default.createElement(_intlReact.Trans, {
|
|
80
|
+
_: "Beta",
|
|
81
|
+
id: "common.beta"
|
|
82
|
+
}))), subtitle && /*#__PURE__*/_react.default.createElement(_Heading.Heading, {
|
|
83
|
+
level: title ? 2 : 1,
|
|
84
|
+
offset: title ? 0 : 1,
|
|
85
|
+
innerRef: subtitleRef
|
|
86
|
+
}, subtitle), description && (subtitle ? /*#__PURE__*/_react.default.createElement(PageDescription, null, description) : /*#__PURE__*/_react.default.createElement(_Heading.Heading, {
|
|
87
|
+
level: 2,
|
|
88
|
+
fontSize: 4,
|
|
89
|
+
color: "gray.3"
|
|
90
|
+
}, description)))), /*#__PURE__*/_react.default.createElement(_Heading.Section, {
|
|
91
|
+
level: titlesCount,
|
|
92
|
+
offset: maxPageTitles - titlesCount
|
|
93
|
+
}, children));
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
PageHeader.displayName = 'PageHeader'; // firstPage is used when dealing with focus. When navigating the dash, focus
|
|
76
97
|
// jumps to the page content, but not when the dash is initially loaded.
|
|
77
98
|
|
|
78
99
|
var firstPage = ''; // firstLoad is used to ensure focus is handled correctly if the user navigates
|
|
@@ -93,25 +114,27 @@ var focus = function focus(el) {
|
|
|
93
114
|
}
|
|
94
115
|
};
|
|
95
116
|
|
|
96
|
-
var Page = function Page(
|
|
117
|
+
var Page = function Page(_ref4) {
|
|
97
118
|
var _history$location;
|
|
98
119
|
|
|
99
|
-
var title =
|
|
100
|
-
subtitle =
|
|
101
|
-
description =
|
|
102
|
-
centerHeader =
|
|
103
|
-
beta =
|
|
104
|
-
testId =
|
|
105
|
-
className =
|
|
106
|
-
sidebar =
|
|
107
|
-
|
|
108
|
-
type =
|
|
109
|
-
|
|
110
|
-
sidebarPosition =
|
|
111
|
-
|
|
112
|
-
autofocus =
|
|
113
|
-
control =
|
|
114
|
-
|
|
120
|
+
var title = _ref4.title,
|
|
121
|
+
subtitle = _ref4.subtitle,
|
|
122
|
+
description = _ref4.description,
|
|
123
|
+
centerHeader = _ref4.centerHeader,
|
|
124
|
+
beta = _ref4.beta,
|
|
125
|
+
testId = _ref4.testId,
|
|
126
|
+
className = _ref4.className,
|
|
127
|
+
sidebar = _ref4.sidebar,
|
|
128
|
+
_ref4$type = _ref4.type,
|
|
129
|
+
type = _ref4$type === void 0 ? 'wide' : _ref4$type,
|
|
130
|
+
_ref4$sidebarPosition = _ref4.sidebarPosition,
|
|
131
|
+
sidebarPosition = _ref4$sidebarPosition === void 0 ? 'inside' : _ref4$sidebarPosition,
|
|
132
|
+
_ref4$autofocus = _ref4.autofocus,
|
|
133
|
+
autofocus = _ref4$autofocus === void 0 ? true : _ref4$autofocus,
|
|
134
|
+
control = _ref4.control,
|
|
135
|
+
titleRef = _ref4.titleRef,
|
|
136
|
+
subtitleRef = _ref4.subtitleRef,
|
|
137
|
+
children = _ref4.children;
|
|
115
138
|
var history = (0, _reactRouterDom.useHistory)();
|
|
116
139
|
var skipTargetRef = (0, _react.useRef)(null);
|
|
117
140
|
var path = history === null || history === void 0 ? void 0 : (_history$location = history.location) === null || _history$location === void 0 ? void 0 : _history$location.pathname;
|
|
@@ -127,38 +150,17 @@ var Page = function Page(_ref5) {
|
|
|
127
150
|
}
|
|
128
151
|
}
|
|
129
152
|
}, [path]);
|
|
130
|
-
var headerVisible = !!(title || subtitle || description);
|
|
131
|
-
|
|
132
|
-
var header = /*#__PURE__*/_react.default.createElement(_elements.Header, {
|
|
133
|
-
mb: headerVisible ? 3 : 0,
|
|
134
|
-
textAlign: centerHeader ? 'center' : undefined
|
|
135
|
-
}, title && /*#__PURE__*/_react.default.createElement(PageTitle, null, title, beta && /*#__PURE__*/_react.default.createElement(_componentLabel.Label, {
|
|
136
|
-
hue: "orange",
|
|
137
|
-
ml: 2,
|
|
138
|
-
verticalAlign: "middle"
|
|
139
|
-
}, /*#__PURE__*/_react.default.createElement(_intlReact.Trans, {
|
|
140
|
-
_: "Beta",
|
|
141
|
-
id: "common.beta"
|
|
142
|
-
}))), subtitle && /*#__PURE__*/_react.default.createElement(PageSubtitle, null, subtitle), description && (subtitle ? /*#__PURE__*/_react.default.createElement(PageDescription, null, description) : /*#__PURE__*/_react.default.createElement(PageSubtitleDescription, null, description)));
|
|
143
|
-
|
|
144
|
-
if (control) {
|
|
145
|
-
header = /*#__PURE__*/_react.default.createElement(_elements.Div, {
|
|
146
|
-
display: ['block', 'flex'],
|
|
147
|
-
justifyContent: "space-between"
|
|
148
|
-
}, header, control);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
153
|
var sidebarInside = sidebarPosition === 'inside';
|
|
152
|
-
var width = type === 'unbounded' ? '100%' : '90%';
|
|
153
154
|
return /*#__PURE__*/_react.default.createElement(_elements.Main, {
|
|
154
155
|
"data-testid": testId,
|
|
155
156
|
className: className,
|
|
156
|
-
display: sidebar && sidebarInside ? undefined : 'flex'
|
|
157
|
+
display: sidebar && sidebarInside ? undefined : 'flex',
|
|
158
|
+
py: 4
|
|
157
159
|
}, /*#__PURE__*/_react.default.createElement(_elements.Div, {
|
|
158
160
|
ml: "auto",
|
|
159
161
|
mr: sidebar && !sidebarInside ? 0 : 'auto',
|
|
160
162
|
display: sidebar ? ['block', 'block', 'flex'] : undefined,
|
|
161
|
-
width:
|
|
163
|
+
width: type === 'unbounded' ? '100%' : '90%',
|
|
162
164
|
maxWidth: maxWidthByType[type] || maxWidthByType.narrow
|
|
163
165
|
}, /*#__PURE__*/_react.default.createElement(_elements.Div, {
|
|
164
166
|
width: sidebar && sidebarInside ? [1, 1, 2 / 3] : undefined,
|
|
@@ -168,7 +170,17 @@ var Page = function Page(_ref5) {
|
|
|
168
170
|
id: "skipTarget",
|
|
169
171
|
ref: skipTargetRef,
|
|
170
172
|
tabIndex: -1
|
|
171
|
-
}),
|
|
173
|
+
}), /*#__PURE__*/_react.default.createElement(PageHeader, {
|
|
174
|
+
title: title,
|
|
175
|
+
subtitle: subtitle,
|
|
176
|
+
description: description,
|
|
177
|
+
centerHeader: centerHeader,
|
|
178
|
+
control: control,
|
|
179
|
+
children: children,
|
|
180
|
+
beta: beta,
|
|
181
|
+
titleRef: titleRef,
|
|
182
|
+
subtitleRef: subtitleRef
|
|
183
|
+
})), sidebar && sidebarInside && /*#__PURE__*/_react.default.createElement(_elements.Div, {
|
|
172
184
|
width: [1, 1, 1 / 3],
|
|
173
185
|
pl: [0, 0, 3],
|
|
174
186
|
pt: [4, 4, 0]
|
package/lib/index.js
CHANGED
|
@@ -9,7 +9,21 @@ Object.defineProperty(exports, "Page", {
|
|
|
9
9
|
return _Page.default;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
+
Object.defineProperty(exports, "Heading", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function get() {
|
|
15
|
+
return _Heading.Heading;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "Section", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function get() {
|
|
21
|
+
return _Heading.Section;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
12
24
|
|
|
13
25
|
var _Page = _interopRequireDefault(require("./Page"));
|
|
14
26
|
|
|
27
|
+
var _Heading = require("./Heading");
|
|
28
|
+
|
|
15
29
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudflare/component-page",
|
|
3
3
|
"description": "Cloudflare Page Component",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.2.1",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "es/index.js",
|
|
7
7
|
"author": "James Kyle <jkyle@cloudflare.com>",
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@cloudflare/component-label": "^3.3.
|
|
15
|
-
"@cloudflare/elements": "^1.11.
|
|
16
|
-
"@cloudflare/intl-react": "^1.9.
|
|
17
|
-
"@cloudflare/style-container": "^7.5.
|
|
14
|
+
"@cloudflare/component-label": "^3.3.30",
|
|
15
|
+
"@cloudflare/elements": "^1.11.32",
|
|
16
|
+
"@cloudflare/intl-react": "^1.9.18",
|
|
17
|
+
"@cloudflare/style-container": "^7.5.21",
|
|
18
18
|
"react-router-dom": "^5.1.0"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
@@ -31,5 +31,5 @@
|
|
|
31
31
|
"test-coverage": "stratus test --coverage",
|
|
32
32
|
"test-watch": "stratus test --watch"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "ceaeb1a7b750bec5b0dfc6edbba94bf2ddac31bf"
|
|
35
35
|
}
|
package/src/Heading.tsx
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { H1, H2, H3, H4, H5 } from '@cloudflare/elements';
|
|
3
|
+
import { createStyledComponent, ThemeProp } from '@cloudflare/style-container';
|
|
4
|
+
|
|
5
|
+
type SectionProps = {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
level?: number;
|
|
8
|
+
offset?: number;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type HeadingProps = React.ComponentProps<typeof H1> & {
|
|
12
|
+
level?: number;
|
|
13
|
+
offset?: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const HeadingInfo = React.createContext({
|
|
17
|
+
level: 0,
|
|
18
|
+
offset: 0
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const headerThemes = [
|
|
22
|
+
({ theme }: { theme: ThemeProp['theme'] }) => ({
|
|
23
|
+
fontSize: theme.fontSizes[6],
|
|
24
|
+
lineHeight: 1.25,
|
|
25
|
+
color: theme.colors.gray[1],
|
|
26
|
+
fontWeight: 600
|
|
27
|
+
}),
|
|
28
|
+
({ theme }: { theme: ThemeProp['theme'] }) => ({
|
|
29
|
+
fontSize: theme.fontSizes[5],
|
|
30
|
+
lineHeight: 1.25,
|
|
31
|
+
color: theme.colors.gray[3],
|
|
32
|
+
fontWeight: 400
|
|
33
|
+
}),
|
|
34
|
+
({ theme }: { theme: ThemeProp['theme'] }) => ({
|
|
35
|
+
fontSize: theme.fontSizes[4],
|
|
36
|
+
fontWeight: 600
|
|
37
|
+
}),
|
|
38
|
+
({ theme }: { theme: ThemeProp['theme'] }) => ({
|
|
39
|
+
fontSize: theme.fontSizes[3],
|
|
40
|
+
lineHeight: 1.25,
|
|
41
|
+
fontWeight: 600
|
|
42
|
+
})
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const headings = [H1, H2, H3, H4, H5];
|
|
46
|
+
|
|
47
|
+
const maxHeadingLevel = headings.length - 1;
|
|
48
|
+
|
|
49
|
+
const maxOffset = 2;
|
|
50
|
+
|
|
51
|
+
const standardHeadings = headings.map((h, index) => {
|
|
52
|
+
const themeIndex = Math.min(index, headerThemes.length);
|
|
53
|
+
return createStyledComponent(headerThemes[themeIndex], h);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Renders H1 with H2 style, H2 with H3 style etc.
|
|
57
|
+
const offsetOneHeadings = headings.map((h, index) => {
|
|
58
|
+
const themeIndex = Math.min(index + 1, headerThemes.length);
|
|
59
|
+
return createStyledComponent(headerThemes[themeIndex], h);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Renders H1 with H3 style, H2 with H4 style etc.
|
|
63
|
+
const offsetTwoHeadings = headings.map((h, index) => {
|
|
64
|
+
const themeIndex = Math.min(index + 2, headerThemes.length);
|
|
65
|
+
return createStyledComponent(headerThemes[themeIndex], h);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export function Section(props: SectionProps) {
|
|
69
|
+
return (
|
|
70
|
+
<HeadingInfo.Consumer>
|
|
71
|
+
{info => (
|
|
72
|
+
<HeadingInfo.Provider
|
|
73
|
+
value={{
|
|
74
|
+
level: props.level ?? info.level + 1,
|
|
75
|
+
offset: info.offset + (props.offset ?? 0)
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
{props.children}
|
|
79
|
+
</HeadingInfo.Provider>
|
|
80
|
+
)}
|
|
81
|
+
</HeadingInfo.Consumer>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function Heading({ level, offset = 0, ...props }: HeadingProps) {
|
|
86
|
+
return (
|
|
87
|
+
<HeadingInfo.Consumer>
|
|
88
|
+
{info => {
|
|
89
|
+
const headingOffset = Math.min(maxOffset, info.offset + offset);
|
|
90
|
+
const headings =
|
|
91
|
+
headingOffset === 1
|
|
92
|
+
? offsetOneHeadings
|
|
93
|
+
: headingOffset === 2
|
|
94
|
+
? offsetTwoHeadings
|
|
95
|
+
: standardHeadings;
|
|
96
|
+
|
|
97
|
+
const headingLevel = Math.min(
|
|
98
|
+
level !== undefined ? level - 1 : info.level,
|
|
99
|
+
maxHeadingLevel
|
|
100
|
+
);
|
|
101
|
+
const Heading = headings[Math.max(0, headingLevel)];
|
|
102
|
+
// @ts-ignore
|
|
103
|
+
return <Heading {...props} />;
|
|
104
|
+
}}
|
|
105
|
+
</HeadingInfo.Consumer>
|
|
106
|
+
);
|
|
107
|
+
}
|
package/src/Page.tsx
CHANGED
|
@@ -7,22 +7,28 @@ import {
|
|
|
7
7
|
import { Main, Header, Div } from '@cloudflare/elements';
|
|
8
8
|
import { Label } from '@cloudflare/component-label';
|
|
9
9
|
import { Trans } from '@cloudflare/intl-react';
|
|
10
|
+
import { Heading, Section } from './Heading';
|
|
10
11
|
|
|
11
12
|
type PageWidth = 'narrow' | 'wide' | 'unbounded';
|
|
12
13
|
|
|
13
|
-
type
|
|
14
|
-
type?: PageWidth;
|
|
15
|
-
className?: string;
|
|
16
|
-
testId?: string;
|
|
14
|
+
type PageHeaderProps = {
|
|
17
15
|
title?: React.ReactNode;
|
|
18
16
|
subtitle?: React.ReactNode;
|
|
19
17
|
description?: React.ReactNode;
|
|
20
18
|
control?: React.ReactNode;
|
|
19
|
+
children?: React.ReactNode;
|
|
21
20
|
centerHeader?: boolean;
|
|
21
|
+
beta?: boolean;
|
|
22
|
+
titleRef?: React.RefObject<HTMLHeadingElement>;
|
|
23
|
+
subtitleRef?: React.RefObject<HTMLHeadingElement>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type Props = PageHeaderProps & {
|
|
27
|
+
type?: PageWidth;
|
|
28
|
+
className?: string;
|
|
29
|
+
testId?: string;
|
|
22
30
|
sidebar?: React.ReactNode;
|
|
23
31
|
sidebarPosition?: 'outside' | 'inside' | 'left';
|
|
24
|
-
beta?: boolean;
|
|
25
|
-
children?: any;
|
|
26
32
|
autofocus?: boolean;
|
|
27
33
|
};
|
|
28
34
|
|
|
@@ -32,33 +38,6 @@ const maxWidthByType = {
|
|
|
32
38
|
unbounded: '100%'
|
|
33
39
|
};
|
|
34
40
|
|
|
35
|
-
const PageTitle = createComponent(
|
|
36
|
-
({ theme }) => ({
|
|
37
|
-
fontSize: theme.fontSizes[6],
|
|
38
|
-
marginTop: theme.space[0],
|
|
39
|
-
marginBottom: theme.space[0],
|
|
40
|
-
lineHeight: 1.25,
|
|
41
|
-
color: theme.colors.gray[1],
|
|
42
|
-
fontWeight: 600
|
|
43
|
-
}),
|
|
44
|
-
'h1'
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
PageTitle.displayName = 'Title';
|
|
48
|
-
|
|
49
|
-
const PageSubtitle = createComponent(
|
|
50
|
-
({ theme }) => ({
|
|
51
|
-
fontSize: theme.fontSizes[5],
|
|
52
|
-
marginBottom: theme.space[0],
|
|
53
|
-
lineHeight: 1.25,
|
|
54
|
-
color: theme.colors.gray[3],
|
|
55
|
-
fontWeight: 400
|
|
56
|
-
}),
|
|
57
|
-
'h2'
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
PageTitle.displayName = 'PageSubtitle';
|
|
61
|
-
|
|
62
41
|
const PageDescription = createComponent(
|
|
63
42
|
({ theme }) => ({
|
|
64
43
|
fontSize: theme.fontSizes[4],
|
|
@@ -72,18 +51,85 @@ const PageDescription = createComponent(
|
|
|
72
51
|
|
|
73
52
|
PageDescription.displayName = 'PageDescription';
|
|
74
53
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
lineHeight: 1.25,
|
|
80
|
-
color: theme.colors.gray[3],
|
|
81
|
-
fontWeight: 400
|
|
82
|
-
}),
|
|
83
|
-
'h2'
|
|
84
|
-
);
|
|
54
|
+
type ControlWrapperProps = {
|
|
55
|
+
control?: React.ReactNode;
|
|
56
|
+
children: React.ReactNode;
|
|
57
|
+
};
|
|
85
58
|
|
|
86
|
-
|
|
59
|
+
const ControlWrapper = ({ control, children }: ControlWrapperProps) => {
|
|
60
|
+
return control ? (
|
|
61
|
+
<Div display={['block', 'flex']} justifyContent="space-between">
|
|
62
|
+
{children}
|
|
63
|
+
{control}
|
|
64
|
+
</Div>
|
|
65
|
+
) : (
|
|
66
|
+
<>{children}</>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const maxPageTitles = 2;
|
|
71
|
+
|
|
72
|
+
const PageHeader = ({
|
|
73
|
+
title,
|
|
74
|
+
subtitle,
|
|
75
|
+
description,
|
|
76
|
+
centerHeader,
|
|
77
|
+
control,
|
|
78
|
+
children,
|
|
79
|
+
beta,
|
|
80
|
+
titleRef,
|
|
81
|
+
subtitleRef
|
|
82
|
+
}: PageHeaderProps) => {
|
|
83
|
+
const headerVisible = !!(title || subtitle || description);
|
|
84
|
+
const titlesCount = Math.min(
|
|
85
|
+
[title, subtitle, description].filter(Boolean).length,
|
|
86
|
+
2
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<>
|
|
91
|
+
<ControlWrapper control={control}>
|
|
92
|
+
<Header
|
|
93
|
+
mb={headerVisible ? 3 : 0}
|
|
94
|
+
textAlign={centerHeader ? 'center' : undefined}
|
|
95
|
+
>
|
|
96
|
+
{title && (
|
|
97
|
+
<Heading innerRef={titleRef}>
|
|
98
|
+
{title}
|
|
99
|
+
{beta && (
|
|
100
|
+
<Label hue="orange" ml={2} verticalAlign="middle">
|
|
101
|
+
<Trans _="Beta" id="common.beta" />
|
|
102
|
+
</Label>
|
|
103
|
+
)}
|
|
104
|
+
</Heading>
|
|
105
|
+
)}
|
|
106
|
+
{subtitle && (
|
|
107
|
+
<Heading
|
|
108
|
+
level={title ? 2 : 1}
|
|
109
|
+
offset={title ? 0 : 1}
|
|
110
|
+
innerRef={subtitleRef}
|
|
111
|
+
>
|
|
112
|
+
{subtitle}
|
|
113
|
+
</Heading>
|
|
114
|
+
)}
|
|
115
|
+
{description &&
|
|
116
|
+
(subtitle ? (
|
|
117
|
+
<PageDescription>{description}</PageDescription>
|
|
118
|
+
) : (
|
|
119
|
+
<Heading level={2} fontSize={4} color="gray.3">
|
|
120
|
+
{description}
|
|
121
|
+
</Heading>
|
|
122
|
+
))}
|
|
123
|
+
</Header>
|
|
124
|
+
</ControlWrapper>
|
|
125
|
+
<Section level={titlesCount} offset={maxPageTitles - titlesCount}>
|
|
126
|
+
{children}
|
|
127
|
+
</Section>
|
|
128
|
+
</>
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
PageHeader.displayName = 'PageHeader';
|
|
87
133
|
|
|
88
134
|
// firstPage is used when dealing with focus. When navigating the dash, focus
|
|
89
135
|
// jumps to the page content, but not when the dash is initially loaded.
|
|
@@ -119,6 +165,8 @@ const Page = ({
|
|
|
119
165
|
sidebarPosition = 'inside',
|
|
120
166
|
autofocus = true,
|
|
121
167
|
control,
|
|
168
|
+
titleRef,
|
|
169
|
+
subtitleRef,
|
|
122
170
|
children
|
|
123
171
|
}: Props) => {
|
|
124
172
|
const history = useHistory();
|
|
@@ -138,56 +186,20 @@ const Page = ({
|
|
|
138
186
|
}
|
|
139
187
|
}, [path]);
|
|
140
188
|
|
|
141
|
-
const headerVisible = !!(title || subtitle || description);
|
|
142
|
-
|
|
143
|
-
let header = (
|
|
144
|
-
<Header
|
|
145
|
-
mb={headerVisible ? 3 : 0}
|
|
146
|
-
textAlign={centerHeader ? 'center' : undefined}
|
|
147
|
-
>
|
|
148
|
-
{title && (
|
|
149
|
-
<PageTitle>
|
|
150
|
-
{title}
|
|
151
|
-
{beta && (
|
|
152
|
-
<Label hue="orange" ml={2} verticalAlign="middle">
|
|
153
|
-
<Trans _="Beta" id="common.beta" />
|
|
154
|
-
</Label>
|
|
155
|
-
)}
|
|
156
|
-
</PageTitle>
|
|
157
|
-
)}
|
|
158
|
-
{subtitle && <PageSubtitle>{subtitle}</PageSubtitle>}
|
|
159
|
-
{description &&
|
|
160
|
-
(subtitle ? (
|
|
161
|
-
<PageDescription>{description}</PageDescription>
|
|
162
|
-
) : (
|
|
163
|
-
<PageSubtitleDescription>{description}</PageSubtitleDescription>
|
|
164
|
-
))}
|
|
165
|
-
</Header>
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
if (control) {
|
|
169
|
-
header = (
|
|
170
|
-
<Div display={['block', 'flex']} justifyContent="space-between">
|
|
171
|
-
{header}
|
|
172
|
-
{control}
|
|
173
|
-
</Div>
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
189
|
const sidebarInside = sidebarPosition === 'inside';
|
|
178
|
-
const width = type === 'unbounded' ? '100%' : '90%';
|
|
179
190
|
|
|
180
191
|
return (
|
|
181
192
|
<Main
|
|
182
193
|
data-testid={testId}
|
|
183
194
|
className={className}
|
|
184
195
|
display={sidebar && sidebarInside ? undefined : 'flex'}
|
|
196
|
+
py={4}
|
|
185
197
|
>
|
|
186
198
|
<Div
|
|
187
199
|
ml="auto"
|
|
188
200
|
mr={sidebar && !sidebarInside ? 0 : 'auto'}
|
|
189
201
|
display={sidebar ? ['block', 'block', 'flex'] : undefined}
|
|
190
|
-
width={
|
|
202
|
+
width={type === 'unbounded' ? '100%' : '90%'}
|
|
191
203
|
maxWidth={maxWidthByType[type] || maxWidthByType.narrow}
|
|
192
204
|
>
|
|
193
205
|
<Div
|
|
@@ -196,8 +208,18 @@ const Page = ({
|
|
|
196
208
|
mt={0}
|
|
197
209
|
>
|
|
198
210
|
<a id="skipTarget" ref={skipTargetRef} tabIndex={-1} />
|
|
199
|
-
|
|
200
|
-
|
|
211
|
+
|
|
212
|
+
<PageHeader
|
|
213
|
+
title={title}
|
|
214
|
+
subtitle={subtitle}
|
|
215
|
+
description={description}
|
|
216
|
+
centerHeader={centerHeader}
|
|
217
|
+
control={control}
|
|
218
|
+
children={children}
|
|
219
|
+
beta={beta}
|
|
220
|
+
titleRef={titleRef}
|
|
221
|
+
subtitleRef={subtitleRef}
|
|
222
|
+
/>
|
|
201
223
|
</Div>
|
|
202
224
|
{sidebar && sidebarInside && (
|
|
203
225
|
<Div width={[1, 1, 1 / 3]} pl={[0, 0, 3]} pt={[4, 4, 0]}>
|
package/src/index.ts
CHANGED