@canonical/react-components 0.56.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Panel/Panel.d.ts +123 -0
- package/dist/components/Panel/Panel.js +92 -0
- package/dist/components/Panel/Panel.stories.d.ts +17 -0
- package/dist/components/Panel/Panel.stories.js +60 -0
- package/dist/components/Panel/index.d.ts +1 -0
- package/dist/components/Panel/index.js +13 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +9 -2
- package/package.json +1 -1
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { PropsWithSpread } from "../../types";
|
|
3
|
+
import type { ComponentType, ElementType, HTMLProps, PropsWithChildren, ReactNode } from "react";
|
|
4
|
+
import type { ExclusiveProps } from "../../types";
|
|
5
|
+
export type LogoDefaultElement = HTMLProps<HTMLAnchorElement>;
|
|
6
|
+
type PanelLogo<L = LogoDefaultElement> = ReactNode | PropsWithSpread<{
|
|
7
|
+
/**
|
|
8
|
+
* The url of the icon image.
|
|
9
|
+
*/
|
|
10
|
+
icon: string;
|
|
11
|
+
/**
|
|
12
|
+
* The alt text for the icon image.
|
|
13
|
+
*/
|
|
14
|
+
iconAlt?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The url of the name image.
|
|
17
|
+
*/
|
|
18
|
+
name: string;
|
|
19
|
+
/**
|
|
20
|
+
* The alt text for the name image.
|
|
21
|
+
*/
|
|
22
|
+
nameAlt?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The element or component to use for displaying the logo e.g. `a` or `NavLink`.
|
|
25
|
+
* @default a
|
|
26
|
+
*/
|
|
27
|
+
component?: ElementType | ComponentType<L>;
|
|
28
|
+
}, L>;
|
|
29
|
+
type PanelToggle = {
|
|
30
|
+
/**
|
|
31
|
+
* The panel toggle label.
|
|
32
|
+
*/
|
|
33
|
+
label: string;
|
|
34
|
+
/**
|
|
35
|
+
* The function to call when clicking the panel toggle.
|
|
36
|
+
*/
|
|
37
|
+
onClick: () => void;
|
|
38
|
+
};
|
|
39
|
+
type LogoProps<L = LogoDefaultElement> = {
|
|
40
|
+
/**
|
|
41
|
+
* The panel logo content or attributes.
|
|
42
|
+
*/
|
|
43
|
+
logo?: PanelLogo<L>;
|
|
44
|
+
};
|
|
45
|
+
type TitleProps = {
|
|
46
|
+
/**
|
|
47
|
+
* The panel title.
|
|
48
|
+
*/
|
|
49
|
+
title: ReactNode;
|
|
50
|
+
/**
|
|
51
|
+
* Classes to apply to the title element.
|
|
52
|
+
*/
|
|
53
|
+
titleClassName?: string;
|
|
54
|
+
/**
|
|
55
|
+
* The element to use for the panel title e.g. `h1`.
|
|
56
|
+
* @default h4
|
|
57
|
+
*/
|
|
58
|
+
titleComponent?: ElementType;
|
|
59
|
+
/**
|
|
60
|
+
* An ID for the title element.
|
|
61
|
+
*/
|
|
62
|
+
titleId?: string;
|
|
63
|
+
};
|
|
64
|
+
type HeaderProps<L = LogoDefaultElement> = ExclusiveProps<{
|
|
65
|
+
/**
|
|
66
|
+
* This prop can be used to replace the header area of the panel when the default implementation is not sufficient.
|
|
67
|
+
*/
|
|
68
|
+
header: ReactNode;
|
|
69
|
+
}, {
|
|
70
|
+
/**
|
|
71
|
+
* Content that will be displayed in the controls area.
|
|
72
|
+
*/
|
|
73
|
+
controls?: ReactNode;
|
|
74
|
+
/**
|
|
75
|
+
* Classes that will be applied to the controls element.
|
|
76
|
+
*/
|
|
77
|
+
controlsClassName?: string;
|
|
78
|
+
/**
|
|
79
|
+
* Whether the header should be sticky.
|
|
80
|
+
*/
|
|
81
|
+
stickyHeader?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* The panel toggle attributes.
|
|
84
|
+
*/
|
|
85
|
+
toggle?: PanelToggle;
|
|
86
|
+
} & ExclusiveProps<LogoProps<L>, TitleProps>>;
|
|
87
|
+
export type Props<L = LogoDefaultElement> = {
|
|
88
|
+
/**
|
|
89
|
+
* The panel content.
|
|
90
|
+
*/
|
|
91
|
+
children?: PropsWithChildren["children"];
|
|
92
|
+
/**
|
|
93
|
+
* Classes that are applied to the content container (when using `wrapContent`).
|
|
94
|
+
*/
|
|
95
|
+
contentClassName?: string | null;
|
|
96
|
+
/**
|
|
97
|
+
* Classes that are applied to the top level panel element.
|
|
98
|
+
*/
|
|
99
|
+
className?: string | null;
|
|
100
|
+
/**
|
|
101
|
+
* Whether to use the dark theme.
|
|
102
|
+
*/
|
|
103
|
+
dark?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Whether the panel should wrap the content in the `p-panel__content` element.
|
|
106
|
+
* @default true
|
|
107
|
+
*/
|
|
108
|
+
wrapContent?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* A ref to pass to the top level panel element.
|
|
111
|
+
*/
|
|
112
|
+
forwardRef?: React.Ref<HTMLDivElement> | null;
|
|
113
|
+
} & HeaderProps<L>;
|
|
114
|
+
/**
|
|
115
|
+
* This is a [React](https://reactjs.org/) component for panels in the
|
|
116
|
+
* [Vanilla](https://vanillaframework.io/docs/) layouts.
|
|
117
|
+
*
|
|
118
|
+
* The Panel component can be used in many areas of the application layout. It
|
|
119
|
+
* can be the child element of `AppAside`, `AppMain`, `AppNavigation`, `AppNavigationBar`
|
|
120
|
+
* and `AppStatus`.
|
|
121
|
+
*/
|
|
122
|
+
declare const Panel: <L = LogoDefaultElement>({ forwardRef, children, className, contentClassName, controlsClassName, controls, dark, header, logo, stickyHeader, title, titleClassName, titleComponent: TitleComponent, titleId, toggle, wrapContent, ...props }: Props<L>) => React.JSX.Element;
|
|
123
|
+
export default Panel;
|
|
@@ -0,0 +1,92 @@
|
|
|
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 _utils = require("../../utils");
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
12
|
+
const generateLogo = logo => {
|
|
13
|
+
if ((0, _utils.isReactNode)(logo)) {
|
|
14
|
+
return logo;
|
|
15
|
+
}
|
|
16
|
+
const {
|
|
17
|
+
icon,
|
|
18
|
+
iconAlt,
|
|
19
|
+
name,
|
|
20
|
+
nameAlt,
|
|
21
|
+
component: Component = "a",
|
|
22
|
+
...props
|
|
23
|
+
} = logo;
|
|
24
|
+
return /*#__PURE__*/_react.default.createElement(Component, _extends({
|
|
25
|
+
className: "p-panel__logo"
|
|
26
|
+
}, props), /*#__PURE__*/_react.default.createElement("img", {
|
|
27
|
+
className: "p-panel__logo-icon",
|
|
28
|
+
src: icon,
|
|
29
|
+
alt: iconAlt,
|
|
30
|
+
width: "24",
|
|
31
|
+
height: "24"
|
|
32
|
+
}), /*#__PURE__*/_react.default.createElement("img", {
|
|
33
|
+
className: "p-panel__logo-name is-fading-when-collapsed",
|
|
34
|
+
src: name,
|
|
35
|
+
alt: nameAlt,
|
|
36
|
+
height: "16"
|
|
37
|
+
}));
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* This is a [React](https://reactjs.org/) component for panels in the
|
|
42
|
+
* [Vanilla](https://vanillaframework.io/docs/) layouts.
|
|
43
|
+
*
|
|
44
|
+
* The Panel component can be used in many areas of the application layout. It
|
|
45
|
+
* can be the child element of `AppAside`, `AppMain`, `AppNavigation`, `AppNavigationBar`
|
|
46
|
+
* and `AppStatus`.
|
|
47
|
+
*/
|
|
48
|
+
const Panel = _ref => {
|
|
49
|
+
let {
|
|
50
|
+
forwardRef,
|
|
51
|
+
children,
|
|
52
|
+
className,
|
|
53
|
+
contentClassName,
|
|
54
|
+
controlsClassName,
|
|
55
|
+
controls,
|
|
56
|
+
dark,
|
|
57
|
+
header,
|
|
58
|
+
logo,
|
|
59
|
+
stickyHeader,
|
|
60
|
+
title,
|
|
61
|
+
titleClassName,
|
|
62
|
+
titleComponent: TitleComponent = "h4",
|
|
63
|
+
titleId,
|
|
64
|
+
toggle,
|
|
65
|
+
wrapContent = true,
|
|
66
|
+
...props
|
|
67
|
+
} = _ref;
|
|
68
|
+
return /*#__PURE__*/_react.default.createElement("div", _extends({}, props, {
|
|
69
|
+
className: (0, _classnames.default)("p-panel", className, {
|
|
70
|
+
"is-dark": dark
|
|
71
|
+
}),
|
|
72
|
+
ref: forwardRef
|
|
73
|
+
}), logo || title || controls || toggle ? /*#__PURE__*/_react.default.createElement("div", {
|
|
74
|
+
className: (0, _classnames.default)("p-panel__header", {
|
|
75
|
+
"is-sticky": stickyHeader
|
|
76
|
+
})
|
|
77
|
+
}, logo ? generateLogo(logo) : /*#__PURE__*/_react.default.createElement(TitleComponent, {
|
|
78
|
+
className: (0, _classnames.default)("p-panel__title", titleClassName),
|
|
79
|
+
id: titleId
|
|
80
|
+
}, title), /*#__PURE__*/_react.default.createElement("div", {
|
|
81
|
+
className: (0, _classnames.default)("p-panel__controls", controlsClassName)
|
|
82
|
+
}, toggle ? /*#__PURE__*/_react.default.createElement("span", {
|
|
83
|
+
role: "button",
|
|
84
|
+
tabIndex: 0,
|
|
85
|
+
className: "p-panel__toggle",
|
|
86
|
+
onClick: () => toggle.onClick(),
|
|
87
|
+
onKeyDown: () => toggle.onClick()
|
|
88
|
+
}, toggle.label) : null, controls)) : header, children && wrapContent ? /*#__PURE__*/_react.default.createElement("div", {
|
|
89
|
+
className: (0, _classnames.default)("p-panel__content", contentClassName)
|
|
90
|
+
}, children) : children);
|
|
91
|
+
};
|
|
92
|
+
var _default = exports.default = Panel;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import Panel from "./Panel";
|
|
3
|
+
declare const meta: Meta<typeof Panel>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Panel>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Header: Story;
|
|
8
|
+
/**
|
|
9
|
+
* The logo may be provided as attributes to use the standard logo. If this is
|
|
10
|
+
* not sufficient the a `ReactNode` can be passed to the `logo` prop instead.
|
|
11
|
+
*/
|
|
12
|
+
export declare const Logo: Story;
|
|
13
|
+
/**
|
|
14
|
+
* If the default header does not meet your needs then a `ReactNode` can be
|
|
15
|
+
* passed to the `header` prop to replace the header.
|
|
16
|
+
*/
|
|
17
|
+
export declare const CustomHeader: Story;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.Logo = exports.Header = exports.Default = exports.CustomHeader = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _Panel = _interopRequireDefault(require("./Panel"));
|
|
9
|
+
var _Button = _interopRequireDefault(require("../Button"));
|
|
10
|
+
var _Icon = _interopRequireDefault(require("../Icon"));
|
|
11
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
|
+
const meta = {
|
|
13
|
+
component: _Panel.default,
|
|
14
|
+
tags: ["autodocs"]
|
|
15
|
+
};
|
|
16
|
+
var _default = exports.default = meta;
|
|
17
|
+
const Default = exports.Default = {
|
|
18
|
+
args: {
|
|
19
|
+
children: "Panel content",
|
|
20
|
+
title: "Panel"
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const Header = exports.Header = {
|
|
24
|
+
args: {
|
|
25
|
+
controls: /*#__PURE__*/_react.default.createElement(_Button.default, {
|
|
26
|
+
appearance: "positive"
|
|
27
|
+
}, /*#__PURE__*/_react.default.createElement(_Icon.default, {
|
|
28
|
+
name: "plus",
|
|
29
|
+
light: true
|
|
30
|
+
}), " Create"),
|
|
31
|
+
title: "Panel title",
|
|
32
|
+
titleComponent: "h1"
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The logo may be provided as attributes to use the standard logo. If this is
|
|
38
|
+
* not sufficient the a `ReactNode` can be passed to the `logo` prop instead.
|
|
39
|
+
*/
|
|
40
|
+
const Logo = exports.Logo = {
|
|
41
|
+
args: {
|
|
42
|
+
logo: {
|
|
43
|
+
icon: "https://assets.ubuntu.com/v1/7144ec6d-logo-jaas-icon.svg",
|
|
44
|
+
name: "https://assets.ubuntu.com/v1/a85f7947-juju_black-text-only.svg",
|
|
45
|
+
nameAlt: "Juju"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* If the default header does not meet your needs then a `ReactNode` can be
|
|
52
|
+
* passed to the `header` prop to replace the header.
|
|
53
|
+
*/
|
|
54
|
+
const CustomHeader = exports.CustomHeader = {
|
|
55
|
+
args: {
|
|
56
|
+
header: /*#__PURE__*/_react.default.createElement("div", {
|
|
57
|
+
className: "p-panel__header"
|
|
58
|
+
}, "This header replaces the entire header area")
|
|
59
|
+
}
|
|
60
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, type Props as PanelProps, type LogoDefaultElement as PanelLogoDefaultElement, } from "./Panel";
|
|
@@ -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 _Panel.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _Panel = _interopRequireDefault(require("./Panel"));
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export { default as Notification, NotificationSeverity, } from "./components/Not
|
|
|
31
31
|
export { NotificationConsumer, NotificationProvider, useNotify, info, success, failure, queue, } from "./components/NotificationProvider";
|
|
32
32
|
export { default as LoginPageLayout } from "./components/LoginPageLayout";
|
|
33
33
|
export { default as Pagination } from "./components/Pagination";
|
|
34
|
+
export { default as Panel } from "./components/Panel";
|
|
34
35
|
export { default as PasswordToggle } from "./components/PasswordToggle";
|
|
35
36
|
export { default as RadioInput } from "./components/RadioInput";
|
|
36
37
|
export { default as Row } from "./components/Row";
|
|
@@ -82,6 +83,7 @@ export type { NotificationProps } from "./components/Notification";
|
|
|
82
83
|
export type { NotificationAction, NotificationType, QueuedNotification, NotificationHelper, } from "./components/NotificationProvider";
|
|
83
84
|
export type { LoginPageLayoutProps } from "./components/LoginPageLayout";
|
|
84
85
|
export type { PaginationProps } from "./components/Pagination";
|
|
86
|
+
export type { PanelProps } from "./components/Panel";
|
|
85
87
|
export type { RadioInputProps } from "./components/RadioInput";
|
|
86
88
|
export type { RowProps } from "./components/Row";
|
|
87
89
|
export type { SearchAndFilterProps } from "./components/SearchAndFilter";
|
package/dist/index.js
CHANGED
|
@@ -46,6 +46,7 @@ var _exportNames = {
|
|
|
46
46
|
queue: true,
|
|
47
47
|
LoginPageLayout: true,
|
|
48
48
|
Pagination: true,
|
|
49
|
+
Panel: true,
|
|
49
50
|
PasswordToggle: true,
|
|
50
51
|
RadioInput: true,
|
|
51
52
|
Row: true,
|
|
@@ -302,6 +303,12 @@ Object.defineProperty(exports, "Pagination", {
|
|
|
302
303
|
return _Pagination.default;
|
|
303
304
|
}
|
|
304
305
|
});
|
|
306
|
+
Object.defineProperty(exports, "Panel", {
|
|
307
|
+
enumerable: true,
|
|
308
|
+
get: function () {
|
|
309
|
+
return _Panel.default;
|
|
310
|
+
}
|
|
311
|
+
});
|
|
305
312
|
Object.defineProperty(exports, "PasswordToggle", {
|
|
306
313
|
enumerable: true,
|
|
307
314
|
get: function () {
|
|
@@ -574,6 +581,7 @@ var _Notification = _interopRequireWildcard(require("./components/Notification")
|
|
|
574
581
|
var _NotificationProvider = require("./components/NotificationProvider");
|
|
575
582
|
var _LoginPageLayout = _interopRequireDefault(require("./components/LoginPageLayout"));
|
|
576
583
|
var _Pagination = _interopRequireDefault(require("./components/Pagination"));
|
|
584
|
+
var _Panel = _interopRequireDefault(require("./components/Panel"));
|
|
577
585
|
var _PasswordToggle = _interopRequireDefault(require("./components/PasswordToggle"));
|
|
578
586
|
var _RadioInput = _interopRequireDefault(require("./components/RadioInput"));
|
|
579
587
|
var _Row = _interopRequireDefault(require("./components/Row"));
|
package/dist/types/index.d.ts
CHANGED
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NavLink, NavLinkAnchor, NavLinkButton } from "./components/Navigation";
|
|
2
|
+
import { ReactNode } from "react";
|
|
2
3
|
export declare const IS_DEV: boolean;
|
|
3
4
|
/**
|
|
4
5
|
* Find substring and wrap in <strong /> tag
|
|
@@ -20,3 +21,7 @@ export declare const isNavigationAnchor: (link: NavLink) => link is NavLinkAncho
|
|
|
20
21
|
* @param link - The navigation item.
|
|
21
22
|
*/
|
|
22
23
|
export declare const isNavigationButton: (link: NavLink) => link is NavLinkButton;
|
|
24
|
+
/**
|
|
25
|
+
* A typeguard for whether an element is a ReactNode.
|
|
26
|
+
*/
|
|
27
|
+
export declare const isReactNode: (element: unknown) => element is ReactNode;
|
package/dist/utils.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isNavigationButton = exports.isNavigationAnchor = exports.highlightSubString = exports.IS_DEV = void 0;
|
|
6
|
+
exports.isReactNode = exports.isNavigationButton = exports.isNavigationAnchor = exports.highlightSubString = exports.IS_DEV = void 0;
|
|
7
|
+
var _react = require("react");
|
|
7
8
|
const IS_DEV = exports.IS_DEV = process.env.NODE_ENV === "development";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -40,4 +41,10 @@ const isNavigationAnchor = link => !!link.url;
|
|
|
40
41
|
*/
|
|
41
42
|
exports.isNavigationAnchor = isNavigationAnchor;
|
|
42
43
|
const isNavigationButton = link => !link.url;
|
|
43
|
-
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A typeguard for whether an element is a ReactNode.
|
|
47
|
+
*/
|
|
48
|
+
exports.isNavigationButton = isNavigationButton;
|
|
49
|
+
const isReactNode = element => /*#__PURE__*/(0, _react.isValidElement)(element);
|
|
50
|
+
exports.isReactNode = isReactNode;
|