@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 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
@@ -1,2 +1,3 @@
1
1
  import Page from './Page';
2
- export { Page };
2
+ import { Heading, Section } from './Heading';
3
+ export { Page, Heading, Section };
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
- const PageSubtitleDescription = createComponent(({
44
- theme
45
- }) => ({
46
- fontSize: theme.fontSizes[4],
47
- marginBottom: theme.space[0],
48
- lineHeight: 1.25,
49
- color: theme.colors.gray[3],
50
- fontWeight: 400
51
- }), 'h2');
52
- PageSubtitleDescription.displayName = 'PageSubtitleDescription'; // firstPage is used when dealing with focus. When navigating the dash, focus
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: ['100%', width, 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
- }), header, children), sidebar && sidebarInside && /*#__PURE__*/React.createElement(Div, {
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
@@ -1,2 +1,3 @@
1
1
  import Page from './Page';
2
- export { Page };
2
+ import { Heading, Section } from './Heading';
3
+ export { Page, Heading, Section };
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 PageTitle = (0, _styleContainer.createComponent)(function (_ref) {
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
- var PageSubtitleDescription = (0, _styleContainer.createComponent)(function (_ref4) {
66
- var theme = _ref4.theme;
67
- return {
68
- fontSize: theme.fontSizes[4],
69
- marginBottom: theme.space[0],
70
- lineHeight: 1.25,
71
- color: theme.colors.gray[3],
72
- fontWeight: 400
73
- };
74
- }, 'h2');
75
- PageSubtitleDescription.displayName = 'PageSubtitleDescription'; // firstPage is used when dealing with focus. When navigating the dash, focus
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(_ref5) {
117
+ var Page = function Page(_ref4) {
97
118
  var _history$location;
98
119
 
99
- var title = _ref5.title,
100
- subtitle = _ref5.subtitle,
101
- description = _ref5.description,
102
- centerHeader = _ref5.centerHeader,
103
- beta = _ref5.beta,
104
- testId = _ref5.testId,
105
- className = _ref5.className,
106
- sidebar = _ref5.sidebar,
107
- _ref5$type = _ref5.type,
108
- type = _ref5$type === void 0 ? 'wide' : _ref5$type,
109
- _ref5$sidebarPosition = _ref5.sidebarPosition,
110
- sidebarPosition = _ref5$sidebarPosition === void 0 ? 'inside' : _ref5$sidebarPosition,
111
- _ref5$autofocus = _ref5.autofocus,
112
- autofocus = _ref5$autofocus === void 0 ? true : _ref5$autofocus,
113
- control = _ref5.control,
114
- children = _ref5.children;
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: ['100%', width, 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
- }), header, children), sidebar && sidebarInside && /*#__PURE__*/_react.default.createElement(_elements.Div, {
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.0.1",
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.29",
15
- "@cloudflare/elements": "^1.11.31",
16
- "@cloudflare/intl-react": "^1.9.17",
17
- "@cloudflare/style-container": "^7.5.20",
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": "33e724b3b47f1a0afbbf27e0e868959b34e04945"
34
+ "gitHead": "ceaeb1a7b750bec5b0dfc6edbba94bf2ddac31bf"
35
35
  }
@@ -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 Props = {
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
- const PageSubtitleDescription = createComponent(
76
- ({ theme }) => ({
77
- fontSize: theme.fontSizes[4],
78
- marginBottom: theme.space[0],
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
- PageSubtitleDescription.displayName = 'PageSubtitleDescription';
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={['100%', width, 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
- {header}
200
- {children}
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
@@ -1,3 +1,4 @@
1
1
  import Page from './Page';
2
+ import { Heading, Section } from './Heading';
2
3
 
3
- export { Page };
4
+ export { Page, Heading, Section };