Chore: Migrate more SCSS styles (#88780)

* remove animations mixins

* move drop and drop-element to angular file

* migrate submenu scss
This commit is contained in:
Ashley Harrison 2024-06-10 16:10:54 +01:00 committed by GitHub
parent 5f4d07bb75
commit 06c30ee165
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 490 additions and 474 deletions

View File

@ -7890,6 +7890,9 @@ exports[`no gf-form usage`] = {
[0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"],
[0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"]
],
"public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx:5381": [
[0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"]
],
"public/app/features/datasources/components/BasicSettings.tsx:5381": [
[0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"],
[0, 0, 0, "gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.", "5381"],

View File

@ -108,7 +108,7 @@ describe('Variables - Query - Add variable', () => {
.should('have.length', 4)
.eq(3)
.within(() => {
cy.get('.variable-link-wrapper').should('be.visible').click();
e2e.components.Variables.variableLinkWrapper().should('be.visible').click();
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownDropDown()
.should('be.visible')
.within(() => {
@ -168,7 +168,7 @@ describe('Variables - Query - Add variable', () => {
.should('have.length', 4)
.eq(3)
.within(() => {
cy.get('.variable-link-wrapper').should('be.visible').click();
e2e.components.Variables.variableLinkWrapper().should('be.visible').click();
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownDropDown()
.should('be.visible')
.within(() => {

View File

@ -572,6 +572,7 @@ export const Components = {
},
Variables: {
variableOption: 'data-testid variable-option',
variableLinkWrapper: 'data-testid variable-link-wrapper',
},
Annotations: {
annotationsTypeInput: 'data-testid annotations-type-input',

View File

@ -1,6 +1,7 @@
import { css, cx } from '@emotion/css';
import { css, cx, keyframes } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { useStyles2 } from '../../themes';
@ -19,6 +20,7 @@ export type LoadingIndicatorProps = {
* @internal
*/
export const LoadingIndicator = ({ onCancel, loading }: LoadingIndicatorProps) => {
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const styles = useStyles2(getStyles);
if (!loading) {
@ -28,8 +30,8 @@ export const LoadingIndicator = ({ onCancel, loading }: LoadingIndicatorProps) =
return (
<Tooltip content="Cancel query">
<Icon
className={cx('spin-clockwise', { [styles.clickable]: !!onCancel })}
name="sync"
className={cx(styles.spin, { [styles.clickable]: !!onCancel })}
name={prefersReducedMotion ? 'hourglass' : 'sync'}
size="sm"
onClick={onCancel}
data-testid={selectors.components.LoadingIndicator.icon}
@ -38,10 +40,24 @@ export const LoadingIndicator = ({ onCancel, loading }: LoadingIndicatorProps) =
);
};
const getStyles = () => {
const spin = keyframes({
'0%': {
transform: 'rotate(0deg) scaleX(-1)', // scaleX flips the `sync` icon so arrows point the correct way
},
'100%': {
transform: 'rotate(359deg) scaleX(-1)',
},
});
const getStyles = (theme: GrafanaTheme2) => {
return {
clickable: css({
cursor: 'pointer',
}),
spin: css({
[theme.transitions.handleMotion('no-preference')]: {
animation: `${spin} 3s linear infinite`,
},
}),
};
};

View File

@ -1,7 +1,9 @@
import { css } from '@emotion/css';
import React, { useEffect, useState } from 'react';
import { TypedVariableModel, VariableHide } from '@grafana/data';
import { GrafanaTheme2, TypedVariableModel, VariableHide } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { useStyles2 } from '@grafana/ui';
import { PickerRenderer } from '../../../variables/pickers/PickerRenderer';
@ -12,6 +14,7 @@ interface Props {
export const SubMenuItems = ({ variables, readOnly }: Props) => {
const [visibleVariables, setVisibleVariables] = useState<TypedVariableModel[]>([]);
const styles = useStyles2(getStyles);
useEffect(() => {
setVisibleVariables(variables.filter((state) => state.hide !== VariableHide.hideVariable));
@ -24,10 +27,29 @@ export const SubMenuItems = ({ variables, readOnly }: Props) => {
return (
<>
{visibleVariables.map((variable) => (
<div key={variable.id} className="submenu-item" data-testid={selectors.pages.Dashboard.SubMenu.submenuItem}>
<div
key={variable.id}
className={styles.submenuItem}
data-testid={selectors.pages.Dashboard.SubMenu.submenuItem}
>
<PickerRenderer variable={variable} readOnly={readOnly} />
</div>
))}
</>
);
};
const getStyles = (theme: GrafanaTheme2) => ({
submenuItem: css({
display: 'inline-block',
'.fa-caret-down': {
fontSize: '75%',
paddingLeft: theme.spacing(1),
},
'.gf-form': {
marginBottom: 0,
},
}),
});

View File

@ -1,11 +1,12 @@
import { css, keyframes } from '@emotion/css';
import React, { FormEvent, PureComponent } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { bindActionCreators } from 'redux';
import { LoadingState, SelectableValue, VariableHide, VariableType } from '@grafana/data';
import { GrafanaTheme2, LoadingState, SelectableValue, VariableHide, VariableType } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { locationService } from '@grafana/runtime';
import { Button, HorizontalGroup, Icon } from '@grafana/ui';
import { Button, HorizontalGroup, Icon, Themeable2, withTheme2 } from '@grafana/ui';
import { StoreState, ThunkDispatch } from '../../../types';
import { VariableHideSelect } from '../../dashboard-scene/settings/variables/components/VariableHideSelect';
@ -54,7 +55,7 @@ const mapDispatchToProps = (dispatch: ThunkDispatch) => {
const connector = connect(mapStateToProps, mapDispatchToProps);
export interface OwnProps {
export interface OwnProps extends Themeable2 {
identifier: KeyedVariableIdentifier;
}
@ -146,12 +147,14 @@ export class VariableEditorEditorUnConnected extends PureComponent<Props, State>
};
render() {
const { variable } = this.props;
const { theme, variable } = this.props;
const EditorToRender = variableAdapters.get(this.props.variable.type).editor;
if (!EditorToRender) {
return null;
}
const loading = variable.state === LoadingState.Loading;
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const styles = getStyles(theme);
return (
<>
@ -209,7 +212,14 @@ export class VariableEditorEditorUnConnected extends PureComponent<Props, State>
variant="secondary"
>
Run query
{loading && <Icon className="spin-clockwise" name="sync" size="sm" style={{ marginLeft: '2px' }} />}
{loading && (
<Icon
className={styles.spin}
name={prefersReducedMotion ? 'hourglass' : 'sync'}
size="sm"
style={{ marginLeft: '2px' }}
/>
)}
</Button>
<Button
variant="primary"
@ -232,4 +242,23 @@ export class VariableEditorEditorUnConnected extends PureComponent<Props, State>
}
}
export const VariableEditorEditor = connector(VariableEditorEditorUnConnected);
export const VariableEditorEditor = withTheme2(connector(VariableEditorEditorUnConnected));
const spin = keyframes({
'0%': {
transform: 'rotate(0deg) scaleX(-1)', // scaleX flips the `sync` icon so arrows point the correct way
},
'100%': {
transform: 'rotate(359deg) scaleX(-1)',
},
});
const getStyles = (theme: GrafanaTheme2) => {
return {
spin: css({
[theme.transitions.handleMotion('no-preference')]: {
animation: `${spin} 3s linear infinite`,
},
}),
};
};

View File

@ -1,8 +1,10 @@
import { css } from '@emotion/css';
import React, { ComponentType, PureComponent } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { bindActionCreators } from 'redux';
import { LoadingState, VariableOption, VariableWithMultiSupport, VariableWithOptions } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { ClickOutsideWrapper } from '@grafana/ui';
import { StoreState, ThunkDispatch } from 'app/types';
@ -111,9 +113,10 @@ export const optionPickerFactory = <Model extends VariableWithOptions | Variable
render() {
const { variable, picker } = this.props;
const showOptions = picker.id === variable.id;
const styles = getStyles();
return (
<div className="variable-link-wrapper">
<div className={styles.variableLinkWrapper} data-testid={selectors.components.Variables.variableLinkWrapper}>
{showOptions ? this.renderOptions(picker) : this.renderLink(variable)}
</div>
);
@ -170,3 +173,10 @@ export const optionPickerFactory = <Model extends VariableWithOptions | Variable
return OptionsPicker;
};
const getStyles = () => ({
variableLinkWrapper: css({
display: 'inline-block',
position: 'relative',
}),
});

View File

@ -1398,3 +1398,397 @@ input:checked + .gf-form-switch__checkbox {
background: $checkbox-checked-bg;
border: none;
}
@keyframes spin-clockwise {
0% {
transform: rotate(0deg) scaleX(-1); // scaleX flips the `sync` icon so arrows point the correct way
}
100% {
transform: rotate(359deg) scaleX(-1);
}
}
.spin-clockwise {
animation: spin-clockwise 3s infinite linear;
}
@mixin drop-theme($themeName, $theme-bg, $theme-color, $border-color: $theme-bg) {
.drop-element.drop-#{$themeName} {
max-width: 100%;
max-height: 100%;
.drop-content {
border-radius: $border-radius-lg;
position: relative;
font-weight: $font-weight-semi-bold;
background: $theme-bg;
color: $theme-color;
padding: $space-sm;
word-wrap: break-word;
max-width: 280px;
border: 1px solid $border-color;
&:before {
content: '';
display: block;
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-width: $popover-arrow-size;
border-style: solid;
pointer-events: null;
}
}
&.drop-wide {
.drop-content {
max-width: 560px;
}
}
// Centers and middles
&.drop-element-attached-bottom.drop-element-attached-center .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
left: 50%;
margin-left: -$popover-arrow-size;
border-top-color: $border-color;
}
}
&.drop-element-attached-top.drop-element-attached-center .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
left: 50%;
margin-left: -$popover-arrow-size;
border-bottom-color: $border-color;
}
}
&.drop-element-attached-right.drop-element-attached-middle .drop-content {
margin-right: $popover-arrow-size;
&:before {
left: 100%;
top: 50%;
margin-top: -$popover-arrow-size;
border-left-color: $border-color;
}
}
&.drop-element-attached-left.drop-element-attached-middle .drop-content {
margin-left: $popover-arrow-size;
&:before {
right: 100%;
top: 50%;
margin-top: -$popover-arrow-size;
border-right-color: $border-color;
}
}
// Target middle/center, element corner
&.drop-element-attached-left.drop-target-attached-center .drop-content {
left: -$popover-arrow-size * 2;
}
&.drop-element-attached-right.drop-target-attached-center .drop-content {
left: $popover-arrow-size * 2;
}
&.drop-element-attached-top.drop-element-attached-left.drop-target-attached-middle .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
left: $popover-arrow-size;
border-bottom-color: $border-color;
}
}
&.drop-element-attached-top.drop-element-attached-right.drop-target-attached-middle .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
right: $popover-arrow-size;
border-bottom-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-middle .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
left: $popover-arrow-size;
border-top-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-middle .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
right: $popover-arrow-size;
border-top-color: $border-color;
}
}
// Top and bottom corners
&.drop-element-attached-top.drop-element-attached-left.drop-target-attached-bottom .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
left: $popover-arrow-size;
border-bottom-color: $border-color;
}
}
&.drop-element-attached-top.drop-element-attached-right.drop-target-attached-bottom .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
right: $popover-arrow-size;
border-bottom-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-top .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
left: $popover-arrow-size;
border-top-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-top .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
right: $popover-arrow-size;
border-top-color: $border-color;
}
}
// Side corners
&.drop-element-attached-top.drop-element-attached-right.drop-target-attached-left .drop-content {
margin-right: $popover-arrow-size;
&:before {
top: $popover-arrow-size;
left: 100%;
border-left-color: $border-color;
}
}
&.drop-element-attached-top.drop-element-attached-left.drop-target-attached-right .drop-content {
margin-left: $popover-arrow-size;
&:before {
top: $popover-arrow-size;
right: 100%;
border-right-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-left .drop-content {
margin-right: $popover-arrow-size;
&:before {
bottom: $popover-arrow-size;
left: 100%;
border-left-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-right .drop-content {
margin-left: $popover-arrow-size;
&:before {
bottom: $popover-arrow-size;
right: 100%;
border-right-color: $border-color;
}
}
}
}
@mixin drop-animation-scale($themePrefix: 'drop', $themeName: 'default', $attachmentOffset: 0, $easing: 'linear') {
.#{$themePrefix}-element.#{$themePrefix}-#{$themeName} {
transform: translateZ(0);
transition: opacity 100ms;
opacity: 0;
.#{$themePrefix}-content {
transition: transform 0.2s $easing;
transform: scale(0.8) translateZ(0);
}
&.#{$themePrefix}-open {
display: none;
}
&.#{$themePrefix}-open-transitionend {
display: block;
}
&.#{$themePrefix}-after-open {
transition: none;
opacity: 1;
.#{$themePrefix}-content {
transform: scale(1) translateZ(0);
}
}
// Centers and middles
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-center .#{$themePrefix}-content {
transform-origin: 50% calc(100% + #{$attachmentOffset});
}
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-center .#{$themePrefix}-content {
transform-origin: 50% (-$attachmentOffset);
}
&.#{$themePrefix}-element-attached-right.#{$themePrefix}-element-attached-middle .#{$themePrefix}-content {
transform-origin: calc(100% + #{$attachmentOffset}) 50%;
}
&.#{$themePrefix}-element-attached-left.#{$themePrefix}-element-attached-middle .#{$themePrefix}-content {
transform-origin: -($attachmentOffset 50%);
}
// Top and bottom corners
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-bottom
.#{$themePrefix}-content {
transform-origin: 0 (-$attachmentOffset);
}
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-bottom
.#{$themePrefix}-content {
transform-origin: 100% (-$attachmentOffset);
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-top
.#{$themePrefix}-content {
transform-origin: 0 calc(100% + #{$attachmentOffset});
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-top
.#{$themePrefix}-content {
transform-origin: 100% calc(100% + #{$attachmentOffset});
}
// Side corners
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-left
.#{$themePrefix}-content {
transform-origin: calc(100% + #{$attachmentOffset}) 0;
}
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-right
.#{$themePrefix}-content {
transform-origin: (-$attachmentOffset) 0;
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-left
.#{$themePrefix}-content {
transform-origin: calc(100% + #{$attachmentOffset}) 100%;
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-right
.#{$themePrefix}-content {
transform-origin: (-$attachmentOffset) 100%;
}
}
}
$popover-arrow-size: 10px;
$color: inherit;
$color: $text-color;
$useDropShadow: false;
$attachmentOffset: 0%;
$easing: cubic-bezier(0, 0, 0.265, 1);
@include drop-theme('error', $popover-error-bg, $white);
@include drop-theme('popover', $popover-bg, $popover-color, $popover-border-color);
@include drop-theme('help', $popover-help-bg, $popover-help-color);
@include drop-animation-scale('drop', 'help', $attachmentOffset: $attachmentOffset, $easing: $easing);
@include drop-animation-scale('drop', 'error', $attachmentOffset: $attachmentOffset, $easing: $easing);
@include drop-animation-scale('drop', 'popover', $attachmentOffset: $attachmentOffset, $easing: $easing);
.drop-element {
z-index: 10000;
position: absolute;
display: none;
opacity: 0;
&.drop-open {
display: block;
}
}
.drop-element,
.drop-element * {
box-sizing: border-box;
}
.drop-popover-close {
position: absolute;
top: -5px;
right: 0;
font-size: $font-size-lg;
}
.drop-help {
a {
color: $gray-6;
&:hover {
color: $white;
}
}
}
.drop-hide-out-of-bounds {
&.drop-open.drop-help.drop-out-of-bounds,
&.drop-open-transitionend.drop-help.drop-out-of-bounds {
display: none;
}
}
.drop-element.drop-popover {
.drop-content {
box-shadow: $popover-shadow;
}
}
.drop-element.drop-popover--form {
.drop-content {
max-width: none;
padding: 0;
}
}
.drop-element.drop-popover--annotation {
.drop-content {
padding: 0;
}
}
.drop-popover.gf-color-picker {
.drop-content {
width: 210px;
}
}
// TODO: Remove. This is a temporary solution until color picker popovers are used
// with Drop.js.
.drop-popover.drop-popover--transparent {
.drop-content {
border: none;
background: none;
padding: 0;
max-width: none;
&:before {
display: none;
}
}
}

View File

@ -1,13 +1,11 @@
// MIXINS
@import 'mixins/mixins';
@import 'mixins/animations';
@import 'mixins/buttons';
@import 'mixins/breakpoints';
@import 'mixins/grid';
@import 'mixins/grid-framework';
@import 'mixins/hover';
@import 'mixins/forms';
@import 'mixins/drop_element';
// BASE
@import 'base/normalize';
@ -28,14 +26,12 @@
@import 'components/buttons';
@import 'components/alerts';
@import 'components/tags';
@import 'components/submenu';
@import 'components/gf-form';
@import 'components/filter-table';
@import 'components/slate_editor';
@import 'components/modals';
@import 'components/dropdown';
@import 'components/infobox';
@import 'components/drop';
@import 'components/query_editor';
@import 'components/tabbed_view';
@import 'components/query_part';

View File

@ -1,94 +0,0 @@
$popover-arrow-size: 10px;
$color: inherit;
$color: $text-color;
$useDropShadow: false;
$attachmentOffset: 0%;
$easing: cubic-bezier(0, 0, 0.265, 1);
@include drop-theme('error', $popover-error-bg, $white);
@include drop-theme('popover', $popover-bg, $popover-color, $popover-border-color);
@include drop-theme('help', $popover-help-bg, $popover-help-color);
@include drop-animation-scale('drop', 'help', $attachmentOffset: $attachmentOffset, $easing: $easing);
@include drop-animation-scale('drop', 'error', $attachmentOffset: $attachmentOffset, $easing: $easing);
@include drop-animation-scale('drop', 'popover', $attachmentOffset: $attachmentOffset, $easing: $easing);
.drop-element {
z-index: 10000;
position: absolute;
display: none;
opacity: 0;
&.drop-open {
display: block;
}
}
.drop-element,
.drop-element * {
box-sizing: border-box;
}
.drop-popover-close {
position: absolute;
top: -5px;
right: 0;
font-size: $font-size-lg;
}
.drop-help {
a {
color: $gray-6;
&:hover {
color: $white;
}
}
}
.drop-hide-out-of-bounds {
&.drop-open.drop-help.drop-out-of-bounds,
&.drop-open-transitionend.drop-help.drop-out-of-bounds {
display: none;
}
}
.drop-element.drop-popover {
.drop-content {
box-shadow: $popover-shadow;
}
}
.drop-element.drop-popover--form {
.drop-content {
max-width: none;
padding: 0;
}
}
.drop-element.drop-popover--annotation {
.drop-content {
padding: 0;
}
}
.drop-popover.gf-color-picker {
.drop-content {
width: 210px;
}
}
// TODO: Remove. This is a temporary solution until color picker popovers are used
// with Drop.js.
.drop-popover.drop-popover--transparent {
.drop-content {
border: none;
background: none;
padding: 0;
max-width: none;
&:before {
display: none;
}
}
}

View File

@ -1,27 +0,0 @@
.submenu-controls {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: flex-start;
align-items: flex-start;
gap: $space-sm $space-md;
padding: 0 0 $space-sm 0;
}
.submenu-item {
display: inline-block;
.fa-caret-down {
font-size: 75%;
padding-left: 8px;
}
.gf-form {
margin-bottom: 0;
}
}
.variable-link-wrapper {
display: inline-block;
position: relative;
}

View File

@ -1,49 +0,0 @@
@mixin keyframes($animation-name) {
@-webkit-keyframes #{$animation-name} {
@content;
}
@-moz-keyframes #{$animation-name} {
@content;
}
@-ms-keyframes #{$animation-name} {
@content;
}
@-o-keyframes #{$animation-name} {
@content;
}
@keyframes #{$animation-name} {
@content;
}
}
@mixin animation($str) {
-webkit-animation: #{$str};
-moz-animation: #{$str};
-ms-animation: #{$str};
-o-animation: #{$str};
animation: #{$str};
}
.animate-height {
max-height: 0;
overflow: hidden;
&--open {
max-height: 1000px;
overflow: auto;
transition: max-height 250ms ease-in-out;
}
}
@keyframes spin-clockwise {
0% {
transform: rotate(0deg) scaleX(-1); // scaleX flips the `sync` icon so arrows point the correct way
}
100% {
transform: rotate(359deg) scaleX(-1);
}
}
.spin-clockwise {
animation: spin-clockwise 3s infinite linear;
}

View File

@ -1,285 +0,0 @@
@mixin drop-theme($themeName, $theme-bg, $theme-color, $border-color: $theme-bg) {
.drop-element.drop-#{$themeName} {
max-width: 100%;
max-height: 100%;
.drop-content {
border-radius: $border-radius-lg;
position: relative;
font-weight: $font-weight-semi-bold;
background: $theme-bg;
color: $theme-color;
padding: $space-sm;
word-wrap: break-word;
max-width: 280px;
border: 1px solid $border-color;
&:before {
content: '';
display: block;
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-width: $popover-arrow-size;
border-style: solid;
pointer-events: null;
}
}
&.drop-wide {
.drop-content {
max-width: 560px;
}
}
// Centers and middles
&.drop-element-attached-bottom.drop-element-attached-center .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
left: 50%;
margin-left: -$popover-arrow-size;
border-top-color: $border-color;
}
}
&.drop-element-attached-top.drop-element-attached-center .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
left: 50%;
margin-left: -$popover-arrow-size;
border-bottom-color: $border-color;
}
}
&.drop-element-attached-right.drop-element-attached-middle .drop-content {
margin-right: $popover-arrow-size;
&:before {
left: 100%;
top: 50%;
margin-top: -$popover-arrow-size;
border-left-color: $border-color;
}
}
&.drop-element-attached-left.drop-element-attached-middle .drop-content {
margin-left: $popover-arrow-size;
&:before {
right: 100%;
top: 50%;
margin-top: -$popover-arrow-size;
border-right-color: $border-color;
}
}
// Target middle/center, element corner
&.drop-element-attached-left.drop-target-attached-center .drop-content {
left: -$popover-arrow-size * 2;
}
&.drop-element-attached-right.drop-target-attached-center .drop-content {
left: $popover-arrow-size * 2;
}
&.drop-element-attached-top.drop-element-attached-left.drop-target-attached-middle .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
left: $popover-arrow-size;
border-bottom-color: $border-color;
}
}
&.drop-element-attached-top.drop-element-attached-right.drop-target-attached-middle .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
right: $popover-arrow-size;
border-bottom-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-middle .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
left: $popover-arrow-size;
border-top-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-middle .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
right: $popover-arrow-size;
border-top-color: $border-color;
}
}
// Top and bottom corners
&.drop-element-attached-top.drop-element-attached-left.drop-target-attached-bottom .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
left: $popover-arrow-size;
border-bottom-color: $border-color;
}
}
&.drop-element-attached-top.drop-element-attached-right.drop-target-attached-bottom .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
right: $popover-arrow-size;
border-bottom-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-top .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
left: $popover-arrow-size;
border-top-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-top .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
right: $popover-arrow-size;
border-top-color: $border-color;
}
}
// Side corners
&.drop-element-attached-top.drop-element-attached-right.drop-target-attached-left .drop-content {
margin-right: $popover-arrow-size;
&:before {
top: $popover-arrow-size;
left: 100%;
border-left-color: $border-color;
}
}
&.drop-element-attached-top.drop-element-attached-left.drop-target-attached-right .drop-content {
margin-left: $popover-arrow-size;
&:before {
top: $popover-arrow-size;
right: 100%;
border-right-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-left .drop-content {
margin-right: $popover-arrow-size;
&:before {
bottom: $popover-arrow-size;
left: 100%;
border-left-color: $border-color;
}
}
&.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-right .drop-content {
margin-left: $popover-arrow-size;
&:before {
bottom: $popover-arrow-size;
right: 100%;
border-right-color: $border-color;
}
}
}
}
@mixin drop-animation-scale($themePrefix: 'drop', $themeName: 'default', $attachmentOffset: 0, $easing: 'linear') {
.#{$themePrefix}-element.#{$themePrefix}-#{$themeName} {
transform: translateZ(0);
transition: opacity 100ms;
opacity: 0;
.#{$themePrefix}-content {
transition: transform 0.2s $easing;
transform: scale(0.8) translateZ(0);
}
&.#{$themePrefix}-open {
display: none;
}
&.#{$themePrefix}-open-transitionend {
display: block;
}
&.#{$themePrefix}-after-open {
transition: none;
opacity: 1;
.#{$themePrefix}-content {
transform: scale(1) translateZ(0);
}
}
// Centers and middles
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-center .#{$themePrefix}-content {
transform-origin: 50% calc(100% + #{$attachmentOffset});
}
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-center .#{$themePrefix}-content {
transform-origin: 50% (-$attachmentOffset);
}
&.#{$themePrefix}-element-attached-right.#{$themePrefix}-element-attached-middle .#{$themePrefix}-content {
transform-origin: calc(100% + #{$attachmentOffset}) 50%;
}
&.#{$themePrefix}-element-attached-left.#{$themePrefix}-element-attached-middle .#{$themePrefix}-content {
transform-origin: -($attachmentOffset 50%);
}
// Top and bottom corners
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-bottom
.#{$themePrefix}-content {
transform-origin: 0 (-$attachmentOffset);
}
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-bottom
.#{$themePrefix}-content {
transform-origin: 100% (-$attachmentOffset);
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-top
.#{$themePrefix}-content {
transform-origin: 0 calc(100% + #{$attachmentOffset});
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-top
.#{$themePrefix}-content {
transform-origin: 100% calc(100% + #{$attachmentOffset});
}
// Side corners
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-left
.#{$themePrefix}-content {
transform-origin: calc(100% + #{$attachmentOffset}) 0;
}
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-right
.#{$themePrefix}-content {
transform-origin: (-$attachmentOffset) 0;
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-left
.#{$themePrefix}-content {
transform-origin: calc(100% + #{$attachmentOffset}) 100%;
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-right
.#{$themePrefix}-content {
transform-origin: (-$attachmentOffset) 100%;
}
}
}