Skip to content

Commit

Permalink
Select: Fix input cursor position so that it is at the start for sing…
Browse files Browse the repository at this point in the history
…le value selects (grafana#41693)

* Select: Fix input cursor position so that it is at the start for single value selects

* Fixing e2e tests

* Fixes cursor issue

* Fixing e2e tests

* e2e fix

* Select: ensure input always overlays singleValue, update pa11y config

Co-authored-by: Ashley Harrison <[email protected]>
  • Loading branch information
torkelo and ashharrison90 authored Nov 26, 2021
1 parent 130386f commit 9f4aa47
Show file tree
Hide file tree
Showing 13 changed files with 53 additions and 42 deletions.
4 changes: 3 additions & 1 deletion .pa11yci-pr.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ var config = {
chromeLaunchConfig: {
args: ['--no-sandbox'],
},
hideElements: '#updateVersion',
// see https://github.com/grafana/grafana/pull/41693#issuecomment-979921463 for context
// on why we're ignoring singleValue/react-select-*-placeholder elements
hideElements: '#updateVersion, [class*="-singleValue"], [id^="react-select-"][id$="-placeholder"]',
},

urls: [
Expand Down
4 changes: 3 additions & 1 deletion .pa11yci.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ var config = {
chromeLaunchConfig: {
args: ['--no-sandbox'],
},
hideElements: '#updateVersion',
// see https://github.com/grafana/grafana/pull/41693#issuecomment-979921463 for context
// on why we're ignoring singleValue/react-select-*-placeholder elements
hideElements: '#updateVersion, [class*="-singleValue"], [id^="react-select-"][id$="-placeholder"]',
},

urls: [
Expand Down
2 changes: 1 addition & 1 deletion e2e/dashboards-suite/dashboard-time-zone.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ e2e.scenario({
e2e.components.TimeZonePicker.containerV2()
.should('be.visible')
.within(() => {
e2e.components.Select.singleValue().should('be.visible').should('have.text', 'Coordinated Universal Time');
e2e.components.Select.singleValue().should('have.text', 'Coordinated Universal Time');
e2e.components.Select.input().should('be.visible').click();
});

Expand Down
6 changes: 3 additions & 3 deletions e2e/smoke-tests-suite/variables/new-query-variable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('Variables - Add variable', () => {
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelect()
.should('be.visible')
.within((select) => {
e2e.components.Select.singleValue().should('be.visible').should('have.text', 'Query');
e2e.components.Select.singleValue().should('have.text', 'Query');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInput()
.should('be.visible')
Expand Down Expand Up @@ -82,7 +82,7 @@ describe('Variables - Add variable', () => {

e2e().get('#Description').should('be.visible').clear().type('a description');

e2e.components.DataSourcePicker.inputV2().should('be.visible').type('gdev-testdata{enter}');
e2e.components.DataSourcePicker.container().should('be.visible').type('gdev-testdata{enter}');

e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsQueryInput()
.should('be.visible')
Expand Down Expand Up @@ -132,7 +132,7 @@ describe('Variables - Add variable', () => {

e2e().get('#Description').should('be.visible').clear().type('a description');

e2e.components.DataSourcePicker.inputV2().should('be.visible').type('gdev-testdata{enter}');
e2e.components.DataSourcePicker.container().type('gdev-testdata{enter}');

e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsQueryInput()
.should('be.visible')
Expand Down
2 changes: 1 addition & 1 deletion e2e/various-suite/exemplars.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe('Exemplars', () => {

e2e.pages.Explore.visit();

e2e.components.DataSourcePicker.input().should('be.visible').click();
e2e.components.DataSourcePicker.container().should('be.visible').click();
e2e().contains(dataSourceName).scrollIntoView().should('be.visible').click();

// we need to wait for the query-field being lazy-loaded, in two steps:
Expand Down
2 changes: 1 addition & 1 deletion e2e/various-suite/query-editor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ e2e.scenario({
skipScenario: false,
scenario: () => {
e2e.pages.Explore.visit();
e2e.components.DataSourcePicker.inputV2().should('be.visible').click();
e2e.components.DataSourcePicker.container().should('be.visible').click();

cy.contains('gdev-prometheus').scrollIntoView().should('be.visible').click();
const queryText = 'http_requests_total';
Expand Down
4 changes: 1 addition & 3 deletions e2e/various-suite/trace-view-scrolling.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ describe('Trace view', () => {

e2e.pages.Explore.visit();

e2e.components.DataSourcePicker.inputV2().should('be.visible').click();

e2e().contains('gdev-jaeger').scrollIntoView().should('be.visible').click();
e2e.components.DataSourcePicker.container().should('be.visible').type('gdev-jaeger{enter}');

e2e.components.QueryField.container().should('be.visible').type('long-trace');

Expand Down
2 changes: 1 addition & 1 deletion packages/grafana-e2e/src/flows/importDashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const importDashboard = (dashboardToImport: Dashboard, queryTimeout?: num
e2e.components.Panels.Panel.title(panel.title).should('be.visible').click();
e2e.components.Panels.Panel.headerItems('Inspect').should('be.visible').click();
e2e.components.Tab.title('JSON').should('be.visible').click();
e2e.components.PanelInspector.Json.content().should('be.visible').contains('Panel JSON').click();
e2e.components.PanelInspector.Json.content().should('be.visible').contains('Panel JSON').click({ force: true });
e2e.components.Select.option().should('be.visible').contains('Data').click();

// ensures that panel has loaded without knowingly hitting an error
Expand Down
3 changes: 0 additions & 3 deletions packages/grafana-ui/src/components/Select/InputControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,12 @@ const getInputControlStyles = stylesFactory(
css`
width: 100%;
max-width: 100%;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
justify-content: space-between;
padding-right: 0;
position: relative;
box-sizing: border-box;
`,
Expand Down
2 changes: 1 addition & 1 deletion packages/grafana-ui/src/components/Select/SelectBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ export function SelectBase<T>({
css`
display: inline-block;
color: ${theme.colors.text.disabled};
grid-area: 1 / 1 / 2 / 3;
box-sizing: border-box;
line-height: 1;
white-space: nowrap;
Expand Down
47 changes: 23 additions & 24 deletions packages/grafana-ui/src/components/Select/SingleValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ const getStyles = (theme: GrafanaTheme2) => {
text-overflow: ellipsis;
box-sizing: border-box;
max-width: 100%;
grid-area: 1 / 1 / 2 / 3;
`;
const container = css`
const spinnerWrapper = css`
width: 16px;
height: 16px;
display: inline-block;
Expand All @@ -29,7 +30,7 @@ const getStyles = (theme: GrafanaTheme2) => {
overflow: hidden;
`;

const item = css`
const spinnerIcon = css`
width: 100%;
height: 100%;
position: absolute;
Expand All @@ -39,7 +40,7 @@ const getStyles = (theme: GrafanaTheme2) => {
color: ${tinycolor(theme.colors.text.disabled).setAlpha(0.64).toString()};
`;

return { singleValue, container, item, disabled };
return { singleValue, spinnerWrapper, spinnerIcon, disabled };
};

type StylesType = ReturnType<typeof getStyles>;
Expand All @@ -52,36 +53,34 @@ export const SingleValue = <T extends unknown>(props: Props<T>) => {
const loading = useDelayedSwitch(data.loading || false, { delay: 250, duration: 750 });

return (
<components.SingleValue {...props}>
<div className={cx(styles.singleValue, isDisabled && styles.disabled)}>
{data.imgUrl ? (
<FadeWithImage
loading={loading}
imgUrl={data.imgUrl}
styles={styles}
alt={(data.label || data.value) as string}
/>
) : (
<SlideOutTransition horizontal size={16} visible={loading} duration={150}>
<div className={styles.container}>
<Spinner className={styles.item} inline />
</div>
</SlideOutTransition>
)}
{!data.hideText && children}
</div>
<components.SingleValue {...props} className={cx(styles.singleValue, isDisabled && styles.disabled)}>
{data.imgUrl ? (
<FadeWithImage
loading={loading}
imgUrl={data.imgUrl}
styles={styles}
alt={(data.label ?? data.value) as string}
/>
) : (
<SlideOutTransition horizontal size={16} visible={loading} duration={150}>
<div className={styles.spinnerWrapper}>
<Spinner className={styles.spinnerIcon} inline />
</div>
</SlideOutTransition>
)}
{!data.hideText && children}
</components.SingleValue>
);
};

const FadeWithImage = (props: { loading: boolean; imgUrl: string; styles: StylesType; alt?: string }) => {
return (
<div className={props.styles.container}>
<div className={props.styles.spinnerWrapper}>
<FadeTransition duration={150} visible={props.loading}>
<Spinner className={props.styles.item} inline />
<Spinner className={props.styles.spinnerIcon} inline />
</FadeTransition>
<FadeTransition duration={150} visible={!props.loading}>
<img className={props.styles.item} src={props.imgUrl} alt={props.alt} />
<img className={props.styles.spinnerIcon} src={props.imgUrl} alt={props.alt} />
</FadeTransition>
</div>
);
Expand Down
4 changes: 3 additions & 1 deletion packages/grafana-ui/src/components/Select/getSelectStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => {
singleValue: css`
label: grafana-select-single-value;
color: ${theme.components.input.text};
grid-area: 1 / 1 / 2 / 3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
Expand All @@ -75,7 +76,7 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => {
valueContainer: css`
label: grafana-select-value-container;
align-items: center;
display: flex;
display: grid;
position: relative;
box-sizing: border-box;
flex: 1 1 0%;
Expand All @@ -85,6 +86,7 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => {
valueContainerMulti: css`
label: grafana-select-value-container-multi;
flex-wrap: wrap;
display: flex;
`,
loadingMessage: css`
label: grafana-select-loading-message;
Expand Down
13 changes: 12 additions & 1 deletion packages/grafana-ui/src/components/Select/resetSelectStyles.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { CSSObjectWithLabel } from 'react-select';

export default function resetSelectStyles() {
return {
clearIndicator: () => ({}),
Expand All @@ -8,7 +10,16 @@ export default function resetSelectStyles() {
groupHeading: () => ({}),
indicatorsContainer: () => ({}),
indicatorSeparator: () => ({}),
input: () => ({}),
input: function (originalStyles: CSSObjectWithLabel) {
return {
...originalStyles,
color: 'inherit',
margin: 0,
padding: 0,
// Set an explicit z-index here to ensure this element always overlays the singleValue
zIndex: 1,
};
},
loadingIndicator: () => ({}),
loadingMessage: () => ({}),
menu: () => ({}),
Expand Down

0 comments on commit 9f4aa47

Please sign in to comment.