@cloudflare/component-page 4.2.511 → 5.1.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/CHANGELOG.md +60 -0
- package/README.md +2 -5
- package/dist/Heading.d.ts +14 -0
- package/dist/Page.d.ts +18 -260
- package/dist/index.d.ts +3 -327
- package/es/Heading.js +81 -0
- package/es/Page.js +159 -5
- package/es/index.js +3 -5
- package/lib/Heading.js +101 -0
- package/lib/Page.js +176 -4
- package/lib/index.js +12 -12
- package/package.json +7 -6
- package/src/Heading.tsx +107 -0
- package/src/Page.tsx +225 -7
- package/src/index.ts +3 -6
- package/dist/PageContent.d.ts +0 -10
- package/dist/PageHeader.d.ts +0 -8
- package/es/PageContent.js +0 -29
- package/es/PageHeader.js +0 -50
- package/lib/PageContent.js +0 -43
- package/lib/PageHeader.js +0 -67
- package/src/PageContent.tsx +0 -34
- package/src/PageHeader.tsx +0 -66
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
|
@@ -1,18 +1,190 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
4
|
+
|
|
3
5
|
Object.defineProperty(exports, "__esModule", {
|
|
4
6
|
value: true
|
|
5
7
|
});
|
|
6
8
|
exports.default = void 0;
|
|
7
9
|
|
|
10
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
+
|
|
12
|
+
var _reactRouterDom = require("react-router-dom");
|
|
13
|
+
|
|
8
14
|
var _styleContainer = require("@cloudflare/style-container");
|
|
9
15
|
|
|
10
|
-
var
|
|
16
|
+
var _elements = require("@cloudflare/elements");
|
|
17
|
+
|
|
18
|
+
var _componentLabel = require("@cloudflare/component-label");
|
|
19
|
+
|
|
20
|
+
var _intlReact = require("@cloudflare/intl-react");
|
|
21
|
+
|
|
22
|
+
var _Heading = require("./Heading");
|
|
23
|
+
|
|
24
|
+
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
|
|
25
|
+
|
|
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; }
|
|
27
|
+
|
|
28
|
+
var maxWidthByType = {
|
|
29
|
+
narrow: '64em',
|
|
30
|
+
wide: '79em',
|
|
31
|
+
unbounded: '100%'
|
|
32
|
+
};
|
|
33
|
+
var PageDescription = (0, _styleContainer.createComponent)(function (_ref) {
|
|
34
|
+
var theme = _ref.theme;
|
|
35
|
+
return {
|
|
36
|
+
fontSize: theme.fontSizes[4],
|
|
37
|
+
marginBottom: theme.space[0],
|
|
38
|
+
lineHeight: 1.25,
|
|
39
|
+
color: theme.colors.gray[3],
|
|
40
|
+
fontWeight: 400
|
|
41
|
+
};
|
|
42
|
+
}, 'p');
|
|
43
|
+
PageDescription.displayName = 'PageDescription';
|
|
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
|
+
var headerVisible = !!(title || subtitle || description);
|
|
65
|
+
var titlesCount = Math.min([title, subtitle, description].filter(Boolean).length, 2);
|
|
66
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(ControlWrapper, {
|
|
67
|
+
control: control
|
|
68
|
+
}, /*#__PURE__*/_react.default.createElement(_elements.Header, {
|
|
69
|
+
mb: headerVisible ? 3 : 0,
|
|
70
|
+
textAlign: centerHeader ? 'center' : undefined
|
|
71
|
+
}, title && /*#__PURE__*/_react.default.createElement(_Heading.Heading, null, title, beta && /*#__PURE__*/_react.default.createElement(_componentLabel.Label, {
|
|
72
|
+
hue: "orange",
|
|
73
|
+
ml: 2,
|
|
74
|
+
verticalAlign: "middle"
|
|
75
|
+
}, /*#__PURE__*/_react.default.createElement(_intlReact.Trans, {
|
|
76
|
+
_: "Beta",
|
|
77
|
+
id: "common.beta"
|
|
78
|
+
}))), subtitle && /*#__PURE__*/_react.default.createElement(_Heading.Heading, {
|
|
79
|
+
level: title ? 2 : 1,
|
|
80
|
+
offset: title ? 0 : 1
|
|
81
|
+
}, subtitle), description && (subtitle ? /*#__PURE__*/_react.default.createElement(PageDescription, null, description) : /*#__PURE__*/_react.default.createElement(_Heading.Heading, {
|
|
82
|
+
level: 2,
|
|
83
|
+
fontSize: 4,
|
|
84
|
+
color: "gray.3"
|
|
85
|
+
}, description)))), /*#__PURE__*/_react.default.createElement(_Heading.Section, {
|
|
86
|
+
level: titlesCount,
|
|
87
|
+
offset: maxPageTitles - titlesCount
|
|
88
|
+
}, children));
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
PageHeader.displayName = 'PageHeader'; // firstPage is used when dealing with focus. When navigating the dash, focus
|
|
92
|
+
// jumps to the page content, but not when the dash is initially loaded.
|
|
93
|
+
|
|
94
|
+
var firstPage = ''; // firstLoad is used to ensure focus is handled correctly if the user navigates
|
|
95
|
+
// back to the first page that was loaded.
|
|
96
|
+
|
|
97
|
+
var firstLoad = true; // Workaround for a bug where elements don't focus correctly.
|
|
98
|
+
|
|
99
|
+
var maxFocusAttempts = 10;
|
|
100
|
+
|
|
101
|
+
var focus = function focus(el) {
|
|
102
|
+
var attempt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
103
|
+
el === null || el === void 0 ? void 0 : el.focus();
|
|
104
|
+
|
|
105
|
+
if (typeof document !== 'undefined' && document.activeElement !== el && attempt < maxFocusAttempts) {
|
|
106
|
+
setTimeout(function () {
|
|
107
|
+
return focus(el, attempt + 1);
|
|
108
|
+
}, 10);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
var Page = function Page(_ref4) {
|
|
113
|
+
var _history$location;
|
|
114
|
+
|
|
115
|
+
var title = _ref4.title,
|
|
116
|
+
subtitle = _ref4.subtitle,
|
|
117
|
+
description = _ref4.description,
|
|
118
|
+
centerHeader = _ref4.centerHeader,
|
|
119
|
+
beta = _ref4.beta,
|
|
120
|
+
testId = _ref4.testId,
|
|
121
|
+
className = _ref4.className,
|
|
122
|
+
sidebar = _ref4.sidebar,
|
|
123
|
+
_ref4$type = _ref4.type,
|
|
124
|
+
type = _ref4$type === void 0 ? 'wide' : _ref4$type,
|
|
125
|
+
_ref4$sidebarPosition = _ref4.sidebarPosition,
|
|
126
|
+
sidebarPosition = _ref4$sidebarPosition === void 0 ? 'inside' : _ref4$sidebarPosition,
|
|
127
|
+
_ref4$autofocus = _ref4.autofocus,
|
|
128
|
+
autofocus = _ref4$autofocus === void 0 ? true : _ref4$autofocus,
|
|
129
|
+
control = _ref4.control,
|
|
130
|
+
children = _ref4.children;
|
|
131
|
+
var history = (0, _reactRouterDom.useHistory)();
|
|
132
|
+
var skipTargetRef = (0, _react.useRef)(null);
|
|
133
|
+
var path = history === null || history === void 0 ? void 0 : (_history$location = history.location) === null || _history$location === void 0 ? void 0 : _history$location.pathname;
|
|
134
|
+
(0, _react.useEffect)(function () {
|
|
135
|
+
// If autofocus is enabled, then focus will move to the title block when
|
|
136
|
+
// the page is navigated to (but not when the dash is first loaded)
|
|
137
|
+
if (autofocus) {
|
|
138
|
+
if (!firstPage) {
|
|
139
|
+
firstPage = path;
|
|
140
|
+
} else if (firstPage !== path || !firstLoad) {
|
|
141
|
+
focus(skipTargetRef.current);
|
|
142
|
+
firstLoad = false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}, [path]);
|
|
146
|
+
var sidebarInside = sidebarPosition === 'inside';
|
|
147
|
+
return /*#__PURE__*/_react.default.createElement(_elements.Main, {
|
|
148
|
+
"data-testid": testId,
|
|
149
|
+
className: className,
|
|
150
|
+
display: sidebar && sidebarInside ? undefined : 'flex',
|
|
151
|
+
py: 4
|
|
152
|
+
}, /*#__PURE__*/_react.default.createElement(_elements.Div, {
|
|
153
|
+
ml: "auto",
|
|
154
|
+
mr: sidebar && !sidebarInside ? 0 : 'auto',
|
|
155
|
+
display: sidebar ? ['block', 'block', 'flex'] : undefined,
|
|
156
|
+
width: type === 'unbounded' ? '100%' : '90%',
|
|
157
|
+
maxWidth: maxWidthByType[type] || maxWidthByType.narrow
|
|
158
|
+
}, /*#__PURE__*/_react.default.createElement(_elements.Div, {
|
|
159
|
+
width: sidebar && sidebarInside ? [1, 1, 2 / 3] : undefined,
|
|
160
|
+
pr: sidebar && sidebarInside ? [0, 0, 3] : undefined,
|
|
161
|
+
mt: 0
|
|
162
|
+
}, /*#__PURE__*/_react.default.createElement("a", {
|
|
163
|
+
id: "skipTarget",
|
|
164
|
+
ref: skipTargetRef,
|
|
165
|
+
tabIndex: -1
|
|
166
|
+
}), /*#__PURE__*/_react.default.createElement(PageHeader, {
|
|
167
|
+
title: title,
|
|
168
|
+
subtitle: subtitle,
|
|
169
|
+
description: description,
|
|
170
|
+
centerHeader: centerHeader,
|
|
171
|
+
control: control,
|
|
172
|
+
children: children,
|
|
173
|
+
beta: beta
|
|
174
|
+
})), sidebar && sidebarInside && /*#__PURE__*/_react.default.createElement(_elements.Div, {
|
|
175
|
+
width: [1, 1, 1 / 3],
|
|
176
|
+
pl: [0, 0, 3],
|
|
177
|
+
pt: [4, 4, 0]
|
|
178
|
+
}, sidebar)), !sidebarInside && sidebar);
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
Page.displayName = 'Page';
|
|
182
|
+
|
|
183
|
+
var _default = (0, _styleContainer.createStyledComponent)(function () {
|
|
11
184
|
return {
|
|
12
185
|
py: 4,
|
|
13
186
|
minHeight: 411
|
|
14
187
|
};
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
var _default = Page;
|
|
188
|
+
}, Page);
|
|
189
|
+
|
|
18
190
|
exports.default = _default;
|
package/lib/index.js
CHANGED
|
@@ -3,27 +3,27 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
Object.defineProperty(exports, "
|
|
6
|
+
Object.defineProperty(exports, "Page", {
|
|
7
7
|
enumerable: true,
|
|
8
8
|
get: function get() {
|
|
9
|
-
return
|
|
9
|
+
return _Page.default;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
-
Object.defineProperty(exports, "
|
|
12
|
+
Object.defineProperty(exports, "Heading", {
|
|
13
13
|
enumerable: true,
|
|
14
14
|
get: function get() {
|
|
15
|
-
return
|
|
15
|
+
return _Heading.Heading;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "Section", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function get() {
|
|
21
|
+
return _Heading.Section;
|
|
16
22
|
}
|
|
17
23
|
});
|
|
18
|
-
exports.Page = void 0;
|
|
19
24
|
|
|
20
25
|
var _Page = _interopRequireDefault(require("./Page"));
|
|
21
26
|
|
|
22
|
-
var
|
|
23
|
-
|
|
24
|
-
var _PageContent = _interopRequireDefault(require("./PageContent"));
|
|
25
|
-
|
|
26
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
27
|
+
var _Heading = require("./Heading");
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
exports.Page = Page;
|
|
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": "
|
|
4
|
+
"version": "5.1.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "es/index.js",
|
|
7
7
|
"author": "James Kyle <jkyle@cloudflare.com>",
|
|
@@ -11,10 +11,11 @@
|
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@cloudflare/component-label": "^3.3.
|
|
15
|
-
"@cloudflare/
|
|
16
|
-
"@cloudflare/
|
|
17
|
-
"
|
|
14
|
+
"@cloudflare/component-label": "^3.3.29",
|
|
15
|
+
"@cloudflare/elements": "^1.11.31",
|
|
16
|
+
"@cloudflare/intl-react": "^1.9.17",
|
|
17
|
+
"@cloudflare/style-container": "^7.5.20",
|
|
18
|
+
"react-router-dom": "^5.1.0"
|
|
18
19
|
},
|
|
19
20
|
"peerDependencies": {
|
|
20
21
|
"react": "^15.0.0-0 || ^16.0.0-0 || ^17.0.0-0"
|
|
@@ -30,5 +31,5 @@
|
|
|
30
31
|
"test-coverage": "stratus test --coverage",
|
|
31
32
|
"test-watch": "stratus test --watch"
|
|
32
33
|
},
|
|
33
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "e1f1fecb460540213dd9f08e78e91e8d71dcbe27"
|
|
34
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
|
+
}
|