From b078473c5f32f8d3f1de999e1b20883a2c9bb36a Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Mon, 20 Feb 2023 14:38:48 +0700 Subject: [PATCH] [Joy] Add `zIndex` to theme (#36236) --- .../AutocompleteListbox.tsx | 2 +- packages/mui-joy/src/Badge/Badge.tsx | 2 +- packages/mui-joy/src/Menu/Menu.tsx | 2 +- packages/mui-joy/src/Modal/Modal.tsx | 4 +-- packages/mui-joy/src/Select/Select.tsx | 2 +- packages/mui-joy/src/Table/Table.tsx | 2 +- packages/mui-joy/src/Tooltip/Tooltip.tsx | 2 +- .../src/styles/CssVarsProvider.test.tsx | 29 +++++++++++++++++++ .../mui-joy/src/styles/defaultTheme.test.js | 1 + packages/mui-joy/src/styles/defaultTheme.ts | 3 ++ .../mui-joy/src/styles/extendTheme.test.js | 1 + packages/mui-joy/src/styles/extendTheme.ts | 7 +++++ packages/mui-joy/src/styles/types/theme.ts | 2 ++ packages/mui-joy/src/styles/types/zIndex.ts | 16 ++++++++++ test/e2e-website/joy-docs.spec.ts | 29 +++++++++++++++++++ 15 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 packages/mui-joy/src/styles/types/zIndex.ts create mode 100644 test/e2e-website/joy-docs.spec.ts diff --git a/packages/mui-joy/src/AutocompleteListbox/AutocompleteListbox.tsx b/packages/mui-joy/src/AutocompleteListbox/AutocompleteListbox.tsx index 0aba3162179d35..dac1558aa2a517 100644 --- a/packages/mui-joy/src/AutocompleteListbox/AutocompleteListbox.tsx +++ b/packages/mui-joy/src/AutocompleteListbox/AutocompleteListbox.tsx @@ -60,7 +60,7 @@ export const StyledAutocompleteListbox = styled(StyledList)<{ ...(!variantStyle?.backgroundColor && { backgroundColor: theme.vars.palette.background.popup, }), - zIndex: 1200, + zIndex: theme.vars.zIndex.popup, overflow: 'auto', maxHeight: '40vh', position: 'relative', // to make sure that the listbox is positioned for grouped options to work. diff --git a/packages/mui-joy/src/Badge/Badge.tsx b/packages/mui-joy/src/Badge/Badge.tsx index f01bc72a24dc9b..effb210044ef2d 100644 --- a/packages/mui-joy/src/Badge/Badge.tsx +++ b/packages/mui-joy/src/Badge/Badge.tsx @@ -121,7 +121,7 @@ const BadgeBadge = styled('span', { minHeight: 'var(--Badge-minHeight)', minWidth: 'var(--Badge-minHeight)', borderRadius: 'var(--Badge-radius, var(--Badge-minHeight))', - zIndex: 1, + zIndex: theme.vars.zIndex.badge, backgroundColor: theme.vars.palette.background.surface, [ownerState.anchorOrigin!.vertical]: inset[ownerState.anchorOrigin!.vertical], [ownerState.anchorOrigin!.horizontal]: inset[ownerState.anchorOrigin!.horizontal], diff --git a/packages/mui-joy/src/Menu/Menu.tsx b/packages/mui-joy/src/Menu/Menu.tsx index 659999312e131e..d1d32b2daa6543 100644 --- a/packages/mui-joy/src/Menu/Menu.tsx +++ b/packages/mui-joy/src/Menu/Menu.tsx @@ -45,7 +45,7 @@ const MenuRoot = styled(StyledList, { ...scopedVariables, boxShadow: theme.shadow.md, overflow: 'auto', - zIndex: 1300, // the same value as Material UI Menu. TODO: revisit the appropriate value later. + zIndex: theme.vars.zIndex.popup, ...(!variantStyle?.backgroundColor && { backgroundColor: theme.vars.palette.background.popup, }), diff --git a/packages/mui-joy/src/Modal/Modal.tsx b/packages/mui-joy/src/Modal/Modal.tsx index f14459f1e74463..0d64b735468952 100644 --- a/packages/mui-joy/src/Modal/Modal.tsx +++ b/packages/mui-joy/src/Modal/Modal.tsx @@ -49,9 +49,9 @@ const ModalRoot = styled('div', { name: 'JoyModal', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})<{ ownerState: ModalOwnerState }>(({ ownerState }) => ({ +})<{ ownerState: ModalOwnerState }>(({ ownerState, theme }) => ({ position: 'fixed', - zIndex: 9999, + zIndex: theme.vars.zIndex.modal, right: 0, bottom: 0, top: 0, diff --git a/packages/mui-joy/src/Select/Select.tsx b/packages/mui-joy/src/Select/Select.tsx index 02c9a1273d0ca4..17f8949a9d9f54 100644 --- a/packages/mui-joy/src/Select/Select.tsx +++ b/packages/mui-joy/src/Select/Select.tsx @@ -242,7 +242,7 @@ const SelectListbox = styled(StyledList, { minWidth: 'max-content', // prevent options from shrinking if some of them is wider than the Select's root. outline: 0, boxShadow: theme.shadow.md, - zIndex: 1000, + zIndex: theme.vars.zIndex.popup, ...(!variantStyle?.backgroundColor && { backgroundColor: theme.vars.palette.background.popup, }), diff --git a/packages/mui-joy/src/Table/Table.tsx b/packages/mui-joy/src/Table/Table.tsx index df975578177caf..2b3335ade30c60 100644 --- a/packages/mui-joy/src/Table/Table.tsx +++ b/packages/mui-joy/src/Table/Table.tsx @@ -259,7 +259,7 @@ const TableRoot = styled('table', { top: 0, }, [tableSelector.getHeaderCell()]: { - zIndex: 10, + zIndex: theme.vars.zIndex.table, }, [tableSelector.getHeaderCellOfRow(2)]: { // support upto 2 rows for the sticky header diff --git a/packages/mui-joy/src/Tooltip/Tooltip.tsx b/packages/mui-joy/src/Tooltip/Tooltip.tsx index 8abb0da179ca67..e99f1fcaf75dc9 100644 --- a/packages/mui-joy/src/Tooltip/Tooltip.tsx +++ b/packages/mui-joy/src/Tooltip/Tooltip.tsx @@ -68,7 +68,7 @@ const TooltipRoot = styled('div', { padding: theme.spacing(0.75, 1), fontSize: theme.vars.fontSize.md, }), - zIndex: 1500, + zIndex: theme.vars.zIndex.tooltip, pointerEvents: 'none', borderRadius: theme.vars.radius.xs, boxShadow: theme.shadow.sm, diff --git a/packages/mui-joy/src/styles/CssVarsProvider.test.tsx b/packages/mui-joy/src/styles/CssVarsProvider.test.tsx index be14a2ede3f4e8..3e85fb35d75779 100644 --- a/packages/mui-joy/src/styles/CssVarsProvider.test.tsx +++ b/packages/mui-joy/src/styles/CssVarsProvider.test.tsx @@ -464,6 +464,35 @@ describe('[Joy] CssVarsProvider', () => { expect(screen.getByTestId('shadow-ring').textContent).to.equal('var(--joy-shadowRing)'); expect(screen.getByTestId('shadow-channel').textContent).to.equal('var(--joy-shadowChannel)'); }); + + it('zIndex', () => { + function Vars() { + const theme = useTheme(); + return ( +
+
{theme.vars.zIndex.badge}
+
{theme.vars.zIndex.table}
+
{theme.vars.zIndex.popup}
+
{theme.vars.zIndex.modal}
+
{theme.vars.zIndex.tooltip}
+
+ ); + } + + render( + + + , + ); + + expect(screen.getByTestId('zIndex-badge').textContent).to.equal('var(--joy-zIndex-badge)'); + expect(screen.getByTestId('zIndex-table').textContent).to.equal('var(--joy-zIndex-table)'); + expect(screen.getByTestId('zIndex-popup').textContent).to.equal('var(--joy-zIndex-popup)'); + expect(screen.getByTestId('zIndex-modal').textContent).to.equal('var(--joy-zIndex-modal)'); + expect(screen.getByTestId('zIndex-tooltip').textContent).to.equal( + 'var(--joy-zIndex-tooltip)', + ); + }); }); describe('Color Inversion', () => { diff --git a/packages/mui-joy/src/styles/defaultTheme.test.js b/packages/mui-joy/src/styles/defaultTheme.test.js index b3125cabadaff9..060399dab55ad0 100644 --- a/packages/mui-joy/src/styles/defaultTheme.test.js +++ b/packages/mui-joy/src/styles/defaultTheme.test.js @@ -22,6 +22,7 @@ describe('defaultTheme', () => { 'spacing', 'radius', 'shadow', + 'zIndex', 'typography', 'variants', 'colorInversion', diff --git a/packages/mui-joy/src/styles/defaultTheme.ts b/packages/mui-joy/src/styles/defaultTheme.ts index 6187ce753b6f18..29a4a2f8d0b556 100644 --- a/packages/mui-joy/src/styles/defaultTheme.ts +++ b/packages/mui-joy/src/styles/defaultTheme.ts @@ -17,6 +17,7 @@ export const getThemeWithVars = ( lineHeight, radius, shadow, + zIndex, palette: paletteInput, colorInversion: colorInversionInput, ...restTheme @@ -40,6 +41,7 @@ export const getThemeWithVars = ( lineHeight, radius, shadow, + zIndex, ...restTheme, colorSchemes: { ...colorSchemes, @@ -60,6 +62,7 @@ export const getThemeWithVars = ( radius, shadow, palette, + zIndex, }, getColorSchemeSelector: () => '&', } as unknown as Theme; diff --git a/packages/mui-joy/src/styles/extendTheme.test.js b/packages/mui-joy/src/styles/extendTheme.test.js index ede03ca6c5ca85..9d06d11172c8e1 100644 --- a/packages/mui-joy/src/styles/extendTheme.test.js +++ b/packages/mui-joy/src/styles/extendTheme.test.js @@ -21,6 +21,7 @@ describe('extendTheme', () => { 'spacing', 'radius', 'shadow', + 'zIndex', 'typography', 'colorInversionConfig', 'variants', diff --git a/packages/mui-joy/src/styles/extendTheme.ts b/packages/mui-joy/src/styles/extendTheme.ts index 031006611556d1..c3b4184e05d37c 100644 --- a/packages/mui-joy/src/styles/extendTheme.ts +++ b/packages/mui-joy/src/styles/extendTheme.ts @@ -428,6 +428,13 @@ export default function extendTheme(themeOptions?: CssVarsThemeOptions): Theme { 'shadowChannel', )} / 0.27), 21px 52.3px 74px -1.2px rgba(${getCssVar('shadowChannel')} / 0.29)`, }, + zIndex: { + badge: 1, + table: 10, + popup: 1000, + modal: 1300, + tooltip: 1500, + }, typography: { display1: { fontFamily: getCssVar('fontFamily-display'), diff --git a/packages/mui-joy/src/styles/types/theme.ts b/packages/mui-joy/src/styles/types/theme.ts index d82884023fd34b..d89ae7ea9aafe9 100644 --- a/packages/mui-joy/src/styles/types/theme.ts +++ b/packages/mui-joy/src/styles/types/theme.ts @@ -21,6 +21,7 @@ import { TypographySystem, } from './typography'; import { Variants, ColorInversion, ColorInversionConfig } from './variants'; +import { ZIndex } from './zIndex'; type Split = K extends string | number ? { [k in K]: Exclude } @@ -58,6 +59,7 @@ export interface ThemeScales { fontWeight: FontWeight; lineHeight: LineHeight; letterSpacing: LetterSpacing; + zIndex: ZIndex; } interface ColorSystemVars extends Omit { diff --git a/packages/mui-joy/src/styles/types/zIndex.ts b/packages/mui-joy/src/styles/types/zIndex.ts new file mode 100644 index 00000000000000..af7a71803f8062 --- /dev/null +++ b/packages/mui-joy/src/styles/types/zIndex.ts @@ -0,0 +1,16 @@ +/** + * From lowest to highest value + */ +export interface ZIndex { + badge: number; + /** + * For sticky `th` cells + */ + table: number; + /** + * Including `Menu`, `Autocomplete`, `Select` + */ + popup: number; + modal: number; + tooltip: number; +} diff --git a/test/e2e-website/joy-docs.spec.ts b/test/e2e-website/joy-docs.spec.ts new file mode 100644 index 00000000000000..2aa94f87f12c0d --- /dev/null +++ b/test/e2e-website/joy-docs.spec.ts @@ -0,0 +1,29 @@ +import { test as base, expect } from '@playwright/test'; +import kebabCase from 'lodash/kebabCase'; +import { TestFixture } from './playwright.config'; + +const test = base.extend({}); + +test.describe('Joy docs', () => { + test('should have correct link with hash in the TOC', async ({ page }) => { + await page.goto('/joy-ui/getting-started/installation/'); + + const anchors = page.locator('[aria-label="Page table of contents"] ul a'); + + const firstAnchor = anchors.first(); + const textContent = await firstAnchor.textContent(); + + await expect(firstAnchor).toHaveAttribute( + 'href', + `/joy-ui/getting-started/installation/#${kebabCase(textContent || '')}`, + ); + }); + + test('should be able to see demos', async ({ page }) => { + await page.goto('/joy-ui/react-button/'); + + const headline = page.locator('main h1'); + + await expect(headline).toHaveText('Button'); + }); +});