mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Clean up some @grafana/ui SCSS (#87986)
* clean up drawer and slider styles * clean up cascader styles
This commit is contained in:
parent
20294b0fb6
commit
3800b97a5b
@ -1,4 +1,4 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import RCCascader, { BaseOptionType } from 'rc-cascader';
|
||||
import React from 'react';
|
||||
|
||||
@ -9,6 +9,7 @@ import { IconName } from '../../types/icon';
|
||||
import { Button, ButtonProps } from '../Button';
|
||||
import { CascaderOption } from '../Cascader/Cascader';
|
||||
import { onChangeCascader, onLoadDataCascader } from '../Cascader/optionMappings';
|
||||
import { getCascaderStyles } from '../Cascader/styles';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
export interface ButtonCascaderProps {
|
||||
@ -30,6 +31,7 @@ export interface ButtonCascaderProps {
|
||||
export const ButtonCascader = (props: ButtonCascaderProps) => {
|
||||
const { onChange, className, loadData, icon, buttonProps, hideDownIcon, variant, disabled, ...rest } = props;
|
||||
const styles = useStyles2(getStyles);
|
||||
const cascaderStyles = useStyles2(getCascaderStyles);
|
||||
|
||||
// Weird way to do this bit it goes around a styling issue in Button where even null/undefined child triggers
|
||||
// styling change which messes up the look if there is only single icon content.
|
||||
@ -42,7 +44,7 @@ export const ButtonCascader = (props: ButtonCascaderProps) => {
|
||||
<RCCascader
|
||||
onChange={onChangeCascader(onChange)}
|
||||
loadData={onLoadDataCascader(loadData)}
|
||||
dropdownClassName={styles.popup}
|
||||
dropdownClassName={cx(cascaderStyles.dropdown, styles.popup)}
|
||||
{...rest}
|
||||
expandIcon={null}
|
||||
>
|
||||
|
@ -1,197 +0,0 @@
|
||||
.rc-cascader {
|
||||
font-size: 12px;
|
||||
|
||||
&-dropdown {
|
||||
position: absolute;
|
||||
// Required, otherwise the portal that the popup is shown in will render under other components
|
||||
z-index: 9999;
|
||||
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-menus {
|
||||
//font-size: 12px;
|
||||
overflow: hidden;
|
||||
background: $page-bg;
|
||||
border: $panel-border;
|
||||
border-radius: $border-radius;
|
||||
box-shadow: $typeahead-shadow;
|
||||
white-space: nowrap;
|
||||
|
||||
&.slide-up-enter,
|
||||
&.slide-up-appear {
|
||||
animation-duration: 0.3s;
|
||||
animation-fill-mode: both;
|
||||
transform-origin: 0 0;
|
||||
opacity: 0;
|
||||
animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
&.slide-up-enter.slide-up-enter-active.rc-cascader-menus-placement,
|
||||
&.slide-up-appear.slide-up-appear-active.rc-cascader-menus-placement {
|
||||
&-bottomLeft {
|
||||
animation-name: SlideUpIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
&-topLeft {
|
||||
animation-name: SlideDownIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
}
|
||||
|
||||
&.slide-up-leave {
|
||||
animation-duration: 0.3s;
|
||||
animation-fill-mode: both;
|
||||
transform-origin: 0 0;
|
||||
opacity: 1;
|
||||
animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34);
|
||||
animation-play-state: paused;
|
||||
|
||||
&.slide-up-leave-active.rc-cascader-menus-placement {
|
||||
&-bottomLeft {
|
||||
animation-name: SlideUpOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
&-topLeft {
|
||||
animation-name: SlideDownOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-menu {
|
||||
display: inline-block;
|
||||
/* width: 100px; */
|
||||
max-width: 50vw;
|
||||
height: 192px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-right: $panel-border;
|
||||
overflow: auto;
|
||||
|
||||
&:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
&-item {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0 2.5em 0 16px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
background: $colors-action-hover;
|
||||
}
|
||||
|
||||
&-disabled {
|
||||
cursor: not-allowed;
|
||||
color: $text-color-weak;
|
||||
|
||||
&:hover {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
content: 'loading';
|
||||
color: $text-color-weak;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
&-active {
|
||||
color: $text-color-strong;
|
||||
background: $colors-action-selected;
|
||||
|
||||
&:hover {
|
||||
background: $colors-action-hover;
|
||||
}
|
||||
}
|
||||
|
||||
&-expand {
|
||||
position: relative;
|
||||
|
||||
&:after {
|
||||
background: $text-color-weak;
|
||||
content: '';
|
||||
height: 24px;
|
||||
mask: url(../img/icons/unicons/angle-right.svg);
|
||||
mask-type: luminance;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: calc((32px - 24px) / 2);
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes SlideUpIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes SlideUpOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 0%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes SlideDownIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes SlideDownOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 0% 100%;
|
||||
transform: scaleY(0.8);
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ const options = [
|
||||
},
|
||||
];
|
||||
|
||||
const CascaderWithOptionsStateUpdate = (props: Omit<CascaderProps, 'options'>) => {
|
||||
const CascaderWithOptionsStateUpdate = (props: Omit<CascaderProps, 'options' | 'theme'>) => {
|
||||
const [updatedOptions, setOptions] = React.useState<CascaderOption[]>([
|
||||
{
|
||||
label: 'Initial state option',
|
||||
|
@ -5,6 +5,8 @@ import React, { PureComponent } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
|
||||
import { withTheme2 } from '../../themes';
|
||||
import { Themeable2 } from '../../types';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { IconButton } from '../IconButton/IconButton';
|
||||
import { Input } from '../Input/Input';
|
||||
@ -12,8 +14,9 @@ import { Stack } from '../Layout/Stack/Stack';
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
import { onChangeCascader } from './optionMappings';
|
||||
import { getCascaderStyles } from './styles';
|
||||
|
||||
export interface CascaderProps {
|
||||
export interface CascaderProps extends Themeable2 {
|
||||
/** The separator between levels in the search */
|
||||
separator?: string;
|
||||
placeholder?: string;
|
||||
@ -81,7 +84,7 @@ const disableDivFocus = css({
|
||||
|
||||
const DEFAULT_SEPARATOR = ' / ';
|
||||
|
||||
export class Cascader extends PureComponent<CascaderProps, CascaderState> {
|
||||
class UnthemedCascader extends PureComponent<CascaderProps, CascaderState> {
|
||||
constructor(props: CascaderProps) {
|
||||
super(props);
|
||||
const searchableOptions = this.getSearchableOptions(props.options);
|
||||
@ -231,10 +234,12 @@ export class Cascader extends PureComponent<CascaderProps, CascaderState> {
|
||||
disabled,
|
||||
id,
|
||||
isClearable,
|
||||
theme,
|
||||
} = this.props;
|
||||
const { focusCascade, isSearching, rcValue, activeLabel, inputValue } = this.state;
|
||||
|
||||
const searchableOptions = this.getSearchableOptions(options);
|
||||
const styles = getCascaderStyles(theme);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -264,6 +269,7 @@ export class Cascader extends PureComponent<CascaderProps, CascaderState> {
|
||||
expandIcon={null}
|
||||
open={this.props.alwaysOpen}
|
||||
disabled={disabled}
|
||||
dropdownClassName={styles.dropdown}
|
||||
>
|
||||
<div className={disableDivFocus}>
|
||||
<Input
|
||||
@ -301,3 +307,5 @@ export class Cascader extends PureComponent<CascaderProps, CascaderState> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const Cascader = withTheme2(UnthemedCascader);
|
||||
|
199
packages/grafana-ui/src/components/Cascader/styles.ts
Normal file
199
packages/grafana-ui/src/components/Cascader/styles.ts
Normal file
@ -0,0 +1,199 @@
|
||||
import { css, keyframes } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
const slideUpIn = keyframes({
|
||||
'0%': {
|
||||
opacity: 0,
|
||||
transformOrigin: '0% 0%',
|
||||
transform: 'scaleY(0.8)',
|
||||
},
|
||||
|
||||
'100%': {
|
||||
opacity: 1,
|
||||
transformOrigin: '0% 0%',
|
||||
transform: 'scaleY(1)',
|
||||
},
|
||||
});
|
||||
|
||||
const slideUpOut = keyframes({
|
||||
'0%': {
|
||||
opacity: 1,
|
||||
transformOrigin: '0% 0%',
|
||||
transform: 'scaleY(1)',
|
||||
},
|
||||
|
||||
'100%': {
|
||||
opacity: 0,
|
||||
transformOrigin: '0% 0%',
|
||||
transform: 'scaleY(0.8)',
|
||||
},
|
||||
});
|
||||
|
||||
const slideDownIn = keyframes({
|
||||
'0%': {
|
||||
opacity: 0,
|
||||
transformOrigin: '0% 100%',
|
||||
transform: 'scaleY(0.8)',
|
||||
},
|
||||
|
||||
'100%': {
|
||||
opacity: 1,
|
||||
transformOrigin: '0% 100%',
|
||||
transform: 'scaleY(1)',
|
||||
},
|
||||
});
|
||||
|
||||
const slideDownOut = keyframes({
|
||||
'0%': {
|
||||
opacity: 1,
|
||||
transformOrigin: '0% 100%',
|
||||
transform: 'scaleY(1)',
|
||||
},
|
||||
|
||||
'100%': {
|
||||
opacity: 0,
|
||||
transformOrigin: '0% 100%',
|
||||
transform: 'scaleY(0.8)',
|
||||
},
|
||||
});
|
||||
|
||||
export const getCascaderStyles = (theme: GrafanaTheme2) => ({
|
||||
dropdown: css({
|
||||
'&.rc-cascader-dropdown': {
|
||||
position: 'absolute',
|
||||
// Required, otherwise the portal that the popup is shown in will render under other components
|
||||
zIndex: 9999,
|
||||
|
||||
'&-hidden': {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
'.rc-cascader': {
|
||||
'&-menus': {
|
||||
overflow: 'hidden',
|
||||
background: theme.colors.background.canvas,
|
||||
border: `1px solid ${theme.colors.border.weak}`,
|
||||
borderRadius: theme.shape.radius.default,
|
||||
boxShadow: theme.shadows.z3,
|
||||
whiteSpace: 'nowrap',
|
||||
|
||||
'&.slide-up-enter, &.slide-up-appear': {
|
||||
animationDuration: '0.3s',
|
||||
animationFillMode: 'both',
|
||||
transformOrigin: '0 0',
|
||||
opacity: 0,
|
||||
animationTimingFunction: 'cubic-bezier(0.08, 0.82, 0.17, 1)',
|
||||
animationPlayState: 'paused',
|
||||
},
|
||||
|
||||
'&.slide-up-enter.slide-up-enter-active.rc-cascader-menus-placement, &.slide-up-appear.slide-up-appear-active.rc-cascader-menus-placement':
|
||||
{
|
||||
'&-bottomLeft': {
|
||||
animationName: slideUpIn,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
|
||||
'&-topLeft': {
|
||||
animationName: slideDownIn,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
},
|
||||
|
||||
'&.slide-up-leave': {
|
||||
animationDuration: '0.3s',
|
||||
animationFillMode: 'both',
|
||||
transformOrigin: '0 0',
|
||||
opacity: 1,
|
||||
animationTimingFunction: 'cubic-bezier(0.6, 0.04, 0.98, 0.34)',
|
||||
animationPlayState: 'paused',
|
||||
|
||||
'&.slide-up-leave-active.rc-cascader-menus-placement': {
|
||||
'&-bottomLeft': {
|
||||
animationName: slideUpOut,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
|
||||
'&-topLeft': {
|
||||
animationName: slideDownOut,
|
||||
animationPlayState: 'running',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
'&-menu': {
|
||||
display: 'inline-block',
|
||||
maxWidth: '50vw',
|
||||
height: '192px',
|
||||
listStyle: 'none',
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
borderRight: `1px solid ${theme.colors.border.weak}`,
|
||||
overflow: 'auto',
|
||||
|
||||
'&:last-child': {
|
||||
borderRight: 0,
|
||||
},
|
||||
|
||||
'&-item': {
|
||||
height: theme.spacing(4),
|
||||
lineHeight: theme.spacing(4),
|
||||
padding: theme.spacing(0, 4, 0, 2),
|
||||
cursor: 'pointer',
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
transition: 'all 0.3s ease',
|
||||
position: 'relative',
|
||||
|
||||
'&:hover': {
|
||||
background: theme.colors.action.hover,
|
||||
},
|
||||
|
||||
'&-disabled': {
|
||||
cursor: 'not-allowed',
|
||||
color: theme.colors.text.disabled,
|
||||
|
||||
'&:hover': {
|
||||
background: 'transparent',
|
||||
},
|
||||
|
||||
'&:after': {
|
||||
position: 'absolute',
|
||||
right: '12px',
|
||||
content: "'loading'",
|
||||
color: theme.colors.text.disabled,
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
|
||||
'&-active': {
|
||||
color: theme.colors.text.maxContrast,
|
||||
background: theme.colors.background.secondary,
|
||||
|
||||
'&:hover': {
|
||||
background: theme.colors.action.hover,
|
||||
},
|
||||
},
|
||||
|
||||
'&-expand': {
|
||||
position: 'relative',
|
||||
|
||||
'&:after': {
|
||||
background: theme.colors.background.secondary,
|
||||
content: "''",
|
||||
height: theme.spacing(3),
|
||||
mask: 'url(../img/icons/unicons/angle-right.svg)',
|
||||
maskType: 'luminance',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: theme.spacing(0.5),
|
||||
width: theme.spacing(3),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
@ -15,6 +15,8 @@ import { getDragStyles } from '../DragHandle/DragHandle';
|
||||
import { IconButton } from '../IconButton/IconButton';
|
||||
import { Text } from '../Text/Text';
|
||||
|
||||
import 'rc-drawer/assets/index.css';
|
||||
|
||||
export interface Props {
|
||||
children: ReactNode;
|
||||
/** Title shown at the top of the drawer */
|
||||
|
@ -1,2 +0,0 @@
|
||||
// Need to import this to get default styles from rc-drawer
|
||||
@import 'rc-drawer/assets/index.css';
|
@ -1 +0,0 @@
|
||||
@import 'rc-slider/assets/index.css';
|
@ -3,6 +3,8 @@ import { css as cssCore } from '@emotion/react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import 'rc-slider/assets/index.css';
|
||||
|
||||
export const getStyles = (theme: GrafanaTheme2, isHorizontal: boolean, hasMarks = false) => {
|
||||
const { spacing } = theme;
|
||||
const railColor = theme.colors.border.strong;
|
||||
|
@ -1,6 +1,3 @@
|
||||
@import 'ButtonCascader/ButtonCascader';
|
||||
@import 'Drawer/Drawer';
|
||||
@import 'Forms/Legacy/Select/Select';
|
||||
@import 'DateTimePickers/TimeOfDayPicker';
|
||||
@import 'Slider/Slider';
|
||||
@import 'uPlot/Plot';
|
||||
|
Loading…
Reference in New Issue
Block a user