@canonical/react-components 2.7.9 → 2.8.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/dist/components/SidePanel/SidePanel.d.ts +55 -0
- package/dist/components/SidePanel/SidePanel.js +97 -0
- package/dist/components/SidePanel/SidePanel.scss +45 -0
- package/dist/components/SidePanel/SidePanel.stories.d.ts +11 -0
- package/dist/components/SidePanel/SidePanel.stories.js +176 -0
- package/dist/components/SidePanel/SidePanel.test.d.ts +1 -0
- package/dist/components/SidePanel/common/Content.d.ts +7 -0
- package/dist/components/SidePanel/common/Content.js +19 -0
- package/dist/components/SidePanel/common/Footer.d.ts +7 -0
- package/dist/components/SidePanel/common/Footer.js +22 -0
- package/dist/components/SidePanel/common/Header.d.ts +7 -0
- package/dist/components/SidePanel/common/Header.js +19 -0
- package/dist/components/SidePanel/common/HeaderControls.d.ts +7 -0
- package/dist/components/SidePanel/common/HeaderControls.js +19 -0
- package/dist/components/SidePanel/common/HeaderTitle.d.ts +6 -0
- package/dist/components/SidePanel/common/HeaderTitle.js +19 -0
- package/dist/components/SidePanel/common/Sticky.d.ts +8 -0
- package/dist/components/SidePanel/common/Sticky.js +23 -0
- package/dist/components/SidePanel/index.d.ts +1 -0
- package/dist/components/SidePanel/index.js +13 -0
- package/dist/esm/components/SidePanel/SidePanel.d.ts +55 -0
- package/dist/esm/components/SidePanel/SidePanel.js +91 -0
- package/dist/esm/components/SidePanel/SidePanel.scss +45 -0
- package/dist/esm/components/SidePanel/SidePanel.stories.d.ts +11 -0
- package/dist/esm/components/SidePanel/SidePanel.stories.js +167 -0
- package/dist/esm/components/SidePanel/SidePanel.test.d.ts +1 -0
- package/dist/esm/components/SidePanel/common/Content.d.ts +7 -0
- package/dist/esm/components/SidePanel/common/Content.js +12 -0
- package/dist/esm/components/SidePanel/common/Footer.d.ts +7 -0
- package/dist/esm/components/SidePanel/common/Footer.js +15 -0
- package/dist/esm/components/SidePanel/common/Header.d.ts +7 -0
- package/dist/esm/components/SidePanel/common/Header.js +12 -0
- package/dist/esm/components/SidePanel/common/HeaderControls.d.ts +7 -0
- package/dist/esm/components/SidePanel/common/HeaderControls.js +12 -0
- package/dist/esm/components/SidePanel/common/HeaderTitle.d.ts +6 -0
- package/dist/esm/components/SidePanel/common/HeaderTitle.js +12 -0
- package/dist/esm/components/SidePanel/common/Sticky.d.ts +8 -0
- package/dist/esm/components/SidePanel/common/Sticky.js +16 -0
- package/dist/esm/components/SidePanel/index.d.ts +1 -0
- package/dist/esm/components/SidePanel/index.js +1 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { FC, PropsWithChildren, ReactNode } from "react";
|
|
2
|
+
import { type ContentProps } from "./common/Content";
|
|
3
|
+
import { type FooterProps } from "./common/Footer";
|
|
4
|
+
import { type HeaderProps } from "./common/Header";
|
|
5
|
+
import { type HeaderControlsProps } from "./common/HeaderControls";
|
|
6
|
+
import { type HeaderTitleProps } from "./common/HeaderTitle";
|
|
7
|
+
import { type StickyProps } from "./common/Sticky";
|
|
8
|
+
import "./SidePanel.scss";
|
|
9
|
+
/**
|
|
10
|
+
* The props for the SidePanelComponent component.
|
|
11
|
+
*/
|
|
12
|
+
export type Props = {
|
|
13
|
+
/**
|
|
14
|
+
* The content of the side panel.
|
|
15
|
+
*/
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* Additional CSS classes to apply.
|
|
19
|
+
*/
|
|
20
|
+
className?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Whether the side panel has an error. This will show an error message in the panel instead of rendering the children.
|
|
23
|
+
*/
|
|
24
|
+
hasError?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the side panel is currently loading. This will show a spinner in the panel instead of rendering the children.
|
|
27
|
+
*/
|
|
28
|
+
loading?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the side panel is an overlay with background or should allow seeing the content below it.
|
|
31
|
+
*/
|
|
32
|
+
overlay?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The ID of the parent element to which the side panel will be appended
|
|
35
|
+
*/
|
|
36
|
+
parentId?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Whether the side panel should be pinned. When pinned, it will remain visible alongside the main content.
|
|
39
|
+
*/
|
|
40
|
+
pinned?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Width of the side panel, available options are wide and narrow and the default.
|
|
43
|
+
*/
|
|
44
|
+
width?: "wide" | "narrow" | "";
|
|
45
|
+
};
|
|
46
|
+
type SidePanelComponents = FC<Props> & {
|
|
47
|
+
Header: FC<PropsWithChildren & HeaderProps>;
|
|
48
|
+
HeaderTitle: FC<PropsWithChildren & HeaderTitleProps>;
|
|
49
|
+
HeaderControls: FC<PropsWithChildren & HeaderControlsProps>;
|
|
50
|
+
Sticky: FC<PropsWithChildren & StickyProps>;
|
|
51
|
+
Content: FC<PropsWithChildren & ContentProps>;
|
|
52
|
+
Footer: FC<PropsWithChildren & FooterProps>;
|
|
53
|
+
};
|
|
54
|
+
declare const SidePanel: SidePanelComponents;
|
|
55
|
+
export default SidePanel;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
var _reactDom = require("react-dom");
|
|
10
|
+
var _Content = _interopRequireDefault(require("./common/Content"));
|
|
11
|
+
var _Footer = _interopRequireDefault(require("./common/Footer"));
|
|
12
|
+
var _Header = _interopRequireDefault(require("./common/Header"));
|
|
13
|
+
var _HeaderControls = _interopRequireDefault(require("./common/HeaderControls"));
|
|
14
|
+
var _HeaderTitle = _interopRequireDefault(require("./common/HeaderTitle"));
|
|
15
|
+
var _Sticky = _interopRequireDefault(require("./common/Sticky"));
|
|
16
|
+
var _AppAside = _interopRequireDefault(require("../ApplicationLayout/AppAside"));
|
|
17
|
+
var _Spinner = _interopRequireDefault(require("../Spinner"));
|
|
18
|
+
require("./SidePanel.scss");
|
|
19
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
20
|
+
/**
|
|
21
|
+
* The props for the SidePanelComponent component.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
This is a [React](https://reactjs.org/) component for the Vanilla application layout [Side Panel](https://vanillaframework.io/docs/layouts/application#panels).
|
|
26
|
+
|
|
27
|
+
The sidepanel component should be used to show additional information relating to the main content on the page. It is using a composable structure with building blocks:
|
|
28
|
+
|
|
29
|
+
* **SidePanel.Header:** Defines the header of the side panel, which can include a title and controls.
|
|
30
|
+
|
|
31
|
+
* **SidePanel.HeaderTitle:** To show the title of the side panel as heading.
|
|
32
|
+
|
|
33
|
+
* **SidePanel.HeaderControls:** To show controls in the header, such as buttons or icons for actions like closing the panel.
|
|
34
|
+
|
|
35
|
+
* **SidePanel.Sticky:** Can be wrapped around the header or footer to make them sticky when scrolling.
|
|
36
|
+
|
|
37
|
+
* **SidePanel.Content:** To show the main content of the side panel.
|
|
38
|
+
|
|
39
|
+
* **SidePanel.Footer:** To show additional information or actions at the bottom of the side panel.
|
|
40
|
+
|
|
41
|
+
## Example
|
|
42
|
+
|
|
43
|
+
Usage of the composable structure:
|
|
44
|
+
|
|
45
|
+
```jsx
|
|
46
|
+
<SidePanel className="u-no-padding--top u-no-padding--bottom">
|
|
47
|
+
<SidePanel.Sticky>
|
|
48
|
+
<SidePanel.Header>
|
|
49
|
+
<SidePanel.HeaderTitle>Edit panel</SidePanel.HeaderTitle>
|
|
50
|
+
</SidePanel.Header>
|
|
51
|
+
</SidePanel.Sticky>
|
|
52
|
+
<SidePanel.Content className="u-no-padding">
|
|
53
|
+
<p>Here be dragons!</p>
|
|
54
|
+
</SidePanel.Content>
|
|
55
|
+
<SidePanel.Sticky position="bottom">
|
|
56
|
+
<SidePanel.Footer className="u-align--right">
|
|
57
|
+
<Button appearance="base">Cancel</Button>
|
|
58
|
+
<ActionButton appearance="positive">Save changes</ActionButton>
|
|
59
|
+
</SidePanel.Footer>
|
|
60
|
+
</SidePanel.Sticky>
|
|
61
|
+
</SidePanel>
|
|
62
|
+
```
|
|
63
|
+
*/
|
|
64
|
+
const SidePanelComponent = _ref => {
|
|
65
|
+
let {
|
|
66
|
+
children,
|
|
67
|
+
className,
|
|
68
|
+
hasError = false,
|
|
69
|
+
loading = false,
|
|
70
|
+
overlay,
|
|
71
|
+
pinned,
|
|
72
|
+
width = "",
|
|
73
|
+
parentId = "l-application"
|
|
74
|
+
} = _ref;
|
|
75
|
+
const container = document.getElementById(parentId) || document.body;
|
|
76
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/(0, _reactDom.createPortal)( /*#__PURE__*/_react.default.createElement(_AppAside.default, {
|
|
77
|
+
className: (0, _classnames.default)("side-panel", className, {
|
|
78
|
+
"is-overlay": overlay
|
|
79
|
+
}),
|
|
80
|
+
"aria-label": "Side panel",
|
|
81
|
+
pinned: pinned,
|
|
82
|
+
narrow: width === "narrow",
|
|
83
|
+
wide: width === "wide"
|
|
84
|
+
}, loading ? /*#__PURE__*/_react.default.createElement("div", {
|
|
85
|
+
className: "loading"
|
|
86
|
+
}, /*#__PURE__*/_react.default.createElement(_Spinner.default, null)) : hasError ? /*#__PURE__*/_react.default.createElement("div", {
|
|
87
|
+
className: "error"
|
|
88
|
+
}, "Loading failed") : children), container));
|
|
89
|
+
};
|
|
90
|
+
const SidePanel = SidePanelComponent;
|
|
91
|
+
SidePanel.Header = _Header.default;
|
|
92
|
+
SidePanel.HeaderTitle = _HeaderTitle.default;
|
|
93
|
+
SidePanel.HeaderControls = _HeaderControls.default;
|
|
94
|
+
SidePanel.Sticky = _Sticky.default;
|
|
95
|
+
SidePanel.Content = _Content.default;
|
|
96
|
+
SidePanel.Footer = _Footer.default;
|
|
97
|
+
var _default = exports.default = SidePanel;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
@import "vanilla-framework";
|
|
2
|
+
|
|
3
|
+
.side-panel.is-overlay {
|
|
4
|
+
position: absolute;
|
|
5
|
+
right: 0;
|
|
6
|
+
z-index: 103 !important;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.side-panel {
|
|
10
|
+
background-color: $colors--theme--background-default;
|
|
11
|
+
height: 100dvh;
|
|
12
|
+
padding: 0 $sph--x-large;
|
|
13
|
+
padding-bottom: $spv--medium;
|
|
14
|
+
padding-top: $spv--small;
|
|
15
|
+
|
|
16
|
+
.error,
|
|
17
|
+
.loading {
|
|
18
|
+
padding-top: $spv--medium;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.p-panel__header {
|
|
22
|
+
padding: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.panel-footer {
|
|
26
|
+
.rule {
|
|
27
|
+
margin-bottom: $spv--medium;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.sticky-wrapper {
|
|
32
|
+
background: $colors--theme--background-default;
|
|
33
|
+
position: sticky;
|
|
34
|
+
top: 0;
|
|
35
|
+
z-index: 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.sticky-wrapper--top {
|
|
39
|
+
top: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.sticky-wrapper--bottom {
|
|
43
|
+
bottom: 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import SidePanel from "./SidePanel";
|
|
3
|
+
declare const meta: Meta<typeof SidePanel>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof meta>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Pinned: Story;
|
|
8
|
+
export declare const Loading: Story;
|
|
9
|
+
export declare const Error: Story;
|
|
10
|
+
export declare const Narrow: Story;
|
|
11
|
+
export declare const Wide: Story;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.Wide = exports.Pinned = exports.Narrow = exports.Loading = exports.Error = exports.Default = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _SidePanel = _interopRequireDefault(require("./SidePanel"));
|
|
9
|
+
var _Button = _interopRequireDefault(require("../Button"));
|
|
10
|
+
var _Application = _interopRequireDefault(require("../ApplicationLayout/Application"));
|
|
11
|
+
var _AppMain = _interopRequireDefault(require("../ApplicationLayout/AppMain"));
|
|
12
|
+
var _index = require("../../index");
|
|
13
|
+
var _Icon = _interopRequireDefault(require("../Icon"));
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
16
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
17
|
+
const meta = {
|
|
18
|
+
component: _SidePanel.default,
|
|
19
|
+
tags: ["autodocs"],
|
|
20
|
+
decorators: [Story => {
|
|
21
|
+
const ref = (0, _react.useRef)(null);
|
|
22
|
+
(0, _react.useEffect)(() => {
|
|
23
|
+
const el = ref.current;
|
|
24
|
+
if (el) {
|
|
25
|
+
var _el$parentElement, _wrapper$parentElemen;
|
|
26
|
+
const wrapper = el === null || el === void 0 || (_el$parentElement = el.parentElement) === null || _el$parentElement === void 0 || (_el$parentElement = _el$parentElement.parentElement) === null || _el$parentElement === void 0 ? void 0 : _el$parentElement.parentElement;
|
|
27
|
+
const parent = wrapper === null || wrapper === void 0 || (_wrapper$parentElemen = wrapper.parentElement) === null || _wrapper$parentElemen === void 0 || (_wrapper$parentElemen = _wrapper$parentElemen.parentElement) === null || _wrapper$parentElemen === void 0 ? void 0 : _wrapper$parentElemen.parentElement;
|
|
28
|
+
if (wrapper) {
|
|
29
|
+
wrapper.style.setProperty("border", "0", "important");
|
|
30
|
+
}
|
|
31
|
+
if (parent) {
|
|
32
|
+
parent.style.margin = "0";
|
|
33
|
+
parent.style.padding = "0";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}, []);
|
|
37
|
+
document.body.style.padding = "0";
|
|
38
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
39
|
+
ref: ref
|
|
40
|
+
}, /*#__PURE__*/_react.default.createElement(Story, null));
|
|
41
|
+
}]
|
|
42
|
+
};
|
|
43
|
+
var _default = exports.default = meta;
|
|
44
|
+
const StoryExample = args => {
|
|
45
|
+
const [isOpen, setIsOpen] = (0, _react.useState)(false);
|
|
46
|
+
|
|
47
|
+
// Multiple stories get rendered on the docs page, ensure the ids are not colliding
|
|
48
|
+
const id = (0, _react.useId)();
|
|
49
|
+
const parentId = args.parentId + id;
|
|
50
|
+
const openPanel = () => {
|
|
51
|
+
setIsOpen(true);
|
|
52
|
+
};
|
|
53
|
+
const closePanel = () => {
|
|
54
|
+
setIsOpen(false);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Delay opening the panel, so the l-application container is ready to receive it
|
|
58
|
+
(0, _react.useEffect)(() => void setTimeout(openPanel, 100), []);
|
|
59
|
+
return /*#__PURE__*/_react.default.createElement(_Application.default, {
|
|
60
|
+
id: parentId
|
|
61
|
+
}, /*#__PURE__*/_react.default.createElement(_AppMain.default, null, /*#__PURE__*/_react.default.createElement(_Button.default, {
|
|
62
|
+
onClick: openPanel,
|
|
63
|
+
style: {
|
|
64
|
+
margin: "1rem"
|
|
65
|
+
}
|
|
66
|
+
}, "Open side panel"), /*#__PURE__*/_react.default.createElement(_Button.default, {
|
|
67
|
+
onClick: closePanel,
|
|
68
|
+
style: {
|
|
69
|
+
margin: "1rem"
|
|
70
|
+
}
|
|
71
|
+
}, "Close side panel")), isOpen && /*#__PURE__*/_react.default.createElement(_SidePanel.default, {
|
|
72
|
+
overlay: args.overlay,
|
|
73
|
+
loading: args.loading,
|
|
74
|
+
hasError: args.hasError,
|
|
75
|
+
parentId: parentId,
|
|
76
|
+
pinned: args.pinned,
|
|
77
|
+
width: args.width,
|
|
78
|
+
className: "u-no-padding--top u-no-padding--bottom"
|
|
79
|
+
}, /*#__PURE__*/_react.default.createElement(_SidePanel.default.Sticky, null, /*#__PURE__*/_react.default.createElement(_SidePanel.default.Header, null, /*#__PURE__*/_react.default.createElement(_SidePanel.default.HeaderTitle, null, "Edit panel"), /*#__PURE__*/_react.default.createElement(_SidePanel.default.HeaderControls, null, /*#__PURE__*/_react.default.createElement(_Button.default, {
|
|
80
|
+
appearance: "base",
|
|
81
|
+
className: "u-no-margin--bottom",
|
|
82
|
+
hasIcon: true,
|
|
83
|
+
onClick: closePanel,
|
|
84
|
+
"aria-label": "Close"
|
|
85
|
+
}, /*#__PURE__*/_react.default.createElement(_Icon.default, {
|
|
86
|
+
name: "close"
|
|
87
|
+
}))))), /*#__PURE__*/_react.default.createElement(_SidePanel.default.Content, {
|
|
88
|
+
className: "u-no-padding"
|
|
89
|
+
}, /*#__PURE__*/_react.default.createElement("p", null, "Here be dragons!"), /*#__PURE__*/_react.default.createElement("p", null, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras varius mi eu pretium vulputate. Nunc commodo sit amet nibh quis rhoncus. Aliquam rhoncus porttitor semper. Aenean faucibus consectetur neque in sodales. Sed cursus mauris id ex sollicitudin sodales. Quisque molestie rutrum odio, ornare pharetra ligula. Pellentesque ornare tristique feugiat. In a augue neque. Aenean eget arcu quis lacus tempus posuere in sit amet dui. Suspendisse faucibus sapien nisl, nec laoreet sem convallis nec."), /*#__PURE__*/_react.default.createElement("p", null, "Vestibulum sed placerat lorem. Nam luctus ex id nisi luctus, id vestibulum sem bibendum. Vivamus turpis sem, pellentesque fermentum malesuada eu, faucibus porta libero. Duis eget venenatis odio. Etiam sed volutpat magna, non tempus erat. Nunc id tortor ac quam consectetur dapibus ac ut tellus. Pellentesque ut tellus venenatis elit vehicula condimentum eget quis lorem. Ut non consectetur est, a fringilla ipsum. Nunc vitae ligula ipsum. Etiam suscipit, libero ut lacinia viverra, nunc urna consequat ex, vel eleifend eros mauris vitae ipsum. Pellentesque sed dictum augue. Ut sit amet ullamcorper mauris. Nunc congue orci mollis purus sodales facilisis ac ut arcu. Maecenas feugiat sapien ac massa mollis sodales. Donec vitae turpis eu nisi laoreet pulvinar quis at nisl. Integer volutpat, metus eget elementum dictum, lacus sapien viverra felis, consequat fermentum nisl mi ac dui."), /*#__PURE__*/_react.default.createElement("p", null, "Nullam nulla turpis, dignissim vel dapibus ut, volutpat ac dui. Donec vel elementum lacus. Mauris maximus nec felis at faucibus. Nunc faucibus gravida velit, id blandit lectus tincidunt ac. Vestibulum orci diam, elementum in congue eu, placerat id risus. Sed tempor tempus tellus, vitae iaculis turpis fringilla nec. Phasellus imperdiet facilisis velit, sit amet lobortis odio dignissim ut."), /*#__PURE__*/_react.default.createElement("p", null, "Nam placerat urna vitae ligula hendrerit, ac tincidunt lorem maximus. Mauris eu odio nisi. Nulla facilisi. Sed egestas elit sed velit rutrum, sit amet bibendum metus hendrerit. Pellentesque luctus placerat tellus, eu bibendum justo. Cras eget leo ac ex volutpat gravida. Duis vitae mollis ante. Duis a congue nunc. Aenean aliquet, sapien quis tincidunt tincidunt, odio eros consectetur lacus, vel finibus mauris tortor id velit. Donec tincidunt vitae purus eu interdum. Pellentesque scelerisque dui viverra ex ullamcorper volutpat. Vestibulum lacinia vitae arcu volutpat porta. Etiam et cursus nulla, id aliquet felis. Nam ultricies, urna id mattis pretium, velit erat viverra elit, eu maximus diam eros id nisi."), /*#__PURE__*/_react.default.createElement("p", null, "Nullam eget nisl lectus. Pellentesque eu mauris ut tortor malesuada sagittis. Cras dictum cursus est non ultricies. Duis mollis non neque at commodo. Nunc feugiat justo et consequat aliquam. Ut consectetur libero eu erat feugiat finibus. Duis varius convallis quam eu sagittis. Maecenas ac est arcu. Suspendisse at enim eget nibh ultricies dictum. Etiam aliquet tellus vel felis malesuada laoreet.")), /*#__PURE__*/_react.default.createElement(_SidePanel.default.Sticky, {
|
|
90
|
+
position: "bottom"
|
|
91
|
+
}, /*#__PURE__*/_react.default.createElement(_SidePanel.default.Footer, {
|
|
92
|
+
className: "u-align--right"
|
|
93
|
+
}, /*#__PURE__*/_react.default.createElement(_Button.default, {
|
|
94
|
+
appearance: "base",
|
|
95
|
+
onClick: closePanel
|
|
96
|
+
}, "Cancel"), /*#__PURE__*/_react.default.createElement(_index.ActionButton, {
|
|
97
|
+
appearance: "positive"
|
|
98
|
+
}, "Save changes")))));
|
|
99
|
+
};
|
|
100
|
+
const Default = exports.Default = {
|
|
101
|
+
args: {
|
|
102
|
+
className: "",
|
|
103
|
+
hasError: false,
|
|
104
|
+
parentId: "l-application-default",
|
|
105
|
+
pinned: false,
|
|
106
|
+
loading: false,
|
|
107
|
+
overlay: true,
|
|
108
|
+
width: ""
|
|
109
|
+
},
|
|
110
|
+
render: StoryExample
|
|
111
|
+
};
|
|
112
|
+
const Pinned = exports.Pinned = {
|
|
113
|
+
args: {
|
|
114
|
+
className: "",
|
|
115
|
+
hasError: false,
|
|
116
|
+
parentId: "l-application-pinned",
|
|
117
|
+
pinned: true,
|
|
118
|
+
loading: false,
|
|
119
|
+
overlay: false,
|
|
120
|
+
width: ""
|
|
121
|
+
},
|
|
122
|
+
render: StoryExample,
|
|
123
|
+
parameters: {
|
|
124
|
+
docs: {
|
|
125
|
+
disable: true
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const Loading = exports.Loading = {
|
|
130
|
+
args: {
|
|
131
|
+
className: "",
|
|
132
|
+
hasError: false,
|
|
133
|
+
parentId: "l-application-loading",
|
|
134
|
+
pinned: false,
|
|
135
|
+
loading: true,
|
|
136
|
+
overlay: true,
|
|
137
|
+
width: ""
|
|
138
|
+
},
|
|
139
|
+
render: StoryExample
|
|
140
|
+
};
|
|
141
|
+
const Error = exports.Error = {
|
|
142
|
+
args: {
|
|
143
|
+
className: "",
|
|
144
|
+
hasError: true,
|
|
145
|
+
parentId: "l-application-error",
|
|
146
|
+
pinned: false,
|
|
147
|
+
loading: false,
|
|
148
|
+
overlay: true,
|
|
149
|
+
width: ""
|
|
150
|
+
},
|
|
151
|
+
render: StoryExample
|
|
152
|
+
};
|
|
153
|
+
const Narrow = exports.Narrow = {
|
|
154
|
+
args: {
|
|
155
|
+
className: "",
|
|
156
|
+
hasError: false,
|
|
157
|
+
parentId: "l-application-narrow",
|
|
158
|
+
pinned: false,
|
|
159
|
+
loading: false,
|
|
160
|
+
overlay: true,
|
|
161
|
+
width: "narrow"
|
|
162
|
+
},
|
|
163
|
+
render: StoryExample
|
|
164
|
+
};
|
|
165
|
+
const Wide = exports.Wide = {
|
|
166
|
+
args: {
|
|
167
|
+
className: "",
|
|
168
|
+
hasError: false,
|
|
169
|
+
parentId: "l-application-wide",
|
|
170
|
+
pinned: false,
|
|
171
|
+
loading: false,
|
|
172
|
+
overlay: true,
|
|
173
|
+
width: "wide"
|
|
174
|
+
},
|
|
175
|
+
render: StoryExample
|
|
176
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
const Content = _ref => {
|
|
11
|
+
let {
|
|
12
|
+
children,
|
|
13
|
+
className
|
|
14
|
+
} = _ref;
|
|
15
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
16
|
+
className: (0, _classnames.default)("p-panel__content", className)
|
|
17
|
+
}, children);
|
|
18
|
+
};
|
|
19
|
+
var _default = exports.default = Content;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
const Footer = _ref => {
|
|
11
|
+
let {
|
|
12
|
+
children,
|
|
13
|
+
className
|
|
14
|
+
} = _ref;
|
|
15
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
16
|
+
className: (0, _classnames.default)("panel-footer", className),
|
|
17
|
+
id: "panel-footer"
|
|
18
|
+
}, /*#__PURE__*/_react.default.createElement("hr", {
|
|
19
|
+
className: "rule"
|
|
20
|
+
}), children);
|
|
21
|
+
};
|
|
22
|
+
var _default = exports.default = Footer;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
const Header = _ref => {
|
|
11
|
+
let {
|
|
12
|
+
children,
|
|
13
|
+
className
|
|
14
|
+
} = _ref;
|
|
15
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
16
|
+
className: (0, _classnames.default)("p-panel__header", className)
|
|
17
|
+
}, children);
|
|
18
|
+
};
|
|
19
|
+
var _default = exports.default = Header;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
const HeaderControls = _ref => {
|
|
11
|
+
let {
|
|
12
|
+
children,
|
|
13
|
+
className
|
|
14
|
+
} = _ref;
|
|
15
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
16
|
+
className: (0, _classnames.default)("p-panel__controls", className)
|
|
17
|
+
}, children);
|
|
18
|
+
};
|
|
19
|
+
var _default = exports.default = HeaderControls;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
const HeaderTitle = _ref => {
|
|
11
|
+
let {
|
|
12
|
+
children,
|
|
13
|
+
className
|
|
14
|
+
} = _ref;
|
|
15
|
+
return /*#__PURE__*/_react.default.createElement("h2", {
|
|
16
|
+
className: (0, _classnames.default)("p-panel__title", className)
|
|
17
|
+
}, children);
|
|
18
|
+
};
|
|
19
|
+
var _default = exports.default = HeaderTitle;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
const Sticky = _ref => {
|
|
11
|
+
let {
|
|
12
|
+
children,
|
|
13
|
+
className,
|
|
14
|
+
position = "top"
|
|
15
|
+
} = _ref;
|
|
16
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
17
|
+
className: (0, _classnames.default)("sticky-wrapper", className, {
|
|
18
|
+
"sticky-wrapper--top": position === "top",
|
|
19
|
+
"sticky-wrapper--bottom": position === "bottom"
|
|
20
|
+
})
|
|
21
|
+
}, children);
|
|
22
|
+
};
|
|
23
|
+
var _default = exports.default = Sticky;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, type Props as SidePanelProps } from "./SidePanel";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "default", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _SidePanel.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _SidePanel = _interopRequireDefault(require("./SidePanel"));
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { FC, PropsWithChildren, ReactNode } from "react";
|
|
2
|
+
import { type ContentProps } from "./common/Content";
|
|
3
|
+
import { type FooterProps } from "./common/Footer";
|
|
4
|
+
import { type HeaderProps } from "./common/Header";
|
|
5
|
+
import { type HeaderControlsProps } from "./common/HeaderControls";
|
|
6
|
+
import { type HeaderTitleProps } from "./common/HeaderTitle";
|
|
7
|
+
import { type StickyProps } from "./common/Sticky";
|
|
8
|
+
import "./SidePanel.scss";
|
|
9
|
+
/**
|
|
10
|
+
* The props for the SidePanelComponent component.
|
|
11
|
+
*/
|
|
12
|
+
export type Props = {
|
|
13
|
+
/**
|
|
14
|
+
* The content of the side panel.
|
|
15
|
+
*/
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* Additional CSS classes to apply.
|
|
19
|
+
*/
|
|
20
|
+
className?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Whether the side panel has an error. This will show an error message in the panel instead of rendering the children.
|
|
23
|
+
*/
|
|
24
|
+
hasError?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the side panel is currently loading. This will show a spinner in the panel instead of rendering the children.
|
|
27
|
+
*/
|
|
28
|
+
loading?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the side panel is an overlay with background or should allow seeing the content below it.
|
|
31
|
+
*/
|
|
32
|
+
overlay?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The ID of the parent element to which the side panel will be appended
|
|
35
|
+
*/
|
|
36
|
+
parentId?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Whether the side panel should be pinned. When pinned, it will remain visible alongside the main content.
|
|
39
|
+
*/
|
|
40
|
+
pinned?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Width of the side panel, available options are wide and narrow and the default.
|
|
43
|
+
*/
|
|
44
|
+
width?: "wide" | "narrow" | "";
|
|
45
|
+
};
|
|
46
|
+
type SidePanelComponents = FC<Props> & {
|
|
47
|
+
Header: FC<PropsWithChildren & HeaderProps>;
|
|
48
|
+
HeaderTitle: FC<PropsWithChildren & HeaderTitleProps>;
|
|
49
|
+
HeaderControls: FC<PropsWithChildren & HeaderControlsProps>;
|
|
50
|
+
Sticky: FC<PropsWithChildren & StickyProps>;
|
|
51
|
+
Content: FC<PropsWithChildren & ContentProps>;
|
|
52
|
+
Footer: FC<PropsWithChildren & FooterProps>;
|
|
53
|
+
};
|
|
54
|
+
declare const SidePanel: SidePanelComponents;
|
|
55
|
+
export default SidePanel;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
4
|
+
import Content from "./common/Content";
|
|
5
|
+
import Footer from "./common/Footer";
|
|
6
|
+
import Header from "./common/Header";
|
|
7
|
+
import HeaderControls from "./common/HeaderControls";
|
|
8
|
+
import HeaderTitle from "./common/HeaderTitle";
|
|
9
|
+
import Sticky from "./common/Sticky";
|
|
10
|
+
import AppAside from "../ApplicationLayout/AppAside";
|
|
11
|
+
import Spinner from "../Spinner";
|
|
12
|
+
import "./SidePanel.scss";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The props for the SidePanelComponent component.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
This is a [React](https://reactjs.org/) component for the Vanilla application layout [Side Panel](https://vanillaframework.io/docs/layouts/application#panels).
|
|
20
|
+
|
|
21
|
+
The sidepanel component should be used to show additional information relating to the main content on the page. It is using a composable structure with building blocks:
|
|
22
|
+
|
|
23
|
+
* **SidePanel.Header:** Defines the header of the side panel, which can include a title and controls.
|
|
24
|
+
|
|
25
|
+
* **SidePanel.HeaderTitle:** To show the title of the side panel as heading.
|
|
26
|
+
|
|
27
|
+
* **SidePanel.HeaderControls:** To show controls in the header, such as buttons or icons for actions like closing the panel.
|
|
28
|
+
|
|
29
|
+
* **SidePanel.Sticky:** Can be wrapped around the header or footer to make them sticky when scrolling.
|
|
30
|
+
|
|
31
|
+
* **SidePanel.Content:** To show the main content of the side panel.
|
|
32
|
+
|
|
33
|
+
* **SidePanel.Footer:** To show additional information or actions at the bottom of the side panel.
|
|
34
|
+
|
|
35
|
+
## Example
|
|
36
|
+
|
|
37
|
+
Usage of the composable structure:
|
|
38
|
+
|
|
39
|
+
```jsx
|
|
40
|
+
<SidePanel className="u-no-padding--top u-no-padding--bottom">
|
|
41
|
+
<SidePanel.Sticky>
|
|
42
|
+
<SidePanel.Header>
|
|
43
|
+
<SidePanel.HeaderTitle>Edit panel</SidePanel.HeaderTitle>
|
|
44
|
+
</SidePanel.Header>
|
|
45
|
+
</SidePanel.Sticky>
|
|
46
|
+
<SidePanel.Content className="u-no-padding">
|
|
47
|
+
<p>Here be dragons!</p>
|
|
48
|
+
</SidePanel.Content>
|
|
49
|
+
<SidePanel.Sticky position="bottom">
|
|
50
|
+
<SidePanel.Footer className="u-align--right">
|
|
51
|
+
<Button appearance="base">Cancel</Button>
|
|
52
|
+
<ActionButton appearance="positive">Save changes</ActionButton>
|
|
53
|
+
</SidePanel.Footer>
|
|
54
|
+
</SidePanel.Sticky>
|
|
55
|
+
</SidePanel>
|
|
56
|
+
```
|
|
57
|
+
*/
|
|
58
|
+
var SidePanelComponent = _ref => {
|
|
59
|
+
var {
|
|
60
|
+
children,
|
|
61
|
+
className,
|
|
62
|
+
hasError = false,
|
|
63
|
+
loading = false,
|
|
64
|
+
overlay,
|
|
65
|
+
pinned,
|
|
66
|
+
width = "",
|
|
67
|
+
parentId = "l-application"
|
|
68
|
+
} = _ref;
|
|
69
|
+
var container = document.getElementById(parentId) || document.body;
|
|
70
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement(AppAside, {
|
|
71
|
+
className: classnames("side-panel", className, {
|
|
72
|
+
"is-overlay": overlay
|
|
73
|
+
}),
|
|
74
|
+
"aria-label": "Side panel",
|
|
75
|
+
pinned: pinned,
|
|
76
|
+
narrow: width === "narrow",
|
|
77
|
+
wide: width === "wide"
|
|
78
|
+
}, loading ? /*#__PURE__*/React.createElement("div", {
|
|
79
|
+
className: "loading"
|
|
80
|
+
}, /*#__PURE__*/React.createElement(Spinner, null)) : hasError ? /*#__PURE__*/React.createElement("div", {
|
|
81
|
+
className: "error"
|
|
82
|
+
}, "Loading failed") : children), container));
|
|
83
|
+
};
|
|
84
|
+
var SidePanel = SidePanelComponent;
|
|
85
|
+
SidePanel.Header = Header;
|
|
86
|
+
SidePanel.HeaderTitle = HeaderTitle;
|
|
87
|
+
SidePanel.HeaderControls = HeaderControls;
|
|
88
|
+
SidePanel.Sticky = Sticky;
|
|
89
|
+
SidePanel.Content = Content;
|
|
90
|
+
SidePanel.Footer = Footer;
|
|
91
|
+
export default SidePanel;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
@import "vanilla-framework";
|
|
2
|
+
|
|
3
|
+
.side-panel.is-overlay {
|
|
4
|
+
position: absolute;
|
|
5
|
+
right: 0;
|
|
6
|
+
z-index: 103 !important;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.side-panel {
|
|
10
|
+
background-color: $colors--theme--background-default;
|
|
11
|
+
height: 100dvh;
|
|
12
|
+
padding: 0 $sph--x-large;
|
|
13
|
+
padding-bottom: $spv--medium;
|
|
14
|
+
padding-top: $spv--small;
|
|
15
|
+
|
|
16
|
+
.error,
|
|
17
|
+
.loading {
|
|
18
|
+
padding-top: $spv--medium;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.p-panel__header {
|
|
22
|
+
padding: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.panel-footer {
|
|
26
|
+
.rule {
|
|
27
|
+
margin-bottom: $spv--medium;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.sticky-wrapper {
|
|
32
|
+
background: $colors--theme--background-default;
|
|
33
|
+
position: sticky;
|
|
34
|
+
top: 0;
|
|
35
|
+
z-index: 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.sticky-wrapper--top {
|
|
39
|
+
top: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.sticky-wrapper--bottom {
|
|
43
|
+
bottom: 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import SidePanel from "./SidePanel";
|
|
3
|
+
declare const meta: Meta<typeof SidePanel>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof meta>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Pinned: Story;
|
|
8
|
+
export declare const Loading: Story;
|
|
9
|
+
export declare const Error: Story;
|
|
10
|
+
export declare const Narrow: Story;
|
|
11
|
+
export declare const Wide: Story;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import React, { useEffect, useId, useRef, useState } from "react";
|
|
2
|
+
import SidePanel from "./SidePanel";
|
|
3
|
+
import Button from "../Button";
|
|
4
|
+
import Application from "../ApplicationLayout/Application";
|
|
5
|
+
import AppMain from "../ApplicationLayout/AppMain";
|
|
6
|
+
import { ActionButton } from "../../index";
|
|
7
|
+
import Icon from "../Icon";
|
|
8
|
+
var meta = {
|
|
9
|
+
component: SidePanel,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
decorators: [Story => {
|
|
12
|
+
var ref = useRef(null);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
var el = ref.current;
|
|
15
|
+
if (el) {
|
|
16
|
+
var _el$parentElement, _wrapper$parentElemen;
|
|
17
|
+
var wrapper = el === null || el === void 0 || (_el$parentElement = el.parentElement) === null || _el$parentElement === void 0 || (_el$parentElement = _el$parentElement.parentElement) === null || _el$parentElement === void 0 ? void 0 : _el$parentElement.parentElement;
|
|
18
|
+
var parent = wrapper === null || wrapper === void 0 || (_wrapper$parentElemen = wrapper.parentElement) === null || _wrapper$parentElemen === void 0 || (_wrapper$parentElemen = _wrapper$parentElemen.parentElement) === null || _wrapper$parentElemen === void 0 ? void 0 : _wrapper$parentElemen.parentElement;
|
|
19
|
+
if (wrapper) {
|
|
20
|
+
wrapper.style.setProperty("border", "0", "important");
|
|
21
|
+
}
|
|
22
|
+
if (parent) {
|
|
23
|
+
parent.style.margin = "0";
|
|
24
|
+
parent.style.padding = "0";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}, []);
|
|
28
|
+
document.body.style.padding = "0";
|
|
29
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
30
|
+
ref: ref
|
|
31
|
+
}, /*#__PURE__*/React.createElement(Story, null));
|
|
32
|
+
}]
|
|
33
|
+
};
|
|
34
|
+
export default meta;
|
|
35
|
+
var StoryExample = args => {
|
|
36
|
+
var [isOpen, setIsOpen] = useState(false);
|
|
37
|
+
|
|
38
|
+
// Multiple stories get rendered on the docs page, ensure the ids are not colliding
|
|
39
|
+
var id = useId();
|
|
40
|
+
var parentId = args.parentId + id;
|
|
41
|
+
var openPanel = () => {
|
|
42
|
+
setIsOpen(true);
|
|
43
|
+
};
|
|
44
|
+
var closePanel = () => {
|
|
45
|
+
setIsOpen(false);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Delay opening the panel, so the l-application container is ready to receive it
|
|
49
|
+
useEffect(() => void setTimeout(openPanel, 100), []);
|
|
50
|
+
return /*#__PURE__*/React.createElement(Application, {
|
|
51
|
+
id: parentId
|
|
52
|
+
}, /*#__PURE__*/React.createElement(AppMain, null, /*#__PURE__*/React.createElement(Button, {
|
|
53
|
+
onClick: openPanel,
|
|
54
|
+
style: {
|
|
55
|
+
margin: "1rem"
|
|
56
|
+
}
|
|
57
|
+
}, "Open side panel"), /*#__PURE__*/React.createElement(Button, {
|
|
58
|
+
onClick: closePanel,
|
|
59
|
+
style: {
|
|
60
|
+
margin: "1rem"
|
|
61
|
+
}
|
|
62
|
+
}, "Close side panel")), isOpen && /*#__PURE__*/React.createElement(SidePanel, {
|
|
63
|
+
overlay: args.overlay,
|
|
64
|
+
loading: args.loading,
|
|
65
|
+
hasError: args.hasError,
|
|
66
|
+
parentId: parentId,
|
|
67
|
+
pinned: args.pinned,
|
|
68
|
+
width: args.width,
|
|
69
|
+
className: "u-no-padding--top u-no-padding--bottom"
|
|
70
|
+
}, /*#__PURE__*/React.createElement(SidePanel.Sticky, null, /*#__PURE__*/React.createElement(SidePanel.Header, null, /*#__PURE__*/React.createElement(SidePanel.HeaderTitle, null, "Edit panel"), /*#__PURE__*/React.createElement(SidePanel.HeaderControls, null, /*#__PURE__*/React.createElement(Button, {
|
|
71
|
+
appearance: "base",
|
|
72
|
+
className: "u-no-margin--bottom",
|
|
73
|
+
hasIcon: true,
|
|
74
|
+
onClick: closePanel,
|
|
75
|
+
"aria-label": "Close"
|
|
76
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
77
|
+
name: "close"
|
|
78
|
+
}))))), /*#__PURE__*/React.createElement(SidePanel.Content, {
|
|
79
|
+
className: "u-no-padding"
|
|
80
|
+
}, /*#__PURE__*/React.createElement("p", null, "Here be dragons!"), /*#__PURE__*/React.createElement("p", null, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras varius mi eu pretium vulputate. Nunc commodo sit amet nibh quis rhoncus. Aliquam rhoncus porttitor semper. Aenean faucibus consectetur neque in sodales. Sed cursus mauris id ex sollicitudin sodales. Quisque molestie rutrum odio, ornare pharetra ligula. Pellentesque ornare tristique feugiat. In a augue neque. Aenean eget arcu quis lacus tempus posuere in sit amet dui. Suspendisse faucibus sapien nisl, nec laoreet sem convallis nec."), /*#__PURE__*/React.createElement("p", null, "Vestibulum sed placerat lorem. Nam luctus ex id nisi luctus, id vestibulum sem bibendum. Vivamus turpis sem, pellentesque fermentum malesuada eu, faucibus porta libero. Duis eget venenatis odio. Etiam sed volutpat magna, non tempus erat. Nunc id tortor ac quam consectetur dapibus ac ut tellus. Pellentesque ut tellus venenatis elit vehicula condimentum eget quis lorem. Ut non consectetur est, a fringilla ipsum. Nunc vitae ligula ipsum. Etiam suscipit, libero ut lacinia viverra, nunc urna consequat ex, vel eleifend eros mauris vitae ipsum. Pellentesque sed dictum augue. Ut sit amet ullamcorper mauris. Nunc congue orci mollis purus sodales facilisis ac ut arcu. Maecenas feugiat sapien ac massa mollis sodales. Donec vitae turpis eu nisi laoreet pulvinar quis at nisl. Integer volutpat, metus eget elementum dictum, lacus sapien viverra felis, consequat fermentum nisl mi ac dui."), /*#__PURE__*/React.createElement("p", null, "Nullam nulla turpis, dignissim vel dapibus ut, volutpat ac dui. Donec vel elementum lacus. Mauris maximus nec felis at faucibus. Nunc faucibus gravida velit, id blandit lectus tincidunt ac. Vestibulum orci diam, elementum in congue eu, placerat id risus. Sed tempor tempus tellus, vitae iaculis turpis fringilla nec. Phasellus imperdiet facilisis velit, sit amet lobortis odio dignissim ut."), /*#__PURE__*/React.createElement("p", null, "Nam placerat urna vitae ligula hendrerit, ac tincidunt lorem maximus. Mauris eu odio nisi. Nulla facilisi. Sed egestas elit sed velit rutrum, sit amet bibendum metus hendrerit. Pellentesque luctus placerat tellus, eu bibendum justo. Cras eget leo ac ex volutpat gravida. Duis vitae mollis ante. Duis a congue nunc. Aenean aliquet, sapien quis tincidunt tincidunt, odio eros consectetur lacus, vel finibus mauris tortor id velit. Donec tincidunt vitae purus eu interdum. Pellentesque scelerisque dui viverra ex ullamcorper volutpat. Vestibulum lacinia vitae arcu volutpat porta. Etiam et cursus nulla, id aliquet felis. Nam ultricies, urna id mattis pretium, velit erat viverra elit, eu maximus diam eros id nisi."), /*#__PURE__*/React.createElement("p", null, "Nullam eget nisl lectus. Pellentesque eu mauris ut tortor malesuada sagittis. Cras dictum cursus est non ultricies. Duis mollis non neque at commodo. Nunc feugiat justo et consequat aliquam. Ut consectetur libero eu erat feugiat finibus. Duis varius convallis quam eu sagittis. Maecenas ac est arcu. Suspendisse at enim eget nibh ultricies dictum. Etiam aliquet tellus vel felis malesuada laoreet.")), /*#__PURE__*/React.createElement(SidePanel.Sticky, {
|
|
81
|
+
position: "bottom"
|
|
82
|
+
}, /*#__PURE__*/React.createElement(SidePanel.Footer, {
|
|
83
|
+
className: "u-align--right"
|
|
84
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
85
|
+
appearance: "base",
|
|
86
|
+
onClick: closePanel
|
|
87
|
+
}, "Cancel"), /*#__PURE__*/React.createElement(ActionButton, {
|
|
88
|
+
appearance: "positive"
|
|
89
|
+
}, "Save changes")))));
|
|
90
|
+
};
|
|
91
|
+
export var Default = {
|
|
92
|
+
args: {
|
|
93
|
+
className: "",
|
|
94
|
+
hasError: false,
|
|
95
|
+
parentId: "l-application-default",
|
|
96
|
+
pinned: false,
|
|
97
|
+
loading: false,
|
|
98
|
+
overlay: true,
|
|
99
|
+
width: ""
|
|
100
|
+
},
|
|
101
|
+
render: StoryExample
|
|
102
|
+
};
|
|
103
|
+
export var Pinned = {
|
|
104
|
+
args: {
|
|
105
|
+
className: "",
|
|
106
|
+
hasError: false,
|
|
107
|
+
parentId: "l-application-pinned",
|
|
108
|
+
pinned: true,
|
|
109
|
+
loading: false,
|
|
110
|
+
overlay: false,
|
|
111
|
+
width: ""
|
|
112
|
+
},
|
|
113
|
+
render: StoryExample,
|
|
114
|
+
parameters: {
|
|
115
|
+
docs: {
|
|
116
|
+
disable: true
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
export var Loading = {
|
|
121
|
+
args: {
|
|
122
|
+
className: "",
|
|
123
|
+
hasError: false,
|
|
124
|
+
parentId: "l-application-loading",
|
|
125
|
+
pinned: false,
|
|
126
|
+
loading: true,
|
|
127
|
+
overlay: true,
|
|
128
|
+
width: ""
|
|
129
|
+
},
|
|
130
|
+
render: StoryExample
|
|
131
|
+
};
|
|
132
|
+
export var Error = {
|
|
133
|
+
args: {
|
|
134
|
+
className: "",
|
|
135
|
+
hasError: true,
|
|
136
|
+
parentId: "l-application-error",
|
|
137
|
+
pinned: false,
|
|
138
|
+
loading: false,
|
|
139
|
+
overlay: true,
|
|
140
|
+
width: ""
|
|
141
|
+
},
|
|
142
|
+
render: StoryExample
|
|
143
|
+
};
|
|
144
|
+
export var Narrow = {
|
|
145
|
+
args: {
|
|
146
|
+
className: "",
|
|
147
|
+
hasError: false,
|
|
148
|
+
parentId: "l-application-narrow",
|
|
149
|
+
pinned: false,
|
|
150
|
+
loading: false,
|
|
151
|
+
overlay: true,
|
|
152
|
+
width: "narrow"
|
|
153
|
+
},
|
|
154
|
+
render: StoryExample
|
|
155
|
+
};
|
|
156
|
+
export var Wide = {
|
|
157
|
+
args: {
|
|
158
|
+
className: "",
|
|
159
|
+
hasError: false,
|
|
160
|
+
parentId: "l-application-wide",
|
|
161
|
+
pinned: false,
|
|
162
|
+
loading: false,
|
|
163
|
+
overlay: true,
|
|
164
|
+
width: "wide"
|
|
165
|
+
},
|
|
166
|
+
render: StoryExample
|
|
167
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
var Content = _ref => {
|
|
4
|
+
var {
|
|
5
|
+
children,
|
|
6
|
+
className
|
|
7
|
+
} = _ref;
|
|
8
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
9
|
+
className: classnames("p-panel__content", className)
|
|
10
|
+
}, children);
|
|
11
|
+
};
|
|
12
|
+
export default Content;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
var Footer = _ref => {
|
|
4
|
+
var {
|
|
5
|
+
children,
|
|
6
|
+
className
|
|
7
|
+
} = _ref;
|
|
8
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
9
|
+
className: classnames("panel-footer", className),
|
|
10
|
+
id: "panel-footer"
|
|
11
|
+
}, /*#__PURE__*/React.createElement("hr", {
|
|
12
|
+
className: "rule"
|
|
13
|
+
}), children);
|
|
14
|
+
};
|
|
15
|
+
export default Footer;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
var Header = _ref => {
|
|
4
|
+
var {
|
|
5
|
+
children,
|
|
6
|
+
className
|
|
7
|
+
} = _ref;
|
|
8
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
9
|
+
className: classnames("p-panel__header", className)
|
|
10
|
+
}, children);
|
|
11
|
+
};
|
|
12
|
+
export default Header;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
var HeaderControls = _ref => {
|
|
4
|
+
var {
|
|
5
|
+
children,
|
|
6
|
+
className
|
|
7
|
+
} = _ref;
|
|
8
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
9
|
+
className: classnames("p-panel__controls", className)
|
|
10
|
+
}, children);
|
|
11
|
+
};
|
|
12
|
+
export default HeaderControls;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
var HeaderTitle = _ref => {
|
|
4
|
+
var {
|
|
5
|
+
children,
|
|
6
|
+
className
|
|
7
|
+
} = _ref;
|
|
8
|
+
return /*#__PURE__*/React.createElement("h2", {
|
|
9
|
+
className: classnames("p-panel__title", className)
|
|
10
|
+
}, children);
|
|
11
|
+
};
|
|
12
|
+
export default HeaderTitle;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
var Sticky = _ref => {
|
|
4
|
+
var {
|
|
5
|
+
children,
|
|
6
|
+
className,
|
|
7
|
+
position = "top"
|
|
8
|
+
} = _ref;
|
|
9
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
10
|
+
className: classnames("sticky-wrapper", className, {
|
|
11
|
+
"sticky-wrapper--top": position === "top",
|
|
12
|
+
"sticky-wrapper--bottom": position === "bottom"
|
|
13
|
+
})
|
|
14
|
+
}, children);
|
|
15
|
+
};
|
|
16
|
+
export default Sticky;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, type Props as SidePanelProps } from "./SidePanel";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./SidePanel";
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ export { default as SideNavigation } from "./components/SideNavigation";
|
|
|
51
51
|
export { default as SideNavigationItem } from "./components/SideNavigation/SideNavigationItem";
|
|
52
52
|
export { default as SideNavigationLink } from "./components/SideNavigation/SideNavigationLink";
|
|
53
53
|
export { default as SideNavigationText } from "./components/SideNavigation/SideNavigationText";
|
|
54
|
+
export { default as SidePanel } from "./components/SidePanel";
|
|
54
55
|
export { default as SkipLink } from "./components/SkipLink";
|
|
55
56
|
export { default as Slider } from "./components/Slider";
|
|
56
57
|
export { default as Switch } from "./components/Switch";
|
|
@@ -120,6 +121,7 @@ export type { SideNavigationProps } from "./components/SideNavigation";
|
|
|
120
121
|
export type { SideNavigationItemProps } from "./components/SideNavigation/SideNavigationItem";
|
|
121
122
|
export type { SideNavigationLinkProps } from "./components/SideNavigation/SideNavigationLink";
|
|
122
123
|
export type { SideNavigationTextProps } from "./components/SideNavigation/SideNavigationText";
|
|
124
|
+
export type { SidePanelProps } from "./components/SidePanel";
|
|
123
125
|
export type { SkipLinkProps } from "./components/SkipLink";
|
|
124
126
|
export type { SliderProps } from "./components/Slider";
|
|
125
127
|
export type { SpinnerProps } from "./components/Spinner";
|
package/dist/esm/index.js
CHANGED
|
@@ -51,6 +51,7 @@ export { default as SideNavigation } from "./components/SideNavigation";
|
|
|
51
51
|
export { default as SideNavigationItem } from "./components/SideNavigation/SideNavigationItem";
|
|
52
52
|
export { default as SideNavigationLink } from "./components/SideNavigation/SideNavigationLink";
|
|
53
53
|
export { default as SideNavigationText } from "./components/SideNavigation/SideNavigationText";
|
|
54
|
+
export { default as SidePanel } from "./components/SidePanel";
|
|
54
55
|
export { default as SkipLink } from "./components/SkipLink";
|
|
55
56
|
export { default as Slider } from "./components/Slider";
|
|
56
57
|
export { default as Switch } from "./components/Switch";
|
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ export { default as SideNavigation } from "./components/SideNavigation";
|
|
|
51
51
|
export { default as SideNavigationItem } from "./components/SideNavigation/SideNavigationItem";
|
|
52
52
|
export { default as SideNavigationLink } from "./components/SideNavigation/SideNavigationLink";
|
|
53
53
|
export { default as SideNavigationText } from "./components/SideNavigation/SideNavigationText";
|
|
54
|
+
export { default as SidePanel } from "./components/SidePanel";
|
|
54
55
|
export { default as SkipLink } from "./components/SkipLink";
|
|
55
56
|
export { default as Slider } from "./components/Slider";
|
|
56
57
|
export { default as Switch } from "./components/Switch";
|
|
@@ -120,6 +121,7 @@ export type { SideNavigationProps } from "./components/SideNavigation";
|
|
|
120
121
|
export type { SideNavigationItemProps } from "./components/SideNavigation/SideNavigationItem";
|
|
121
122
|
export type { SideNavigationLinkProps } from "./components/SideNavigation/SideNavigationLink";
|
|
122
123
|
export type { SideNavigationTextProps } from "./components/SideNavigation/SideNavigationText";
|
|
124
|
+
export type { SidePanelProps } from "./components/SidePanel";
|
|
123
125
|
export type { SkipLinkProps } from "./components/SkipLink";
|
|
124
126
|
export type { SliderProps } from "./components/Slider";
|
|
125
127
|
export type { SpinnerProps } from "./components/Spinner";
|
package/dist/index.js
CHANGED
|
@@ -70,6 +70,7 @@ var _exportNames = {
|
|
|
70
70
|
SideNavigationItem: true,
|
|
71
71
|
SideNavigationLink: true,
|
|
72
72
|
SideNavigationText: true,
|
|
73
|
+
SidePanel: true,
|
|
73
74
|
SkipLink: true,
|
|
74
75
|
Slider: true,
|
|
75
76
|
Switch: true,
|
|
@@ -447,6 +448,12 @@ Object.defineProperty(exports, "SideNavigationText", {
|
|
|
447
448
|
return _SideNavigationText.default;
|
|
448
449
|
}
|
|
449
450
|
});
|
|
451
|
+
Object.defineProperty(exports, "SidePanel", {
|
|
452
|
+
enumerable: true,
|
|
453
|
+
get: function () {
|
|
454
|
+
return _SidePanel.default;
|
|
455
|
+
}
|
|
456
|
+
});
|
|
450
457
|
Object.defineProperty(exports, "SkipLink", {
|
|
451
458
|
enumerable: true,
|
|
452
459
|
get: function () {
|
|
@@ -769,6 +776,7 @@ var _SideNavigation = _interopRequireDefault(require("./components/SideNavigatio
|
|
|
769
776
|
var _SideNavigationItem = _interopRequireDefault(require("./components/SideNavigation/SideNavigationItem"));
|
|
770
777
|
var _SideNavigationLink = _interopRequireDefault(require("./components/SideNavigation/SideNavigationLink"));
|
|
771
778
|
var _SideNavigationText = _interopRequireDefault(require("./components/SideNavigation/SideNavigationText"));
|
|
779
|
+
var _SidePanel = _interopRequireDefault(require("./components/SidePanel"));
|
|
772
780
|
var _SkipLink = _interopRequireDefault(require("./components/SkipLink"));
|
|
773
781
|
var _Slider = _interopRequireDefault(require("./components/Slider"));
|
|
774
782
|
var _Switch = _interopRequireDefault(require("./components/Switch"));
|