-
Notifications
You must be signed in to change notification settings - Fork 841
/
panel.tsx
161 lines (145 loc) Β· 3.92 KB
/
panel.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, {
ButtonHTMLAttributes,
FunctionComponent,
HTMLAttributes,
Ref,
} from 'react';
import classNames from 'classnames';
import { CommonProps, keysOf, ExclusiveUnion } from '../common';
export const panelPaddingValues = {
none: 0,
s: 8,
m: 16,
l: 24,
};
const paddingSizeToClassNameMap = {
none: null,
s: 'euiPanel--paddingSmall',
m: 'euiPanel--paddingMedium',
l: 'euiPanel--paddingLarge',
};
export const SIZES = keysOf(paddingSizeToClassNameMap);
const borderRadiusToClassNameMap = {
none: 'euiPanel--borderRadiusNone',
m: 'euiPanel--borderRadiusMedium',
};
export const BORDER_RADII = keysOf(borderRadiusToClassNameMap);
export const COLORS = [
'transparent',
'plain',
'subdued',
'accent',
'primary',
'success',
'warning',
'danger',
] as const;
export type PanelColor = typeof COLORS[number];
export type PanelPaddingSize = typeof SIZES[number];
export type PanelBorderRadius = typeof BORDER_RADII[number];
export interface _EuiPanelProps extends CommonProps {
/**
* Adds a medium shadow to the panel;
* Only works when `color="plain"`
*/
hasShadow?: boolean;
/**
* Adds a slight 1px border on all edges.
* Only works when `color="plain | transparent"`
* Default is `undefined` and will default to that theme's panel style
*/
hasBorder?: boolean;
/**
* Padding for all four sides
*/
paddingSize?: PanelPaddingSize;
/**
* Corner border radius
*/
borderRadius?: PanelBorderRadius;
/**
* When true the panel will grow in height to match `EuiFlexItem`
*/
grow?: boolean;
panelRef?: Ref<HTMLDivElement>;
/**
* Background color of the panel;
* Usually a lightened form of the brand colors
*/
color?: PanelColor;
}
export interface _EuiPanelDivlike
extends _EuiPanelProps,
Omit<HTMLAttributes<HTMLDivElement>, 'color'> {
element?: 'div';
}
export interface _EuiPanelButtonlike
extends _EuiPanelProps,
Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'color'> {
element?: 'button';
}
export type EuiPanelProps = ExclusiveUnion<
_EuiPanelButtonlike,
_EuiPanelDivlike
>;
export const EuiPanel: FunctionComponent<EuiPanelProps> = ({
children,
className,
paddingSize = 'm',
borderRadius = 'm',
color = 'plain',
hasShadow = true,
hasBorder,
grow = true,
panelRef,
element,
...rest
}) => {
// Shadows are only allowed when there's a white background (plain)
const canHaveShadow = color === 'plain';
const canHaveBorder = color === 'plain' || color === 'transparent';
const classes = classNames(
'euiPanel',
paddingSizeToClassNameMap[paddingSize],
borderRadiusToClassNameMap[borderRadius],
`euiPanel--${color}`,
{
// The `no` classes turn off the option for default theme
// While the `has` classes turn it on for Amsterdam
'euiPanel--hasShadow': canHaveShadow && hasShadow === true,
'euiPanel--noShadow': !canHaveShadow || hasShadow === false,
'euiPanel--hasBorder': canHaveBorder && hasBorder === true,
'euiPanel--noBorder': !canHaveBorder || hasBorder === false,
'euiPanel--flexGrowZero': !grow,
'euiPanel--isClickable': rest.onClick,
},
className
);
if (rest.onClick && element !== 'div') {
return (
<button
ref={panelRef as Ref<HTMLButtonElement>}
className={classes}
{...(rest as ButtonHTMLAttributes<HTMLButtonElement>)}
>
{children}
</button>
);
}
return (
<div
ref={panelRef as Ref<HTMLDivElement>}
className={classes}
{...(rest as HTMLAttributes<HTMLDivElement>)}
>
{children}
</div>
);
};