mirror of
				https://github.com/grafana/grafana.git
				synced 2025-02-25 18:55:37 -06:00 
			
		
		
		
	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:
		| @@ -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"], | ||||
|   | ||||
| @@ -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(() => { | ||||
|   | ||||
| @@ -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', | ||||
|   | ||||
| @@ -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`, | ||||
|       }, | ||||
|     }), | ||||
|   }; | ||||
| }; | ||||
|   | ||||
| @@ -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, | ||||
|     }, | ||||
|   }), | ||||
| }); | ||||
|   | ||||
| @@ -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`, | ||||
|       }, | ||||
|     }), | ||||
|   }; | ||||
| }; | ||||
|   | ||||
| @@ -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', | ||||
|   }), | ||||
| }); | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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'; | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -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; | ||||
| } | ||||
| @@ -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; | ||||
| } | ||||
| @@ -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%; | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user