From 97f225cf1c72184e48982410371d93e74489834c Mon Sep 17 00:00:00 2001 From: Jaswanth-Sriram-Veturi <62434140+Jaswanth-Sriram-Veturi@users.noreply.github.com> Date: Tue, 30 Jan 2024 13:07:58 +0530 Subject: [PATCH 001/120] [base-ui][Menu] Focus last item after opening a menu using up arrow (#40764) --- packages/mui-base/src/Menu/Menu.test.tsx | 114 +++++++++++++++++- .../src/MenuButton/MenuButton.test.tsx | 14 +-- .../src/useDropdown/dropdownReducer.ts | 10 +- .../mui-base/src/useDropdown/useDropdown.ts | 9 +- .../src/useDropdown/useDropdown.types.ts | 5 +- .../mui-base/src/useList/listActions.types.ts | 7 ++ .../mui-base/src/useList/listReducer.test.ts | 56 +++++++++ packages/mui-base/src/useList/listReducer.ts | 12 ++ packages/mui-base/src/useMenu/useMenu.ts | 19 ++- .../src/useMenuButton/useMenuButton.test.tsx | 2 +- .../mui-base/src/useMenuItem/useMenuItem.ts | 2 +- packages/mui-joy/src/Menu/Menu.test.tsx | 2 +- .../src/MenuButton/MenuButton.test.tsx | 4 +- 13 files changed, 232 insertions(+), 24 deletions(-) diff --git a/packages/mui-base/src/Menu/Menu.test.tsx b/packages/mui-base/src/Menu/Menu.test.tsx index 3c6f8e2636b5bc..3ed34f1e10686b 100644 --- a/packages/mui-base/src/Menu/Menu.test.tsx +++ b/packages/mui-base/src/Menu/Menu.test.tsx @@ -11,13 +11,15 @@ import { import { Menu, menuClasses } from '@mui/base/Menu'; import { MenuItem, MenuItemRootSlotProps } from '@mui/base/MenuItem'; import { DropdownContext, DropdownContextValue } from '@mui/base/useDropdown'; +import { Popper } from '@mui/base/Popper'; +import { MenuProvider, useMenu } from '@mui/base/useMenu'; const testContext: DropdownContextValue = { dispatch: () => {}, popupId: 'menu-popup', registerPopup: () => {}, registerTrigger: () => {}, - state: { open: true }, + state: { open: true, changeReason: null }, triggerElement: null, }; @@ -72,6 +74,116 @@ describe('', () => { expect(item.tabIndex).to.equal(-1); }); }); + + it('highlights first item when down arrow key opens the menu', () => { + const context: DropdownContextValue = { + ...testContext, + state: { + ...testContext.state, + open: true, + changeReason: { + type: 'keydown', + key: 'ArrowDown', + } as React.KeyboardEvent, + }, + }; + const { getAllByRole } = render( + + + 1 + 2 + 3 + + , + ); + const [firstItem, ...otherItems] = getAllByRole('menuitem'); + + expect(firstItem.tabIndex).to.equal(0); + otherItems.forEach((item) => { + expect(item.tabIndex).to.equal(-1); + }); + }); + + it('highlights last item when up arrow key opens the menu', () => { + const context: DropdownContextValue = { + ...testContext, + state: { + ...testContext.state, + open: true, + changeReason: { + key: 'ArrowUp', + type: 'keydown', + } as React.KeyboardEvent, + }, + }; + const { getAllByRole } = render( + + + 1 + 2 + 3 + + , + ); + + const [firstItem, secondItem, lastItem] = getAllByRole('menuitem'); + + expect(lastItem.tabIndex).to.equal(0); + [firstItem, secondItem].forEach((item) => { + expect(item.tabIndex).to.equal(-1); + }); + }); + + it('highlights last non-disabled item when disabledItemsFocusable is set to false', () => { + const CustomMenu = React.forwardRef(function CustomMenu( + props: React.ComponentPropsWithoutRef<'ul'>, + ref: React.Ref, + ) { + const { children, ...other } = props; + + const { open, triggerElement, contextValue, getListboxProps } = useMenu({ + listboxRef: ref, + disabledItemsFocusable: false, + }); + + const anchorEl = triggerElement ?? document.createElement('div'); + + return ( + +
    + {children} +
+
+ ); + }); + + const context: DropdownContextValue = { + ...testContext, + state: { + ...testContext.state, + open: true, + changeReason: { + key: 'ArrowUp', + type: 'keydown', + } as React.KeyboardEvent, + }, + }; + const { getAllByRole } = render( + + + 1 + 2 + 3 + + , + ); + const [firstItem, secondItem, lastItem] = getAllByRole('menuitem'); + + expect(secondItem.tabIndex).to.equal(0); + [firstItem, lastItem].forEach((item) => { + expect(item.tabIndex).to.equal(-1); + }); + }); }); describe('keyboard navigation', () => { diff --git a/packages/mui-base/src/MenuButton/MenuButton.test.tsx b/packages/mui-base/src/MenuButton/MenuButton.test.tsx index f3ebf1031ea5f1..38ce00432147c0 100644 --- a/packages/mui-base/src/MenuButton/MenuButton.test.tsx +++ b/packages/mui-base/src/MenuButton/MenuButton.test.tsx @@ -20,7 +20,7 @@ const testContext: DropdownContextValue = { popupId: 'menu-popup', registerPopup: () => {}, registerTrigger: () => {}, - state: { open: true }, + state: { open: true, changeReason: null }, triggerElement: null, }; @@ -67,7 +67,7 @@ describe('', () => { const dispatchSpy = spy(); const context = { ...testContext, - state: { open: false }, + state: { open: false, changeReason: null }, dispatch: dispatchSpy, }; @@ -117,7 +117,7 @@ describe('', () => { const dispatchSpy = spy(); const context = { ...testContext, - state: { open: false }, + state: { open: false, changeReason: null }, dispatch: dispatchSpy, }; @@ -142,7 +142,7 @@ describe('', () => { const dispatchSpy = spy(); const context = { ...testContext, - state: { open: false }, + state: { open: false, changeReason: null }, dispatch: dispatchSpy, }; @@ -167,7 +167,7 @@ describe('', () => { const dispatchSpy = spy(); const context = { ...testContext, - state: { open: false }, + state: { open: false, changeReason: null }, dispatch: dispatchSpy, }; @@ -204,7 +204,7 @@ describe('', () => { it('has the aria-expanded=false attribute when closed', () => { const context = { ...testContext, - state: { open: false }, + state: { open: false, changeReason: null }, }; const { getByRole } = render( @@ -219,7 +219,7 @@ describe('', () => { it('has the aria-expanded=true attribute when open', () => { const context = { ...testContext, - state: { open: true }, + state: { open: true, changeReason: null }, }; const { getByRole } = render( diff --git a/packages/mui-base/src/useDropdown/dropdownReducer.ts b/packages/mui-base/src/useDropdown/dropdownReducer.ts index f2a0269eb44d67..66ee1a28aa5fb0 100644 --- a/packages/mui-base/src/useDropdown/dropdownReducer.ts +++ b/packages/mui-base/src/useDropdown/dropdownReducer.ts @@ -3,15 +3,15 @@ import { DropdownAction, DropdownActionTypes, DropdownState } from './useDropdow export function dropdownReducer(state: DropdownState, action: DropdownAction): DropdownState { switch (action.type) { case DropdownActionTypes.blur: - return { open: false }; + return { open: false, changeReason: action.event }; case DropdownActionTypes.escapeKeyDown: - return { open: false }; + return { open: false, changeReason: action.event }; case DropdownActionTypes.toggle: - return { open: !state.open }; + return { open: !state.open, changeReason: action.event }; case DropdownActionTypes.open: - return { open: true }; + return { open: true, changeReason: action.event }; case DropdownActionTypes.close: - return { open: false }; + return { open: false, changeReason: action.event }; default: throw new Error(`Unhandled action`); } diff --git a/packages/mui-base/src/useDropdown/useDropdown.ts b/packages/mui-base/src/useDropdown/useDropdown.ts index e55186cc0dfbd1..f6b1fc1be5e11c 100644 --- a/packages/mui-base/src/useDropdown/useDropdown.ts +++ b/packages/mui-base/src/useDropdown/useDropdown.ts @@ -25,7 +25,10 @@ export function useDropdown(parameters: UseDropdownParameters = {}) { const handleStateChange: StateChangeCallback = React.useCallback( (event, field, value, reason) => { if (field === 'open') { - onOpenChange?.(event as React.MouseEvent | React.KeyboardEvent | React.FocusEvent, value); + onOpenChange?.( + event as React.MouseEvent | React.KeyboardEvent | React.FocusEvent, + value as boolean, + ); } lastActionType.current = reason; @@ -40,7 +43,9 @@ export function useDropdown(parameters: UseDropdownParameters = {}) { const [state, dispatch] = useControllableReducer({ controlledProps, - initialState: defaultOpen ? { open: true } : { open: false }, + initialState: defaultOpen + ? { open: true, changeReason: null } + : { open: false, changeReason: null }, onStateChange: handleStateChange, reducer: dropdownReducer, componentName, diff --git a/packages/mui-base/src/useDropdown/useDropdown.types.ts b/packages/mui-base/src/useDropdown/useDropdown.types.ts index 568e784a0a3b30..3118ca97913286 100644 --- a/packages/mui-base/src/useDropdown/useDropdown.types.ts +++ b/packages/mui-base/src/useDropdown/useDropdown.types.ts @@ -76,4 +76,7 @@ export type DropdownAction = | DropdownOpenAction | DropdownCloseAction; -export type DropdownState = { open: boolean }; +export type DropdownState = { + open: boolean; + changeReason: React.MouseEvent | React.KeyboardEvent | React.FocusEvent | null; +}; diff --git a/packages/mui-base/src/useList/listActions.types.ts b/packages/mui-base/src/useList/listActions.types.ts index e9ff658d5bc0bb..848858100c775f 100644 --- a/packages/mui-base/src/useList/listActions.types.ts +++ b/packages/mui-base/src/useList/listActions.types.ts @@ -6,6 +6,7 @@ export const ListActionTypes = { itemsChange: 'list:itemsChange', keyDown: 'list:keyDown', resetHighlight: 'list:resetHighlight', + highlightLast: 'list:highlightLast', textNavigation: 'list:textNavigation', clearSelection: 'list:clearSelection', } as const; @@ -56,6 +57,11 @@ interface ResetHighlightAction { event: React.SyntheticEvent | null; } +interface HighlightLastAction { + type: typeof ListActionTypes.highlightLast; + event: React.SyntheticEvent | null; +} + interface ClearSelectionAction { type: typeof ListActionTypes.clearSelection; } @@ -71,5 +77,6 @@ export type ListAction = | ItemsChangeAction | KeyDownAction | ResetHighlightAction + | HighlightLastAction | TextNavigationAction | ClearSelectionAction; diff --git a/packages/mui-base/src/useList/listReducer.test.ts b/packages/mui-base/src/useList/listReducer.test.ts index 047f719b30b169..873be0f0f7430e 100644 --- a/packages/mui-base/src/useList/listReducer.test.ts +++ b/packages/mui-base/src/useList/listReducer.test.ts @@ -1143,6 +1143,62 @@ describe('listReducer', () => { }); }); + describe('action: highlightLast', () => { + it('highlights the last item', () => { + const state: ListState = { + highlightedValue: 'one', + selectedValues: [], + }; + + const action: ListReducerAction = { + type: ListActionTypes.highlightLast, + event: null, + context: { + items: ['one', 'two', 'three'], + disableListWrap: false, + disabledItemsFocusable: false, + focusManagement: 'DOM', + isItemDisabled: () => false, + itemComparer: (o, v) => o === v, + getItemAsString: (option) => option, + orientation: 'vertical', + pageSize: 5, + selectionMode: 'none', + }, + }; + + const result = listReducer(state, action); + expect(result.highlightedValue).to.equal('three'); + }); + + it('highlights the last non-disabled item', () => { + const state: ListState = { + highlightedValue: 'one', + selectedValues: [], + }; + + const action: ListReducerAction = { + type: ListActionTypes.highlightLast, + event: null, + context: { + items: ['one', 'two', 'three'], + disableListWrap: false, + disabledItemsFocusable: false, + focusManagement: 'DOM', + isItemDisabled: (item) => item === 'three', + itemComparer: (o, v) => o === v, + getItemAsString: (option) => option, + orientation: 'vertical', + pageSize: 5, + selectionMode: 'none', + }, + }; + + const result = listReducer(state, action); + expect(result.highlightedValue).to.equal('two'); + }); + }); + describe('action: clearSelection', () => { it('clears the selection', () => { const state: ListState = { diff --git a/packages/mui-base/src/useList/listReducer.ts b/packages/mui-base/src/useList/listReducer.ts index ad32bdbafa8c50..975d692834e2f8 100644 --- a/packages/mui-base/src/useList/listReducer.ts +++ b/packages/mui-base/src/useList/listReducer.ts @@ -431,6 +431,16 @@ function handleResetHighlight>( }; } +function handleHighlightLast>( + state: State, + context: ListActionContext, +) { + return { + ...state, + highlightedValue: moveHighlight(null, 'end', context), + }; +} + function handleClearSelection>( state: State, context: ListActionContext, @@ -461,6 +471,8 @@ export function listReducer>( return handleItemsChange(action.items, action.previousItems, state, context); case ListActionTypes.resetHighlight: return handleResetHighlight(state, context); + case ListActionTypes.highlightLast: + return handleHighlightLast(state, context); case ListActionTypes.clearSelection: return handleClearSelection(state, context); default: diff --git a/packages/mui-base/src/useMenu/useMenu.ts b/packages/mui-base/src/useMenu/useMenu.ts index 456f34b4ac8483..aa4215ee4b3b92 100644 --- a/packages/mui-base/src/useMenu/useMenu.ts +++ b/packages/mui-base/src/useMenu/useMenu.ts @@ -8,7 +8,7 @@ import { import { UseMenuListboxSlotProps, UseMenuParameters, UseMenuReturnValue } from './useMenu.types'; import { menuReducer } from './menuReducer'; import { DropdownContext, DropdownContextValue } from '../useDropdown/DropdownContext'; -import { useList } from '../useList'; +import { ListActionTypes, useList } from '../useList'; import { MenuItemMetadata } from '../useMenuItem'; import { DropdownActionTypes } from '../useDropdown'; import { EventHandlers } from '../utils/types'; @@ -22,7 +22,7 @@ const FALLBACK_MENU_CONTEXT: DropdownContextValue = { popupId: '', registerPopup: () => {}, registerTrigger: () => {}, - state: { open: true }, + state: { open: true, changeReason: null }, triggerElement: null, }; @@ -53,7 +53,7 @@ export function useMenu(parameters: UseMenuParameters = {}): UseMenuReturnValue const listboxId = useId(idParam) ?? ''; const { - state: { open }, + state: { open, changeReason }, dispatch: menuDispatch, triggerElement, registerPopup, @@ -123,6 +123,19 @@ export function useMenu(parameters: UseMenuParameters = {}): UseMenuReturnValue registerPopup(listboxId); }, [listboxId, registerPopup]); + useEnhancedEffect(() => { + if ( + open && + changeReason?.type === 'keydown' && + (changeReason as React.KeyboardEvent).key === 'ArrowUp' + ) { + listDispatch({ + type: ListActionTypes.highlightLast, + event: changeReason as React.KeyboardEvent, + }); + } + }, [open, changeReason, listDispatch]); + React.useEffect(() => { if (open && autoFocus && highlightedValue && !isInitiallyOpen.current) { subitems.get(highlightedValue)?.ref?.current?.focus(); diff --git a/packages/mui-base/src/useMenuButton/useMenuButton.test.tsx b/packages/mui-base/src/useMenuButton/useMenuButton.test.tsx index d14beef942ad9a..9bf81af45f0a93 100644 --- a/packages/mui-base/src/useMenuButton/useMenuButton.test.tsx +++ b/packages/mui-base/src/useMenuButton/useMenuButton.test.tsx @@ -10,7 +10,7 @@ const testContext: DropdownContextValue = { popupId: 'menu-popup', registerPopup: () => {}, registerTrigger: () => {}, - state: { open: true }, + state: { open: true, changeReason: null }, triggerElement: null, }; diff --git a/packages/mui-base/src/useMenuItem/useMenuItem.ts b/packages/mui-base/src/useMenuItem/useMenuItem.ts index 8a99206fef4c25..40f6fee89998ea 100644 --- a/packages/mui-base/src/useMenuItem/useMenuItem.ts +++ b/packages/mui-base/src/useMenuItem/useMenuItem.ts @@ -26,7 +26,7 @@ const FALLBACK_MENU_CONTEXT: DropdownContextValue = { popupId: '', registerPopup: () => {}, registerTrigger: () => {}, - state: { open: true }, + state: { open: true, changeReason: null }, triggerElement: null, }; diff --git a/packages/mui-joy/src/Menu/Menu.test.tsx b/packages/mui-joy/src/Menu/Menu.test.tsx index 13221bcafb8d49..6d2e67fc43cd7f 100644 --- a/packages/mui-joy/src/Menu/Menu.test.tsx +++ b/packages/mui-joy/src/Menu/Menu.test.tsx @@ -21,7 +21,7 @@ const testContext: DropdownContextValue = { popupId: 'menu-popup', registerPopup: () => {}, registerTrigger: () => {}, - state: { open: true }, + state: { open: true, changeReason: null }, triggerElement: document.createElement('div'), }; diff --git a/packages/mui-joy/src/MenuButton/MenuButton.test.tsx b/packages/mui-joy/src/MenuButton/MenuButton.test.tsx index ba265e18575be2..bb12143611c677 100644 --- a/packages/mui-joy/src/MenuButton/MenuButton.test.tsx +++ b/packages/mui-joy/src/MenuButton/MenuButton.test.tsx @@ -11,7 +11,7 @@ const testContext: DropdownContextValue = { popupId: 'menu-popup', registerPopup: () => {}, registerTrigger: () => {}, - state: { open: true }, + state: { open: true, changeReason: null }, triggerElement: null, }; @@ -59,7 +59,7 @@ describe('', () => { const dispatchSpy = spy(); const context = { ...testContext, - state: { open: false }, + state: { open: false, changeReason: null }, dispatch: dispatchSpy, }; From fb2cb7fdfc5a56a612b87d90f523ed211ab3d4b6 Mon Sep 17 00:00:00 2001 From: Colm Date: Tue, 30 Jan 2024 12:00:36 +0000 Subject: [PATCH 002/120] [website] Add new Base UI role (#40773) Signed-off-by: Marija Najdova Co-authored-by: Marija Najdova --- docs/pages/careers.tsx | 6 ++ .../careers/staff-ui-engineer-base-ui.js | 7 ++ .../careers/staff-ui-engineer-base-ui.md | 94 +++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 docs/pages/careers/staff-ui-engineer-base-ui.js create mode 100644 docs/pages/careers/staff-ui-engineer-base-ui.md diff --git a/docs/pages/careers.tsx b/docs/pages/careers.tsx index 33d1e44c1f9f63..12f9bc4c124b50 100644 --- a/docs/pages/careers.tsx +++ b/docs/pages/careers.tsx @@ -158,6 +158,12 @@ const openRolesData = [ 'You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.', url: '/careers/react-engineer-x/', }, + { + title: 'Staff UI Engineer - Base UI', + description: + 'Research, build, document, and ship high-quality, unstyled UI components with a focus on a11y.', + url: '/careers/staff-ui-engineer-base-ui/', + }, ], }, { diff --git a/docs/pages/careers/staff-ui-engineer-base-ui.js b/docs/pages/careers/staff-ui-engineer-base-ui.js new file mode 100644 index 00000000000000..8442642075b668 --- /dev/null +++ b/docs/pages/careers/staff-ui-engineer-base-ui.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import TopLayoutCareers from 'docs/src/modules/components/TopLayoutCareers'; +import * as pageProps from 'docs/pages/careers/staff-ui-engineer-base-ui.md?@mui/markdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/careers/staff-ui-engineer-base-ui.md b/docs/pages/careers/staff-ui-engineer-base-ui.md new file mode 100644 index 00000000000000..5261a8a4693d55 --- /dev/null +++ b/docs/pages/careers/staff-ui-engineer-base-ui.md @@ -0,0 +1,94 @@ +# Staff UI Engineer — Base UI + +

Research, build, document, and ship high-quality, unstyled UI components with a focus on a11y.

+ +## Details of the role + +- **Location**: Remote (preference for UTC-6 to UTC+5). +- **Type of work**: Full-time (contractor or employee [depending on circumstances](https://mui-org.notion.site/Hiring-FAQ-64763b756ae44c37b47b081f98915501#494af1f358794028beb4b7697b5d3102)). +- **Level**: [IC5 or above](https://mui-org.notion.site/Levelling-at-MUI-5c30f9bfe65149d697f346447cef9db1). + +## The company + +MUI's story began in 2014 with Material UI, the most successful React implementation of Google's Material Design. +Today, Material UI stands as one of the most popular open-source libraries on GitHub and has paved the way for the fully-fledged startup known as MUI (founded in 2019), which now boasts an ever-expanding ecosystem of React UI products. +We're a company of 31+ people as of late 2023, and we're growing. + +## The products + +MUI is best known for our flagship product, Material UI—but this is just one of three core component libraries we maintain. +Base UI is our headless component library, and Joy UI is a sister library to Material UI that implements our own in-house Joy Design system. +We also host Design Kits and pre-built Templates. + +Beyond the core libraries, MUI X offers advanced components like the Data Grid, Date and Time Pickers, and Charts, for more complex user interactions and data visualization needs. + +We're also making ambitious moves to incorporate our full suite of components into Toolpad, a low-code admin builder tool for assembling full-stack apps faster than ever. + +Learn more about MUI's products in this blog post: [An introduction to the MUI ecosystem](https://mui.com/blog/mui-product-comparison/). + +## The culture + +MUI is a fully remote company with a team that spans the globe. +The majority of our work is asynchronous, and we rely on written communication to collaborate. +We're radically transparent: nearly all of our work happens in public. +Each contributor has the freedom to decide how and when they work, and that work is primarily self-directed: it's your responsibility to define and complete your own tasks in a timely manner. + +For additional details about the culture, you can check our [careers](https://mui.com/careers/) and [about](https://mui.com/about/) pages and also our [public Handbook](https://mui-org.notion.site/Handbook-f086d47e10794d5e839aef9dc67f324b). + +## Why we're hiring + +The Base UI team is just starting to take shape now, and we have big goals for the next few years. We need experienced people to work alongside excellent UI engineers and designers, in an IC capacity, to research, spec, build, document, and ship high-quality, unstyled UI components with a focus on a11y. + +Overall, both our open-source community and our premium products are growing fast (x2 YoY). +We need talented people to keep that going! + +### Why this is interesting + +Our products empower React developers to build awesome applications faster – we see millions of developers on MUI's docs every year, one million a month. We're planning to invest heavily in Base UI this year and into the future. Our goal is to make Base UI one the best unstyled UI libs available, and in the process, help millions of developers build more accessible products. + +## The role + +### What you'll do on a day-to-day basis + +Depending on the day, you'll: + +- Build UI components with React and TypeScript. +- Perform code reviews and help to maintain a high-bar for code quality. +- Test Base UI components on various devices, browsers, platforms, and screen readers. +- Research a11y requirements for UI components. +- Contribute to component API design decisions and architecture. +- Contribute to Base UI documentation. +- Help out with community support on GitHub and Discord. + +## Who we're looking for + +### Required + +- **Expertise with the modern JavaScript ecosystem**. Base UI is built on modern front-end technologies like TypeScript, Node.js, React, Next.js, Webpack, and Babel. Working knowledge of these technologies is critical. +- **Expertise with CSS.** Deep knowledge of the functional aspects of CSS will be required. +- **Familiarity with a11y requirements.** We are looking for someone familiar with ARIA requirements, who cares about building accessible UI, and wants to make the web a more accessible place. +- **An eye for detail.** We appreciate people who sweat the details. People who go above and beyond to make interfaces fast, accessible, beautiful, and delightful. +- **Experience shipping production code in a team setting.** We are looking for someone with multiple years of experience working on production code. +- **Strong written and verbal communication skills**. As part of the team, you'll communicate both directly and indirectly with community members and enterprise customers, and contribute to user documentation. Clear communication is important in creating intuitive and compelling resources. + +### Nice to have (but not required) + +- **Experience working remotely.** Experience is not necessarily mandatory, but remote work can be a different challenge sometimes, so some experience would be helpful. +- **Experience working with design systems**. We are not looking for visual designers, but familiarity with the needs of design system maintainers would be helpful. +- **Experience contributing to OSS**. MUI is all about open-source software, so OSS experience would be awesome. + +## Benefits and compensation + +Competitive compensation depending on the profile and location. +We are ready to pay top market rates for a person that can clearly exceed the role's expectations. +You can find the other perks & benefits on the [careers](https://mui.com/careers/#perks-and-benefits) page. + +## How to apply + +[Apply now for this position 📮](https://jobs.ashbyhq.com/MUI/3094f65a-0144-4bd2-ba5b-6b9c61040858/application?utm_source=ZNRrPGBkqO) + +Don't meet every requirement? +Apply anyway! +Research shows that certain folks are less likely to apply for a role than others [unless they meet 100%](https://hbr.org/2014/08/why-women-dont-apply-for-jobs-unless-theyre-100-qualified) of the outlined qualifications. +If this role excites you, we want to hear from you. +We'd love for you to share the unique skills, passion, and experience you could bring to MUI. From 41548cb2ed4c31ec6cb01fea2c5a0e6d26a13be4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 16:28:00 -0300 Subject: [PATCH 003/120] Bump globby to ^14.0.0 (#40824) --- package.json | 2 +- pnpm-lock.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 44f3bd2ad69baa..d9ea4bff642acf 100644 --- a/package.json +++ b/package.json @@ -150,7 +150,7 @@ "eslint-plugin-react-hooks": "^4.6.0", "fast-glob": "^3.3.2", "fs-extra": "^11.2.0", - "globby": "^13.2.2", + "globby": "^14.0.0", "karma": "^6.4.2", "karma-browserstack-launcher": "~1.6.0", "karma-chrome-launcher": "^3.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aa78bcd5868b9b..2886c99100ec88 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -240,8 +240,8 @@ importers: specifier: ^11.2.0 version: 11.2.0 globby: - specifier: ^13.2.2 - version: 13.2.2 + specifier: ^14.0.0 + version: 14.0.0 karma: specifier: ^6.4.2 version: 6.4.2 From 5d098127dfbb8e75a0309ef5fb4343d681d491dc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 16:29:15 -0300 Subject: [PATCH 004/120] Bump compression-webpack-plugin to ^11.0.0 (#40822) --- package.json | 2 +- pnpm-lock.yaml | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index d9ea4bff642acf..dc1c4760193ecc 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "babel-plugin-react-remove-properties": "^0.3.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "chalk": "^5.3.0", - "compression-webpack-plugin": "^10.0.0", + "compression-webpack-plugin": "^11.0.0", "concurrently": "^8.2.2", "cpy-cli": "^5.0.0", "cross-env": "^7.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2886c99100ec88..9a8cecf4e008ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -174,8 +174,8 @@ importers: specifier: ^5.3.0 version: 5.3.0 compression-webpack-plugin: - specifier: ^10.0.0 - version: 10.0.0(webpack@5.90.0) + specifier: ^11.0.0 + version: 11.0.0(webpack@5.90.0) concurrently: specifier: ^8.2.2 version: 8.2.2 @@ -9109,7 +9109,7 @@ packages: dependencies: '@babel/core': 7.23.9 find-cache-dir: 4.0.0 - schema-utils: 4.0.0 + schema-utils: 4.2.0 webpack: 5.90.0(esbuild@0.19.11)(webpack-cli@5.1.4) dev: true @@ -10216,14 +10216,14 @@ packages: dependencies: mime-db: 1.52.0 - /compression-webpack-plugin@10.0.0(webpack@5.90.0): - resolution: {integrity: sha512-wLXLIBwpul/ALcm7Aj+69X0pYT3BYt6DdPn3qrgBIh9YejV9Bju9ShhlAsjujLyWMo6SAweFIWaUoFmXZNuNrg==} - engines: {node: '>= 14.15.0'} + /compression-webpack-plugin@11.0.0(webpack@5.90.0): + resolution: {integrity: sha512-Nz9dMiu0sag+mgJ5QTkRx0+vwrDZPU/gps7IdrkFE+oRSkgyoX4wbMol7QnXjI5/TEWx8yEwew9MiMjZgdLtjg==} + engines: {node: '>= 18.12.0'} peerDependencies: webpack: ^5.1.0 dependencies: - schema-utils: 4.0.0 - serialize-javascript: 6.0.1 + schema-utils: 4.2.0 + serialize-javascript: 6.0.2 webpack: 5.90.0(esbuild@0.19.11)(webpack-cli@5.1.4) dev: true @@ -19277,8 +19277,8 @@ packages: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) - /schema-utils@4.0.0: - resolution: {integrity: sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==} + /schema-utils@4.2.0: + resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} engines: {node: '>= 12.13.0'} dependencies: '@types/json-schema': 7.0.12 @@ -19359,8 +19359,8 @@ packages: dependencies: randombytes: 2.1.0 - /serialize-javascript@6.0.1: - resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==} + /serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} dependencies: randombytes: 2.1.0 @@ -20465,7 +20465,7 @@ packages: esbuild: 0.19.11 jest-worker: 27.5.1 schema-utils: 3.3.0 - serialize-javascript: 6.0.1 + serialize-javascript: 6.0.2 terser: 5.26.0 webpack: 5.90.0(esbuild@0.19.11)(webpack-cli@5.1.4) From 4e797158fe59df81bc604f57d2620726e93a82a8 Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 30 Jan 2024 13:15:33 -0700 Subject: [PATCH 005/120] [material-ui][docs] Fix typo on styled-components guide (#40858) --- .../data/material/guides/styled-components/styled-components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/material/guides/styled-components/styled-components.md b/docs/data/material/guides/styled-components/styled-components.md index 8340fb35fd75d3..5c7c38d7b1626e 100644 --- a/docs/data/material/guides/styled-components/styled-components.md +++ b/docs/data/material/guides/styled-components/styled-components.md @@ -14,7 +14,7 @@ By default, Material UI uses [Emotion](https://github.com/emotion-js/emotion) t All components rely on the `styled()` API to inject CSS into the page. This API is supported by multiple popular styling libraries, which makes it possible to switch between them in Material UI. -We provides two different packages to wrap your chosen styling solution for compatibility with Material UI: +We provide two different packages to wrap your chosen styling solution for compatibility with Material UI: - `@mui/styled-engine`: a thin wrapper around Emotion's [`styled()`](https://emotion.sh/docs/styled) API that includes required utilities like the `` component, the `css` and `keyframe` helpers, and more. This is the default, and you do not need to install it. - `@mui/styled-engine-sc`: a similar wrapper, but specifically tailored for styled-components. You must install and implement this package to use styled-components with Material UI. From 720dd1a9b31fee192f4aad6eef68746c658727d3 Mon Sep 17 00:00:00 2001 From: Danail Hadjiatanasov Date: Wed, 31 Jan 2024 11:06:11 +0200 Subject: [PATCH 006/120] [website] Move `React Engineer - X` into the future roles section (#40867) --- docs/pages/careers.tsx | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/pages/careers.tsx b/docs/pages/careers.tsx index 12f9bc4c124b50..055fe0e3193c3f 100644 --- a/docs/pages/careers.tsx +++ b/docs/pages/careers.tsx @@ -152,12 +152,12 @@ const openRolesData = [ 'You will help form the xCharts team, build ambitious and complex new features, work on strategic problems, and help grow adoption.', url: '/careers/react-engineer-x-charts/', }, - { - title: 'React Engineer - X', - description: - 'You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.', - url: '/careers/react-engineer-x/', - }, + // { + // title: 'React Engineer - X', + // description: + // 'You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.', + // url: '/careers/react-engineer-x/', + // }, { title: 'Staff UI Engineer - Base UI', description: @@ -206,12 +206,12 @@ const nextRolesData = [ 'You will join the MUI Toolpad team, to explore the role of MUI in the low code space and help bring the early prototype to a usable product.', url: '/careers/fullstack-engineer/', }, - // { - // title: 'React Engineer - X', - // description: - // 'You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.', - // url: '/careers/react-engineer-x/', - // }, + { + title: 'React Engineer - X', + description: + 'You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.', + url: '/careers/react-engineer-x/', + }, { title: 'React Tech Lead - Core', description: From 1c13e7e754c8e31eb2c9238fc0bcdad8706df8e2 Mon Sep 17 00:00:00 2001 From: Zeeshan Tamboli Date: Wed, 31 Jan 2024 15:25:51 +0530 Subject: [PATCH 007/120] [material-ui][Select] Fix to show notched outline when `displayEmpty` (#40865) --- packages/mui-material/src/Select/Select.js | 4 +++- .../mui-material/src/Select/Select.test.js | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/mui-material/src/Select/Select.js b/packages/mui-material/src/Select/Select.js index 2d4af6c1c6beaf..1902ac88385fab 100644 --- a/packages/mui-material/src/Select/Select.js +++ b/packages/mui-material/src/Select/Select.js @@ -117,7 +117,9 @@ const Select = React.forwardRef(function Select(inProps, ref) { classes: inputProps ? deepmerge(restOfClasses, inputProps.classes) : restOfClasses, ...(input ? input.props.inputProps : {}), }, - ...(multiple && native && variant === 'outlined' ? { notched: true } : {}), + ...(((multiple && native) || displayEmpty) && variant === 'outlined' + ? { notched: true } + : {}), ref: inputComponentRef, className: clsx(InputComponent.props.className, className, classes.root), // If a custom input is provided via 'input' prop, do not allow 'variant' to be propagated to it's root element. See https://github.com/mui/material-ui/issues/33894. diff --git a/packages/mui-material/src/Select/Select.test.js b/packages/mui-material/src/Select/Select.test.js index 2bf908c203d38e..c1a3225b43cd58 100644 --- a/packages/mui-material/src/Select/Select.test.js +++ b/packages/mui-material/src/Select/Select.test.js @@ -911,6 +911,24 @@ describe(' + None + Ten + Twenty + , + ); + + expect(container.querySelector('legend')).toHaveComputedStyle({ + maxWidth: '100%', + }); + }); }); describe('prop: renderValue', () => { From e526ccfb3c382d82209bcbfd4a88276a2a59daa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dudak?= Date: Wed, 31 Jan 2024 13:16:19 +0100 Subject: [PATCH 008/120] [zero-runtime] Use lodash instead of its subpackages (#40868) --- packages/zero-runtime/package.json | 8 +--- packages/zero-runtime/src/processors/css.ts | 2 +- .../src/utils/cssFunctionTransformerPlugin.ts | 2 +- pnpm-lock.yaml | 47 +++---------------- 4 files changed, 11 insertions(+), 48 deletions(-) diff --git a/packages/zero-runtime/package.json b/packages/zero-runtime/package.json index cfcd19350385ee..27c456b14f5cff 100644 --- a/packages/zero-runtime/package.json +++ b/packages/zero-runtime/package.json @@ -26,9 +26,7 @@ "@linaria/tags": "^5.0.2", "@linaria/utils": "^5.0.2", "@mui/system": "workspace:^", - "lodash.merge": "^4.6.2", - "lodash.set": "^4.3.2", - "lodash.get": "^4.4.2", + "lodash": "^4.17.21", "stylis": "^4.2.0" }, "devDependencies": { @@ -36,9 +34,7 @@ "@types/babel__helper-module-imports": "^7.18.3", "@types/babel__helper-plugin-utils": "^7.10.3", "@types/cssesc": "^3.0.2", - "@types/lodash.get": "^4.4.9", - "@types/lodash.merge": "^4.6.9", - "@types/lodash.set": "^4.3.9", + "@types/lodash": "^4.14.202", "@types/node": "^18.19.10", "@types/react": "^18.2.48", "@types/stylis": "^4.2.0", diff --git a/packages/zero-runtime/src/processors/css.ts b/packages/zero-runtime/src/processors/css.ts index 59f2f4f5ecbc62..6b8ea4fd1e4480 100644 --- a/packages/zero-runtime/src/processors/css.ts +++ b/packages/zero-runtime/src/processors/css.ts @@ -10,7 +10,7 @@ import type { import type { Replacements, Rules } from '@linaria/utils'; import { ValueType } from '@linaria/utils'; import type { CSSInterpolation } from '@emotion/css'; -import deepMerge from 'lodash.merge'; +import deepMerge from 'lodash/merge'; import BaseProcessor from './base-processor'; import type { IOptions } from './styled'; import { cache, css } from '../utils/emotion'; diff --git a/packages/zero-runtime/src/utils/cssFunctionTransformerPlugin.ts b/packages/zero-runtime/src/utils/cssFunctionTransformerPlugin.ts index f7d49d24a2554b..30ef433de1813f 100644 --- a/packages/zero-runtime/src/utils/cssFunctionTransformerPlugin.ts +++ b/packages/zero-runtime/src/utils/cssFunctionTransformerPlugin.ts @@ -1,6 +1,6 @@ import { declare } from '@babel/helper-plugin-utils'; import defaultSxConfig from '@mui/system/styleFunctionSx/defaultSxConfig'; -import get from 'lodash.get'; +import get from 'lodash/get'; import type { PluginCustomOptions } from './cssFnValueToVariable'; type Theme = { [key: 'unstable_sxConfig' | string]: string | number | Theme }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a8cecf4e008ff..50b7cc7884be7c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2357,15 +2357,9 @@ importers: csstype: specifier: ^3.1.2 version: 3.1.2 - lodash.get: - specifier: ^4.4.2 - version: 4.4.2 - lodash.merge: - specifier: ^4.6.2 - version: 4.6.2 - lodash.set: - specifier: ^4.3.2 - version: 4.3.2 + lodash: + specifier: ^4.17.21 + version: 4.17.21 stylis: specifier: ^4.2.0 version: 4.2.0 @@ -2382,15 +2376,9 @@ importers: '@types/cssesc': specifier: ^3.0.2 version: 3.0.2 - '@types/lodash.get': - specifier: ^4.4.9 - version: 4.4.9 - '@types/lodash.merge': - specifier: ^4.6.9 - version: 4.6.9 - '@types/lodash.set': - specifier: ^4.3.9 - version: 4.3.9 + '@types/lodash': + specifier: ^4.14.202 + version: 4.14.202 '@types/node': specifier: ^18.19.10 version: 18.19.10 @@ -7837,30 +7825,12 @@ packages: '@types/node': 18.19.10 dev: true - /@types/lodash.get@4.4.9: - resolution: {integrity: sha512-J5dvW98sxmGnamqf+/aLP87PYXyrha9xIgc2ZlHl6OHMFR2Ejdxep50QfU0abO1+CH6+ugx+8wEUN1toImAinA==} - dependencies: - '@types/lodash': 4.14.202 - dev: true - - /@types/lodash.merge@4.6.9: - resolution: {integrity: sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==} - dependencies: - '@types/lodash': 4.14.202 - dev: true - /@types/lodash.mergewith@4.6.7: resolution: {integrity: sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A==} dependencies: '@types/lodash': 4.14.202 dev: false - /@types/lodash.set@4.3.9: - resolution: {integrity: sha512-KOxyNkZpbaggVmqbpr82N2tDVTx05/3/j0f50Es1prxrWB0XYf9p3QNxqcbWb7P1Q9wlvsUSlCFnwlPCIJ46PQ==} - dependencies: - '@types/lodash': 4.14.202 - dev: true - /@types/lodash@4.14.202: resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} @@ -15308,14 +15278,11 @@ packages: /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true /lodash.mergewith@4.6.2: resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} - /lodash.set@4.3.2: - resolution: {integrity: sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==} - dev: false - /lodash.snakecase@4.1.1: resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} dev: true From e4bc65e9f61f72634587465135234e6c1e0c3907 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Wed, 31 Jan 2024 09:47:53 -0300 Subject: [PATCH 009/120] [material-ui][docs] Fix the icon preview dialog (#40863) Co-authored-by: Olivier Tassinari --- .../components/material-icons/SearchIcons.js | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/docs/data/material/components/material-icons/SearchIcons.js b/docs/data/material/components/material-icons/SearchIcons.js index 30863dcf8a4d69..7a846af8d02a22 100644 --- a/docs/data/material/components/material-icons/SearchIcons.js +++ b/docs/data/material/components/material-icons/SearchIcons.js @@ -114,15 +114,16 @@ const StyledSvgIcon = styled(SvgIcon)(({ theme }) => ({ boxSizing: 'content-box', cursor: 'pointer', color: theme.palette.text.primary, - borderRadius: theme.shape.borderRadius, + border: '1px solid transparent', + borderRadius: '12px', transition: theme.transitions.create(['background-color', 'box-shadow'], { duration: theme.transitions.duration.shortest, }), padding: theme.spacing(2), margin: theme.spacing(0.5, 0), '&:hover': { - backgroundColor: theme.palette.background.paper, - boxShadow: theme.shadows[1], + backgroundColor: theme.palette.background.default, + borderColor: theme.palette.primary.light, }, })); @@ -210,7 +211,6 @@ const Title = styled(Typography)(({ theme }) => ({ const CanvasComponent = styled('div')(({ theme }) => ({ fontSize: 210, - marginTop: theme.spacing(2), color: theme.palette.text.primary, backgroundSize: '30px 30px', backgroundColor: 'transparent', @@ -226,7 +226,7 @@ const FontSizeComponent = styled('span')(({ theme }) => ({ })); const ContextComponent = styled('div', { - shouldForwardProp: (prop) => prop !== 'contextColor', + shouldForwardProp: (prop) => prop !== 'contextColor' && prop !== 'as', })(({ theme, contextColor }) => ({ margin: theme.spacing(0.5), padding: theme.spacing(1, 2), @@ -270,7 +270,20 @@ const DialogDetails = React.memo(function DialogDetails(props) { }; return ( - + {selectedIcon ? ( @@ -309,7 +322,7 @@ const DialogDetails = React.memo(function DialogDetails(props) { - + @@ -338,38 +351,38 @@ const DialogDetails = React.memo(function DialogDetails(props) { - + @@ -394,7 +407,6 @@ const Form = styled('form')({ const Paper = styled(MuiPaper)(({ theme }) => ({ position: 'sticky', top: 80, - padding: '2px 4px', display: 'flex', alignItems: 'center', marginBottom: theme.spacing(2), @@ -402,6 +414,7 @@ const Paper = styled(MuiPaper)(({ theme }) => ({ borderRadius: '12px', border: '1px solid', borderColor: theme.palette.divider, + boxShadow: 'none', })); function formatNumber(value) { @@ -409,7 +422,6 @@ function formatNumber(value) { } const Input = styled(InputBase)({ - marginLeft: 8, flex: 1, }); @@ -523,7 +535,7 @@ export default function SearchIcons() { ); return ( - +
From b80acd69c7c848709d01465d6727b13ed6109258 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Wed, 31 Jan 2024 09:59:53 -0300 Subject: [PATCH 010/120] v5.15.7 (#40857) --- CHANGELOG.md | 94 +++++++++++++++++++ package.json | 2 +- packages/mui-base/package.json | 2 +- packages/mui-codemod/package.json | 2 +- .../mui-core-downloads-tracker/package.json | 2 +- packages/mui-docs/package.json | 2 +- packages/mui-envinfo/package.json | 2 +- packages/mui-icons-material/package.json | 2 +- packages/mui-joy/package.json | 2 +- packages/mui-lab/package.json | 2 +- packages/mui-material-next/package.json | 2 +- packages/mui-material-nextjs/package.json | 2 +- packages/mui-material/package.json | 2 +- packages/mui-private-theming/package.json | 2 +- packages/mui-styled-engine-sc/package.json | 2 +- packages/mui-styled-engine/package.json | 2 +- packages/mui-styles/package.json | 2 +- packages/mui-system/package.json | 2 +- packages/mui-utils/package.json | 2 +- 19 files changed, 112 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9242c865a78b40..30cbddca976369 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,99 @@ # [Versions](https://mui.com/versions/) +## v5.15.7 + + + +_Jan 31, 2024_ + +A big thanks to the 21 contributors who made this release possible. +This release was mostly about 🐛 bug fixes and 📚 documentation improvements. + +### `@mui/material@5.15.7` + +- ​[Select] Fix to show notched outline when `displayEmpty` (#40865) @ZeeshanTamboli +- ​[Avatar] Improve fallback when `children` is empty string or boolean (#40766) @mirus-ua +- ​[AvatarGroup] Refactor component thereby fixing custom spacing logic (#40686) @ZeeshanTamboli + +### `@mui/codemod@5.15.7` + +- ​Add accordion props deprecation (#40771) @siriwatknp + +### `@mui/system@5.15.7` + +- ​[zero-runtime] Use lodash instead of its subpackages (#40868) @michaldudak +- ​Add `applyStyles()` to theme (#40667) @siriwatknp +- ​[zero] Use `theme.applyStyles` in the demo app (#40787) @siriwatknp +- ​[zero] Add `useThemeProps` processor (#40648) @siriwatknp + +### `@mui/utils@5.15.7` + +- ​[core] Remove unnecessary default export (#40788) @siriwatknp +- ​[core] Convert all exports to modules (#39882) @mnajdova +- ​[perf] Prevent unneeded `clearTimeout` calls (#39060) @romgrk + +### `@mui/base@5.0.0-beta.34` + +- ​[Input] Add OTP input demo (#40539) @sai6855 +- ​[Menu] Focus last item after opening a menu using up arrow (#40764) @Jaswanth-Sriram-Veturi +- ​[Menu] Focus Menu Items on hover (#40755) @michaldudak + +### `@mui/joy@5.0.0-beta.25` + +- ​Change the color scheme type to `SupportedColorScheme` (#40776) @Nikhilh26 + +### `@mui/lab@5.0.0-alpha.163` + +- ​[TabContext] Support number type in `value` (#40829) @srinidhi9831 + +### Docs + +- ​[material-ui] Fix typo on styled-components guide (#40858) @dancielos +- ​[base-ui] Fix CSS vars from the plain CSS theme stylesheet (#40762) @zanivan +- ​[material-ui][Divider] Remove light prop references from docs (#40782) @sai6855 +- ​Fix build @oliviertassinari +- ​Add support pages for each product @oliviertassinari +- ​Add survey banner to docs and website (#40553) @joserodolfofreitas +- ​[Menu] Fix hydration mismatch error on Base UI's Menu docs (#40758) @michaldudak +- ​[material-nextjs] Add theming and configuration content to the page (#40626) @siriwatknp + +### Core + +- ​[website] Move `React Engineer - X` into the future roles section (#40867) @DanailH +- ​[material-ui][test][Alert] Add action, icon, and iconMapping tests (#40682) @DiegoAndai +- ​[blog] Lint duplicate h1 on the page (#40835) @oliviertassinari +- ​[blog] MUI X v7 beta announcement blogpost (#40784) @joserodolfofreitas +- ​[code-infra] Remove custom TS installation script (#40636) @michaldudak +- ​[code-infra] Correct API Docs Builder dependencies (#40775) @michaldudak +- ​[code-infra] Migrate to prettier async APIs (#40668) @Janpot +- ​[code-infra] Refined docs generation (#40603) @alexfauquette +- ​[code-infra] Explain how to install the browsers (#40474) @oliviertassinari +- ​`missingKeyGenerator` do no longer exist (#40830) @oliviertassinari +- ​Rely on immutable ref when possible (#40831) @oliviertassinari +- ​Remove deprecated `@types/markdown-to-jsx` package from docs (#40828) @ZeeshanTamboli +- ​Remove unneeded `@slack/web-api` package (#40840) @ZeeshanTamboli +- ​Clarify TODO instruction @oliviertassinari +- ​Remove unneeded use-clients (#40663) @oliviertassinari +- ​[docs-infra] Fix anchor link hook (#40836) @oliviertassinari +- ​[docs-infra] Avoid layout shift on docs-pages (#40749) @oliviertassinari +- ​[examples] Fix build on Next.js Pages Router examples (#40665) @oliviertassinari +- ​[test] Speed up the envinfo test (#40669) @michaldudak +- ​[typescript-to-proptypes] Allow to represent dates as `PropTypes.object` (#40774) @flaviendelangle +- ​[website] Add new Base UI role (#40773) @colmtuite +- ​[website] Fix a couple of rough edges (#40849) @danilo-leal +- ​[website] Small polishing after latest changes to the theme (#40846) @zanivan +- ​[website] Polish some pages and stray components (#40797) @danilo-leal +- ​[website] Refine the careers page slightly (#40793) @danilo-leal +- ​[website] Fix missing key on the Testimonials section (#40791) @Janpot +- ​[website] Fix Footer layout shift (#40786) @oliviertassinari +- ​[website] Revamp the testimonial section in the homepage (#40752) @danilo-leal +- ​[website] Fix pricing license model toggle style (#40747) @oliviertassinari +- ​[website] Fine-tune colors and styles on the branding theme (#40751) @danilo-leal +- ​[website] Fix Toggle Button styles in the homepage demos (#40744) @mohamedsaiedd +- ​[website] Update stats on the testimonials section (#40769) @EyaOuenniche + +All contributors of this release in alphabetical order: @alexfauquette, @colmtuite, @danilo-leal, @DiegoAndai, @EyaOuenniche, @flaviendelangle, @Janpot, @Jaswanth-Sriram-Veturi, @joserodolfofreitas, @michaldudak, @mirus-ua, @mnajdova, @mohamedsaiedd, @Nikhilh26, @oliviertassinari, @romgrk, @sai6855, @siriwatknp, @srinidhi9831, @zanivan, @ZeeshanTamboli + ## v5.15.6 diff --git a/package.json b/package.json index dc1c4760193ecc..d48f0129b3ab65 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mui/monorepo", - "version": "5.15.6", + "version": "5.15.7", "private": true, "scripts": { "preinstall": "npx only-allow pnpm", diff --git a/packages/mui-base/package.json b/packages/mui-base/package.json index 1a16022db63bd2..3fbcf198a357e8 100644 --- a/packages/mui-base/package.json +++ b/packages/mui-base/package.json @@ -1,6 +1,6 @@ { "name": "@mui/base", - "version": "5.0.0-beta.33", + "version": "5.0.0-beta.34", "private": false, "author": "MUI Team", "description": "Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.", diff --git a/packages/mui-codemod/package.json b/packages/mui-codemod/package.json index 5c23792f3cb66b..d171cde25d3381 100644 --- a/packages/mui-codemod/package.json +++ b/packages/mui-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@mui/codemod", - "version": "5.15.6", + "version": "5.15.7", "bin": "./codemod.js", "private": false, "author": "MUI Team", diff --git a/packages/mui-core-downloads-tracker/package.json b/packages/mui-core-downloads-tracker/package.json index 941b54ed9fe060..92c77db6d57f03 100644 --- a/packages/mui-core-downloads-tracker/package.json +++ b/packages/mui-core-downloads-tracker/package.json @@ -1,6 +1,6 @@ { "name": "@mui/core-downloads-tracker", - "version": "5.15.6", + "version": "5.15.7", "private": false, "author": "MUI Team", "description": "Internal package to track number of downloads of our design system libraries", diff --git a/packages/mui-docs/package.json b/packages/mui-docs/package.json index db0678f55ee6f5..7d39a0ee4423dd 100644 --- a/packages/mui-docs/package.json +++ b/packages/mui-docs/package.json @@ -1,6 +1,6 @@ { "name": "@mui/docs", - "version": "5.15.6", + "version": "5.15.7", "private": false, "author": "MUI Team", "description": "MUI Docs - Documentation building blocks.", diff --git a/packages/mui-envinfo/package.json b/packages/mui-envinfo/package.json index 2de87ce034c8b1..321dad3a093459 100644 --- a/packages/mui-envinfo/package.json +++ b/packages/mui-envinfo/package.json @@ -1,6 +1,6 @@ { "name": "@mui/envinfo", - "version": "2.0.16", + "version": "2.0.17", "private": false, "author": "MUI Team", "description": "Logs infos about the environment relevant to @mui/*", diff --git a/packages/mui-icons-material/package.json b/packages/mui-icons-material/package.json index 7e61d5fbd6b89d..f22853385b243c 100644 --- a/packages/mui-icons-material/package.json +++ b/packages/mui-icons-material/package.json @@ -1,6 +1,6 @@ { "name": "@mui/icons-material", - "version": "5.15.6", + "version": "5.15.7", "private": false, "author": "MUI Team", "description": "Material Design icons distributed as SVG React components.", diff --git a/packages/mui-joy/package.json b/packages/mui-joy/package.json index 3f67a2f0ea6c38..e0c4fc4776fa21 100644 --- a/packages/mui-joy/package.json +++ b/packages/mui-joy/package.json @@ -1,6 +1,6 @@ { "name": "@mui/joy", - "version": "5.0.0-beta.24", + "version": "5.0.0-beta.25", "private": false, "author": "MUI Team", "description": "Joy UI is an open-source React component library that implements MUI's own design principles. It's comprehensive and can be used in production out of the box.", diff --git a/packages/mui-lab/package.json b/packages/mui-lab/package.json index e53ae68ca62f53..b4b5dbed0d3195 100644 --- a/packages/mui-lab/package.json +++ b/packages/mui-lab/package.json @@ -1,6 +1,6 @@ { "name": "@mui/lab", - "version": "5.0.0-alpha.162", + "version": "5.0.0-alpha.163", "private": false, "author": "MUI Team", "description": "Laboratory for new MUI modules.", diff --git a/packages/mui-material-next/package.json b/packages/mui-material-next/package.json index 68fad75381ed32..4cc3e61fa72e62 100644 --- a/packages/mui-material-next/package.json +++ b/packages/mui-material-next/package.json @@ -1,6 +1,6 @@ { "name": "@mui/material-next", - "version": "6.0.0-alpha.119", + "version": "6.0.0-alpha.120", "private": false, "author": "MUI Team", "description": "v6-alpha: React components that implement Google's Material Design", diff --git a/packages/mui-material-nextjs/package.json b/packages/mui-material-nextjs/package.json index 4210cdc12b12b6..1e1a2848adc460 100644 --- a/packages/mui-material-nextjs/package.json +++ b/packages/mui-material-nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@mui/material-nextjs", - "version": "5.15.6", + "version": "5.15.7", "private": false, "author": "MUI Team", "description": "Collection of utilities for integration between Material UI and Next.js.", diff --git a/packages/mui-material/package.json b/packages/mui-material/package.json index a79ce316a03768..3a2a310ab61db7 100644 --- a/packages/mui-material/package.json +++ b/packages/mui-material/package.json @@ -1,6 +1,6 @@ { "name": "@mui/material", - "version": "5.15.6", + "version": "5.15.7", "private": false, "author": "MUI Team", "description": "Material UI is an open-source React component library that implements Google's Material Design. It's comprehensive and can be used in production out of the box.", diff --git a/packages/mui-private-theming/package.json b/packages/mui-private-theming/package.json index 7d0f863cc48581..7e49a71b2e52aa 100644 --- a/packages/mui-private-theming/package.json +++ b/packages/mui-private-theming/package.json @@ -1,6 +1,6 @@ { "name": "@mui/private-theming", - "version": "5.15.6", + "version": "5.15.7", "private": false, "author": "MUI Team", "description": "Private - The React theme context to be shared between `@mui/styles` and `@mui/material`.", diff --git a/packages/mui-styled-engine-sc/package.json b/packages/mui-styled-engine-sc/package.json index b5a299cb07de76..465429b4cfa090 100644 --- a/packages/mui-styled-engine-sc/package.json +++ b/packages/mui-styled-engine-sc/package.json @@ -1,6 +1,6 @@ { "name": "@mui/styled-engine-sc", - "version": "6.0.0-alpha.13", + "version": "6.0.0-alpha.14", "private": false, "author": "MUI Team", "description": "styled() API wrapper package for styled-components.", diff --git a/packages/mui-styled-engine/package.json b/packages/mui-styled-engine/package.json index 47d4e6b7061380..7a927786a87d58 100644 --- a/packages/mui-styled-engine/package.json +++ b/packages/mui-styled-engine/package.json @@ -1,6 +1,6 @@ { "name": "@mui/styled-engine", - "version": "5.15.6", + "version": "5.15.7", "private": false, "author": "MUI Team", "description": "styled() API wrapper package for emotion.", diff --git a/packages/mui-styles/package.json b/packages/mui-styles/package.json index 6310426b41ef2a..222fbb0d11e143 100644 --- a/packages/mui-styles/package.json +++ b/packages/mui-styles/package.json @@ -1,6 +1,6 @@ { "name": "@mui/styles", - "version": "5.15.6", + "version": "5.15.7", "private": false, "author": "MUI Team", "description": "MUI Styles - The legacy JSS-based styling solution of Material UI.", diff --git a/packages/mui-system/package.json b/packages/mui-system/package.json index cf552bdbca3f59..650938f7b35a15 100644 --- a/packages/mui-system/package.json +++ b/packages/mui-system/package.json @@ -1,6 +1,6 @@ { "name": "@mui/system", - "version": "5.15.6", + "version": "5.15.7", "private": false, "author": "MUI Team", "description": "MUI System is a set of CSS utilities to help you build custom designs more efficiently. It makes it possible to rapidly lay out custom designs.", diff --git a/packages/mui-utils/package.json b/packages/mui-utils/package.json index 57803ad1d4f1dc..6931410d10dc3a 100644 --- a/packages/mui-utils/package.json +++ b/packages/mui-utils/package.json @@ -1,6 +1,6 @@ { "name": "@mui/utils", - "version": "5.15.6", + "version": "5.15.7", "private": false, "author": "MUI Team", "description": "Utility functions for React components.", From 7b47c12cf69f3429bf05fbb3455aec605d2a6245 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Wed, 31 Jan 2024 10:49:59 -0300 Subject: [PATCH 011/120] [core] Add missing change to v5.15.7 changelog (#40872) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30cbddca976369..721e3c164b85fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ This release was mostly about 🐛 bug fixes and 📚 documentation improvements ### Docs +- ​[material-ui] Fix the icon preview dialog (#40863) @danilo-leal - ​[material-ui] Fix typo on styled-components guide (#40858) @dancielos - ​[base-ui] Fix CSS vars from the plain CSS theme stylesheet (#40762) @zanivan - ​[material-ui][Divider] Remove light prop references from docs (#40782) @sai6855 From 19ff6ada02dafa827531653801a3b657d58047ba Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Wed, 31 Jan 2024 15:23:21 +0100 Subject: [PATCH 012/120] [docs-infra] Improve StackBlitz support (#40832) --- docs/src/modules/components/DemoToolbar.js | 24 ++++----- docs/src/modules/sandbox/CodeSandbox.ts | 10 ++-- docs/src/modules/sandbox/Dependencies.ts | 58 +++++++++++----------- docs/src/modules/sandbox/StackBlitz.ts | 4 +- 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/src/modules/components/DemoToolbar.js b/docs/src/modules/components/DemoToolbar.js index 37314192980a39..88b25a700b6d15 100644 --- a/docs/src/modules/components/DemoToolbar.js +++ b/docs/src/modules/components/DemoToolbar.js @@ -549,31 +549,31 @@ export default function DemoToolbar(props) { {demoOptions.hideEditButton ? null : ( - + codeSandbox.createReactApp(demoData).openSandbox()} - {...getControlProps(4)} + data-ga-event-action="stackblitz" + onClick={() => stackBlitz.createReactApp(demoData).openSandbox()} + {...getControlProps(5)} sx={{ borderRadius: 1 }} > - - + + - + stackBlitz.createReactApp(demoData).openSandbox()} - {...getControlProps(5)} + data-ga-event-action="codesandbox" + onClick={() => codeSandbox.createReactApp(demoData).openSandbox()} + {...getControlProps(4)} sx={{ borderRadius: 1 }} > - - + + diff --git a/docs/src/modules/sandbox/CodeSandbox.ts b/docs/src/modules/sandbox/CodeSandbox.ts index 81b45a41e9d8a6..44b007be440ac2 100644 --- a/docs/src/modules/sandbox/CodeSandbox.ts +++ b/docs/src/modules/sandbox/CodeSandbox.ts @@ -33,7 +33,7 @@ function openSandbox({ files, codeVariant, initialFile }: any) { document.body.removeChild(form); } -const createReactApp = (demoData: DemoData) => { +function createReactApp(demoData: DemoData) { const ext = getFileExtension(demoData.codeVariant); const { title, githubLocation: description } = demoData; @@ -86,15 +86,15 @@ const createReactApp = (demoData: DemoData) => { openSandbox: (initialFile: string = `/src/Demo.${ext}`) => openSandbox({ files, codeVariant: demoData.codeVariant, initialFile }), }; -}; +} -const createJoyTemplate = (templateData: { +function createJoyTemplate(templateData: { title: string; files: Record; githubLocation: string; codeVariant: CodeVariant; codeStyling?: CodeStyling; -}) => { +}) { const ext = getFileExtension(templateData.codeVariant); const { title, githubLocation: description } = templateData; @@ -172,7 +172,7 @@ ReactDOM.createRoot(document.querySelector("#root")${type}).render( openSandbox: (initialFile: string = '/App') => openSandbox({ files, codeVariant: templateData.codeVariant, initialFile }), }; -}; +} export default { createReactApp, diff --git a/docs/src/modules/sandbox/Dependencies.ts b/docs/src/modules/sandbox/Dependencies.ts index 9e6a4ebad56770..1f0f69ae774749 100644 --- a/docs/src/modules/sandbox/Dependencies.ts +++ b/docs/src/modules/sandbox/Dependencies.ts @@ -1,6 +1,34 @@ import { CODE_VARIANTS } from 'docs/src/modules/constants'; import type { MuiProductId } from 'docs/src/modules/utils/getProductInfoFromUrl'; +const packagesWithBundledTypes = ['date-fns', '@emotion/react', '@emotion/styled', 'dayjs']; + +/** + * WARNING: Always uses `latest` typings. + * + * Adds dependencies to @types packages only for packages that are not listed + * in packagesWithBundledTypes + * + * @param deps - list of dependency as `name => version` + */ +function addTypeDeps(deps: Record): void { + const packagesWithDTPackage = Object.keys(deps) + .filter((name) => packagesWithBundledTypes.indexOf(name) === -1) + // All the MUI packages come with bundled types + .filter((name) => name.indexOf('@mui/') !== 0); + + packagesWithDTPackage.forEach((name) => { + let resolvedName = name; + // scoped package? + if (name.startsWith('@')) { + // https://github.com/DefinitelyTyped/DefinitelyTyped#what-about-scoped-packages + resolvedName = name.slice(1).replace('/', '__'); + } + + deps[`@types/${resolvedName}`] = 'latest'; + }); +} + export default function SandboxDependencies( demo: { raw: string; @@ -11,33 +39,6 @@ export default function SandboxDependencies( ) { const { commitRef } = options || {}; - /** - * WARNING: Always uses `latest` typings. - * - * Adds dependencies to @types packages only for packages that are not listed - * in packagesWithBundledTypes - * - * @param deps - list of dependency as `name => version` - */ - function addTypeDeps(deps: Record): void { - const packagesWithBundledTypes = ['date-fns', '@emotion/react', '@emotion/styled', 'dayjs']; - const packagesWithDTPackage = Object.keys(deps) - .filter((name) => packagesWithBundledTypes.indexOf(name) === -1) - // All the MUI packages come with bundled types - .filter((name) => name.indexOf('@mui/') !== 0); - - packagesWithDTPackage.forEach((name) => { - let resolvedName = name; - // scoped package? - if (name.startsWith('@')) { - // https://github.com/DefinitelyTyped/DefinitelyTyped#what-about-scoped-packages - resolvedName = name.slice(1).replace('/', '__'); - } - - deps[`@types/${resolvedName}`] = 'latest'; - }); - } - /** * @param packageName - The name of a package living inside this repository. * @return string - A valid version for a dependency entry in a package.json @@ -109,8 +110,7 @@ export default function SandboxDependencies( // TODO: consider if this configuration could be injected in a "cleaner" way. if (muiDocConfig) { - const muiCommitRef = process.env.PULL_REQUEST_ID ? process.env.COMMIT_REF : undefined; - versions = muiDocConfig.csbGetVersions(versions, { muiCommitRef }); + versions = muiDocConfig.csbGetVersions(versions, { muiCommitRef: commitRef }); } const re = /^import\s'([^']+)'|import\s[\s\S]*?\sfrom\s+'([^']+)/gm; diff --git a/docs/src/modules/sandbox/StackBlitz.ts b/docs/src/modules/sandbox/StackBlitz.ts index 9575f09de75bfc..38b43c7d20abb0 100644 --- a/docs/src/modules/sandbox/StackBlitz.ts +++ b/docs/src/modules/sandbox/StackBlitz.ts @@ -5,7 +5,7 @@ import * as CRA from 'docs/src/modules/sandbox/CreateReactApp'; import getFileExtension from 'docs/src/modules/sandbox/FileExtension'; import { DemoData } from 'docs/src/modules/sandbox/types'; -const createReactApp = (demoData: DemoData) => { +function createReactApp(demoData: DemoData) { const ext = getFileExtension(demoData.codeVariant); const { title, githubLocation: description } = demoData; @@ -52,7 +52,7 @@ const createReactApp = (demoData: DemoData) => { document.body.removeChild(form); }, }; -}; +} export default { createReactApp, From 69b7a29b3deafe941a7d450c90a19d49df9fab84 Mon Sep 17 00:00:00 2001 From: sai chand <60743144+sai6855@users.noreply.github.com> Date: Thu, 1 Feb 2024 01:47:59 +0530 Subject: [PATCH 013/120] [mui-codemod] Fix `findComponentJSX` util (#40855) --- packages/mui-codemod/src/util/findComponentJSX.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mui-codemod/src/util/findComponentJSX.js b/packages/mui-codemod/src/util/findComponentJSX.js index e079d004648f7e..57719b9ea28492 100644 --- a/packages/mui-codemod/src/util/findComponentJSX.js +++ b/packages/mui-codemod/src/util/findComponentJSX.js @@ -18,7 +18,7 @@ export default function findComponentJSX(j, options, callback) { root .find(j.ImportDeclaration) .filter((path) => - path.node.source.value.match(new RegExp(`^@mui/material/?(${componentName})?`)), + path.node.source.value.match(new RegExp(`^@mui/material(/${componentName})?$`)), ) .forEach((path) => { path.node.specifiers.forEach((specifier) => { From 56302c9b1fabe43078576878915b0710fb89336e Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Thu, 1 Feb 2024 00:53:12 +0100 Subject: [PATCH 014/120] [website] Use em-dash when relevant over hyphen Colm started to use it in https://github.com/mui/material-ui/pull/40773 --- .github/ISSUE_TEMPLATE/1.bug.yml | 2 +- .github/ISSUE_TEMPLATE/2.feature.yml | 2 +- .github/ISSUE_TEMPLATE/4.docs-feedback.yml | 2 +- .github/ISSUE_TEMPLATE/5.priority-support.yml | 2 +- .github/ISSUE_TEMPLATE/config.yml | 2 +- CHANGELOG.md | 2 +- docs/notifications.json | 4 ++-- docs/pages/blog/2021.md | 2 +- docs/pages/careers.tsx | 16 ++++++++-------- docs/pages/careers/ROLE_TEMPLATE.md | 2 +- docs/pages/careers/design-engineer-x-grid.md | 2 +- .../careers/developer-experience-engineer.md | 2 +- docs/pages/careers/engineering-manager.md | 2 +- docs/pages/careers/full-stack-engineer.md | 2 +- docs/pages/careers/product-engineer.md | 2 +- docs/pages/careers/react-community-engineer.md | 2 +- docs/pages/careers/react-engineer-core.md | 2 +- docs/pages/careers/react-engineer-x-charts.md | 2 +- docs/pages/careers/react-engineer-x-grid.md | 2 +- docs/pages/careers/react-engineer-x.md | 2 +- docs/pages/careers/react-tech-lead-core.md | 2 +- docs/pages/careers/react-tech-lead-x-grid.md | 2 +- docs/pages/careers/staff-ui-engineer-base-ui.md | 14 +++++++------- docs/pages/careers/support-agent.md | 2 +- 24 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/1.bug.yml b/.github/ISSUE_TEMPLATE/1.bug.yml index 48829628394f4f..faf654a00f515b 100644 --- a/.github/ISSUE_TEMPLATE/1.bug.yml +++ b/.github/ISSUE_TEMPLATE/1.bug.yml @@ -1,5 +1,5 @@ name: Bug report 🐛 -description: Create a bug report for Material UI, Base UI, MUI System, or Joy UI. +description: Create a bug report for Material UI, Base UI, MUI System, or Joy UI. labels: ['status: waiting for maintainer'] body: - type: markdown diff --git a/.github/ISSUE_TEMPLATE/2.feature.yml b/.github/ISSUE_TEMPLATE/2.feature.yml index 5ee6b7e56a5b35..b225d797ae8cd8 100644 --- a/.github/ISSUE_TEMPLATE/2.feature.yml +++ b/.github/ISSUE_TEMPLATE/2.feature.yml @@ -1,5 +1,5 @@ name: Feature request 💄 -description: Suggest a new idea for Material UI, Base UI, MUI System, or Joy UI. +description: Suggest a new idea for Material UI, Base UI, MUI System, or Joy UI. labels: ['status: waiting for maintainer'] body: - type: markdown diff --git a/.github/ISSUE_TEMPLATE/4.docs-feedback.yml b/.github/ISSUE_TEMPLATE/4.docs-feedback.yml index 7c585dea0d228d..8c41c69d7c074a 100644 --- a/.github/ISSUE_TEMPLATE/4.docs-feedback.yml +++ b/.github/ISSUE_TEMPLATE/4.docs-feedback.yml @@ -1,5 +1,5 @@ name: Docs feedback -description: Improve documentation about Material UI, Base UI, MUI System, or Joy UI. +description: Improve documentation about Material UI, Base UI, MUI System, or Joy UI. labels: ['status: waiting for maintainer', 'support: docs-feedback'] title: '[docs] ' body: diff --git a/.github/ISSUE_TEMPLATE/5.priority-support.yml b/.github/ISSUE_TEMPLATE/5.priority-support.yml index c425b846387078..fb19f4eb3b26d2 100644 --- a/.github/ISSUE_TEMPLATE/5.priority-support.yml +++ b/.github/ISSUE_TEMPLATE/5.priority-support.yml @@ -1,5 +1,5 @@ name: 'Priority Support: SLA ⏰' -description: I'm an MUI X Premium user and we have purchased the Priority Support add-on. I can't find a solution to my problem with Material UI, Base UI, MUI System, or Joy UI. +description: I'm an MUI X Premium user and we have purchased the Priority Support add-on. I can't find a solution to my problem with Material UI, Base UI, MUI System, or Joy UI. title: '[question] ' labels: ['status: waiting for maintainer', 'support: unknown'] body: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 6f728a37481983..1bc33bd5c715cb 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ contact_links: - name: Support ❔ url: https://mui.com/getting-started/support/ - about: I need support with Material UI, Base UI, MUI System, or Joy UI. + about: I need support with Material UI, Base UI, MUI System, or Joy UI. diff --git a/CHANGELOG.md b/CHANGELOG.md index 721e3c164b85fb..75c4d3b92fdb44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -150,7 +150,7 @@ This release was mostly about 🐛 bug fixes and 📚 documentation improvements - ​[core] Polish issue templates @oliviertassinari - ​[docs-infra] Support markdown link in slots descriptions (#40679) @alexfauquette - ​[examples] Simplify Next.js example (#40661) @oliviertassinari -- ​[website] Fix broken styles on Base UI page (#40683) @michaldudak +- ​[website] Fix broken styles on Base UI page (#40683) @michaldudak All contributors of this release in alphabetical order: @alexfauquette, @anle9650, @ANUGLYPLUGIN, @brijeshb42, @danilo-leal, @devhik0, @DiegoAndai, @DonikaV, @joserodolfofreitas, @michaldudak, @mj12albert, @mnajdova, @mohamedsaiedd, @oliviertassinari, @pcorpet, @sai6855, @zanivan diff --git a/docs/notifications.json b/docs/notifications.json index de203b60e3b834..8942f5e762fef6 100644 --- a/docs/notifications.json +++ b/docs/notifications.json @@ -1,8 +1,8 @@ [ { "id": 68, - "title": "Check out Base UI today 💥", - "text": "Love Material UI, but don't need Material Design? Try Base UI, the new \"unstyled\" alternative. Read more in this announcement." + "title": "Check out Base UI today 💥", + "text": "Love Material UI, but don't need Material Design? Try Base UI, the new \"unstyled\" alternative. Read more in this announcement." }, { "id": 76, diff --git a/docs/pages/blog/2021.md b/docs/pages/blog/2021.md index 6dac727d301afe..8ef1763138ef0b 100644 --- a/docs/pages/blog/2021.md +++ b/docs/pages/blog/2021.md @@ -68,7 +68,7 @@ We have achieved most of what we could have hoped for. - We held our first company [retreat](/blog/2021-q3-update/#retreat) 🏝 in Lisbon, Portugal 🇵🇹 , for members of the team that were not prevented by COVID-19 related travel restrictions, and who felt safe enough to travel. - We have [rebranded](/blog/material-ui-is-now-mui/) the company to a clean 3 letters acronym: mui.com. This move was key for us to grow beyond Material Design. -### Core (Material UI, Joy UI, Base UI, MUI System) +### Core (Material UI, Joy UI, Base UI, MUI System) - We have released [v5](/blog/mui-core-v5/), 21% of the npm downloads are on this major version now. - We have broken down the demos into smaller and focus on one aspect at a time. diff --git a/docs/pages/careers.tsx b/docs/pages/careers.tsx index 055fe0e3193c3f..1ebc9fd6879637 100644 --- a/docs/pages/careers.tsx +++ b/docs/pages/careers.tsx @@ -147,7 +147,7 @@ const openRolesData = [ title: 'Engineering', roles: [ { - title: 'React Engineer - xCharts', + title: 'React Engineer — xCharts', description: 'You will help form the xCharts team, build ambitious and complex new features, work on strategic problems, and help grow adoption.', url: '/careers/react-engineer-x-charts/', @@ -159,7 +159,7 @@ const openRolesData = [ // url: '/careers/react-engineer-x/', // }, { - title: 'Staff UI Engineer - Base UI', + title: 'Staff UI Engineer — Base UI', description: 'Research, build, document, and ship high-quality, unstyled UI components with a focus on a11y.', url: '/careers/staff-ui-engineer-base-ui/', @@ -170,7 +170,7 @@ const openRolesData = [ title: 'Design', roles: [ { - title: 'Design Engineer - xGrid', + title: 'Design Engineer — xGrid', description: 'You will design and implement a great user and developer experience for the MUI X Data Grid.', url: '/careers/design-engineer-x-grid/', @@ -201,31 +201,31 @@ const nextRolesData = [ url: '/careers/accessibility-engineer/', }, { - title: 'Full-stack Engineer - Toolpad', + title: 'Full-stack Engineer — Toolpad', description: 'You will join the MUI Toolpad team, to explore the role of MUI in the low code space and help bring the early prototype to a usable product.', url: '/careers/fullstack-engineer/', }, { - title: 'React Engineer - X', + title: 'React Engineer — X', description: 'You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.', url: '/careers/react-engineer-x/', }, { - title: 'React Tech Lead - Core', + title: 'React Tech Lead — Core', description: 'You will lead the development of MUI Core, positioning the library as the industry standard for design teams while doubling its adoption.', url: '/careers/react-tech-lead-core/', }, { - title: 'React Engineer - Core', + title: 'React Engineer — Core', description: 'You will strengthen the core components team by collaborating with the community to land contributions.', url: '/careers/react-engineer-core/', }, { - title: 'React Community Engineer - X', + title: 'React Community Engineer — X', description: 'You will provide guidance to the community and solve their struggle, working primarily in the advanced components team.', url: '/careers/react-community-engineer/', diff --git a/docs/pages/careers/ROLE_TEMPLATE.md b/docs/pages/careers/ROLE_TEMPLATE.md index 9dbd149a25caa9..a257c10daedec4 100644 --- a/docs/pages/careers/ROLE_TEMPLATE.md +++ b/docs/pages/careers/ROLE_TEMPLATE.md @@ -1,4 +1,4 @@ -# XXXXXX +# XXXXXX — YYYY

XXXXXX.

diff --git a/docs/pages/careers/design-engineer-x-grid.md b/docs/pages/careers/design-engineer-x-grid.md index 18ba45a0a02b4b..d75512d4be6021 100644 --- a/docs/pages/careers/design-engineer-x-grid.md +++ b/docs/pages/careers/design-engineer-x-grid.md @@ -1,4 +1,4 @@ -# Design Engineer - xGrid +# Design Engineer — xGrid

You will design and implement a great user and developer experience for the MUI X Data Grid.

diff --git a/docs/pages/careers/developer-experience-engineer.md b/docs/pages/careers/developer-experience-engineer.md index de81d351a5d11f..aca2934404634f 100644 --- a/docs/pages/careers/developer-experience-engineer.md +++ b/docs/pages/careers/developer-experience-engineer.md @@ -1,4 +1,4 @@ -# Developer Experience Engineer - Core +# Developer Experience Engineer — Core

You will focus on providing experiences that delight developers using MUI. This role is mostly about MUI Core.

diff --git a/docs/pages/careers/engineering-manager.md b/docs/pages/careers/engineering-manager.md index da912d611b2120..7b17cc7265121a 100644 --- a/docs/pages/careers/engineering-manager.md +++ b/docs/pages/careers/engineering-manager.md @@ -1,4 +1,4 @@ -# Engineering Manager - Toolpad +# Engineering Manager — Toolpad

You will grow the small engineering team currently working on MUI Toolpad.

diff --git a/docs/pages/careers/full-stack-engineer.md b/docs/pages/careers/full-stack-engineer.md index 605d5387ec6c96..2e2e9e5420380e 100644 --- a/docs/pages/careers/full-stack-engineer.md +++ b/docs/pages/careers/full-stack-engineer.md @@ -1,4 +1,4 @@ -# Full-stack Engineer - Toolpad (future role) +# Full-stack Engineer — Toolpad (future role)

You will join the MUI Toolpad team, to explore the role of MUI in the low code space and help bring the early prototype to a usable product.

diff --git a/docs/pages/careers/product-engineer.md b/docs/pages/careers/product-engineer.md index 58e4c97e3a75d6..706a493dcdb0d2 100644 --- a/docs/pages/careers/product-engineer.md +++ b/docs/pages/careers/product-engineer.md @@ -1,4 +1,4 @@ -# Product Engineer - Store +# Product Engineer — Store

You will lead the technical, product, and operational development of the store.

diff --git a/docs/pages/careers/react-community-engineer.md b/docs/pages/careers/react-community-engineer.md index d0b176bdf6dd7e..0e1cf2f61363b8 100644 --- a/docs/pages/careers/react-community-engineer.md +++ b/docs/pages/careers/react-community-engineer.md @@ -1,4 +1,4 @@ -# React Community Engineer - X (future role) +# React Community Engineer — X (future role)

You will provide guidance to the community and solve their struggle, working primarily in the advanced components team.

diff --git a/docs/pages/careers/react-engineer-core.md b/docs/pages/careers/react-engineer-core.md index 2efbac07ca9d83..cadf2d5e1941fd 100644 --- a/docs/pages/careers/react-engineer-core.md +++ b/docs/pages/careers/react-engineer-core.md @@ -1,4 +1,4 @@ -# React Engineer - Core (future role) +# React Engineer — Core (future role)

You will strengthen the core components team by collaborating with the community to land contributions.

diff --git a/docs/pages/careers/react-engineer-x-charts.md b/docs/pages/careers/react-engineer-x-charts.md index 7c5783fbe9b616..633bb8e6521bac 100644 --- a/docs/pages/careers/react-engineer-x-charts.md +++ b/docs/pages/careers/react-engineer-x-charts.md @@ -1,4 +1,4 @@ -# React Engineer - xCharts +# React Engineer — xCharts

You will help form the xCharts team, build ambitious and complex new features, work on strategic problems, and help grow adoption.

diff --git a/docs/pages/careers/react-engineer-x-grid.md b/docs/pages/careers/react-engineer-x-grid.md index 834cad6ed53a61..70fa973d23ae55 100644 --- a/docs/pages/careers/react-engineer-x-grid.md +++ b/docs/pages/careers/react-engineer-x-grid.md @@ -1,4 +1,4 @@ -# React Engineer - xGrid +# React Engineer — xGrid

You will strengthen the Data Grid team, build ambitious and complex new features, work on strategic problems, and help grow adoption.

diff --git a/docs/pages/careers/react-engineer-x.md b/docs/pages/careers/react-engineer-x.md index 4e6a22d9034f75..ecf697c998394e 100644 --- a/docs/pages/careers/react-engineer-x.md +++ b/docs/pages/careers/react-engineer-x.md @@ -1,4 +1,4 @@ -# React Engineer - X +# React Engineer — X

You will strengthen the MUI X product, build ambitious and complex new features, work on strategic problems, and help grow adoption.

diff --git a/docs/pages/careers/react-tech-lead-core.md b/docs/pages/careers/react-tech-lead-core.md index f8cf0414dec49b..12c0f03789884c 100644 --- a/docs/pages/careers/react-tech-lead-core.md +++ b/docs/pages/careers/react-tech-lead-core.md @@ -1,4 +1,4 @@ -# React Tech Lead - Core (future role) +# React Tech Lead — Core (future role)

You will lead the development of MUI Core, positioning the library as the industry standard for design teams while doubling its adoption.

diff --git a/docs/pages/careers/react-tech-lead-x-grid.md b/docs/pages/careers/react-tech-lead-x-grid.md index 247fa16843a564..6357fd72930a08 100644 --- a/docs/pages/careers/react-tech-lead-x-grid.md +++ b/docs/pages/careers/react-tech-lead-x-grid.md @@ -1,4 +1,4 @@ -# React Tech Lead - xGrid +# React Tech Lead — xGrid

You will lead the development of the MUI X Data Grid, positioning the component as the next industry standard.

diff --git a/docs/pages/careers/staff-ui-engineer-base-ui.md b/docs/pages/careers/staff-ui-engineer-base-ui.md index 5261a8a4693d55..a27c8afa1cd5fc 100644 --- a/docs/pages/careers/staff-ui-engineer-base-ui.md +++ b/docs/pages/careers/staff-ui-engineer-base-ui.md @@ -1,4 +1,4 @@ -# Staff UI Engineer — Base UI +# Staff UI Engineer — Base UI

Research, build, document, and ship high-quality, unstyled UI components with a focus on a11y.

@@ -37,14 +37,14 @@ For additional details about the culture, you can check our [careers](https://mu ## Why we're hiring -The Base UI team is just starting to take shape now, and we have big goals for the next few years. We need experienced people to work alongside excellent UI engineers and designers, in an IC capacity, to research, spec, build, document, and ship high-quality, unstyled UI components with a focus on a11y. +The Base UI team is just starting to take shape now, and we have big goals for the next few years. We need experienced people to work alongside excellent UI engineers and designers, in an IC capacity, to research, spec, build, document, and ship high-quality, unstyled UI components with a focus on a11y. Overall, both our open-source community and our premium products are growing fast (x2 YoY). We need talented people to keep that going! ### Why this is interesting -Our products empower React developers to build awesome applications faster – we see millions of developers on MUI's docs every year, one million a month. We're planning to invest heavily in Base UI this year and into the future. Our goal is to make Base UI one the best unstyled UI libs available, and in the process, help millions of developers build more accessible products. +Our products empower React developers to build awesome applications faster – we see millions of developers on MUI's docs every year, one million a month. We're planning to invest heavily in Base UI this year and into the future. Our goal is to make Base UI one the best unstyled UI libs available, and in the process, help millions of developers build more accessible products. ## The role @@ -53,18 +53,18 @@ Our products empower React developers to build awesome applications faster – w Depending on the day, you'll: - Build UI components with React and TypeScript. -- Perform code reviews and help to maintain a high-bar for code quality. -- Test Base UI components on various devices, browsers, platforms, and screen readers. +- Perform code reviews and help to maintain a high bar for code quality. +- Test Base UI components on various devices, browsers, platforms, and screen readers. - Research a11y requirements for UI components. - Contribute to component API design decisions and architecture. -- Contribute to Base UI documentation. +- Contribute to Base UI documentation. - Help out with community support on GitHub and Discord. ## Who we're looking for ### Required -- **Expertise with the modern JavaScript ecosystem**. Base UI is built on modern front-end technologies like TypeScript, Node.js, React, Next.js, Webpack, and Babel. Working knowledge of these technologies is critical. +- **Expertise with the modern JavaScript ecosystem**. Base UI is built on modern front-end technologies like TypeScript, Node.js, React, Next.js, Webpack, and Babel. Working knowledge of these technologies is critical. - **Expertise with CSS.** Deep knowledge of the functional aspects of CSS will be required. - **Familiarity with a11y requirements.** We are looking for someone familiar with ARIA requirements, who cares about building accessible UI, and wants to make the web a more accessible place. - **An eye for detail.** We appreciate people who sweat the details. People who go above and beyond to make interfaces fast, accessible, beautiful, and delightful. diff --git a/docs/pages/careers/support-agent.md b/docs/pages/careers/support-agent.md index 2105a025cd5a60..a3fe251e5fd92e 100644 --- a/docs/pages/careers/support-agent.md +++ b/docs/pages/careers/support-agent.md @@ -1,4 +1,4 @@ -# Support Agent - Store (future role) +# Support Agent — Store (future role)

You will provide support for the customers of MUI Store. You will directly impact customers' satisfaction and success.

From 5e811b81d6f394aae079a239af0b108335559e8b Mon Sep 17 00:00:00 2001 From: Siriwat K Date: Thu, 1 Feb 2024 10:00:21 +0700 Subject: [PATCH 015/120] [utils] Use consistent build approach (#40837) --- packages/mui-utils/package.json | 4 ++-- scripts/build.mjs | 11 +++-------- scripts/sizeSnapshot/webpack.config.js | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/mui-utils/package.json b/packages/mui-utils/package.json index 6931410d10dc3a..5f97d78e7b0bc2 100644 --- a/packages/mui-utils/package.json +++ b/packages/mui-utils/package.json @@ -29,8 +29,8 @@ "build": "pnpm build:legacy && pnpm build:modern && pnpm build:node && pnpm build:stable && pnpm build:types && pnpm build:copy-files", "build:legacy": "node ../../scripts/build.mjs legacy", "build:modern": "node ../../scripts/build.mjs modern", - "build:node": "node ../../scripts/build.mjs node --ignoreTopLevel", - "build:stable": "node ../../scripts/build.mjs stable --ignoreTopLevel", + "build:node": "node ../../scripts/build.mjs node", + "build:stable": "node ../../scripts/build.mjs stable", "build:copy-files": "node ../../scripts/copyFiles.mjs", "build:types": "node ../../scripts/buildTypes.mjs", "prebuild": "rimraf build tsconfig.build.tsbuildinfo", diff --git a/scripts/build.mjs b/scripts/build.mjs index 0ba59aac2937e0..711bcf389ae274 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -19,7 +19,7 @@ const validBundles = [ ]; async function run(argv) { - const { bundle, largeFiles, outDir: relativeOutDir, verbose, ignoreTopLevel } = argv; + const { bundle, largeFiles, outDir: relativeOutDir, verbose } = argv; if (validBundles.indexOf(bundle) === -1) { throw new TypeError( @@ -62,9 +62,9 @@ async function run(argv) { // // TODO v6: Switch to `exports` field. { - node: !ignoreTopLevel && topLevelPathImportsCanBePackages ? './node' : './', + node: topLevelPathImportsCanBePackages ? './node' : './', modern: './modern', - stable: !ignoreTopLevel && topLevelPathImportsCanBePackages ? './' : './esm', + stable: topLevelPathImportsCanBePackages ? './' : './esm', legacy: './legacy', }[bundle], ); @@ -119,11 +119,6 @@ yargs(process.argv.slice(2)) describe: 'Set to `true` if you know you are transpiling large files.', }) .option('out-dir', { default: './build', type: 'string' }) - .option('ignoreTopLevel', { - type: 'boolean', - default: false, - describe: 'Set to `true` to ignore switching out-dir based on top level import.', - }) .option('verbose', { type: 'boolean' }); }, handler: run, diff --git a/scripts/sizeSnapshot/webpack.config.js b/scripts/sizeSnapshot/webpack.config.js index e0b7c581aa8fb8..c32d969700b063 100644 --- a/scripts/sizeSnapshot/webpack.config.js +++ b/scripts/sizeSnapshot/webpack.config.js @@ -139,7 +139,7 @@ async function getWebpackEntries() { ...coreComponents, { id: '@material-ui/utils', - path: 'packages/mui-utils/build/esm/index.js', + path: 'packages/mui-utils/build/index.js', }, // TODO: Requires webpack v5 // Resolution of webpack/acorn to 7.x is blocked by nextjs (https://github.com/vercel/next.js/issues/11947) From b7b84a612630a68026ac8501a5ab7e62b2e4bf37 Mon Sep 17 00:00:00 2001 From: Brijesh Bittu Date: Thu, 1 Feb 2024 09:12:22 +0530 Subject: [PATCH 016/120] [zero] Add README with installation and basic usage (#40761) --- packages/zero-runtime/README.md | 251 ++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 packages/zero-runtime/README.md diff --git a/packages/zero-runtime/README.md b/packages/zero-runtime/README.md new file mode 100644 index 00000000000000..680f6510386cfd --- /dev/null +++ b/packages/zero-runtime/README.md @@ -0,0 +1,251 @@ +# zero-runtime + +A zero-runtime CSS-in-JS library that extracts the colocated css to it's own css files at build-time. + +## Getting started + +Zero-runtime supports Next.js and Vite with future support for more bundlers—you must install the corresponding plugin, as shown below. + +The package currently has a dependency on `@mui/material` to initialize the theme object, but this is only at build time. There won't be any Material UI code at runtime if you're not using it otherwise—in that case, you can move it to dev dependencies instead (as shown with the plugin packages). + +### Next.js + +#### Installation + +```bash +npm install @mui/zero-runtime @mui/material +npm install --save-dev @mui/zero-next-plugin +``` + +#### Configuration + +In your `next.config.js` file, + +1. Import the plugin + +```js +const { withZeroPlugin } = require('@mui/zero-next-plugin'); +``` + +2. Create a theme object + +```js +const { experimental_extendTheme: extendTheme } = require('@mui/material/styles'); +const theme = extendTheme(); +``` + +3. Wrap the exported config object + +```js +module.exports = withZeroPlugin(nextConfig, { + theme, +}); +``` + +### Vite + +#### Installation + +```bash +npm install @mui/zero-runtime @mui/material +npm install --save-dev @mui/zero-vite-plugin +``` + +#### Configuration + +In your vite config file, + +1. Import the plugin + +```js +import { zeroVitePlugin } from '@mui/zero-vite-plugin'; +``` + +2. Create a theme object + +```js +import { experimental_extendTheme as extendTheme } from '@mui/material/styles'; +const theme = extendTheme(); +``` + +3. Add the plugin to the `plugins` array. The position does not matter. + +```js +export default defineConfig({ + plugins: [ + zeroVitePlugin({ + theme, + }), + // ... Your other plugins. + ], +}); +``` + +### Usage + +In your source files, you can import the `styled` function from `@mui/zero-runtime`. The usage should be familiar if you've worked with Emotion or styled-components: + +```js +import { styled } from '@mui/zero-runtime'; + +const Heading = styled.h1({ + fontSize: '4rem', + fontWeight: 'bold', + padding: '10px 0px', +}); + +function App() { + return Hello; +} +``` + +The zero-runtime package differs from "standard" runtime CSS-in-JS libraries in a few ways: + +1. You never get direct access to props in your styled declarations. This is because prop values are only available at runtime, but the CSS is extracted at build time. See [Styling based on runtime values](#styling-based-on-runtime-values) for a workaround. +2. Your styles must be declarative, and must account for all combinations of props that you want to style. +3. The theme lets you declare CSS tokens that become part of the CSS bundle after the build. Any other values and methods that it might have are only available during build time—not at runtime. This leads to smaller bundle sizes. + +You can access the same `theme` object that you provided in the bundler config by declaring styles as callbacks—for example: + +```js +const Heading = styled.h1(({ theme }) => ({ + ...theme.typography.h1, +})); +``` + +Visit the [Default theme viewer](https://mui.com/material-ui/customization/default-theme/) to learn more about the structure of the theme object. + +#### Styling variants + +The `styled` function must account for all combinations of props. If you're creating a button component that supports a `size` prop and a `color` prop, for example, you can use the `variants` API to define styles for each possible combination of the two: + +```jsx +const Button = styled.button(() => ({ + border: 'none', + // ... other base css styles to be applied across all prop values. + variants: [ + { + // prop combinations + props: { + color: 'primary', + }, + // styles to be applied when color="primary" is passed on the component + style: { + color: 'blue', + outline: '1px transparent lightblue', + }, + }, + { + props: { + color: 'secondary', + }, + // styles to be applied when color="secondary" is passed on the component + style: { + color: 'green', + outline: '1px transparent lightgreen', + }, + }, + { + props: { + size: 'large', + }, + style: { + padding: '0.5rem', + }, + }, + { + props: { + size: 'medium', + }, + style: { + padding: '0.25rem', + }, + }, + { + props: { + size: 'small', + }, + style: { + padding: '0.1rem', + }, + }, + { + props: { + size: 'small', + color: 'primary', + }, + style: { + // Styles to be applied when + + + ); + } + const { getByRole, getByTestId } = render(); + + const input = getByRole('textbox') as HTMLInputElement; + const button = getByTestId('button') as HTMLButtonElement; + + act(() => { + fireEvent.click(button); + }); + + await userEvent.click(input); + expect(input.value).to.equal('20'); + }); }); diff --git a/packages/mui-base/src/Unstable_NumberInput/NumberInput.tsx b/packages/mui-base/src/Unstable_NumberInput/NumberInput.tsx index 6df3dec6d9a31a..d93cbd44ce69c1 100644 --- a/packages/mui-base/src/Unstable_NumberInput/NumberInput.tsx +++ b/packages/mui-base/src/Unstable_NumberInput/NumberInput.tsx @@ -115,6 +115,7 @@ const NumberInput = React.forwardRef(function NumberInput( readOnly, value, inputId: id, + componentName: 'NumberInput', }); const ownerState: NumberInputOwnerState = { @@ -204,7 +205,7 @@ NumberInput.propTypes /* remove-proptypes */ = { /** * The default value. Use when the component is not controlled. */ - defaultValue: PropTypes.any, + defaultValue: PropTypes.number, /** * If `true`, the component is disabled. * The prop defaults to the value (`false`) inherited from the parent FormControl component. @@ -306,6 +307,7 @@ NumberInput.propTypes /* remove-proptypes */ = { step: PropTypes.number, /** * The current value. Use when the component is controlled. + * @default null */ value: PropTypes.number, } as any; diff --git a/packages/mui-base/src/unstable_useNumberInput/numberInputAction.types.ts b/packages/mui-base/src/unstable_useNumberInput/numberInputAction.types.ts index 1373e6d9924c0c..1fdce02ad16621 100644 --- a/packages/mui-base/src/unstable_useNumberInput/numberInputAction.types.ts +++ b/packages/mui-base/src/unstable_useNumberInput/numberInputAction.types.ts @@ -5,34 +5,45 @@ export const NumberInputActionTypes = { decrement: 'numberInput:decrement', decrementToMin: 'numberInput:decrementToMin', incrementToMax: 'numberInput:incrementToMax', + resetInputValue: 'numberInput:resetInputValue', } as const; interface NumberInputClampAction { type: typeof NumberInputActionTypes.clamp; + event: React.FocusEvent; inputValue: string; } interface NumberInputInputChangeAction { type: typeof NumberInputActionTypes.inputChange; + event: React.ChangeEvent; inputValue: string; } interface NumberInputIncrementAction { type: typeof NumberInputActionTypes.increment; + event: React.PointerEvent | React.KeyboardEvent; applyMultiplier: boolean; } interface NumberInputDecrementAction { type: typeof NumberInputActionTypes.decrement; + event: React.PointerEvent | React.KeyboardEvent; applyMultiplier: boolean; } interface NumberInputIncrementToMaxAction { type: typeof NumberInputActionTypes.incrementToMax; + event: React.KeyboardEvent; } interface NumberInputDecrementToMinAction { type: typeof NumberInputActionTypes.decrementToMin; + event: React.KeyboardEvent; +} + +interface NumberInputResetInputValueAction { + type: typeof NumberInputActionTypes.resetInputValue; } export type NumberInputAction = @@ -41,4 +52,5 @@ export type NumberInputAction = | NumberInputIncrementAction | NumberInputDecrementAction | NumberInputIncrementToMaxAction - | NumberInputDecrementToMinAction; + | NumberInputDecrementToMinAction + | NumberInputResetInputValueAction; diff --git a/packages/mui-base/src/unstable_useNumberInput/numberInputReducer.test.ts b/packages/mui-base/src/unstable_useNumberInput/numberInputReducer.test.ts index 461b40901c64f7..e1ecd6f9654c7e 100644 --- a/packages/mui-base/src/unstable_useNumberInput/numberInputReducer.test.ts +++ b/packages/mui-base/src/unstable_useNumberInput/numberInputReducer.test.ts @@ -4,6 +4,10 @@ import { NumberInputActionTypes } from './numberInputAction.types'; import { numberInputReducer } from './numberInputReducer'; import { getInputValueAsString as defaultGetInputValueAsString } from './useNumberInput'; +// the actual event is irrelevant to the reducer +// it's only part of the action object so it can be passed to the state change callback +const MOCK_EVENT: any = {}; + describe('numberInputReducer', () => { describe('action: clamp', () => { it('clamps the inputValue', () => { @@ -14,6 +18,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.clamp, + event: MOCK_EVENT, inputValue: '1', context: { getInputValueAsString: defaultGetInputValueAsString, @@ -35,6 +40,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.clamp, + event: MOCK_EVENT, inputValue: '3', context: { getInputValueAsString: defaultGetInputValueAsString, @@ -57,6 +63,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.clamp, + event: MOCK_EVENT, inputValue: '0', context: { getInputValueAsString: defaultGetInputValueAsString, @@ -79,6 +86,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.clamp, + event: MOCK_EVENT, inputValue: '10', context: { getInputValueAsString: defaultGetInputValueAsString, @@ -95,12 +103,13 @@ describe('numberInputReducer', () => { it('empty value', () => { const state: NumberInputState = { - value: '', + value: null, inputValue: '', }; const action: NumberInputReducerAction = { type: NumberInputActionTypes.clamp, + event: MOCK_EVENT, inputValue: '', context: { getInputValueAsString: defaultGetInputValueAsString, @@ -110,7 +119,7 @@ describe('numberInputReducer', () => { const result = numberInputReducer(state, action); - expect(result.value).to.equal(''); + expect(result.value).to.equal(null); expect(result.inputValue).to.equal(''); }); }); @@ -124,6 +133,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.inputChange, + event: MOCK_EVENT, inputValue: '1', context: { getInputValueAsString: defaultGetInputValueAsString, @@ -133,7 +143,7 @@ describe('numberInputReducer', () => { const result = numberInputReducer(state, action); - expect(result.value).to.equal(1); + expect(result.value).to.equal(0); expect(result.inputValue).to.equal('1'); }); @@ -145,6 +155,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.inputChange, + event: MOCK_EVENT, inputValue: '1a', context: { getInputValueAsString: defaultGetInputValueAsString, @@ -166,6 +177,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.inputChange, + event: MOCK_EVENT, inputValue: '-', context: { getInputValueAsString: defaultGetInputValueAsString, @@ -175,7 +187,7 @@ describe('numberInputReducer', () => { const result = numberInputReducer(state, action); - expect(result.value).to.equal(''); + expect(result.value).to.equal(-1); expect(result.inputValue).to.equal('-'); }); @@ -187,6 +199,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.inputChange, + event: MOCK_EVENT, inputValue: '', context: { getInputValueAsString: defaultGetInputValueAsString, @@ -196,7 +209,7 @@ describe('numberInputReducer', () => { const result = numberInputReducer(state, action); - expect(result.value).to.equal(''); + expect(result.value).to.equal(1); expect(result.inputValue).to.equal(''); }); }); @@ -210,6 +223,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.increment, + event: MOCK_EVENT, applyMultiplier: false, context: { getInputValueAsString: defaultGetInputValueAsString, @@ -231,6 +245,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.increment, + event: MOCK_EVENT, applyMultiplier: false, context: { getInputValueAsString: defaultGetInputValueAsString, @@ -253,6 +268,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.increment, + event: MOCK_EVENT, applyMultiplier: true, context: { getInputValueAsString: defaultGetInputValueAsString, @@ -277,6 +293,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.decrement, + event: MOCK_EVENT, applyMultiplier: false, context: { getInputValueAsString: defaultGetInputValueAsString, @@ -298,6 +315,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.decrement, + event: MOCK_EVENT, applyMultiplier: false, context: { getInputValueAsString: defaultGetInputValueAsString, @@ -320,6 +338,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.decrement, + event: MOCK_EVENT, applyMultiplier: true, context: { getInputValueAsString: defaultGetInputValueAsString, @@ -344,6 +363,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.incrementToMax, + event: MOCK_EVENT, context: { getInputValueAsString: defaultGetInputValueAsString, max: 99, @@ -365,6 +385,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.incrementToMax, + event: MOCK_EVENT, context: { getInputValueAsString: defaultGetInputValueAsString, shiftMultiplier: 10, @@ -386,6 +407,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.decrementToMin, + event: MOCK_EVENT, context: { getInputValueAsString: defaultGetInputValueAsString, min: 1, @@ -407,6 +429,7 @@ describe('numberInputReducer', () => { const action: NumberInputReducerAction = { type: NumberInputActionTypes.decrementToMin, + event: MOCK_EVENT, context: { getInputValueAsString: defaultGetInputValueAsString, shiftMultiplier: 10, diff --git a/packages/mui-base/src/unstable_useNumberInput/numberInputReducer.ts b/packages/mui-base/src/unstable_useNumberInput/numberInputReducer.ts index 0ccb4c8748c73a..9cfcd9a65678ea 100644 --- a/packages/mui-base/src/unstable_useNumberInput/numberInputReducer.ts +++ b/packages/mui-base/src/unstable_useNumberInput/numberInputReducer.ts @@ -7,13 +7,12 @@ import { import { NumberInputActionTypes } from './numberInputAction.types'; import { clampStepwise, isNumber } from './utils'; -// extracted from handleValueChange -function getClampedValues(rawValue: number | undefined, context: NumberInputActionContext) { +function getClampedValues(rawValue: number | null, context: NumberInputActionContext) { const { min, max, step } = context; - const clampedValue = rawValue === undefined ? '' : clampStepwise(rawValue, min, max, step); + const clampedValue = rawValue === null ? null : clampStepwise(rawValue, min, max, step); - const newInputValue = clampedValue === undefined ? '' : String(clampedValue); + const newInputValue = clampedValue === null ? '' : String(clampedValue); return { value: clampedValue, @@ -38,8 +37,8 @@ function stepValue( } return { - up: min ?? 0, - down: max ?? 0, + up: min ?? 1, + down: max ?? -1, }[direction]; } @@ -54,7 +53,7 @@ function handleClamp( const intermediateValue = numberValueAsString === '' || numberValueAsString === '-' - ? undefined + ? null : parseInt(numberValueAsString, 10); const clampedValues = getClampedValues(intermediateValue, context); @@ -74,19 +73,14 @@ function handleInputChange( const numberValueAsString = getInputValueAsString(inputValue); - if (numberValueAsString === '' || numberValueAsString === '-') { + if ( + numberValueAsString.match(/^-?\d+?$/) || + numberValueAsString === '' || + numberValueAsString === '-' + ) { return { ...state, inputValue: numberValueAsString, - value: '', - }; - } - - if (numberValueAsString.match(/^-?\d+?$/)) { - return { - ...state, - inputValue: numberValueAsString, - value: parseInt(numberValueAsString, 10), }; } @@ -150,6 +144,11 @@ export function numberInputReducer( return handleToMinOrMax(state, context, 'max'); case NumberInputActionTypes.decrementToMin: return handleToMinOrMax(state, context, 'min'); + case NumberInputActionTypes.resetInputValue: + return { + ...state, + inputValue: String(state.value), + }; default: return state; } diff --git a/packages/mui-base/src/unstable_useNumberInput/useNumberInput.test.tsx b/packages/mui-base/src/unstable_useNumberInput/useNumberInput.test.tsx index 3163a2878f98ba..67eb51f76b46bc 100644 --- a/packages/mui-base/src/unstable_useNumberInput/useNumberInput.test.tsx +++ b/packages/mui-base/src/unstable_useNumberInput/useNumberInput.test.tsx @@ -114,14 +114,14 @@ describe('useNumberInput', () => { }); describe('prop: onChange', () => { - it('should call onChange when the input is blurred', async () => { + it('should call onChange when the input is blurred and the value has changed', async () => { const handleChange = spy(); - function NumberInput() { - const { getInputProps } = useNumberInput({ onChange: handleChange }); + function NumberInput(props: { defaultValue: number }) { + const { getInputProps } = useNumberInput({ ...props, onChange: handleChange }); return ; } - render(); + render(); const input = screen.getByTestId('test-input'); @@ -135,6 +135,30 @@ describe('useNumberInput', () => { expect(document.activeElement).to.equal(document.body); expect(handleChange.callCount).to.equal(1); + expect(handleChange.args[0][1]).to.equal(34); + }); + + it('should not call onChange when the input is blurred if the value did not change', async () => { + const handleChange = spy(); + function NumberInput(props: { defaultValue: number }) { + const { getInputProps } = useNumberInput({ ...props, onChange: handleChange }); + + return ; + } + + render(); + + const input = screen.getByTestId('test-input') as HTMLInputElement; + + await userEvent.click(input); + await userEvent.keyboard('1'); + expect(input.value).to.equal('101'); + + await userEvent.keyboard('[Backspace]'); + expect(input.value).to.equal('10'); + + await userEvent.keyboard('[Tab]'); + expect(handleChange.callCount).to.equal(0); }); it('should call onChange with a value within max', async () => { @@ -210,11 +234,12 @@ describe('useNumberInput', () => { expect(handleChange.args[0][1]).to.equal(5); }); - it('should call onChange with undefined when the value is cleared', async () => { + it('should call onChange with null when the value is cleared', async () => { const handleChange = spy(); function NumberInput() { const { getInputProps } = useNumberInput({ onChange: handleChange, + defaultValue: 9, }); return ; @@ -224,11 +249,6 @@ describe('useNumberInput', () => { const input = screen.getByTestId('test-input') as HTMLInputElement; await userEvent.click(input); - - await userEvent.keyboard('9'); - - expect(input.value).to.equal('9'); - await userEvent.keyboard('[Backspace]'); expect(input.value).to.equal(''); @@ -237,14 +257,15 @@ describe('useNumberInput', () => { expect(document.activeElement).to.equal(document.body); expect(handleChange.callCount).to.equal(1); - expect(handleChange.args[0][1]).to.equal(undefined); + expect(handleChange.args[0][1]).to.equal(null); }); - it('should call onChange with undefined when input value is -', async () => { + it('should call onChange with null when input value is -', async () => { const handleChange = spy(); function NumberInput() { const { getInputProps } = useNumberInput({ onChange: handleChange, + defaultValue: -5, }); return ; @@ -254,11 +275,6 @@ describe('useNumberInput', () => { const input = screen.getByTestId('test-input') as HTMLInputElement; await userEvent.click(input); - - await userEvent.keyboard('-5'); - - expect(input.value).to.equal('-5'); - await userEvent.keyboard('[Backspace]'); expect(input.value).to.equal('-'); @@ -267,7 +283,7 @@ describe('useNumberInput', () => { expect(document.activeElement).to.equal(document.body); expect(handleChange.callCount).to.equal(1); - expect(handleChange.args[0][1]).to.equal(undefined); + expect(handleChange.args[0][1]).to.equal(null); }); }); @@ -278,6 +294,7 @@ describe('useNumberInput', () => { const { getInputProps } = useNumberInput({ onChange: handleChange, value, + componentName: 'TestNumberInput', }); return ; @@ -286,7 +303,7 @@ describe('useNumberInput', () => { expect(() => { setProps({ value: 5 }); }).to.toErrorDev( - 'MUI: A component is changing the uncontrolled value state of NumberInput to be controlled', + 'useControllableReducer: The TestNumberInput component is changing an uncontrolled prop to be controlled: value', ); }); @@ -296,6 +313,7 @@ describe('useNumberInput', () => { const { getInputProps } = useNumberInput({ onChange: handleChange, value, + componentName: 'TestNumberInput', }); return ; @@ -304,7 +322,7 @@ describe('useNumberInput', () => { expect(() => { setProps({ value: undefined }); }).to.toErrorDev( - 'MUI: A component is changing the controlled value state of NumberInput to be uncontrolled', + 'useControllableReducer: The TestNumberInput component is changing a controlled prop to be uncontrolled: value', ); }); }); diff --git a/packages/mui-base/src/unstable_useNumberInput/useNumberInput.ts b/packages/mui-base/src/unstable_useNumberInput/useNumberInput.ts index e5ee54ca792c53..2b74b67fdf7a7d 100644 --- a/packages/mui-base/src/unstable_useNumberInput/useNumberInput.ts +++ b/packages/mui-base/src/unstable_useNumberInput/useNumberInput.ts @@ -1,13 +1,11 @@ 'use client'; import * as React from 'react'; import MuiError from '@mui-internal/babel-macros/MuiError.macro'; -import { - unstable_useForkRef as useForkRef, - unstable_useId as useId, - unstable_useControlled as useControlled, -} from '@mui/utils'; +import { unstable_useForkRef as useForkRef, unstable_useId as useId } from '@mui/utils'; import { extractEventHandlers } from '../utils/extractEventHandlers'; import { MuiCancellableEvent } from '../utils/MuiCancellableEvent'; +import { useControllableReducer } from '../utils/useControllableReducer'; +import { StateChangeCallback } from '../utils/useControllableReducer.types'; import { EventHandlers } from '../utils/types'; import { FormControlState, useFormControlContext } from '../FormControl'; import { @@ -18,8 +16,13 @@ import { UseNumberInputDecrementButtonSlotProps, UseNumberInputReturnValue, StepDirection, + NumberInputState, + NumberInputActionContext, + NumberInputReducerAction, } from './useNumberInput.types'; -import { clampStepwise, isNumber } from './utils'; +import { NumberInputActionTypes, NumberInputAction } from './numberInputAction.types'; +import { numberInputReducer } from './numberInputReducer'; +import { isNumber } from './utils'; const STEP_KEYS = ['ArrowUp', 'ArrowDown', 'PageUp', 'PageDown']; @@ -57,6 +60,7 @@ export function useNumberInput(parameters: UseNumberInputParameters): UseNumberI value: valueProp, inputRef: inputRefProp, inputId: inputIdProp, + componentName = 'useNumberInput', } = parameters; // TODO: make it work with FormControl @@ -85,18 +89,67 @@ export function useNumberInput(parameters: UseNumberInputParameters): UseNumberI const [focused, setFocused] = React.useState(false); - // the "final" value - const [value, setValue] = useControlled({ - controlled: valueProp, - default: defaultValueProp, - name: 'NumberInput', - }); + const handleStateChange: StateChangeCallback = React.useCallback( + (event, field, fieldValue, reason) => { + if (field === 'value' && typeof fieldValue !== 'string') { + switch (reason) { + // only a blur event will dispatch `numberInput:clamp` + case 'numberInput:clamp': + onChange?.(event as React.FocusEvent, fieldValue); + break; + case 'numberInput:increment': + case 'numberInput:decrement': + case 'numberInput:incrementToMax': + case 'numberInput:decrementToMin': + onChange?.(event as React.PointerEvent | React.KeyboardEvent, fieldValue); + break; + default: + break; + } + } + }, + [onChange], + ); + + const numberInputActionContext: NumberInputActionContext = React.useMemo(() => { + return { + min, + max, + step, + shiftMultiplier, + getInputValueAsString, + }; + }, [min, max, step, shiftMultiplier]); + + const initialValue = valueProp ?? defaultValueProp ?? null; + + const initialState = { + value: initialValue, + inputValue: initialValue ? String(initialValue) : '', + }; - // the (potentially) dirty or invalid input value - const [dirtyValue, setDirtyValue] = React.useState( - value ? String(value) : undefined, + const controlledState = React.useMemo( + () => ({ + value: valueProp, + }), + [valueProp], ); + const [state, dispatch] = useControllableReducer< + NumberInputState, + NumberInputAction, + NumberInputActionContext + >({ + reducer: numberInputReducer as React.Reducer, + controlledProps: controlledState, + initialState, + onStateChange: handleStateChange, + actionContext: React.useMemo(() => numberInputActionContext, [numberInputActionContext]), + componentName, + }); + + const { value, inputValue } = state; + React.useEffect(() => { if (!formControlContext && disabledProp && focused) { setFocused(false); @@ -105,6 +158,14 @@ export function useNumberInput(parameters: UseNumberInputParameters): UseNumberI } }, [formControlContext, disabledProp, focused, onBlur]); + React.useEffect(() => { + if (isControlled && isNumber(value)) { + dispatch({ + type: NumberInputActionTypes.resetInputValue, + }); + } + }, [value, dispatch, isControlled]); + const createHandleFocus = (otherHandlers: Partial) => (event: React.FocusEvent & MuiCancellableEvent) => { @@ -120,31 +181,6 @@ export function useNumberInput(parameters: UseNumberInputParameters): UseNumberI setFocused(true); }; - const handleValueChange = - () => - ( - event: React.FocusEvent | React.PointerEvent | React.KeyboardEvent, - val: number | undefined, - ) => { - let newValue; - - if (val === undefined) { - newValue = val; - setDirtyValue(''); - } else { - newValue = clampStepwise(val, min, max, step); - setDirtyValue(String(newValue)); - } - - setValue(newValue); - - if (isNumber(newValue)) { - onChange?.(event, newValue); - } else { - onChange?.(event, undefined); - } - }; - const createHandleInputChange = (otherHandlers: Partial) => (event: React.ChangeEvent & MuiCancellableEvent) => { @@ -164,41 +200,29 @@ export function useNumberInput(parameters: UseNumberInputParameters): UseNumberI return; } - // TODO: event.currentTarget.value will be passed straight into the InputChange action - const val = getInputValueAsString(event.currentTarget.value); - - if (val === '' || val === '-') { - setDirtyValue(val); - setValue(undefined); - } - - if (val.match(/^-?\d+?$/)) { - setDirtyValue(val); - setValue(parseInt(val, 10)); - } + dispatch({ + type: NumberInputActionTypes.inputChange, + event, + inputValue: event.currentTarget.value, + }); }; const createHandleBlur = (otherHandlers: Partial) => (event: React.FocusEvent & MuiCancellableEvent) => { + formControlContext?.onBlur(); + otherHandlers.onBlur?.(event); if (event.defaultMuiPrevented || event.defaultPrevented) { return; } - // TODO: event.currentTarget.value will be passed straight into the Blur action, or just pass inputValue from state - const val = getInputValueAsString(event.currentTarget.value); - - if (val === '' || val === '-') { - handleValueChange()(event, undefined); - } else { - handleValueChange()(event, parseInt(val, 10)); - } - - if (formControlContext && formControlContext.onBlur) { - formControlContext.onBlur(); - } + dispatch({ + type: NumberInputActionTypes.clamp, + event, + inputValue: event.currentTarget.value, + }); setFocused(false); }; @@ -219,27 +243,18 @@ export function useNumberInput(parameters: UseNumberInputParameters): UseNumberI const handleStep = (direction: StepDirection) => (event: React.PointerEvent | React.KeyboardEvent) => { - let newValue; - - if (isNumber(value)) { - const multiplier = - event.shiftKey || - (event as React.KeyboardEvent).key === 'PageUp' || - (event as React.KeyboardEvent).key === 'PageDown' - ? shiftMultiplier - : 1; - newValue = { - up: value + (step ?? 1) * multiplier, - down: value - (step ?? 1) * multiplier, - }[direction]; - } else { - // no value - newValue = { - up: min ?? 0, - down: max ?? 0, - }[direction]; - } - handleValueChange()(event, newValue); + const applyMultiplier = Boolean(event.shiftKey); + + const actionType = { + up: NumberInputActionTypes.increment, + down: NumberInputActionTypes.decrement, + }[direction]; + + dispatch({ + type: actionType, + event, + applyMultiplier, + }); }; const createHandleKeyDown = @@ -251,31 +266,54 @@ export function useNumberInput(parameters: UseNumberInputParameters): UseNumberI return; } - if (event.defaultPrevented) { - return; - } - + // this prevents unintended page scrolling if (SUPPORTED_KEYS.includes(event.key)) { event.preventDefault(); } - if (STEP_KEYS.includes(event.key)) { - const direction = { - ArrowUp: 'up', - ArrowDown: 'down', - PageUp: 'up', - PageDown: 'down', - }[event.key] as StepDirection; - - handleStep(direction)(event); - } - - if (event.key === 'Home' && isNumber(max)) { - handleValueChange()(event, max); - } - - if (event.key === 'End' && isNumber(min)) { - handleValueChange()(event, min); + switch (event.key) { + case 'ArrowUp': + dispatch({ + type: NumberInputActionTypes.increment, + event, + applyMultiplier: !!event.shiftKey, + }); + break; + case 'ArrowDown': + dispatch({ + type: NumberInputActionTypes.decrement, + event, + applyMultiplier: !!event.shiftKey, + }); + break; + case 'PageUp': + dispatch({ + type: NumberInputActionTypes.increment, + event, + applyMultiplier: true, + }); + break; + case 'PageDown': + dispatch({ + type: NumberInputActionTypes.decrement, + event, + applyMultiplier: true, + }); + break; + case 'Home': + dispatch({ + type: NumberInputActionTypes.incrementToMax, + event, + }); + break; + case 'End': + dispatch({ + type: NumberInputActionTypes.decrementToMin, + event, + }); + break; + default: + break; } }; @@ -333,7 +371,7 @@ export function useNumberInput(parameters: UseNumberInputParameters): UseNumberI onKeyDown: createHandleKeyDown(externalEventHandlers), }; - const displayValue = (focused ? dirtyValue : value) ?? ''; + const displayValue = (focused ? inputValue : value) ?? ''; // get rid of slotProps.input.onInputChange before returning to prevent it from entering the DOM // if it was passed, it will be in mergedEventHandlers and throw @@ -417,9 +455,9 @@ export function useNumberInput(parameters: UseNumberInputParameters): UseNumberI getDecrementButtonProps, getRootProps, required: requiredProp, - value: focused ? dirtyValue : value, + value, + inputValue, isIncrementDisabled, isDecrementDisabled, - inputValue: dirtyValue, }; } diff --git a/packages/mui-base/src/unstable_useNumberInput/useNumberInput.types.ts b/packages/mui-base/src/unstable_useNumberInput/useNumberInput.types.ts index 9108f6be45a913..791a163b437b62 100644 --- a/packages/mui-base/src/unstable_useNumberInput/useNumberInput.types.ts +++ b/packages/mui-base/src/unstable_useNumberInput/useNumberInput.types.ts @@ -13,11 +13,11 @@ export interface NumberInputState { /** * The clamped `value` of the `input` element. */ - value?: number | ''; + value: number | null; /** * The dirty `value` of the `input` element when it is in focus. */ - inputValue?: string; + inputValue: string; } /** @@ -34,9 +34,9 @@ export type NumberInputActionContext = { getInputValueAsString: (val: string) => string; }; -export type NumberInputReducerAction = ActionWithContext< +export type NumberInputReducerAction = ActionWithContext< NumberInputAction, - NumberInputActionContext & CustomActionContext + NumberInputActionContext >; export interface UseNumberInputParameters { @@ -60,7 +60,7 @@ export interface UseNumberInputParameters { /** * The default value. Use when the component is not controlled. */ - defaultValue?: unknown; + defaultValue?: number | null; /** * If `true`, the component is disabled. * The prop defaults to the value (`false`) inherited from the parent FormControl component. @@ -92,7 +92,7 @@ export interface UseNumberInputParameters { */ onChange?: ( event: React.FocusEvent | React.PointerEvent | React.KeyboardEvent, - value: number | undefined, + value: number | null, ) => void; /** * The `id` attribute of the input element. @@ -115,8 +115,15 @@ export interface UseNumberInputParameters { readOnly?: boolean; /** * The current value. Use when the component is controlled. + * @default null */ - value?: number; + value?: number | null; + /** + * The name of the component using useNumberInput. + * For debugging purposes. + * @default 'useNumberInput' + */ + componentName?: string; } export interface UseNumberInputRootSlotOwnProps { @@ -240,11 +247,11 @@ export interface UseNumberInputReturnValue { /** * The clamped `value` of the `input` element. */ - value: unknown; + value: number | null; /** * The dirty `value` of the `input` element when it is in focus. */ - inputValue: string | undefined; + inputValue: string; /** * If `true`, the increment button will be disabled. * e.g. when the `value` is already at `max` From 0f6b58e2557a8c8b4c8c33dbb9acd0f635bffcd3 Mon Sep 17 00:00:00 2001 From: Albert Yu Date: Mon, 5 Feb 2024 17:14:54 +0800 Subject: [PATCH 045/120] [base-ui][Button] Add support for `hostElementName` prop to improve SSR (#40507) --- docs/pages/base-ui/api/button.json | 1 + docs/pages/base-ui/api/use-button.json | 7 + .../base/use-host-element-name.tsx | 184 ++++++++++++++++++ .../api-docs-base/button/button.json | 3 + .../api-docs/use-button/use-button.json | 1 + packages/mui-base/src/Button/Button.test.tsx | 72 ++++++- packages/mui-base/src/Button/Button.tsx | 15 ++ packages/mui-base/src/Button/Button.types.ts | 5 + packages/mui-base/src/useButton/useButton.ts | 31 +-- .../mui-base/src/useButton/useButton.types.ts | 5 + packages/mui-base/src/utils/index.ts | 1 + .../mui-base/src/utils/useRootElementName.ts | 50 +++++ .../src/ListItemButton/ListItemButton.test.js | 18 +- .../src/describeConformanceUnstyled.tsx | 45 ++++- 14 files changed, 405 insertions(+), 33 deletions(-) create mode 100644 docs/pages/experiments/base/use-host-element-name.tsx create mode 100644 packages/mui-base/src/utils/useRootElementName.ts diff --git a/docs/pages/base-ui/api/button.json b/docs/pages/base-ui/api/button.json index 5213e6099f947e..14e232edc8dce9 100644 --- a/docs/pages/base-ui/api/button.json +++ b/docs/pages/base-ui/api/button.json @@ -8,6 +8,7 @@ }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "focusableWhenDisabled": { "type": { "name": "bool" }, "default": "false" }, + "rootElementName": { "type": { "name": "string" }, "default": "'button'" }, "slotProps": { "type": { "name": "shape", "description": "{ root?: func
| object }" }, "default": "{}" diff --git a/docs/pages/base-ui/api/use-button.json b/docs/pages/base-ui/api/use-button.json index 9831db2972165b..e646d88bb3b0ca 100644 --- a/docs/pages/base-ui/api/use-button.json +++ b/docs/pages/base-ui/api/use-button.json @@ -9,6 +9,13 @@ "onFocusVisible": { "type": { "name": "React.FocusEventHandler", "description": "React.FocusEventHandler" } }, + "rootElementName": { + "type": { + "name": "keyof HTMLElementTagNameMap", + "description": "keyof HTMLElementTagNameMap" + }, + "default": "''" + }, "rootRef": { "type": { "name": "React.Ref<Element>", "description": "React.Ref<Element>" } }, diff --git a/docs/pages/experiments/base/use-host-element-name.tsx b/docs/pages/experiments/base/use-host-element-name.tsx new file mode 100644 index 00000000000000..f2d3f43a9cba04 --- /dev/null +++ b/docs/pages/experiments/base/use-host-element-name.tsx @@ -0,0 +1,184 @@ +import * as React from 'react'; +import { Button as BaseButton, buttonClasses } from '@mui/base/Button'; +import { prepareForSlot } from '@mui/base/utils'; +import { styled, Theme } from '@mui/system'; +import { Stack } from '@mui/material'; +import Link from 'next/link'; + +const LinkSlot = prepareForSlot(Link); + +const blue = { + 200: '#99CCFF', + 300: '#66B2FF', + 400: '#3399FF', + 500: '#007FFF', + 600: '#0072E5', + 700: '#0066CC', +}; + +const grey = { + 50: '#F3F6F9', + 100: '#E5EAF2', + 200: '#DAE2ED', + 300: '#C7D0DD', + 400: '#B0B8C4', + 500: '#9DA8B7', + 600: '#6B7A90', + 700: '#434D5B', + 800: '#303740', + 900: '#1C2025', +}; + +// copy-pasta from base button intro demo +const STYLES = ({ theme }: { theme: Theme }) => ` + font-family: 'IBM Plex Sans', sans-serif; + font-weight: 600; + font-size: 0.875rem; + line-height: 1.5; + text-decoration: none; + background-color: ${blue[500]}; + padding: 8px 16px; + border-radius: 8px; + color: white; + transition: all 150ms ease; + cursor: pointer; + border: 1px solid ${blue[500]}; + box-shadow: 0 2px 1px ${ + theme.palette.mode === 'dark' ? 'rgba(0, 0, 0, 0.5)' : 'rgba(45, 45, 60, 0.2)' + }, inset 0 1.5px 1px ${blue[400]}, inset 0 -2px 1px ${blue[600]}; + + &:hover { + background-color: ${blue[600]}; + } + + &.${buttonClasses.active} { + background-color: ${blue[700]}; + box-shadow: none; + transform: scale(0.99); + } + + &.${buttonClasses.focusVisible} { + box-shadow: 0 0 0 4px ${theme.palette.mode === 'dark' ? blue[300] : blue[200]}; + outline: none; + } + + &.${buttonClasses.disabled} { + background-color: ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + color: ${theme.palette.mode === 'dark' ? grey[200] : grey[700]}; + border: 0; + cursor: default; + box-shadow: none; + transform: scale(1); + } + `; + +const StyledHtmlInput = styled('input')(STYLES); + +const StyledHtmlButton = styled('button')(STYLES); + +const StyledBaseButton = styled(BaseButton)(STYLES); + +const StyledHtmlAnchor = styled('a')(STYLES); + +export default function ServerRenderedButtons() { + return ( + + +
Normal cases:
+
+          1A: defaults
+          
+ 1B: `slots.root` is a `span`, rootElementName is inferred +
+ 1C & 1D: `slots.root` is a styled component, rootElementName is manually passed +
+ + Button 1A + + + Button 1B + + + + Button 1C + + + + + +
+          Cases where the runtime warning is triggered:
+        
+
+          2A: rendering default element, rootElementName is given an incorrect value of `span`
+          
+ 2B: rendering a styled component that returns the default `button` element, + rootElementName is given an incorrect value of `span` +
+ 2C: rendering a styled component that returns the non-default `input` element, + rootElementName is not passed +
+ + + Button 2A + + + + Button 2B + + + + + +
Links:
+
+          3A, 3B, 3C: As long as `href` or `to` are passed, and all involved components only render
+          `a` tags, rootElementName will be inferred automatically
+          
+ 3D: `slots.root` is a styled `input`, but an `a` is expected because `href` is passed so + the warning is triggered +
+ 3E: Achieves the same as 3D but circumvents the warning, even though this results in + invalid HTML +
+ + + Link-3A + + + Link-3B (Next.js Link) + + + Link-3C + + + + +
+
+ ); +} diff --git a/docs/translations/api-docs-base/button/button.json b/docs/translations/api-docs-base/button/button.json index d5ea5736ad2535..44c7999074fe5d 100644 --- a/docs/translations/api-docs-base/button/button.json +++ b/docs/translations/api-docs-base/button/button.json @@ -8,6 +8,9 @@ "focusableWhenDisabled": { "description": "If true, allows a disabled button to receive focus." }, + "rootElementName": { + "description": "The HTML element that is ultimately rendered, for example 'button' or 'a'" + }, "slotProps": { "description": "The props used for each slot inside the Button." }, "slots": { "description": "The components used for each slot inside the Button. Either a string to use a HTML element or a component." diff --git a/docs/translations/api-docs/use-button/use-button.json b/docs/translations/api-docs/use-button/use-button.json index cf09cdf24fa704..8efee361561fb8 100644 --- a/docs/translations/api-docs/use-button/use-button.json +++ b/docs/translations/api-docs/use-button/use-button.json @@ -5,6 +5,7 @@ "focusableWhenDisabled": { "description": "If true, allows a disabled button to receive focus." }, + "rootElementName": { "description": "The HTML element, e.g.'button', 'a' etc" }, "type": { "description": "Type attribute applied when the component is button." } diff --git a/packages/mui-base/src/Button/Button.test.tsx b/packages/mui-base/src/Button/Button.test.tsx index e2c0209dbdd7ec..05bc8ff14936c2 100644 --- a/packages/mui-base/src/Button/Button.test.tsx +++ b/packages/mui-base/src/Button/Button.test.tsx @@ -12,7 +12,7 @@ import { Button, buttonClasses } from '@mui/base/Button'; describe(', + ); + }).toErrorDev( + "useRootElementName: the `rootElementName` prop of the Button component expected the 'span' element, but a 'button' was rendered instead", + ); + }); + + describe('server-side rendering', () => { + before(function beforeHook() { + // Only run the test on node. + if (!/jsdom/.test(window.navigator.userAgent)) { + this.skip(); + } + }); + + it('renders the default element', () => { + const { container } = renderToString(); + + expect((container.firstChild as HTMLElement).tagName).to.equal('BUTTON'); + expect(container.firstChild).to.have.attribute('disabled'); + expect(container.firstChild).to.not.have.attribute('aria-disabled'); + }); + + it('infers rootElementName if `slots.root` is a string', () => { + const { container } = renderToString( + , + ); + + expect((container.firstChild as HTMLElement).tagName).to.equal('SPAN'); + expect(container.firstChild).to.not.have.attribute('disabled'); + expect(container.firstChild).to.have.attribute('aria-disabled'); + }); + + it('renders when slots.root is a wrapped component', () => { + const CustomComponent = React.forwardRef( + ({ ownerState, ...props }: any, ref: React.Ref) => ( + + ), + ); + + const { container } = renderToString( + , + ); + + expect((container.firstChild as HTMLElement).tagName).to.equal('SPAN'); + expect(container.firstChild).to.not.have.attribute('disabled'); + expect(container.firstChild).to.have.attribute('aria-disabled'); + }); }); }); }); diff --git a/packages/mui-base/src/Button/Button.tsx b/packages/mui-base/src/Button/Button.tsx index 8b3cdb1f779ef8..816c3e9c4f1c71 100644 --- a/packages/mui-base/src/Button/Button.tsx +++ b/packages/mui-base/src/Button/Button.tsx @@ -42,14 +42,24 @@ const Button = React.forwardRef(function Button(); + let rootElementName = rootElementNameProp; + + if (typeof slots.root === 'string') { + rootElementName = slots.root as keyof HTMLElementTagNameMap; + } else if (other.href || other.to) { + rootElementName = 'a'; + } + const { active, focusVisible, setFocusVisible, getRootProps } = useButton({ ...props, focusableWhenDisabled, + rootElementName, }); React.useImperativeHandle( @@ -131,6 +141,11 @@ Button.propTypes /* remove-proptypes */ = { * @ignore */ onFocusVisible: PropTypes.func, + /** + * The HTML element that is ultimately rendered, for example 'button' or 'a' + * @default 'button' + */ + rootElementName: PropTypes /* @typescript-to-proptypes-ignore */.string, /** * The props used for each slot inside the Button. * @default {} diff --git a/packages/mui-base/src/Button/Button.types.ts b/packages/mui-base/src/Button/Button.types.ts index 1180d7380acdbb..29f3aaee0e5d7a 100644 --- a/packages/mui-base/src/Button/Button.types.ts +++ b/packages/mui-base/src/Button/Button.types.ts @@ -30,6 +30,11 @@ export interface ButtonOwnProps extends Omit { * @default {} */ slots?: ButtonSlots; + /** + * The HTML element that is ultimately rendered, for example 'button' or 'a' + * @default 'button' + */ + rootElementName?: keyof HTMLElementTagNameMap; } export interface ButtonSlots { diff --git a/packages/mui-base/src/useButton/useButton.ts b/packages/mui-base/src/useButton/useButton.ts index 626f60815a083a..0c6b5da72973aa 100644 --- a/packages/mui-base/src/useButton/useButton.ts +++ b/packages/mui-base/src/useButton/useButton.ts @@ -10,6 +10,7 @@ import { UseButtonRootSlotProps, } from './useButton.types'; import { extractEventHandlers } from '../utils/extractEventHandlers'; +import { useRootElementName } from '../utils/useRootElementName'; import { EventHandlers } from '../utils/types'; import { MuiCancellableEvent } from '../utils/MuiCancellableEvent'; /** @@ -31,6 +32,7 @@ export function useButton(parameters: UseButtonParameters = {}): UseButtonReturn tabIndex, to, type, + rootElementName: rootElementNameProp, } = parameters; const buttonRef = React.useRef(); @@ -52,7 +54,10 @@ export function useButton(parameters: UseButtonParameters = {}): UseButtonReturn isFocusVisibleRef.current = focusVisible; }, [focusVisible, isFocusVisibleRef]); - const [hostElementName, setHostElementName] = React.useState(''); + const [rootElementName, updateRootElementName] = useRootElementName({ + rootElementName: rootElementNameProp ?? (href || to ? 'a' : undefined), + componentName: 'Button', + }); const createHandleMouseLeave = (otherHandlers: EventHandlers) => (event: React.MouseEvent) => { if (focusVisible) { @@ -92,10 +97,10 @@ export function useButton(parameters: UseButtonParameters = {}): UseButtonReturn const button = buttonRef.current; return ( - hostElementName === 'BUTTON' || - (hostElementName === 'INPUT' && + rootElementName === 'BUTTON' || + (rootElementName === 'INPUT' && ['button', 'submit', 'reset'].includes((button as HTMLInputElement)?.type)) || - (hostElementName === 'A' && (button as HTMLAnchorElement)?.href) + (rootElementName === 'A' && (button as HTMLAnchorElement)?.href) ); }; @@ -171,11 +176,7 @@ export function useButton(parameters: UseButtonParameters = {}): UseButtonReturn } }; - const updateHostElementName = React.useCallback((instance: HTMLElement | null) => { - setHostElementName(instance?.tagName ?? ''); - }, []); - - const handleRef = useForkRef(updateHostElementName, externalRef, focusVisibleRef, buttonRef); + const handleRef = useForkRef(updateRootElementName, externalRef, focusVisibleRef, buttonRef); interface AdditionalButtonProps { type?: React.ButtonHTMLAttributes['type']; @@ -191,14 +192,22 @@ export function useButton(parameters: UseButtonParameters = {}): UseButtonReturn buttonProps.tabIndex = tabIndex; } - if (hostElementName === 'BUTTON') { + if (rootElementName === 'BUTTON') { buttonProps.type = type ?? 'button'; if (focusableWhenDisabled) { buttonProps['aria-disabled'] = disabled; } else { buttonProps.disabled = disabled; } - } else if (hostElementName !== '') { + } else if (rootElementName === 'INPUT') { + if (type && ['button', 'submit', 'reset'].includes(type)) { + if (focusableWhenDisabled) { + buttonProps['aria-disabled'] = disabled; + } else { + buttonProps.disabled = disabled; + } + } + } else if (rootElementName !== '') { if (!href && !to) { buttonProps.role = 'button'; buttonProps.tabIndex = tabIndex ?? 0; diff --git a/packages/mui-base/src/useButton/useButton.types.ts b/packages/mui-base/src/useButton/useButton.types.ts index 3fd9a91df6e74c..0eeaf07bb888c1 100644 --- a/packages/mui-base/src/useButton/useButton.types.ts +++ b/packages/mui-base/src/useButton/useButton.types.ts @@ -22,6 +22,11 @@ export interface UseButtonParameters { * @default 'button' */ type?: React.ButtonHTMLAttributes['type']; + /** + * The HTML element, e.g.'button', 'a' etc + * @default '' + */ + rootElementName?: keyof HTMLElementTagNameMap; } export interface UseButtonRootSlotOwnProps { diff --git a/packages/mui-base/src/utils/index.ts b/packages/mui-base/src/utils/index.ts index 574814884c595b..6940094b6697bc 100644 --- a/packages/mui-base/src/utils/index.ts +++ b/packages/mui-base/src/utils/index.ts @@ -5,6 +5,7 @@ export { ClassNameConfigurator } from './ClassNameConfigurator'; export { extractEventHandlers } from './extractEventHandlers'; export { isHostComponent } from './isHostComponent'; export { resolveComponentProps } from './resolveComponentProps'; +export { useRootElementName } from './useRootElementName'; export { useSlotProps } from './useSlotProps'; export { mergeSlotProps } from './mergeSlotProps'; export { prepareForSlot } from './prepareForSlot'; diff --git a/packages/mui-base/src/utils/useRootElementName.ts b/packages/mui-base/src/utils/useRootElementName.ts new file mode 100644 index 00000000000000..71358471fdc70f --- /dev/null +++ b/packages/mui-base/src/utils/useRootElementName.ts @@ -0,0 +1,50 @@ +'use client'; +import * as React from 'react'; + +type UseRootElementNameParameters = { + /** + * The HTML element expected to be rendered, e.g. 'div', 'button' etc + * @default '' + */ + rootElementName?: keyof HTMLElementTagNameMap; + /** + * The name of the component using useRootElementName. + * For debugging purposes. + */ + componentName?: string; +}; + +/** + * @ignore - do not document. + * + * Use this function determine the host element correctly on the server (in a SSR context, e.g. Next.js) + */ +export function useRootElementName( + parameters: UseRootElementNameParameters, +): [string, (instance: HTMLElement | null) => void] { + const { rootElementName: rootElementNameProp = '', componentName } = parameters; + + const [rootElementName, setRootElementName] = React.useState( + rootElementNameProp.toUpperCase(), + ); + + if (process.env.NODE_ENV !== 'production') { + // eslint-disable-next-line react-hooks/rules-of-hooks + React.useEffect(() => { + if (rootElementNameProp && rootElementName !== rootElementNameProp.toUpperCase()) { + console.error( + `useRootElementName: the \`rootElementName\` prop of ${ + componentName ? `the ${componentName} component` : 'a component' + } expected the '${rootElementNameProp}' element, but a '${rootElementName.toLowerCase()}' was rendered instead`, + 'This may cause hydration issues in an SSR context, e.g. in a Next.js app', + ); + } + }, [rootElementNameProp, rootElementName, componentName]); + } + + const updateRootElementName = React.useCallback((instance: HTMLElement | null) => { + setRootElementName(instance?.tagName ?? ''); + }, []); + + return [rootElementName, updateRootElementName]; +} diff --git a/packages/mui-material-next/src/ListItemButton/ListItemButton.test.js b/packages/mui-material-next/src/ListItemButton/ListItemButton.test.js index a64fbcb88ede3a..c415b57b15261c 100644 --- a/packages/mui-material-next/src/ListItemButton/ListItemButton.test.js +++ b/packages/mui-material-next/src/ListItemButton/ListItemButton.test.js @@ -99,7 +99,9 @@ describe('', () => { expect(!!link).to.equal(true); }); - it('should rendered as specifying component', () => { + // TODO v7: support hostElementName prop + // eslint-disable-next-line mocha/no-skipped-tests + it.skip('should be rendered as the specifed component', () => { const { getByRole } = render(); const heading = getByRole('heading'); @@ -135,7 +137,9 @@ describe('', () => { expect(!!link).to.equal(true); }); - it('should rendered as specifying component', () => { + // TODO v7: support hostElementName prop + // eslint-disable-next-line mocha/no-skipped-tests + it.skip('should be rendered as the specifed component', () => { const { getByRole } = render(); const heading = getByRole('heading'); @@ -152,7 +156,7 @@ describe('', () => { return ; }); - it('should rendered as LinkComponent when href is provided', () => { + it('should render as LinkComponent when href is provided', () => { const { container, getByTestId } = render( , ); @@ -163,7 +167,9 @@ describe('', () => { expect(button).to.have.attribute('href', href); }); - it('should ignore LinkComponent is component is provided', () => { + // TODO v7: support hostElementName prop + // eslint-disable-next-line mocha/no-skipped-tests + it.skip('should ignore LinkComponent if component is provided', () => { const { container, queryByTestId } = render( , ); @@ -174,7 +180,7 @@ describe('', () => { expect(button).to.have.attribute('href', href); }); - it('should rendered as LinkComponent (from theme) when href is provided', () => { + it('should render as LinkComponent (from theme) when href is provided', () => { const theme = createTheme({ components: { MuiListItemButton: { @@ -196,7 +202,7 @@ describe('', () => { expect(button).to.have.attribute('href', href); }); - it('should rendered as LinkComponent (from theme MuiButtonBase) when href is provided', () => { + it('should render as LinkComponent (from theme MuiButtonBase) when href is provided', () => { const theme = createTheme({ components: { MuiButtonBase: { diff --git a/packages/test-utils/src/describeConformanceUnstyled.tsx b/packages/test-utils/src/describeConformanceUnstyled.tsx index 09f6fa5eea9a09..6f0c4dfc71a39d 100644 --- a/packages/test-utils/src/describeConformanceUnstyled.tsx +++ b/packages/test-utils/src/describeConformanceUnstyled.tsx @@ -21,6 +21,7 @@ export interface UnstyledConformanceOptions ) => Promise | MuiRenderResult; skip?: (keyof typeof fullSuite)[]; testComponentPropWith?: string; + rootElementNameMustMatchComponentProp?: boolean; } function throwMissingPropError(field: string): never { @@ -60,7 +61,11 @@ function testPropForwarding( element: React.ReactElement, getOptions: () => UnstyledConformanceOptions, ) { - const { render, testComponentPropWith: Element = 'div' } = getOptions(); + const { + render, + testComponentPropWith: Element = 'div', + rootElementNameMustMatchComponentProp = false, + } = getOptions(); if (!render) { throwMissingPropError('render'); @@ -77,6 +82,7 @@ function testPropForwarding( const otherProps = { lang: 'fr', fooBar: randomStringValue(), + ...(rootElementNameMustMatchComponentProp ? { rootElementName: Element } : {}), }; await render(React.cloneElement(element, { slots: { root: CustomRoot }, ...otherProps })); @@ -91,6 +97,7 @@ function testPropForwarding( lang: 'fr', 'data-foobar': randomStringValue(), 'data-testid': 'custom-root', + ...(rootElementNameMustMatchComponentProp ? { rootElementName: Element } : {}), }; render(React.cloneElement(element, { slots: { root: Element }, ...otherProps })); @@ -102,7 +109,13 @@ function testPropForwarding( } function testSlotsProp(element: React.ReactElement, getOptions: () => UnstyledConformanceOptions) { - const { render, slots, skip, testComponentPropWith: Element = 'div' } = getOptions(); + const { + render, + slots, + skip, + testComponentPropWith: Element = 'div', + rootElementNameMustMatchComponentProp = false, + } = getOptions(); if (!render) { throwMissingPropError('render'); @@ -124,7 +137,12 @@ function testSlotsProp(element: React.ReactElement, getOptions: () => UnstyledCo [slotName]: slotComponent, }; - const { getByTestId } = await render(React.cloneElement(element, { slots: components })); + const { getByTestId } = await render( + React.cloneElement(element, { + slots: components, + ...(rootElementNameMustMatchComponentProp ? { rootElementName: 'i' } : {}), + }), + ); const renderedElement = getByTestId('custom'); expect(renderedElement).to.have.class(slotOptions.expectedClassName); }); @@ -144,7 +162,11 @@ function testSlotsProp(element: React.ReactElement, getOptions: () => UnstyledCo }; const { getByTestId } = await render( - React.cloneElement(element, { slots: components, slotProps }), + React.cloneElement(element, { + slots: components, + slotProps, + ...(rootElementNameMustMatchComponentProp ? { rootElementName: slotElement } : {}), + }), ); const renderedElement = getByTestId('customized'); expect(renderedElement.nodeName.toLowerCase()).to.equal(slotElement); @@ -286,7 +308,12 @@ function testOwnerStatePropagation( element: React.ReactElement, getOptions: () => UnstyledConformanceOptions, ) { - const { render, slots, testComponentPropWith: Element = 'div' } = getOptions(); + const { + render, + slots, + testComponentPropWith: Element = 'div', + rootElementNameMustMatchComponentProp = false, + } = getOptions(); if (!render) { throwMissingPropError('render'); @@ -316,7 +343,13 @@ function testOwnerStatePropagation( id: 'foo', }; - render(React.cloneElement(element, { slots: slotOverrides, id: 'foo' })); + render( + React.cloneElement(element, { + slots: slotOverrides, + id: 'foo', + ...(rootElementNameMustMatchComponentProp ? { rootElementName: Element } : {}), + }), + ); expect(componentOwnerState).not.to.equal(undefined); expect(componentOwnerState).to.deep.include(expectedOwnerState); }); From 0086c0eadf89e5fc9a0b63418f467c1d6f7eb35c Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 5 Feb 2024 10:51:03 +0100 Subject: [PATCH 046/120] [Slider] Add support for Arrow Down/Up + Shift and Page Up/Down keys (#40676) --- .../base/components/slider/DiscreteSlider.js | 1 + .../base/components/slider/DiscreteSlider.tsx | 1 + .../slider/DiscreteSlider.tsx.preview | 1 + docs/data/base/components/slider/slider.md | 1 + docs/data/joy/components/slider/slider.md | 1 + .../components/slider/DiscreteSlider.js | 1 + .../components/slider/DiscreteSlider.tsx | 1 + .../slider/DiscreteSlider.tsx.preview | 1 + .../data/material/components/slider/slider.md | 1 + docs/pages/base-ui/api/slider.json | 1 + docs/pages/base-ui/api/use-slider.json | 1 + docs/pages/joy-ui/api/slider.json | 1 + docs/pages/material-ui/api/slider.json | 1 + .../api-docs-base/slider/slider.json | 3 + .../api-docs-joy/slider/slider.json | 3 + docs/translations/api-docs/slider/slider.json | 3 + .../api-docs/use-slider/use-slider.json | 3 + packages/mui-base/src/Slider/Slider.test.tsx | 173 ++++++++++++++++++ packages/mui-base/src/Slider/Slider.tsx | 7 + packages/mui-base/src/useSlider/useSlider.ts | 140 ++++++++------ .../mui-base/src/useSlider/useSlider.types.ts | 5 + packages/mui-joy/src/Slider/Slider.tsx | 7 + packages/mui-material/src/Slider/Slider.d.ts | 5 + packages/mui-material/src/Slider/Slider.js | 7 + 24 files changed, 316 insertions(+), 53 deletions(-) diff --git a/docs/data/base/components/slider/DiscreteSlider.js b/docs/data/base/components/slider/DiscreteSlider.js index c6975ca1881b77..38c906072dc664 100644 --- a/docs/data/base/components/slider/DiscreteSlider.js +++ b/docs/data/base/components/slider/DiscreteSlider.js @@ -10,6 +10,7 @@ export default function DiscreteSlider() { aria-label="Temperature" defaultValue={30} getAriaValueText={valuetext} + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/base/components/slider/DiscreteSlider.tsx b/docs/data/base/components/slider/DiscreteSlider.tsx index 5f05c2d5d8c594..deb51db7f93215 100644 --- a/docs/data/base/components/slider/DiscreteSlider.tsx +++ b/docs/data/base/components/slider/DiscreteSlider.tsx @@ -9,6 +9,7 @@ export default function DiscreteSlider() { aria-label="Temperature" defaultValue={30} getAriaValueText={valuetext} + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/base/components/slider/DiscreteSlider.tsx.preview b/docs/data/base/components/slider/DiscreteSlider.tsx.preview index ff13be9f25149e..1d0ad0d7b2db7d 100644 --- a/docs/data/base/components/slider/DiscreteSlider.tsx.preview +++ b/docs/data/base/components/slider/DiscreteSlider.tsx.preview @@ -2,6 +2,7 @@ aria-label="Temperature" defaultValue={30} getAriaValueText={valuetext} + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/base/components/slider/slider.md b/docs/data/base/components/slider/slider.md index d81c0076673e0f..daf7b9263aa969 100644 --- a/docs/data/base/components/slider/slider.md +++ b/docs/data/base/components/slider/slider.md @@ -152,6 +152,7 @@ The most basic Slider is _continuous_, which means it does not have pre-defined This is suitable for situations in which an approximate value is good enough for the user, such as brightness or volume. But if your users need more precise options, you can create a discrete Slider that snaps the thumb to pre-defined stops along the bar. +Make sure to adjust the `shiftStep` prop (the granularity with which the slider can step when using Page Up/Down or Shift + Arrow Up/Down) to a value divadable with the `step`. To generate a mark for each stop, use `marks={true}`: diff --git a/docs/data/joy/components/slider/slider.md b/docs/data/joy/components/slider/slider.md index efeeb8cbdbaf87..b667754bda120d 100644 --- a/docs/data/joy/components/slider/slider.md +++ b/docs/data/joy/components/slider/slider.md @@ -33,6 +33,7 @@ export default function MyApp() { ### Steps Change the default step increments by setting a desired value to the `step` prop. +Make sure to adjust the `shiftStep` prop (the granularity with which the slider can step when using Page Up/Down or Shift + Arrow Up/Down) to a value divadable with the `step`. {{"demo": "StepsSlider.js"}} diff --git a/docs/data/material/components/slider/DiscreteSlider.js b/docs/data/material/components/slider/DiscreteSlider.js index d5345cede101b5..004b332ce3df91 100644 --- a/docs/data/material/components/slider/DiscreteSlider.js +++ b/docs/data/material/components/slider/DiscreteSlider.js @@ -14,6 +14,7 @@ export default function DiscreteSlider() { defaultValue={30} getAriaValueText={valuetext} valueLabelDisplay="auto" + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/material/components/slider/DiscreteSlider.tsx b/docs/data/material/components/slider/DiscreteSlider.tsx index 97e60b7427fce4..6e073296b309f4 100644 --- a/docs/data/material/components/slider/DiscreteSlider.tsx +++ b/docs/data/material/components/slider/DiscreteSlider.tsx @@ -14,6 +14,7 @@ export default function DiscreteSlider() { defaultValue={30} getAriaValueText={valuetext} valueLabelDisplay="auto" + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/material/components/slider/DiscreteSlider.tsx.preview b/docs/data/material/components/slider/DiscreteSlider.tsx.preview index 32d2616b1cd9c8..44207ee5458b9e 100644 --- a/docs/data/material/components/slider/DiscreteSlider.tsx.preview +++ b/docs/data/material/components/slider/DiscreteSlider.tsx.preview @@ -3,6 +3,7 @@ defaultValue={30} getAriaValueText={valuetext} valueLabelDisplay="auto" + shiftStep={30} step={10} marks min={10} diff --git a/docs/data/material/components/slider/slider.md b/docs/data/material/components/slider/slider.md index 5b206383b9acd4..5e637904b8ff90 100644 --- a/docs/data/material/components/slider/slider.md +++ b/docs/data/material/components/slider/slider.md @@ -38,6 +38,7 @@ You can generate a mark for each step with `marks={true}`. ### Small steps You can change the default step increment. +Make sure to adjust the `shiftStep` prop (the granularity with which the slider can step when using Page Up/Down or Shift + Arrow Up/Down) to a value divadable with the `step`. {{"demo": "DiscreteSliderSteps.js"}} diff --git a/docs/pages/base-ui/api/slider.json b/docs/pages/base-ui/api/slider.json index 43d9d76a9ddb66..295d18e7bfe9d7 100644 --- a/docs/pages/base-ui/api/slider.json +++ b/docs/pages/base-ui/api/slider.json @@ -53,6 +53,7 @@ "default": "function Identity(x) {\n return x;\n}", "signature": { "type": "function(x: any) => any", "describedArgs": [] } }, + "shiftStep": { "type": { "name": "number" }, "default": "10" }, "slotProps": { "type": { "name": "shape", diff --git a/docs/pages/base-ui/api/use-slider.json b/docs/pages/base-ui/api/use-slider.json index 620535067170fd..810000f851844c 100644 --- a/docs/pages/base-ui/api/use-slider.json +++ b/docs/pages/base-ui/api/use-slider.json @@ -41,6 +41,7 @@ }, "default": "function Identity(x) {\nreturn x;\n}" }, + "shiftStep": { "type": { "name": "number", "description": "number" }, "default": "10" }, "step": { "type": { "name": "number | null", "description": "number | null" }, "default": "1" }, "tabIndex": { "type": { "name": "number", "description": "number" } }, "value": { "type": { "name": "number | number[]", "description": "number | number[]" } } diff --git a/docs/pages/joy-ui/api/slider.json b/docs/pages/joy-ui/api/slider.json index 4bdc76958c4fc5..8a1e0e37d54447 100644 --- a/docs/pages/joy-ui/api/slider.json +++ b/docs/pages/joy-ui/api/slider.json @@ -62,6 +62,7 @@ "default": "function Identity(x) {\n return x;\n}", "signature": { "type": "function(x: any) => any", "describedArgs": [] } }, + "shiftStep": { "type": { "name": "number" }, "default": "10" }, "size": { "type": { "name": "union", diff --git a/docs/pages/material-ui/api/slider.json b/docs/pages/material-ui/api/slider.json index 4039796eed612d..e3dc8abbd37c96 100644 --- a/docs/pages/material-ui/api/slider.json +++ b/docs/pages/material-ui/api/slider.json @@ -74,6 +74,7 @@ "default": "function Identity(x) {\n return x;\n}", "signature": { "type": "function(x: any) => any", "describedArgs": [] } }, + "shiftStep": { "type": { "name": "number" }, "default": "10" }, "size": { "type": { "name": "union", diff --git a/docs/translations/api-docs-base/slider/slider.json b/docs/translations/api-docs-base/slider/slider.json index bd9c401ed67948..229cf2f7e48f6d 100644 --- a/docs/translations/api-docs-base/slider/slider.json +++ b/docs/translations/api-docs-base/slider/slider.json @@ -56,6 +56,9 @@ }, "orientation": { "description": "The component orientation." }, "scale": { "description": "A transformation function, to change the scale of the slider." }, + "shiftStep": { + "description": "The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down." + }, "slotProps": { "description": "The props used for each slot inside the Slider." }, "slots": { "description": "The components used for each slot inside the Slider. Either a string to use a HTML element or a component." diff --git a/docs/translations/api-docs-joy/slider/slider.json b/docs/translations/api-docs-joy/slider/slider.json index 3a9034d299a0b4..33406126b456f8 100644 --- a/docs/translations/api-docs-joy/slider/slider.json +++ b/docs/translations/api-docs-joy/slider/slider.json @@ -60,6 +60,9 @@ }, "orientation": { "description": "The component orientation." }, "scale": { "description": "A transformation function, to change the scale of the slider." }, + "shiftStep": { + "description": "The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down." + }, "size": { "description": "The size of the component. It accepts theme values between 'sm' and 'lg'." }, diff --git a/docs/translations/api-docs/slider/slider.json b/docs/translations/api-docs/slider/slider.json index 7da8d565d19b37..12e4419e1cdec1 100644 --- a/docs/translations/api-docs/slider/slider.json +++ b/docs/translations/api-docs/slider/slider.json @@ -63,6 +63,9 @@ }, "orientation": { "description": "The component orientation." }, "scale": { "description": "A transformation function, to change the scale of the slider." }, + "shiftStep": { + "description": "The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down." + }, "size": { "description": "The size of the slider." }, "slotProps": { "description": "The props used for each slot inside the Slider." }, "slots": { diff --git a/docs/translations/api-docs/use-slider/use-slider.json b/docs/translations/api-docs/use-slider/use-slider.json index 56c403349933c5..b155809ae0e334 100644 --- a/docs/translations/api-docs/use-slider/use-slider.json +++ b/docs/translations/api-docs/use-slider/use-slider.json @@ -33,6 +33,9 @@ "orientation": { "description": "The component orientation." }, "rootRef": { "description": "The ref attached to the root of the Slider." }, "scale": { "description": "A transformation function, to change the scale of the slider." }, + "shiftStep": { + "description": "The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down." + }, "step": { "description": "The granularity with which the slider can step through values. (A "discrete" slider.) The min prop serves as the origin for the valid values. We recommend (max - min) to be evenly divisible by the step.
When step is null, the thumb can only be slid onto marks provided with the marks prop." }, diff --git a/packages/mui-base/src/Slider/Slider.test.tsx b/packages/mui-base/src/Slider/Slider.test.tsx index e6c569a2f75279..8e58f636091363 100644 --- a/packages/mui-base/src/Slider/Slider.test.tsx +++ b/packages/mui-base/src/Slider/Slider.test.tsx @@ -447,4 +447,177 @@ describe('', () => { expect(secondThumb.getAttribute('data-active')).to.equal('false'); }); }); + + it('should support Shift + Left Arrow / Right Arrow keys', () => { + const hanleChange = spy(); + const { getByTestId } = render( + ({ + 'data-testid': `thumb-${index}`, + 'data-focused': focused, + 'data-active': active, + }), + }} + />, + ); + + const thumb = getByTestId('thumb-0'); + const input = thumb.firstChild; + + fireEvent.keyDown(document.body, { key: 'TAB' }); + act(() => { + (input as HTMLInputElement).focus(); + }); + + fireEvent.keyDown(input!, { key: 'ArrowLeft', shiftKey: true }); + expect(hanleChange.callCount).to.equal(1); + expect(hanleChange.args[0][1]).to.deep.equal(10); + + fireEvent.keyDown(input!, { key: 'ArrowRight', shiftKey: true }); + expect(hanleChange.callCount).to.equal(2); + expect(hanleChange.args[1][1]).to.deep.equal(20); + }); + + it('should support Shift + Up Arrow / Down Arrow keys', () => { + const hanleChange = spy(); + const { getByTestId } = render( + ({ + 'data-testid': `thumb-${index}`, + 'data-focused': focused, + 'data-active': active, + }), + }} + />, + ); + + const thumb = getByTestId('thumb-0'); + const input = thumb.firstChild; + + fireEvent.keyDown(document.body, { key: 'TAB' }); + act(() => { + (input as HTMLInputElement).focus(); + }); + + fireEvent.keyDown(input!, { key: 'ArrowDown', shiftKey: true }); + expect(hanleChange.callCount).to.equal(1); + expect(hanleChange.args[0][1]).to.deep.equal(10); + + fireEvent.keyDown(input!, { key: 'ArrowUp', shiftKey: true }); + expect(hanleChange.callCount).to.equal(2); + expect(hanleChange.args[1][1]).to.deep.equal(20); + }); + + it('should support PageUp / PageDown keys', () => { + const hanleChange = spy(); + const { getByTestId } = render( + ({ + 'data-testid': `thumb-${index}`, + 'data-focused': focused, + 'data-active': active, + }), + }} + />, + ); + + const thumb = getByTestId('thumb-0'); + const input = thumb.firstChild; + + fireEvent.keyDown(document.body, { key: 'TAB' }); + act(() => { + (input as HTMLInputElement).focus(); + }); + + fireEvent.keyDown(input!, { key: 'PageDown' }); + expect(hanleChange.callCount).to.equal(1); + expect(hanleChange.args[0][1]).to.deep.equal(10); + + fireEvent.keyDown(input!, { key: 'PageUp' }); + expect(hanleChange.callCount).to.equal(2); + expect(hanleChange.args[1][1]).to.deep.equal(20); + }); + + it('should support Shift + Left Arrow / Right Arrow keys by taking acount step and shiftStep', () => { + const hanleChange = spy(); + const defaultValue = 20; + const shiftStep = 15; + const step = 5; + const { getByTestId } = render( + ({ + 'data-testid': `thumb-${index}`, + 'data-focused': focused, + 'data-active': active, + }), + }} + />, + ); + + const thumb = getByTestId('thumb-0'); + const input = thumb.firstChild; + + fireEvent.keyDown(document.body, { key: 'TAB' }); + act(() => { + (input as HTMLInputElement).focus(); + }); + + fireEvent.keyDown(input!, { key: 'ArrowLeft', shiftKey: true }); + expect(hanleChange.callCount).to.equal(1); + expect(hanleChange.args[0][1]).to.deep.equal(defaultValue - shiftStep); + expect(input).to.have.attribute('aria-valuenow', `${defaultValue - shiftStep}`); + + fireEvent.keyDown(input!, { key: 'ArrowRight', shiftKey: true }); + expect(hanleChange.callCount).to.equal(2); + expect(hanleChange.args[1][1]).to.deep.equal(defaultValue); + expect(input).to.have.attribute('aria-valuenow', `${defaultValue}`); + }); + + it('should stop at max/min when using Shift + Left Arrow / Right Arrow keys', () => { + const hanleChange = spy(); + const { getByTestId } = render( + ({ + 'data-testid': `thumb-${index}`, + 'data-focused': focused, + 'data-active': active, + }), + }} + />, + ); + + const thumb = getByTestId('thumb-0'); + const input = thumb.firstChild; + + fireEvent.keyDown(document.body, { key: 'TAB' }); + act(() => { + (input as HTMLInputElement).focus(); + }); + + fireEvent.keyDown(input!, { key: 'ArrowLeft', shiftKey: true }); + expect(hanleChange.callCount).to.equal(1); + expect(hanleChange.args[0][1]).to.deep.equal(0); + + fireEvent.keyDown(input!, { key: 'ArrowRight', shiftKey: true }); + expect(hanleChange.callCount).to.equal(2); + expect(hanleChange.args[1][1]).to.deep.equal(8); + }); }); diff --git a/packages/mui-base/src/Slider/Slider.tsx b/packages/mui-base/src/Slider/Slider.tsx index a3126f09b9b633..3ae33136e6c711 100644 --- a/packages/mui-base/src/Slider/Slider.tsx +++ b/packages/mui-base/src/Slider/Slider.tsx @@ -77,6 +77,7 @@ const Slider = React.forwardRef(function Slider { + const index = Number(event.currentTarget.getAttribute('data-index')); + const value = values[index]; + const marksIndex = marksValues.indexOf(value); + let newValue: number | number[] = valueInput; + + if (marks && step == null) { + const maxMarksValue = marksValues[marksValues.length - 1]; + if (newValue > maxMarksValue) { + newValue = maxMarksValue; + } else if (newValue < marksValues[0]) { + newValue = marksValues[0]; + } else { + newValue = newValue < value ? marksValues[marksIndex - 1] : marksValues[marksIndex + 1]; + } + } + + newValue = clamp(newValue, min, max); + + if (range) { + // Bound the new value to the thumb's neighbours. + if (disableSwap) { + newValue = clamp(newValue, values[index - 1] || -Infinity, values[index + 1] || Infinity); + } + + const previousValue = newValue; + newValue = setValueIndex({ + values, + newValue, + index, + }); + + let activeIndex = index; + + // Potentially swap the index if needed. + if (!disableSwap) { + activeIndex = newValue.indexOf(previousValue); + } + + focusThumb({ sliderRef, activeIndex }); + } + + setValueState(newValue); + setFocusedThumbIndex(index); + + if (handleChange && !areValuesEqual(newValue, valueDerived)) { + handleChange(event, newValue, index); + } + + if (onChangeCommitted) { + onChangeCommitted(event, newValue); + } + }; + + const createHandleHiddenInputKeyDown = + (otherHandlers: EventHandlers) => (event: React.KeyboardEvent) => { + // The Shift + Up/Down keyboard shortcuts for moving the slider makes sense to be supported + // only if the step is defined. If the step is null, this means tha the marks are used for specifying the valid values. + if (step !== null) { + const index = Number(event.currentTarget.getAttribute('data-index')); + const value = values[index]; + + let newValue = null; + if ( + ((event.key === 'ArrowLeft' || event.key === 'ArrowDown') && event.shiftKey) || + event.key === 'PageDown' + ) { + newValue = Math.max(value - shiftStep, min); + } else if ( + ((event.key === 'ArrowRight' || event.key === 'ArrowUp') && event.shiftKey) || + event.key === 'PageUp' + ) { + newValue = Math.min(value + shiftStep, max); + } + + if (newValue !== null) { + changeValue(event, newValue); + event.preventDefault(); + } + } + + otherHandlers?.onKeyDown?.(event); + }; + useEnhancedEffect(() => { if (disabled && sliderRef.current!.contains(document.activeElement)) { // This is necessary because Firefox and Safari will keep focus @@ -316,60 +401,8 @@ export function useSlider(parameters: UseSliderParameters): UseSliderReturnValue const createHandleHiddenInputChange = (otherHandlers: EventHandlers) => (event: React.ChangeEvent) => { otherHandlers.onChange?.(event); - - const index = Number(event.currentTarget.getAttribute('data-index')); - const value = values[index]; - const marksIndex = marksValues.indexOf(value); - // @ts-ignore - let newValue = event.target.valueAsNumber; - - if (marks && step == null) { - const maxMarksValue = marksValues[marksValues.length - 1]; - if (newValue > maxMarksValue) { - newValue = maxMarksValue; - } else if (newValue < marksValues[0]) { - newValue = marksValues[0]; - } else { - newValue = newValue < value ? marksValues[marksIndex - 1] : marksValues[marksIndex + 1]; - } - } - - newValue = clamp(newValue, min, max); - - if (range) { - // Bound the new value to the thumb's neighbours. - if (disableSwap) { - newValue = clamp(newValue, values[index - 1] || -Infinity, values[index + 1] || Infinity); - } - - const previousValue = newValue; - newValue = setValueIndex({ - values, - newValue, - index, - }); - - let activeIndex = index; - - // Potentially swap the index if needed. - if (!disableSwap) { - activeIndex = newValue.indexOf(previousValue); - } - - focusThumb({ sliderRef, activeIndex }); - } - - setValueState(newValue); - setFocusedThumbIndex(index); - - if (handleChange && !areValuesEqual(newValue, valueDerived)) { - handleChange(event, newValue, index); - } - - if (onChangeCommitted) { - onChangeCommitted(event, newValue); - } + changeValue(event, event.target.valueAsNumber); }; const previousIndex = React.useRef(); @@ -670,6 +703,7 @@ export function useSlider(parameters: UseSliderParameters): UseSliderReturnValue onChange: createHandleHiddenInputChange(externalHandlers || {}), onFocus: createHandleHiddenInputFocus(externalHandlers || {}), onBlur: createHandleHiddenInputBlur(externalHandlers || {}), + onKeyDown: createHandleHiddenInputKeyDown(externalHandlers || {}), }; const mergedEventHandlers = { diff --git a/packages/mui-base/src/useSlider/useSlider.types.ts b/packages/mui-base/src/useSlider/useSlider.types.ts index 0319f6384b9c8a..39e6af36e1aeaf 100644 --- a/packages/mui-base/src/useSlider/useSlider.types.ts +++ b/packages/mui-base/src/useSlider/useSlider.types.ts @@ -82,6 +82,11 @@ export interface UseSliderParameters { * } */ scale?: (value: number) => number; + /** + * The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down. + * @default 10 + */ + shiftStep?: number; /** * The granularity with which the slider can step through values. (A "discrete" slider.) * The `min` prop serves as the origin for the valid values. diff --git a/packages/mui-joy/src/Slider/Slider.tsx b/packages/mui-joy/src/Slider/Slider.tsx index d5e7a3763c7307..0ecbcd057d368b 100644 --- a/packages/mui-joy/src/Slider/Slider.tsx +++ b/packages/mui-joy/src/Slider/Slider.tsx @@ -421,6 +421,7 @@ const Slider = React.forwardRef(function Slider(inProps, ref) { onChangeCommitted, onMouseDown, orientation = 'horizontal', + shiftStep = 10, scale = Identity, step = 1, tabIndex, @@ -449,6 +450,7 @@ const Slider = React.forwardRef(function Slider(inProps, ref) { max, min, orientation, + shiftStep, scale, step, track, @@ -793,6 +795,11 @@ Slider.propTypes /* remove-proptypes */ = { * } */ scale: PropTypes.func, + /** + * The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down. + * @default 10 + */ + shiftStep: PropTypes.number, /** * The size of the component. * It accepts theme values between 'sm' and 'lg'. diff --git a/packages/mui-material/src/Slider/Slider.d.ts b/packages/mui-material/src/Slider/Slider.d.ts index fd237e52008051..bbc205f652527e 100644 --- a/packages/mui-material/src/Slider/Slider.d.ts +++ b/packages/mui-material/src/Slider/Slider.d.ts @@ -175,6 +175,11 @@ export interface SliderOwnProps { * } */ scale?: (value: number) => number; + /** + * The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down. + * @default 10 + */ + shiftStep?: number; /** * The size of the slider. * @default 'medium' diff --git a/packages/mui-material/src/Slider/Slider.js b/packages/mui-material/src/Slider/Slider.js index 527d90cdedf4c3..ac67ca95010292 100644 --- a/packages/mui-material/src/Slider/Slider.js +++ b/packages/mui-material/src/Slider/Slider.js @@ -432,6 +432,7 @@ const Slider = React.forwardRef(function Slider(inputProps, ref) { onChange, onChangeCommitted, orientation = 'horizontal', + shiftStep = 10, size = 'medium', step = 1, scale = Identity, @@ -458,6 +459,7 @@ const Slider = React.forwardRef(function Slider(inputProps, ref) { color, size, step, + shiftStep, scale, track, valueLabelDisplay, @@ -898,6 +900,11 @@ Slider.propTypes /* remove-proptypes */ = { * } */ scale: PropTypes.func, + /** + * The granularity with which the slider can step through values when using Page Up/Page Down or Shift + Arrow Up/Arrow Down. + * @default 10 + */ + shiftStep: PropTypes.number, /** * The size of the slider. * @default 'medium' From 65ac6423d0efa3d883e8a7b560ca1c1da04d63a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 10:59:22 +0100 Subject: [PATCH 047/120] Bump piscina to ^4.3.1 (#40931) --- package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 86277485ebb7ac..d461c69541811f 100644 --- a/package.json +++ b/package.json @@ -166,7 +166,7 @@ "mocha": "^10.2.0", "nx": "^17.2.8", "nyc": "^15.1.0", - "piscina": "^4.3.0", + "piscina": "^4.3.1", "postcss-styled-syntax": "^0.6.4", "prettier": "^2.8.8", "pretty-quick": "^3.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7379218aebf565..122a2530f5044a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -288,8 +288,8 @@ importers: specifier: ^15.1.0 version: 15.1.0 piscina: - specifier: ^4.3.0 - version: 4.3.0 + specifier: ^4.3.1 + version: 4.3.1 postcss-styled-syntax: specifier: ^0.6.4 version: 0.6.4(postcss@8.4.33) @@ -17539,8 +17539,8 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - /piscina@4.3.0: - resolution: {integrity: sha512-vTQszGZj78p0BHFNO/cSvpzPUYa4tLXRe30aIYyQjqRS3fK/kPqdxvkTfGXQlEpWOI+mOOkda0iEY6NaanLWJA==} + /piscina@4.3.1: + resolution: {integrity: sha512-MBj0QYm3hJQ/C/wIXTN1OCYC8uQ4BBJ4LVele2P4ZwVQAH04vkk8E1SpDbuemLAL1dZorbuOob9rYqJeWCcCRg==} optionalDependencies: nice-napi: 1.0.2 dev: true From 463474c086c92d9e175ae371291a6cd2c428401c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:00:09 +0100 Subject: [PATCH 048/120] Bump markdown-to-jsx to ^7.4.1 (#40930) --- docs/package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/package.json b/docs/package.json index 52445aab867592..b56922dc4ecd4f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -82,7 +82,7 @@ "jss-rtl": "^0.3.0", "lodash": "^4.17.21", "lz-string": "^1.5.0", - "markdown-to-jsx": "^7.4.0", + "markdown-to-jsx": "^7.4.1", "material-ui-popup-state": "^5.0.10", "next": "13.4.19", "notistack": "3.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 122a2530f5044a..547f53e4e82c38 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -731,8 +731,8 @@ importers: specifier: ^1.5.0 version: 1.5.0 markdown-to-jsx: - specifier: ^7.4.0 - version: 7.4.0(react@18.2.0) + specifier: ^7.4.1 + version: 7.4.1(react@18.2.0) material-ui-popup-state: specifier: ^5.0.10 version: 5.0.10(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) @@ -15530,8 +15530,8 @@ packages: uc.micro: 2.0.0 dev: true - /markdown-to-jsx@7.4.0(react@18.2.0): - resolution: {integrity: sha512-zilc+MIkVVXPyTb4iIUTIz9yyqfcWjszGXnwF9K/aiBWcHXFcmdEMTkG01/oQhwSCH7SY1BnG6+ev5BzWmbPrg==} + /markdown-to-jsx@7.4.1(react@18.2.0): + resolution: {integrity: sha512-GbrbkTnHp9u6+HqbPRFJbObi369AgJNXi/sGqq5HRsoZW063xR1XDCaConqq+whfEIAlzB1YPnOgsPc7B7bc/A==} engines: {node: '>= 10'} peerDependencies: react: '>= 0.14.0' From 5666578a6301dab1b4b25d64c014d6d850438519 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:00:27 +0100 Subject: [PATCH 049/120] Bump envinfo to ^7.11.1 (#40928) --- packages/mui-envinfo/package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/mui-envinfo/package.json b/packages/mui-envinfo/package.json index 321dad3a093459..0c9bfe55092412 100644 --- a/packages/mui-envinfo/package.json +++ b/packages/mui-envinfo/package.json @@ -20,7 +20,7 @@ "build": "node scripts/build" }, "dependencies": { - "envinfo": "^7.11.0" + "envinfo": "^7.11.1" }, "devDependencies": { "@types/chai": "^4.3.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 547f53e4e82c38..786db5463f3baf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1267,8 +1267,8 @@ importers: packages/mui-envinfo: dependencies: envinfo: - specifier: ^7.11.0 - version: 7.11.0 + specifier: ^7.11.1 + version: 7.11.1 devDependencies: '@types/chai': specifier: ^4.3.11 @@ -6535,7 +6535,7 @@ packages: chalk: 4.1.2 command-exists: 1.2.9 deepmerge: 4.3.1 - envinfo: 7.11.0 + envinfo: 7.11.1 execa: 5.1.1 hermes-profile-transformer: 0.0.6 ip: 1.1.8 @@ -11342,8 +11342,8 @@ packages: engines: {node: '>=6'} dev: true - /envinfo@7.11.0: - resolution: {integrity: sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==} + /envinfo@7.11.1: + resolution: {integrity: sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==} engines: {node: '>=4'} hasBin: true @@ -21369,7 +21369,7 @@ packages: colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.3 - envinfo: 7.11.0 + envinfo: 7.11.1 fastest-levenshtein: 1.0.16 import-local: 3.1.0 interpret: 3.1.1 From 032a4887f5e0191f7ad796aa420a0cb2b00803d9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:00:50 +0100 Subject: [PATCH 050/120] Bump babel to ^7.23.9 (#40927) --- packages/typescript-to-proptypes/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/typescript-to-proptypes/package.json b/packages/typescript-to-proptypes/package.json index 4cbcbda402c33b..f82b935e81447e 100644 --- a/packages/typescript-to-proptypes/package.json +++ b/packages/typescript-to-proptypes/package.json @@ -23,11 +23,11 @@ "typescript": "tsc -b tsconfig.json" }, "dependencies": { - "@babel/core": "^7.23.7", + "@babel/core": "^7.23.9", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-jsx": "^7.23.3", "@babel/plugin-syntax-typescript": "^7.23.3", - "@babel/types": "^7.23.6", + "@babel/types": "^7.23.9", "@mui-internal/docs-utils": "workspace:*", "doctrine": "^3.0.0", "lodash": "^4.17.21", From 160adf0d9c52b00de4afc980830dae9c70499c5b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:01:14 +0100 Subject: [PATCH 051/120] Bump Playwright (#40926) --- .circleci/config.yml | 26 +++++------ benchmark/package.json | 2 +- docs/package.json | 2 +- package.json | 2 +- packages/mui-material/package.json | 2 +- packages/test-utils/package.json | 2 +- pnpm-lock.yaml | 44 +++++++++---------- .../fixtures/create-react-app/package.json | 2 +- test/bundling/fixtures/esbuild/package.json | 2 +- test/bundling/fixtures/gatsby/package.json | 2 +- .../fixtures/next-webpack4/package.json | 2 +- .../fixtures/next-webpack5/package.json | 2 +- test/bundling/fixtures/snowpack/package.json | 2 +- test/bundling/fixtures/vite/package.json | 2 +- test/package.json | 4 +- 15 files changed, 49 insertions(+), 49 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bdf92fe6efa1d7..83ecb0ec835077 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -336,7 +336,7 @@ jobs: <<: *defaults resource_class: 'medium+' docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -366,7 +366,7 @@ jobs: test_e2e: <<: *defaults docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -385,7 +385,7 @@ jobs: test_e2e_website: <<: *defaults docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -400,7 +400,7 @@ jobs: test_profile: <<: *defaults docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -427,7 +427,7 @@ jobs: test_regressions: <<: *defaults docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -481,7 +481,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/next-webpack4/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -505,7 +505,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/next-webpack5/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -529,7 +529,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/create-react-app/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -553,7 +553,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/snowpack/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -577,7 +577,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/vite/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -601,7 +601,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/esbuild/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -629,7 +629,7 @@ jobs: <<: *defaults working_directory: /tmp/material-ui/test/bundling/fixtures/gatsby/ docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: @@ -730,7 +730,7 @@ jobs: test_benchmark: <<: *defaults docker: - - image: mcr.microsoft.com/playwright:v1.41.1-focal + - image: mcr.microsoft.com/playwright:v1.41.2-focal environment: NODE_ENV: development # Needed if playwright is in `devDependencies` steps: diff --git a/benchmark/package.json b/benchmark/package.json index 1d90b1ba18663e..72e0ed5a78c2aa 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -24,7 +24,7 @@ "express": "^4.18.2", "fs-extra": "^11.2.0", "jss": "^10.10.0", - "playwright": "^1.41.1", + "playwright": "^1.41.2", "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/docs/package.json b/docs/package.json index b56922dc4ecd4f..6b46640a24e1db 100644 --- a/docs/package.json +++ b/docs/package.json @@ -137,7 +137,7 @@ "cross-fetch": "^4.0.0", "gm": "^1.25.0", "marked": "^5.1.2", - "playwright": "^1.41.1", + "playwright": "^1.41.2", "prettier": "^2.8.8", "tailwindcss": "^3.4.1", "yargs": "^17.7.2" diff --git a/package.json b/package.json index d461c69541811f..e71b2fb0629dfc 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "@mui/utils": "workspace:^", "@next/eslint-plugin-next": "^14.1.0", "@octokit/rest": "^20.0.2", - "@playwright/test": "1.41.1", + "@playwright/test": "1.41.2", "@types/enzyme": "^3.10.18", "@types/fs-extra": "^11.0.4", "@types/lodash": "^4.14.202", diff --git a/packages/mui-material/package.json b/packages/mui-material/package.json index 3a2a310ab61db7..dbdc2f07631c04 100644 --- a/packages/mui-material/package.json +++ b/packages/mui-material/package.json @@ -74,7 +74,7 @@ "fast-glob": "^3.3.2", "fs-extra": "^11.2.0", "lodash": "^4.17.21", - "playwright": "^1.41.1", + "playwright": "^1.41.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.21.3", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index caa4003d9013a3..2913ceaa7dff92 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -36,7 +36,7 @@ "jsdom": "^24.0.0", "lodash": "^4.17.21", "mocha": "^10.2.0", - "playwright": "^1.41.1", + "playwright": "^1.41.2", "prop-types": "^15.8.1", "react-test-renderer": "^18.2.0", "sinon": "^15.2.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 786db5463f3baf..bf35f3fc55f290 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,8 +120,8 @@ importers: specifier: ^20.0.2 version: 20.0.2 '@playwright/test': - specifier: 1.41.1 - version: 1.41.1 + specifier: 1.41.2 + version: 1.41.2 '@types/enzyme': specifier: ^3.10.18 version: 3.10.18 @@ -503,8 +503,8 @@ importers: specifier: ^10.10.0 version: 10.10.0 playwright: - specifier: ^1.41.1 - version: 1.41.1 + specifier: ^1.41.2 + version: 1.41.2 prop-types: specifier: ^15.8.1 version: 15.8.1 @@ -891,8 +891,8 @@ importers: specifier: ^5.1.2 version: 5.1.2 playwright: - specifier: ^1.41.1 - version: 1.41.1 + specifier: ^1.41.2 + version: 1.41.2 prettier: specifier: ^2.8.8 version: 2.8.8 @@ -1609,8 +1609,8 @@ importers: specifier: ^4.17.21 version: 4.17.21 playwright: - specifier: ^1.41.1 - version: 1.41.1 + specifier: ^1.41.2 + version: 1.41.2 react: specifier: ^18.2.0 version: 18.2.0 @@ -2186,8 +2186,8 @@ importers: specifier: ^10.2.0 version: 10.2.0 playwright: - specifier: ^1.41.1 - version: 1.41.1 + specifier: ^1.41.2 + version: 1.41.2 prop-types: specifier: ^15.8.1 version: 15.8.1 @@ -2500,8 +2500,8 @@ importers: specifier: workspace:^ version: link:../packages/mui-utils/build '@playwright/test': - specifier: 1.41.1 - version: 1.41.1 + specifier: 1.41.2 + version: 1.41.2 '@testing-library/dom': specifier: ^9.3.4 version: 9.3.4 @@ -2536,8 +2536,8 @@ importers: specifier: ^4.17.21 version: 4.17.21 playwright: - specifier: ^1.41.1 - version: 1.41.1 + specifier: ^1.41.2 + version: 1.41.2 prop-types: specifier: ^15.8.1 version: 15.8.1 @@ -6480,12 +6480,12 @@ packages: requiresBuild: true optional: true - /@playwright/test@1.41.1: - resolution: {integrity: sha512-9g8EWTjiQ9yFBXc6HjCWe41msLpxEX0KhmfmPl9RPLJdfzL4F0lg2BdJ91O9azFdl11y1pmpwdjBiSxvqc+btw==} + /@playwright/test@1.41.2: + resolution: {integrity: sha512-qQB9h7KbibJzrDpkXkYvsmiDJK14FULCCZgEcoe2AvFAS64oCirWTwzTlAYEbKaRxWs5TFesE1Na6izMv3HfGg==} engines: {node: '>=16'} hasBin: true dependencies: - playwright: 1.41.1 + playwright: 1.41.2 dev: true /@polka/url@1.0.0-next.21: @@ -17574,17 +17574,17 @@ packages: resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} dev: false - /playwright-core@1.41.1: - resolution: {integrity: sha512-/KPO5DzXSMlxSX77wy+HihKGOunh3hqndhqeo/nMxfigiKzogn8kfL0ZBDu0L1RKgan5XHCPmn6zXd2NUJgjhg==} + /playwright-core@1.41.2: + resolution: {integrity: sha512-VaTvwCA4Y8kxEe+kfm2+uUUw5Lubf38RxF7FpBxLPmGe5sdNkSg5e3ChEigaGrX7qdqT3pt2m/98LiyvU2x6CA==} engines: {node: '>=16'} hasBin: true - /playwright@1.41.1: - resolution: {integrity: sha512-gdZAWG97oUnbBdRL3GuBvX3nDDmUOuqzV/D24dytqlKt+eI5KbwusluZRGljx1YoJKZ2NRPaeWiFTeGZO7SosQ==} + /playwright@1.41.2: + resolution: {integrity: sha512-v0bOa6H2GJChDL8pAeLa/LZC4feoAMbSQm1/jF/ySsWWoaNItvrMP7GEkvEEFyCTUYKMxjQKaTSg5up7nR6/8A==} engines: {node: '>=16'} hasBin: true dependencies: - playwright-core: 1.41.1 + playwright-core: 1.41.2 optionalDependencies: fsevents: 2.3.2 diff --git a/test/bundling/fixtures/create-react-app/package.json b/test/bundling/fixtures/create-react-app/package.json index 8e8750cf5c59da..126b6ca76c0743 100644 --- a/test/bundling/fixtures/create-react-app/package.json +++ b/test/bundling/fixtures/create-react-app/package.json @@ -25,7 +25,7 @@ "devDependencies": { "concurrently": "7.4.0", "cross-env": "7.0.3", - "playwright": "1.41.1", + "playwright": "1.41.2", "serve": "14.0.1" }, "browserslist": { diff --git a/test/bundling/fixtures/esbuild/package.json b/test/bundling/fixtures/esbuild/package.json index fc2ec2ac756654..8e4c6c913b2023 100644 --- a/test/bundling/fixtures/esbuild/package.json +++ b/test/bundling/fixtures/esbuild/package.json @@ -25,7 +25,7 @@ }, "devDependencies": { "concurrently": "7.4.0", - "playwright": "1.41.1", + "playwright": "1.41.2", "serve": "14.0.1" } } diff --git a/test/bundling/fixtures/gatsby/package.json b/test/bundling/fixtures/gatsby/package.json index bcf191b66e6fb8..29cca6f642eb07 100644 --- a/test/bundling/fixtures/gatsby/package.json +++ b/test/bundling/fixtures/gatsby/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "concurrently": "7.4.0", - "playwright": "1.41.1" + "playwright": "1.41.2" } } diff --git a/test/bundling/fixtures/next-webpack4/package.json b/test/bundling/fixtures/next-webpack4/package.json index 78bfbacb052e40..b1c1be582cc3d1 100644 --- a/test/bundling/fixtures/next-webpack4/package.json +++ b/test/bundling/fixtures/next-webpack4/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "concurrently": "7.4.0", - "playwright": "1.41.1" + "playwright": "1.41.2" } } diff --git a/test/bundling/fixtures/next-webpack5/package.json b/test/bundling/fixtures/next-webpack5/package.json index e63bc118ffd812..1fe53a131e4707 100644 --- a/test/bundling/fixtures/next-webpack5/package.json +++ b/test/bundling/fixtures/next-webpack5/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "concurrently": "7.4.0", - "playwright": "1.41.1" + "playwright": "1.41.2" } } diff --git a/test/bundling/fixtures/snowpack/package.json b/test/bundling/fixtures/snowpack/package.json index d6d9b879209dff..329cf842af4242 100644 --- a/test/bundling/fixtures/snowpack/package.json +++ b/test/bundling/fixtures/snowpack/package.json @@ -24,7 +24,7 @@ }, "devDependencies": { "concurrently": "7.4.0", - "playwright": "1.41.1", + "playwright": "1.41.2", "serve": "14.0.1" } } diff --git a/test/bundling/fixtures/vite/package.json b/test/bundling/fixtures/vite/package.json index 0626ccf676231a..65f6dc59c135b0 100644 --- a/test/bundling/fixtures/vite/package.json +++ b/test/bundling/fixtures/vite/package.json @@ -24,7 +24,7 @@ }, "devDependencies": { "concurrently": "7.4.0", - "playwright": "1.41.1", + "playwright": "1.41.2", "serve": "14.0.1" } } diff --git a/test/package.json b/test/package.json index 14a900cd3a96a8..a34cf146442758 100644 --- a/test/package.json +++ b/test/package.json @@ -18,7 +18,7 @@ "@mui/material-next": "workspace:*", "@mui/system": "workspace:^", "@mui/utils": "workspace:^", - "@playwright/test": "1.41.1", + "@playwright/test": "1.41.2", "@testing-library/dom": "^9.3.4", "@types/chai": "^4.3.11", "@types/react": "^18.2.48", @@ -30,7 +30,7 @@ "fs-extra": "^11.2.0", "html-webpack-plugin": "^5.6.0", "lodash": "^4.17.21", - "playwright": "^1.41.1", + "playwright": "^1.41.2", "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", From c077ef25e9c198d30c1e8415b10cf6bed9813ece Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:02:26 +0100 Subject: [PATCH 052/120] Bump MUI X to 6.19.3 (#40925) --- docs/package.json | 14 +++++----- pnpm-lock.yaml | 66 +++++++++++++++++++++++------------------------ 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/docs/package.json b/docs/package.json index 6b46640a24e1db..caa9790ae582c8 100644 --- a/docs/package.json +++ b/docs/package.json @@ -46,13 +46,13 @@ "@mui/system": "workspace:^", "@mui/types": "workspace:^", "@mui/utils": "workspace:^", - "@mui/x-charts": "6.19.1", - "@mui/x-data-grid": "6.19.2", - "@mui/x-data-grid-generator": "6.19.2", - "@mui/x-data-grid-premium": "6.19.2", - "@mui/x-data-grid-pro": "6.19.2", - "@mui/x-date-pickers": "6.19.2", - "@mui/x-date-pickers-pro": "6.19.2", + "@mui/x-charts": "6.19.3", + "@mui/x-data-grid": "6.19.3", + "@mui/x-data-grid-generator": "6.19.3", + "@mui/x-data-grid-premium": "6.19.3", + "@mui/x-data-grid-pro": "6.19.3", + "@mui/x-date-pickers": "6.19.3", + "@mui/x-date-pickers-pro": "6.19.3", "@mui/x-license-pro": "6.10.2", "@mui/x-tree-view": "6.17.0", "@popperjs/core": "^2.11.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bf35f3fc55f290..0585bbb4027ca7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -623,26 +623,26 @@ importers: specifier: workspace:^ version: link:../packages/mui-utils/build '@mui/x-charts': - specifier: 6.19.1 - version: 6.19.1(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + specifier: 6.19.3 + version: 6.19.3(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) '@mui/x-data-grid': - specifier: 6.19.2 - version: 6.19.2(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + specifier: 6.19.3 + version: 6.19.3(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) '@mui/x-data-grid-generator': - specifier: 6.19.2 - version: 6.19.2(@mui/icons-material@packages+mui-icons-material+build)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + specifier: 6.19.3 + version: 6.19.3(@mui/icons-material@packages+mui-icons-material+build)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) '@mui/x-data-grid-premium': - specifier: 6.19.2 - version: 6.19.2(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + specifier: 6.19.3 + version: 6.19.3(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) '@mui/x-data-grid-pro': - specifier: 6.19.2 - version: 6.19.2(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + specifier: 6.19.3 + version: 6.19.3(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) '@mui/x-date-pickers': - specifier: 6.19.2 - version: 6.19.2(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) + specifier: 6.19.3 + version: 6.19.3(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) '@mui/x-date-pickers-pro': - specifier: 6.19.2 - version: 6.19.2(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) + specifier: 6.19.3 + version: 6.19.3(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) '@mui/x-license-pro': specifier: 6.10.2 version: 6.10.2(@types/react@18.2.48)(react@18.2.0) @@ -5455,8 +5455,8 @@ packages: react-is: 18.2.0 dev: false - /@mui/x-charts@6.19.1(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-7FJFwL+6o0Qt7RcQCeDeGL5aPzMpX8Dyh7+IOoNoaLiIHVNssAYh4D3uD2mKpZ+pcW6SE54aE5WM1SWDEC8TQA==} + /@mui/x-charts@6.19.3(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-VxF+mHXtmR2LxalH2KRzF4gLT6KFDbYMvis6rkcyr+w6J17KBxMsEGx8V0nn1CIEslzcSXgbv41jIzodhiFyMQ==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 @@ -5490,8 +5490,8 @@ packages: - '@types/react' dev: false - /@mui/x-data-grid-generator@6.19.2(@mui/icons-material@packages+mui-icons-material+build)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-YyeFzbnydS+SFv5U4RW9v8+IHtCsp/9g5sDQzUac4nBD4CkZ3zKoTc6HCfoxdIsojXd9cxhscwmhBCLKjXNgWg==} + /@mui/x-data-grid-generator@6.19.3(@mui/icons-material@packages+mui-icons-material+build)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-C6K5TPRnUE3Jt3V9SZVpVnUjJXnPk2rykt1UT4rsuoSXfVJZY+j1GULbU6f3MUJUb1brC0GsoQcY0cBx3BNqdg==} engines: {node: '>=14.0.0'} peerDependencies: '@mui/icons-material': ^5.4.1 @@ -5502,7 +5502,7 @@ packages: '@mui/base': 5.0.0-beta.30(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) '@mui/icons-material': link:packages/mui-icons-material/build '@mui/material': link:packages/mui-material/build - '@mui/x-data-grid-premium': 6.19.2(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@mui/x-data-grid-premium': 6.19.3(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) chance: 1.1.11 clsx: 2.1.0 lru-cache: 7.18.3 @@ -5513,8 +5513,8 @@ packages: - react-dom dev: false - /@mui/x-data-grid-premium@6.19.2(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-w0Fmrqs/UhDSn/3POf/Fg8DUDz0bTwBzqlp9oln0yeCNOyns8+RpdHcRXl+G9SKFqPrgP2FmizH1l5tE5BS/KQ==} + /@mui/x-data-grid-premium@6.19.3(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-c33MpUG42lAkvmOdA1qURnw4gE1xFwMH9ui2i1XHB96X0gvyKJf64DorkX/Kmen4JzYvqj3tP2p+BpRF9gKHdg==} engines: {node: '>=14.0.0'} peerDependencies: '@mui/material': ^5.4.1 @@ -5526,8 +5526,8 @@ packages: '@mui/material': link:packages/mui-material/build '@mui/system': link:packages/mui-system/build '@mui/utils': 5.15.6(@types/react@18.2.48)(react@18.2.0) - '@mui/x-data-grid': 6.19.2(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) - '@mui/x-data-grid-pro': 6.19.2(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@mui/x-data-grid': 6.19.3(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@mui/x-data-grid-pro': 6.19.3(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) '@mui/x-license-pro': 6.10.2(@types/react@18.2.48)(react@18.2.0) '@types/format-util': 1.0.4 clsx: 2.1.0 @@ -5540,8 +5540,8 @@ packages: - '@types/react' dev: false - /@mui/x-data-grid-pro@6.19.2(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-IOc/i4rM0Ot/G1fcHtHXlKECSb1GOJmllAOQ4ZlTlwsWc7B0V1RbbHngrAG/95svC5/l4UAdqC8ozOuj/TAYfQ==} + /@mui/x-data-grid-pro@6.19.3(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-+NhuEPefj+uiLfxz7MHTr1ALzTAKOz44BHIYA6D2xbsmG4JERAbjYJDyVNx5EEwrOeZsn0zQcFSfl2+ZMDso9A==} engines: {node: '>=14.0.0'} peerDependencies: '@mui/material': ^5.4.1 @@ -5553,7 +5553,7 @@ packages: '@mui/material': link:packages/mui-material/build '@mui/system': link:packages/mui-system/build '@mui/utils': 5.15.6(@types/react@18.2.48)(react@18.2.0) - '@mui/x-data-grid': 6.19.2(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@mui/x-data-grid': 6.19.3(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) '@mui/x-license-pro': 6.10.2(@types/react@18.2.48)(react@18.2.0) '@types/format-util': 1.0.4 clsx: 2.1.0 @@ -5565,8 +5565,8 @@ packages: - '@types/react' dev: false - /@mui/x-data-grid@6.19.2(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-+wizP1jEzCKB5BSQ6OD5TP6RspEbWmFWcxi1XBgKrzryUZii1o4G2BW1+d/n4p3xETCUMKRkYfItrOJGlM/dBw==} + /@mui/x-data-grid@6.19.3(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-RHt+MhTgvpXTWY0MYvzSNLF8npo+mlmWuTO+qKRt42Zj634IlUYDwW5jjQ9fWZnIpWJLunw253KqHoAlSAOXaw==} engines: {node: '>=14.0.0'} peerDependencies: '@mui/material': ^5.4.1 @@ -5587,8 +5587,8 @@ packages: - '@types/react' dev: false - /@mui/x-date-pickers-pro@6.19.2(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-WmMAziML8Zcat1/PjMm4vGeL5ih200wejSM54iLmu5nS4TOEk8XYVR2VEZd1Q99cLZly9vWBdOx9Fa/lnUUFdw==} + /@mui/x-date-pickers-pro@6.19.3(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-AzqEEUhNHl8cpN206MBm78khUDzG02eagYZBp72iq7Pn1yIVrEGqrOTRtDAdE320K43VmuYHL0OlJGYzqt22aQ==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 @@ -5631,7 +5631,7 @@ packages: '@mui/material': link:packages/mui-material/build '@mui/system': link:packages/mui-system/build '@mui/utils': 5.15.6(@types/react@18.2.48)(react@18.2.0) - '@mui/x-date-pickers': 6.19.2(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) + '@mui/x-date-pickers': 6.19.3(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0) '@mui/x-license-pro': 6.10.2(@types/react@18.2.48)(react@18.2.0) clsx: 2.1.0 date-fns: 2.30.0 @@ -5644,8 +5644,8 @@ packages: - '@types/react' dev: false - /@mui/x-date-pickers@6.19.2(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-/bdWZabexuz+1rKG15XryxiMGb5D0XVx65NU7CZYKm/1+HuUzc0FX9smKEa/YVZnLSNsAp6SULIyPZtAKE+3AA==} + /@mui/x-date-pickers@6.19.3(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@18.2.48)(date-fns-jalali@2.21.3-1)(date-fns@2.30.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-0USG4hhrgcMu/nZTYsBUGDcrwCEdzjok2Q4jYB6kHOpP2YxpGMESx0WIzzHtqrDQ67Z3g22v7KTWdPGRDo7HiQ==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.9.0 From 05cdec87e3b22312479ca946920b7077bbabdf3a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:04:45 +0100 Subject: [PATCH 053/120] Bump @argos-ci/core to ^1.5.3 (#40917) --- package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e71b2fb0629dfc..25df4df779dfeb 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "google-auth-library": "^9.5.0" }, "devDependencies": { - "@argos-ci/core": "^1.5.1", + "@argos-ci/core": "^1.5.3", "@babel/cli": "^7.23.9", "@babel/core": "^7.23.9", "@babel/node": "^7.23.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0585bbb4027ca7..0e79934b31f25a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,8 +42,8 @@ importers: version: 9.5.0 devDependencies: '@argos-ci/core': - specifier: ^1.5.1 - version: 1.5.1 + specifier: ^1.5.3 + version: 1.5.3 '@babel/cli': specifier: ^7.23.9 version: 7.23.9(@babel/core@7.23.9) @@ -2731,8 +2731,8 @@ packages: '@jridgewell/gen-mapping': 0.1.1 '@jridgewell/trace-mapping': 0.3.20 - /@argos-ci/core@1.5.1: - resolution: {integrity: sha512-CoCe81ee+eQpah3CRi+Uxv9KAUjnfHWYFHZ3bGz0aUC/p9UkCPFKOEHvakO1W2hjx2Nj1bj6QOSod87Vavty+g==} + /@argos-ci/core@1.5.3: + resolution: {integrity: sha512-qODX23ou3CwagOFwtYZyvXPAd2fXOu5ntnH5MbQcSzP3TdK8H2wkacNaLwvLEVpOeT3jdrfoQvROInewMfbHxQ==} engines: {node: '>=16.0.0'} dependencies: '@argos-ci/util': 1.2.0 From 2c520155bde3fc3c0237067f256a55c1d3fd5269 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:05:14 +0100 Subject: [PATCH 054/120] Bump @types/node to ^18.19.14 (#40922) --- docs/package.json | 2 +- package.json | 4 +- packages/api-docs-builder-core/package.json | 2 +- packages/api-docs-builder/package.json | 2 +- packages/mui-babel-macros/package.json | 2 +- packages/mui-utils/package.json | 2 +- packages/rsc-builder/package.json | 2 +- packages/typescript-to-proptypes/package.json | 2 +- packages/zero-runtime/package.json | 2 +- pnpm-lock.yaml | 128 +++++++++--------- 10 files changed, 74 insertions(+), 74 deletions(-) diff --git a/docs/package.json b/docs/package.json index caa9790ae582c8..f2ea281803923b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -124,7 +124,7 @@ "@types/chai": "^4.3.11", "@types/css-mediaquery": "^0.1.4", "@types/json2mq": "^0.2.2", - "@types/node": "^18.19.10", + "@types/node": "^18.19.14", "@types/prop-types": "^15.7.11", "@types/react": "^18.2.48", "@types/react-dom": "^18.2.18", diff --git a/package.json b/package.json index 25df4df779dfeb..2338f39e395eb5 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "@types/fs-extra": "^11.0.4", "@types/lodash": "^4.14.202", "@types/mocha": "^10.0.6", - "@types/node": "^18.19.10", + "@types/node": "^18.19.14", "@types/prettier": "^2.7.3", "@types/react": "^18.2.48", "@types/yargs": "^17.0.32", @@ -205,7 +205,7 @@ "@definitelytyped/header-parser": "^0.2.1", "@definitelytyped/typescript-versions": "^0.1.0", "@definitelytyped/utils": "^0.1.1", - "@types/node": "^18.19.10", + "@types/node": "^18.19.14", "@types/react": "^18.2.48", "@types/react-dom": "18.2.18", "cross-fetch": "^4.0.0" diff --git a/packages/api-docs-builder-core/package.json b/packages/api-docs-builder-core/package.json index 10e52caf15cd44..d2f5cfe6764dbb 100644 --- a/packages/api-docs-builder-core/package.json +++ b/packages/api-docs-builder-core/package.json @@ -17,7 +17,7 @@ "devDependencies": { "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", - "@types/node": "^18.19.10", + "@types/node": "^18.19.14", "@types/sinon": "^10.0.20", "chai": "^4.4.1", "sinon": "^15.2.0", diff --git a/packages/api-docs-builder/package.json b/packages/api-docs-builder/package.json index fbfde5233bca91..86e46c87a0abec 100644 --- a/packages/api-docs-builder/package.json +++ b/packages/api-docs-builder/package.json @@ -32,7 +32,7 @@ "@types/doctrine": "^0.0.9", "@types/mdast": "4.0.3", "@types/mocha": "^10.0.6", - "@types/node": "^18.19.10", + "@types/node": "^18.19.14", "@types/react-docgen": "workspace:*", "@types/sinon": "^10.0.20", "chai": "^4.4.1", diff --git a/packages/mui-babel-macros/package.json b/packages/mui-babel-macros/package.json index 909b7bdc6c2ed9..d856824c985f4d 100644 --- a/packages/mui-babel-macros/package.json +++ b/packages/mui-babel-macros/package.json @@ -30,7 +30,7 @@ "@types/babel-plugin-macros": "^3.1.3", "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", - "@types/node": "^18.19.10", + "@types/node": "^18.19.14", "babel-plugin-tester": "^11.0.4", "chai": "^4.4.1" }, diff --git a/packages/mui-utils/package.json b/packages/mui-utils/package.json index 5f97d78e7b0bc2..d37c3b2f68df36 100644 --- a/packages/mui-utils/package.json +++ b/packages/mui-utils/package.json @@ -50,7 +50,7 @@ "@mui/types": "workspace:^", "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", - "@types/node": "^18.19.10", + "@types/node": "^18.19.14", "@types/react": "^18.2.48", "@types/react-dom": "^18.2.18", "@types/react-is": "^18.2.4", diff --git a/packages/rsc-builder/package.json b/packages/rsc-builder/package.json index 46c3d2ceb73a90..3b65c9332cb1d2 100644 --- a/packages/rsc-builder/package.json +++ b/packages/rsc-builder/package.json @@ -9,6 +9,6 @@ }, "devDependencies": { "@types/mocha": "^10.0.6", - "@types/node": "^18.19.10" + "@types/node": "^18.19.14" } } diff --git a/packages/typescript-to-proptypes/package.json b/packages/typescript-to-proptypes/package.json index f82b935e81447e..71fd94ce433a29 100644 --- a/packages/typescript-to-proptypes/package.json +++ b/packages/typescript-to-proptypes/package.json @@ -40,7 +40,7 @@ "@types/chai": "^4.3.11", "@types/doctrine": "^0.0.9", "@types/lodash": "^4.14.202", - "@types/node": "^18.19.8", + "@types/node": "^18.19.14", "@types/prettier": "^2.7.3", "@types/react": "^18.2.48", "@types/uuid": "^9.0.7", diff --git a/packages/zero-runtime/package.json b/packages/zero-runtime/package.json index 27c456b14f5cff..321b48e6206b44 100644 --- a/packages/zero-runtime/package.json +++ b/packages/zero-runtime/package.json @@ -35,7 +35,7 @@ "@types/babel__helper-plugin-utils": "^7.10.3", "@types/cssesc": "^3.0.2", "@types/lodash": "^4.14.202", - "@types/node": "^18.19.10", + "@types/node": "^18.19.14", "@types/react": "^18.2.48", "@types/stylis": "^4.2.0", "react": "^18.2.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0e79934b31f25a..07179a4e458aa7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,7 +22,7 @@ overrides: '@definitelytyped/header-parser': ^0.2.1 '@definitelytyped/typescript-versions': ^0.1.0 '@definitelytyped/utils': ^0.1.1 - '@types/node': ^18.19.10 + '@types/node': ^18.19.14 '@types/react': ^18.2.48 '@types/react-dom': 18.2.18 cross-fetch: ^4.0.0 @@ -135,8 +135,8 @@ importers: specifier: ^10.0.6 version: 10.0.6 '@types/node': - specifier: ^18.19.10 - version: 18.19.10 + specifier: ^18.19.14 + version: 18.19.14 '@types/prettier': specifier: ^2.7.3 version: 2.7.3 @@ -385,8 +385,8 @@ importers: specifier: workspace:^ version: link:../../packages/zero-next-plugin '@types/node': - specifier: ^18.19.10 - version: 18.19.10 + specifier: ^18.19.14 + version: 18.19.14 '@types/react': specifier: ^18.2.48 version: 18.2.48 @@ -459,7 +459,7 @@ importers: version: 1.0.1 vite: specifier: 5.0.12 - version: 5.0.12(@types/node@18.19.10) + version: 5.0.12(@types/node@18.19.14) benchmark: dependencies: @@ -852,8 +852,8 @@ importers: specifier: ^0.2.2 version: 0.2.2 '@types/node': - specifier: ^18.19.10 - version: 18.19.10 + specifier: ^18.19.14 + version: 18.19.14 '@types/prop-types': specifier: ^15.7.11 version: 15.7.11 @@ -973,8 +973,8 @@ importers: specifier: ^10.0.6 version: 10.0.6 '@types/node': - specifier: ^18.19.10 - version: 18.19.10 + specifier: ^18.19.14 + version: 18.19.14 '@types/react-docgen': specifier: workspace:* version: link:../react-docgen-types @@ -1010,8 +1010,8 @@ importers: specifier: ^10.0.6 version: 10.0.6 '@types/node': - specifier: ^18.19.10 - version: 18.19.10 + specifier: ^18.19.14 + version: 18.19.14 '@types/sinon': specifier: ^10.0.20 version: 10.0.20 @@ -1117,8 +1117,8 @@ importers: specifier: ^10.0.6 version: 10.0.6 '@types/node': - specifier: ^18.19.10 - version: 18.19.10 + specifier: ^18.19.14 + version: 18.19.14 babel-plugin-tester: specifier: ^11.0.4 version: 11.0.4(@babel/core@7.23.9) @@ -2073,8 +2073,8 @@ importers: specifier: ^10.0.6 version: 10.0.6 '@types/node': - specifier: ^18.19.10 - version: 18.19.10 + specifier: ^18.19.14 + version: 18.19.14 '@types/react': specifier: ^18.2.48 version: 18.2.48 @@ -2126,8 +2126,8 @@ importers: specifier: ^10.0.6 version: 10.0.6 '@types/node': - specifier: ^18.19.10 - version: 18.19.10 + specifier: ^18.19.14 + version: 18.19.14 packages/test-utils: dependencies: @@ -2284,8 +2284,8 @@ importers: specifier: ^4.14.202 version: 4.14.202 '@types/node': - specifier: ^18.19.10 - version: 18.19.10 + specifier: ^18.19.14 + version: 18.19.14 '@types/prettier': specifier: ^2.7.3 version: 2.7.3 @@ -2387,8 +2387,8 @@ importers: specifier: ^4.14.202 version: 4.14.202 '@types/node': - specifier: ^18.19.10 - version: 18.19.10 + specifier: ^18.19.14 + version: 18.19.14 '@types/react': specifier: ^18.2.48 version: 18.2.48 @@ -2459,7 +2459,7 @@ importers: version: 4.1.12 vite: specifier: ^5.0.12 - version: 5.0.12(@types/node@18.19.10) + version: 5.0.12(@types/node@18.19.14) test: devDependencies: @@ -4749,7 +4749,7 @@ packages: /@fast-csv/format@4.3.5: resolution: {integrity: sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 lodash.escaperegexp: 4.1.2 lodash.isboolean: 3.0.3 lodash.isequal: 4.5.0 @@ -4760,7 +4760,7 @@ packages: /@fast-csv/parse@4.3.6: resolution: {integrity: sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 lodash.escaperegexp: 4.1.2 lodash.groupby: 4.6.0 lodash.isfunction: 3.0.9 @@ -4952,7 +4952,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.19.10 + '@types/node': 18.19.14 jest-mock: 29.7.0 dev: false @@ -4962,7 +4962,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 18.19.10 + '@types/node': 18.19.14 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -4980,7 +4980,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.2 - '@types/node': 18.19.10 + '@types/node': 18.19.14 '@types/yargs': 15.0.19 chalk: 4.1.2 dev: false @@ -4992,7 +4992,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.2 - '@types/node': 18.19.10 + '@types/node': 18.19.14 '@types/yargs': 17.0.32 chalk: 4.1.2 dev: false @@ -7265,14 +7265,14 @@ packages: resolution: {integrity: sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA==} engines: {node: '>= 12.13.0', npm: '>= 6.12.0'} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: false /@slack/logger@4.0.0: resolution: {integrity: sha512-Wz7QYfPAlG/DR+DfABddUZeNgoeY7d1J39OCR2jR+v7VBsB8ezulDK5szTnDDPDwLH5IWhLvXIHlCFZV7MSKgA==} engines: {node: '>= 18', npm: '>= 8.6.0'} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: false /@slack/oauth@2.6.2: @@ -7282,7 +7282,7 @@ packages: '@slack/logger': 3.0.0 '@slack/web-api': 6.12.0 '@types/jsonwebtoken': 8.5.9 - '@types/node': 18.19.10 + '@types/node': 18.19.14 jsonwebtoken: 9.0.0 lodash.isstring: 4.0.1 transitivePeerDependencies: @@ -7295,7 +7295,7 @@ packages: dependencies: '@slack/logger': 3.0.0 '@slack/web-api': 6.12.0 - '@types/node': 18.19.10 + '@types/node': 18.19.14 '@types/p-queue': 2.3.2 '@types/ws': 7.4.7 eventemitter3: 3.1.2 @@ -7321,7 +7321,7 @@ packages: '@slack/logger': 3.0.0 '@slack/types': 2.11.0 '@types/is-stream': 1.1.0 - '@types/node': 18.19.10 + '@types/node': 18.19.14 axios: 1.6.5(debug@4.3.4) eventemitter3: 3.1.2 form-data: 2.5.1 @@ -7646,7 +7646,7 @@ packages: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: false /@types/cacheable-request@6.0.2: @@ -7654,7 +7654,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 18.19.10 + '@types/node': 18.19.14 '@types/responselike': 1.0.0 dev: true @@ -7671,13 +7671,13 @@ packages: /@types/cheerio@0.22.31: resolution: {integrity: sha512-Kt7Cdjjdi2XWSfrZ53v4Of0wG3ZcmaegFXjMmz9tfNrZSkzzo36G0AL1YqSdcIA78Etjt6E609pt5h1xnQkPUw==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: true /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: false /@types/cookie@0.4.1: @@ -7731,7 +7731,7 @@ packages: /@types/express-serve-static-core@4.17.35: resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 '@types/send': 0.17.1 @@ -7753,7 +7753,7 @@ packages: resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} dependencies: '@types/jsonfile': 6.1.1 - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: true /@types/hoist-non-react-statics@3.3.5: @@ -7777,7 +7777,7 @@ packages: /@types/is-stream@1.1.0: resolution: {integrity: sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: false /@types/istanbul-lib-coverage@2.0.4: @@ -7817,19 +7817,19 @@ packages: /@types/jsonfile@6.1.1: resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: true /@types/jsonwebtoken@8.5.9: resolution: {integrity: sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: false /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: true /@types/lodash.mergewith@4.6.7: @@ -7877,8 +7877,8 @@ packages: resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} dev: true - /@types/node@18.19.10: - resolution: {integrity: sha512-IZD8kAM02AW1HRDTPOlz3npFava678pr8Ie9Vp8uRhBROXAv8MXT2pCnGZZAKYdromsNQLHQcfWQ6EOatVLtqA==} + /@types/node@18.19.14: + resolution: {integrity: sha512-EnQ4Us2rmOS64nHDWr0XqAD8DsO6f3XR6lf9UIIrZQpUzPVdN/oPuEzfDWNHSyXLvoGgjuEm/sPwFGSSs35Wtg==} dependencies: undici-types: 5.26.5 @@ -7976,13 +7976,13 @@ packages: /@types/resolve@0.0.8: resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: true /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: true /@types/retry@0.12.0: @@ -8000,7 +8000,7 @@ packages: resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} dependencies: '@types/mime': 1.3.2 - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: false /@types/serve-static@1.15.2: @@ -8008,7 +8008,7 @@ packages: dependencies: '@types/http-errors': 2.0.1 '@types/mime': 3.0.1 - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: false /@types/sinon@10.0.20: @@ -8060,7 +8060,7 @@ packages: /@types/ws@7.4.7: resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 dev: false /@types/yargs-parser@21.0.0: @@ -8224,7 +8224,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.9) '@types/babel__core': 7.20.5 react-refresh: 0.14.0 - vite: 5.0.12(@types/node@18.19.10) + vite: 5.0.12(@types/node@18.19.14) transitivePeerDependencies: - supports-color dev: true @@ -9854,7 +9854,7 @@ packages: engines: {node: '>=12.13.0'} hasBin: true dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -9869,7 +9869,7 @@ packages: /chromium-edge-launcher@1.0.0: resolution: {integrity: sha512-pgtgjNKZ7i5U++1g1PWv75umkHvhVTDOQIZ+sjeUX9483S7Y6MUvO0lrd7ShGlQlFHMN4SwKTCq/X8hWrbv2KA==} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -11288,7 +11288,7 @@ packages: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.12 - '@types/node': 18.19.10 + '@types/node': 18.19.14 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.4.2 @@ -14258,7 +14258,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.19.10 + '@types/node': 18.19.14 jest-mock: 29.7.0 jest-util: 29.7.0 dev: false @@ -14287,7 +14287,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 18.19.10 + '@types/node': 18.19.14 jest-util: 29.7.0 dev: false @@ -14296,7 +14296,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 18.19.10 + '@types/node': 18.19.14 chalk: 4.1.2 ci-info: 3.8.0 graceful-fs: 4.2.11 @@ -14319,7 +14319,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true @@ -14328,7 +14328,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -14336,7 +14336,7 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -21227,12 +21227,12 @@ packages: vfile-message: 2.0.4 dev: false - /vite@5.0.12(@types/node@18.19.10): + /vite@5.0.12(@types/node@18.19.14): resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': ^18.19.10 + '@types/node': ^18.19.14 less: '*' lightningcss: ^1.21.0 sass: '*' @@ -21255,7 +21255,7 @@ packages: terser: optional: true dependencies: - '@types/node': 18.19.10 + '@types/node': 18.19.14 esbuild: 0.19.11 postcss: 8.4.33 rollup: 4.9.2 From 166be542dc6d51b28689dad2f26824bf8ba589a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:06:16 +0100 Subject: [PATCH 055/120] Bump @types/uuid to ^9.0.8 (#40924) --- packages/typescript-to-proptypes/package.json | 2 +- pnpm-lock.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/typescript-to-proptypes/package.json b/packages/typescript-to-proptypes/package.json index 71fd94ce433a29..457285713b6091 100644 --- a/packages/typescript-to-proptypes/package.json +++ b/packages/typescript-to-proptypes/package.json @@ -43,7 +43,7 @@ "@types/node": "^18.19.14", "@types/prettier": "^2.7.3", "@types/react": "^18.2.48", - "@types/uuid": "^9.0.7", + "@types/uuid": "^9.0.8", "chai": "^4.4.1", "fast-glob": "^3.3.2", "prettier": "^2.8.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 07179a4e458aa7..d92bc0e40f3f38 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2293,7 +2293,7 @@ importers: specifier: ^18.2.48 version: 18.2.48 '@types/uuid': - specifier: ^9.0.7 + specifier: ^9.0.8 version: 9.0.8 chai: specifier: ^4.4.1 From 572d1ccde0a429d80eb5bed8b9d8c4ef64bbdced Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:06:36 +0100 Subject: [PATCH 056/120] Bump react-virtuoso to ^4.6.3 (#40933) --- docs/package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/package.json b/docs/package.json index f2ea281803923b..4e99dcf2366f14 100644 --- a/docs/package.json +++ b/docs/package.json @@ -105,7 +105,7 @@ "react-swipeable-views": "^0.14.0", "react-swipeable-views-utils": "^0.14.0", "react-transition-group": "^4.4.5", - "react-virtuoso": "^4.6.2", + "react-virtuoso": "^4.6.3", "react-window": "^1.8.10", "rimraf": "^5.0.5", "styled-components": "^6.1.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d92bc0e40f3f38..26674d2961850b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -800,8 +800,8 @@ importers: specifier: ^4.4.5 version: 4.4.5(react-dom@18.2.0)(react@18.2.0) react-virtuoso: - specifier: ^4.6.2 - version: 4.6.2(react-dom@18.2.0)(react@18.2.0) + specifier: ^4.6.3 + version: 4.6.3(react-dom@18.2.0)(react@18.2.0) react-window: specifier: ^1.8.10 version: 1.8.10(react-dom@18.2.0)(react@18.2.0) @@ -18501,8 +18501,8 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /react-virtuoso@4.6.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-vvlqvzPif+MvBrJ09+hJJrVY0xJK9yran+A+/1iwY78k0YCVKsyoNPqoLxOxzYPggspNBNXqUXEcvckN29OxyQ==} + /react-virtuoso@4.6.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-NcoSsf4B0OCx7U8i2s+VWe8b9e+FWzcN/5ly4hKjErynBzGONbWORZ1C5amUlWrPi6+HbUQ2PjnT4OpyQIpP9A==} engines: {node: '>=10'} peerDependencies: react: '>=16 || >=17 || >= 18' From 8f4fef0cbfd1eb524c6abc605ab88857adcd3506 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:07:07 +0100 Subject: [PATCH 057/120] Bump typescript to ^5.3.3 (#40934) --- packages/docs-utils/package.json | 2 +- pnpm-lock.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docs-utils/package.json b/packages/docs-utils/package.json index 5054f175df2ef5..250f6e39bdeded 100644 --- a/packages/docs-utils/package.json +++ b/packages/docs-utils/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "rimraf": "^5.0.5", - "typescript": "^5.1.6" + "typescript": "^5.3.3" }, "publishConfig": { "access": "public" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 26674d2961850b..63f2dcfe3204dc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1031,7 +1031,7 @@ importers: specifier: ^5.0.5 version: 5.0.5 typescript: - specifier: ^5.1.6 + specifier: ^5.3.3 version: 5.3.3 packages/eslint-plugin-material-ui: From ef2f7b156669958de499ecb294e333977e113f29 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 11:08:44 +0100 Subject: [PATCH 058/120] Bump @definitelytyped/header-parser to ^0.2.2 (#40918) --- package.json | 2 +- pnpm-lock.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2338f39e395eb5..0d5301c393ef90 100644 --- a/package.json +++ b/package.json @@ -202,7 +202,7 @@ "@babel/preset-typescript": "^7.23.3", "@babel/runtime": "^7.23.9", "@babel/types": "^7.23.9", - "@definitelytyped/header-parser": "^0.2.1", + "@definitelytyped/header-parser": "^0.2.2", "@definitelytyped/typescript-versions": "^0.1.0", "@definitelytyped/utils": "^0.1.1", "@types/node": "^18.19.14", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 63f2dcfe3204dc..6835d0aee058a7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,7 +19,7 @@ overrides: '@babel/preset-typescript': ^7.23.3 '@babel/runtime': ^7.23.9 '@babel/types': ^7.23.9 - '@definitelytyped/header-parser': ^0.2.1 + '@definitelytyped/header-parser': ^0.2.2 '@definitelytyped/typescript-versions': ^0.1.0 '@definitelytyped/utils': ^0.1.1 '@types/node': ^18.19.14 From 0b38955227cf4fc879fea5c8d23e167a5b9c4936 Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Mon, 5 Feb 2024 05:53:53 -0500 Subject: [PATCH 059/120] [system] Add blend color manipulator (#40258) --- packages/mui-system/src/colorManipulator.d.ts | 1 + packages/mui-system/src/colorManipulator.js | 27 +++++++++++++++++++ .../mui-system/src/colorManipulator.test.js | 19 +++++++++++++ 3 files changed, 47 insertions(+) diff --git a/packages/mui-system/src/colorManipulator.d.ts b/packages/mui-system/src/colorManipulator.d.ts index b23b7f5dd39790..72520697a0eca5 100644 --- a/packages/mui-system/src/colorManipulator.d.ts +++ b/packages/mui-system/src/colorManipulator.d.ts @@ -27,3 +27,4 @@ export function darken(color: string, coefficient: number): string; export function private_safeDarken(color: string, coefficient: number, warning?: string): string; export function lighten(color: string, coefficient: number): string; export function private_safeLighten(color: string, coefficient: number, warning?: string): string; +export function blend(background: string, overlay: string, opacity: number, gamma?: number): string; diff --git a/packages/mui-system/src/colorManipulator.js b/packages/mui-system/src/colorManipulator.js index 1bbea01568563c..dc8960c9027847 100644 --- a/packages/mui-system/src/colorManipulator.js +++ b/packages/mui-system/src/colorManipulator.js @@ -348,3 +348,30 @@ export function private_safeEmphasize(color, coefficient, warning) { return color; } } + +/** + * Blend a transparent overlay color with a background color, resulting in a single + * RGB color. + * @param {string} background - CSS color + * @param {string} overlay - CSS color + * @param {number} opacity - Opacity multiplier in the range 0 - 1 + * @param {number} [gamma=1.0] - Gamma correction factor. For gamma-correct blending, 2.2 is usual. + */ +export function blend(background, overlay, opacity, gamma = 1.0) { + const blendChannel = (b, o) => + Math.round((b ** (1 / gamma) * (1 - opacity) + o ** (1 / gamma) * opacity) ** gamma); + + const backgroundColor = decomposeColor(background); + const overlayColor = decomposeColor(overlay); + + const rgb = [ + blendChannel(backgroundColor.values[0], overlayColor.values[0]), + blendChannel(backgroundColor.values[1], overlayColor.values[1]), + blendChannel(backgroundColor.values[2], overlayColor.values[2]), + ]; + + return recomposeColor({ + type: 'rgb', + values: rgb, + }); +} diff --git a/packages/mui-system/src/colorManipulator.test.js b/packages/mui-system/src/colorManipulator.test.js index 060d0f0117ee42..99ba4aaacf8aea 100644 --- a/packages/mui-system/src/colorManipulator.test.js +++ b/packages/mui-system/src/colorManipulator.test.js @@ -12,6 +12,7 @@ import { getLuminance, lighten, colorChannel, + blend, } from '@mui/system'; describe('utils/colorManipulator', () => { @@ -452,4 +453,22 @@ describe('utils/colorManipulator', () => { expect(colorChannel('hsla(235, 100%, 50%, .5)')).to.equal('235 100% 50%'); }); }); + + describe('blend', () => { + it('works', () => { + expect(blend('rgb(90, 90, 90)', 'rgb(10, 100, 255)', 0.5)).to.equal('rgb(50, 95, 173)'); + }); + + it('works with a gamma correction factor', () => { + expect(blend('rgb(90, 90, 90)', 'rgb(10, 100, 255)', 0.5, 2.2)).to.equal('rgb(39, 95, 161)'); + }); + + it('selects only the background color with an opacity of 0.0', () => { + expect(blend('rgb(90, 90, 90)', 'rgb(10, 100, 255)', 0.0)).to.equal('rgb(90, 90, 90)'); + }); + + it('selects only the overlay color with an opacity of 1.0', () => { + expect(blend('rgb(90, 90, 90)', 'rgb(10, 100, 255)', 1.0)).to.equal('rgb(10, 100, 255)'); + }); + }); }); From 96e8776949f53bb0e0cc4d22bcdd9735427ff265 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 14:37:36 +0100 Subject: [PATCH 060/120] Bump pnpm to 8.15.1 (#40932) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0d5301c393ef90..58efde1188a145 100644 --- a/package.json +++ b/package.json @@ -186,7 +186,7 @@ "webpack-cli": "^5.1.4", "yargs": "^17.7.2" }, - "packageManager": "pnpm@8.15.0", + "packageManager": "pnpm@8.15.1", "resolutions": { "@babel/core": "^7.23.9", "@babel/code-frame": "^7.23.5", From 30b16bac17a7e0bdbf7b3185e7f2ff48279bde6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dudak?= Date: Mon, 5 Feb 2024 14:48:02 +0100 Subject: [PATCH 061/120] [dependencies] Do not update envinfo test dependencies (#40950) --- renovate.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/renovate.json b/renovate.json index 2200b4ff4f69ff..a6e41949546972 100644 --- a/renovate.json +++ b/renovate.json @@ -105,6 +105,12 @@ { "groupName": "@definitelytyped tools", "matchPackagePatterns": ["@definitelytyped/*"] + }, + { + "groupName": "envinfo tests", + "matchPaths": ["packages/mui-envinfo/test/package.json"], + "matchPackagePatterns": ["@mui/*"], + "enabled": false } ], "postUpdateOptions": ["pnpmDedupe"], From 154920c7398baa6358c94a9d38d59a7c07031525 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Mon, 5 Feb 2024 20:36:11 +0100 Subject: [PATCH 062/120] =?UTF-8?q?[docs]=20Fix=20missing=20non=20breaking?= =?UTF-8?q?=20space=20Material=C2=A0UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../guides/material-3-components/material-3-components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/material/guides/material-3-components/material-3-components.md b/docs/data/material/guides/material-3-components/material-3-components.md index 63831f929e0c43..446b425c450b22 100644 --- a/docs/data/material/guides/material-3-components/material-3-components.md +++ b/docs/data/material/guides/material-3-components/material-3-components.md @@ -48,7 +48,7 @@ pnpm add @mui/material-next @emotion/react @emotion/styled -Please note that [react](https://www.npmjs.com/package/react) and [react-dom](https://www.npmjs.com/package/react-dom) are peer dependencies, meaning you should ensure they are installed before installing the Material UI Next package. +Please note that [react](https://www.npmjs.com/package/react) and [react-dom](https://www.npmjs.com/package/react-dom) are peer dependencies, meaning you should ensure they are installed before installing the Material UI Next package. ```json "peerDependencies": { From 0766bde7fb17ab1bf0ad5f27f3b6d8e9d7afaaae Mon Sep 17 00:00:00 2001 From: Victor Zanivan Monteiro Date: Mon, 5 Feb 2024 17:27:30 -0300 Subject: [PATCH 063/120] [material-ui] Replace the Album template with a landing page (#37557) Co-authored-by: Diego Andai Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Co-authored-by: siriwatknp --- .../getting-started/templates/album/Album.js | 137 ---- .../getting-started/templates/album/Album.tsx | 137 ---- .../templates/landing-page/LandingPage.js | 108 +++ .../templates/landing-page/LandingPage.tsx | 108 +++ .../{album => landing-page}/README.md | 6 +- .../landing-page/components/AppAppBar.js | 247 +++++++ .../landing-page/components/AppAppBar.tsx | 246 +++++++ .../templates/landing-page/components/FAQ.js | 149 +++++ .../templates/landing-page/components/FAQ.tsx | 150 +++++ .../landing-page/components/Features.js | 271 ++++++++ .../landing-page/components/Features.tsx | 271 ++++++++ .../landing-page/components/Footer.js | 220 ++++++ .../landing-page/components/Footer.tsx | 220 ++++++ .../templates/landing-page/components/Hero.js | 120 ++++ .../landing-page/components/Hero.tsx | 120 ++++ .../landing-page/components/Highlights.js | 123 ++++ .../landing-page/components/Highlights.tsx | 123 ++++ .../landing-page/components/LogoCollection.js | 59 ++ .../components/LogoCollection.tsx | 59 ++ .../landing-page/components/Pricing.js | 219 ++++++ .../landing-page/components/Pricing.tsx | 219 ++++++ .../landing-page/components/Testimonials.js | 143 ++++ .../landing-page/components/Testimonials.tsx | 143 ++++ .../components/ToggleColorMode.js | 35 + .../components/ToggleColorMode.tsx | 34 + .../templates/landing-page/getLPTheme.js | 614 +++++++++++++++++ .../templates/landing-page/getLPTheme.tsx | 633 ++++++++++++++++++ .../templates/{album.js => landing-page.js} | 4 +- docs/public/static/images/templates/album.png | Bin 33640 -> 0 bytes .../static/images/templates/dashboard.png | Bin 50500 -> 26574 bytes .../static/images/templates/landing-page.png | Bin 0 -> 30575 bytes .../templates/templates-images/dash-dark.png | Bin 0 -> 112650 bytes .../templates/templates-images/dash-light.png | Bin 0 -> 81835 bytes .../templates-images/devices-dark.png | Bin 0 -> 126874 bytes .../templates-images/devices-light.png | Bin 0 -> 94839 bytes .../templates/templates-images/hero-dark.png | Bin 0 -> 216776 bytes .../templates/templates-images/hero-light.png | Bin 0 -> 168563 bytes .../templates-images/mobile-dark.png | Bin 0 -> 53188 bytes .../templates-images/mobile-light.png | Bin 0 -> 33187 bytes .../MaterialFreeTemplatesCollection.js | 21 +- docs/translations/translations.json | 4 +- test/regressions/index.js | 3 +- 42 files changed, 4650 insertions(+), 296 deletions(-) delete mode 100644 docs/data/material/getting-started/templates/album/Album.js delete mode 100644 docs/data/material/getting-started/templates/album/Album.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/LandingPage.js create mode 100644 docs/data/material/getting-started/templates/landing-page/LandingPage.tsx rename docs/data/material/getting-started/templates/{album => landing-page}/README.md (81%) create mode 100644 docs/data/material/getting-started/templates/landing-page/components/AppAppBar.js create mode 100644 docs/data/material/getting-started/templates/landing-page/components/AppAppBar.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/components/FAQ.js create mode 100644 docs/data/material/getting-started/templates/landing-page/components/FAQ.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Features.js create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Features.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Footer.js create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Footer.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Hero.js create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Hero.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Highlights.js create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Highlights.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/components/LogoCollection.js create mode 100644 docs/data/material/getting-started/templates/landing-page/components/LogoCollection.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Pricing.js create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Pricing.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Testimonials.js create mode 100644 docs/data/material/getting-started/templates/landing-page/components/Testimonials.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/components/ToggleColorMode.js create mode 100644 docs/data/material/getting-started/templates/landing-page/components/ToggleColorMode.tsx create mode 100644 docs/data/material/getting-started/templates/landing-page/getLPTheme.js create mode 100644 docs/data/material/getting-started/templates/landing-page/getLPTheme.tsx rename docs/pages/material-ui/getting-started/templates/{album.js => landing-page.js} (59%) delete mode 100644 docs/public/static/images/templates/album.png create mode 100644 docs/public/static/images/templates/landing-page.png create mode 100644 docs/public/static/images/templates/templates-images/dash-dark.png create mode 100644 docs/public/static/images/templates/templates-images/dash-light.png create mode 100644 docs/public/static/images/templates/templates-images/devices-dark.png create mode 100644 docs/public/static/images/templates/templates-images/devices-light.png create mode 100644 docs/public/static/images/templates/templates-images/hero-dark.png create mode 100644 docs/public/static/images/templates/templates-images/hero-light.png create mode 100644 docs/public/static/images/templates/templates-images/mobile-dark.png create mode 100644 docs/public/static/images/templates/templates-images/mobile-light.png diff --git a/docs/data/material/getting-started/templates/album/Album.js b/docs/data/material/getting-started/templates/album/Album.js deleted file mode 100644 index 6e4f02951c5805..00000000000000 --- a/docs/data/material/getting-started/templates/album/Album.js +++ /dev/null @@ -1,137 +0,0 @@ -import * as React from 'react'; -import AppBar from '@mui/material/AppBar'; -import Button from '@mui/material/Button'; -import CameraIcon from '@mui/icons-material/PhotoCamera'; -import Card from '@mui/material/Card'; -import CardActions from '@mui/material/CardActions'; -import CardContent from '@mui/material/CardContent'; -import CardMedia from '@mui/material/CardMedia'; -import CssBaseline from '@mui/material/CssBaseline'; -import Grid from '@mui/material/Grid'; -import Stack from '@mui/material/Stack'; -import Box from '@mui/material/Box'; -import Toolbar from '@mui/material/Toolbar'; -import Typography from '@mui/material/Typography'; -import Container from '@mui/material/Container'; -import Link from '@mui/material/Link'; -import { createTheme, ThemeProvider } from '@mui/material/styles'; - -function Copyright() { - return ( - - {'Copyright © '} - - Your Website - {' '} - {new Date().getFullYear()} - {'.'} - - ); -} - -const cards = [1, 2, 3, 4, 5, 6, 7, 8, 9]; - -// TODO remove, this demo shouldn't need to reset the theme. -const defaultTheme = createTheme(); - -export default function Album() { - return ( - - - - - - - Album layout - - - -
- {/* Hero unit */} - - - - Album layout - - - Something short and leading about the collection below—its contents, - the creator, etc. Make it short and sweet, but not too short so folks - don't simply skip over it entirely. - - - - - - - - - {/* End hero unit */} - - {cards.map((card) => ( - - - - - - Heading - - - This is a media card. You can use this section to describe the - content. - - - - - - - - - ))} - - -
- {/* Footer */} - - - Footer - - - Something here to give the footer a purpose! - - - - {/* End footer */} -
- ); -} diff --git a/docs/data/material/getting-started/templates/album/Album.tsx b/docs/data/material/getting-started/templates/album/Album.tsx deleted file mode 100644 index 6e4f02951c5805..00000000000000 --- a/docs/data/material/getting-started/templates/album/Album.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import * as React from 'react'; -import AppBar from '@mui/material/AppBar'; -import Button from '@mui/material/Button'; -import CameraIcon from '@mui/icons-material/PhotoCamera'; -import Card from '@mui/material/Card'; -import CardActions from '@mui/material/CardActions'; -import CardContent from '@mui/material/CardContent'; -import CardMedia from '@mui/material/CardMedia'; -import CssBaseline from '@mui/material/CssBaseline'; -import Grid from '@mui/material/Grid'; -import Stack from '@mui/material/Stack'; -import Box from '@mui/material/Box'; -import Toolbar from '@mui/material/Toolbar'; -import Typography from '@mui/material/Typography'; -import Container from '@mui/material/Container'; -import Link from '@mui/material/Link'; -import { createTheme, ThemeProvider } from '@mui/material/styles'; - -function Copyright() { - return ( - - {'Copyright © '} - - Your Website - {' '} - {new Date().getFullYear()} - {'.'} - - ); -} - -const cards = [1, 2, 3, 4, 5, 6, 7, 8, 9]; - -// TODO remove, this demo shouldn't need to reset the theme. -const defaultTheme = createTheme(); - -export default function Album() { - return ( - - - - - - - Album layout - - - -
- {/* Hero unit */} - - - - Album layout - - - Something short and leading about the collection below—its contents, - the creator, etc. Make it short and sweet, but not too short so folks - don't simply skip over it entirely. - - - - - - - - - {/* End hero unit */} - - {cards.map((card) => ( - - - - - - Heading - - - This is a media card. You can use this section to describe the - content. - - - - - - - - - ))} - - -
- {/* Footer */} - - - Footer - - - Something here to give the footer a purpose! - - - - {/* End footer */} -
- ); -} diff --git a/docs/data/material/getting-started/templates/landing-page/LandingPage.js b/docs/data/material/getting-started/templates/landing-page/LandingPage.js new file mode 100644 index 00000000000000..470c1ae6cea57d --- /dev/null +++ b/docs/data/material/getting-started/templates/landing-page/LandingPage.js @@ -0,0 +1,108 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; + +import CssBaseline from '@mui/material/CssBaseline'; +import Box from '@mui/material/Box'; +import Divider from '@mui/material/Divider'; +import { ThemeProvider, createTheme } from '@mui/material/styles'; +import ToggleButton from '@mui/material/ToggleButton'; +import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; +import AutoAwesomeRoundedIcon from '@mui/icons-material/AutoAwesomeRounded'; +import SvgMaterialDesign from 'docs/src/icons/SvgMaterialDesign'; +import AppAppBar from './components/AppAppBar'; +import Hero from './components/Hero'; +import LogoCollection from './components/LogoCollection'; +import Highlights from './components/Highlights'; +import Pricing from './components/Pricing'; +import Features from './components/Features'; +import Testimonials from './components/Testimonials'; +import FAQ from './components/FAQ'; +import Footer from './components/Footer'; +import getLPTheme from './getLPTheme'; + +const defaultTheme = createTheme({}); + +function ToggleCustomTheme({ showCustomTheme, toggleCustomTheme }) { + return ( + + + + + Custom theme + + + + Material Design + + + + ); +} + +ToggleCustomTheme.propTypes = { + showCustomTheme: PropTypes.shape({ + valueOf: PropTypes.func.isRequired, + }).isRequired, + toggleCustomTheme: PropTypes.func.isRequired, +}; + +export default function LandingPage() { + const [mode, setMode] = React.useState('dark'); + const [showCustomTheme, setShowCustomTheme] = React.useState(true); + const LPtheme = createTheme(getLPTheme(mode)); + + const toggleColorMode = () => { + setMode((prev) => (prev === 'dark' ? 'light' : 'dark')); + }; + + const toggleCustomTheme = () => { + setShowCustomTheme((prev) => !prev); + }; + + return ( + + + + + + + + + + + + + + + + +