From aeef0e2f4356879d3905014002be058f4d1f6494 Mon Sep 17 00:00:00 2001 From: Sam Sycamore <71297412+samuelsycamore@users.noreply.github.com> Date: Wed, 2 Nov 2022 12:38:30 -0500 Subject: [PATCH 01/25] create base page --- .../customization/customization.md | 10 +-- docs/data/base/getting-started/usage/usage.md | 78 ------------------ .../overriding-component-structure.md | 81 +++++++++++++++++++ docs/data/base/pages.ts | 4 + .../guides/overriding-component-structure.js | 7 ++ 5 files changed, 97 insertions(+), 83 deletions(-) create mode 100644 docs/data/base/guides/overriding-component-structure/overriding-component-structure.md create mode 100644 docs/pages/base/guides/overriding-component-structure.js diff --git a/docs/data/base/getting-started/customization/customization.md b/docs/data/base/getting-started/customization/customization.md index 9de2bf02c97d69..b0d12e7d50c203 100644 --- a/docs/data/base/getting-started/customization/customization.md +++ b/docs/data/base/getting-started/customization/customization.md @@ -4,7 +4,7 @@ With MUI Base, you have the freedom to decide how much you want to customize a component's structure and style. -This document reviews the three levels of customization that are available: applying custom CSS rules, overriding default subcomponent slots, and using hooks to build fully custom components. +This document reviews the three levels of customization that are available: applying custom CSS rules, overriding the default component structure, and using hooks to build fully custom components. ## Applying custom CSS rules @@ -19,11 +19,11 @@ Additionally, you can import a `[componentName]Classes` object that describes al {{"demo": "StylingCustomCss.js", "defaultCodeOpen": true}} -## Overriding subcomponent slots +## Overriding the default structure -If you want to make changes to a component's rendered HTML structure, you can override the default subcomponents ("slots") using the `slots` and/or `component` prop—see ["Shared props" on the Base Usage page](/base/getting-started/usage/#shared-props) for more details. +If you want to make changes to a component's rendered HTML structure, you can override the default subcomponents ("slots") using the `slots` and/or `component` prop—see the guide on [Overriding component structure](/base/guides/overriding-component-structure/) for more details. -The following demo uses [SwitchUnstyled](/base/react-switch/) to show how to create a styled component by applying styles to three of its subcomponent slots: `root`, `thumb`, and `input`. +The following demo uses the [Unstyled Switch](/base/react-switch/) to show how to create a styled component by applying styles to three of its subcomponent slots: `root`, `thumb`, and `input`. Note that although this demo uses [MUI System](/system/styled/) as a styling solution, you are free to choose any alternative. @@ -61,7 +61,7 @@ See ["Components vs. hooks" on the Base Usage page](/base/getting-started/usage/ Hooks return the current state of the component (e.g. `checked`, `disabled`, `open`, etc.) and provide functions that return props you can apply to your fully custom components. -In the case of [SwitchUnstyled](/base/react-switch/), the component is accompanied by the `useSwitch` hook which gives you all of the functionality without any structure. +In the case of the [Unstyled Switch](/base/react-switch/), the component is accompanied by the `useSwitch` hook which gives you all of the functionality without any structure. It returns the following object: diff --git a/docs/data/base/getting-started/usage/usage.md b/docs/data/base/getting-started/usage/usage.md index 8b3709956e3d57..984bf322a6aa81 100644 --- a/docs/data/base/getting-started/usage/usage.md +++ b/docs/data/base/getting-started/usage/usage.md @@ -34,84 +34,6 @@ To ensure proper rendering and touch zooming for all devices, add the responsive ``` -## Shared props - -Base components are self-supporting and fully functional in isolation. - -Each component has its own unique API, but all _non-utility_ components accept the following shared props: - -### slots - -The `slots` prop is an object that lets you override any interior subcomponents—known as **slots**—of the base component itself. - -:::info -Each component contains a root slot, and other appropriate slots based on the nature of the component. -For example, the Unstyled Badge contains two slots: - -- `root`: the container element that wraps the children. -- `badge`: the badge element itself. - ::: - -You can use the `slots` prop to override default slots with either custom components or HTML elements. - -For example, the Unstyled Badge component renders a `` by default. -The code snippet below shows how to override this by assigning a `
` to the root slot: - -```jsx - -``` - -### component - -The `component` prop provides a shortcut to `slots.root`. -This is useful if you are only overriding the root element of the component. - -The code snippet below shows how to override the root element of the Unstyled Badge component using the `component` prop: - -```jsx - -``` - -:::warning -If the root slot is customized with both the `component` and `slots` props, then `component` will take precedence. -::: - -### slotProps - -The `slotProps` prop is an object that contains the props for all slots within a component. -You can use it to define additional custom props for a component's interior elements. - -For example, the code snippet below shows how to add a custom CSS class to the badge slot of the Unstyled Badge component: - -```jsx - -``` - -All additional props placed on the primary component are also propagated into the root slot (just as if they were placed in `slotProps.root`). - -These two examples are equivalent: - -```jsx - -``` - -```jsx - -``` - -:::warning -If both `slotProps.root` and additional props have the same keys but different values, the `slotProps.root` props will take precedence. -This does not apply to classes or the `style` prop—they will be merged instead. -::: - -### Best practices - -If you are customizing a component like the [Unstyled Button](/base/react-button/) that only has a root slot, you may prefer to use the more succinct `component` prop instead of `slots`. - -Overriding with `component` lets you apply the attributes of that element directly to the root. -For instance, if you replace the Unstyled Button root with an `
  • ` tag, you can add the `
  • ` attribute `value` directly to the component. -If you did the same with `slots.root`, you would need to place this attribute on the `slotProps.root` object in order to avoid a TypeScript error. - ## Components vs. hooks MUI Base includes two kinds of building blocks: **components** and **hooks**. diff --git a/docs/data/base/guides/overriding-component-structure/overriding-component-structure.md b/docs/data/base/guides/overriding-component-structure/overriding-component-structure.md new file mode 100644 index 00000000000000..812a0b130d95cd --- /dev/null +++ b/docs/data/base/guides/overriding-component-structure/overriding-component-structure.md @@ -0,0 +1,81 @@ +# Overriding component structure + +

    Overriding component structure.

    + +## Shared props + +Base components are self-supporting and fully functional in isolation. + +Each component has its own unique API, but all _non-utility_ components accept the following shared props: + +### slots + +The `slots` prop is an object that lets you override any interior subcomponents—known as **slots**—of the base component itself. + +:::info +Each component contains a root slot, and other appropriate slots based on the nature of the component. +For example, the Unstyled Badge contains two slots: + +- `root`: the container element that wraps the children. +- `badge`: the badge element itself. + ::: + +You can use the `slots` prop to override default slots with either custom components or HTML elements. + +For example, the Unstyled Badge component renders a `` by default. +The code snippet below shows how to override this by assigning a `
    ` to the root slot: + +```jsx + +``` + +### component + +The `component` prop provides a shortcut to `slots.root`. +This is useful if you are only overriding the root element of the component. + +The code snippet below shows how to override the root element of the Unstyled Badge component using the `component` prop: + +```jsx + +``` + +:::warning +If the root slot is customized with both the `component` and `slots` props, then `component` will take precedence. +::: + +### slotProps + +The `slotProps` prop is an object that contains the props for all slots within a component. +You can use it to define additional custom props for a component's interior elements. + +For example, the code snippet below shows how to add a custom CSS class to the badge slot of the Unstyled Badge component: + +```jsx + +``` + +All additional props placed on the primary component are also propagated into the root slot (just as if they were placed in `slotProps.root`). + +These two examples are equivalent: + +```jsx + +``` + +```jsx + +``` + +:::warning +If both `slotProps.root` and additional props have the same keys but different values, the `slotProps.root` props will take precedence. +This does not apply to classes or the `style` prop—they will be merged instead. +::: + +### Best practices + +If you are customizing a component like the [Unstyled Button](/base/react-button/) that only has a root slot, you may prefer to use the more succinct `component` prop instead of `slots`. + +Overriding with `component` lets you apply the attributes of that element directly to the root. +For instance, if you replace the Unstyled Button root with an `
  • ` tag, you can add the `
  • ` attribute `value` directly to the component. +If you did the same with `slots.root`, you would need to place this attribute on the `slotProps.root` object in order to avoid a TypeScript error. diff --git a/docs/data/base/pages.ts b/docs/data/base/pages.ts index 686b29f4b82b76..d2806f5e76e2d8 100644 --- a/docs/data/base/pages.ts +++ b/docs/data/base/pages.ts @@ -87,6 +87,10 @@ const pages = [ pathname: '/base/guides/working-with-tailwind-css', title: 'Working with Tailwind CSS', }, + { + pathname: '/base/guides/overriding-component-structure', + title: 'Overriding component structure', + }, ], }, ]; diff --git a/docs/pages/base/guides/overriding-component-structure.js b/docs/pages/base/guides/overriding-component-structure.js new file mode 100644 index 00000000000000..5a1ea2d8c934f1 --- /dev/null +++ b/docs/pages/base/guides/overriding-component-structure.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docs/data/base/guides/overriding-component-structure/overriding-component-structure.md?@mui/markdown'; + +export default function Page() { + return ; +} From e5bb57b745a70ab909b7df366b4ca594582e42bf Mon Sep 17 00:00:00 2001 From: Sam Sycamore <71297412+samuelsycamore@users.noreply.github.com> Date: Wed, 2 Nov 2022 13:53:48 -0500 Subject: [PATCH 02/25] base doc first pass --- .../overriding-component-structure.md | 80 ++++++++++++------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/docs/data/base/guides/overriding-component-structure/overriding-component-structure.md b/docs/data/base/guides/overriding-component-structure/overriding-component-structure.md index 812a0b130d95cd..ab13f6e50311d4 100644 --- a/docs/data/base/guides/overriding-component-structure/overriding-component-structure.md +++ b/docs/data/base/guides/overriding-component-structure/overriding-component-structure.md @@ -2,61 +2,82 @@

    Overriding component structure.

    -## Shared props +All _non-utility_ MUI Base components accept two props for overriding their rendered HTML structure: -Base components are self-supporting and fully functional in isolation. +- `component`—to override the root slot +- `slots`—to override any interior slots (when present) -Each component has its own unique API, but all _non-utility_ components accept the following shared props: +Additionally, you can pass custom props to interior slots using `slotProps`. -### slots +## The root slot -The `slots` prop is an object that lets you override any interior subcomponents—known as **slots**—of the base component itself. +The root slot represents the component's "primary" element. +For simpler components, the root slot is often filled by the native HTML element the component is intended to replace. + +For example, the [Unstyled Button's](/base/react-button/) root slot is a `; +} diff --git a/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx b/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx new file mode 100644 index 00000000000000..623ce7485fd488 --- /dev/null +++ b/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx @@ -0,0 +1,8 @@ +import * as React from 'react'; +import Button from '@mui/joy/Button'; + +export default function DivButton() { + return ( + + ); +} diff --git a/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx.preview b/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx.preview new file mode 100644 index 00000000000000..1a3d44bd97a2fa --- /dev/null +++ b/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md b/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md index fc4cfc425dbfa1..73865901116ff9 100644 --- a/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md +++ b/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md @@ -4,7 +4,7 @@ Joy UI components are designed to suit the widest possible range of use cases, but you may occasionally need to change how a component's structure is rendered in the DOM. -To understand how to do this, it helps to have an accurate mental model of Joy UI components. +To understand how to do this, it helps to have an accurate mental model of MUI components. ## The mental model @@ -28,17 +28,17 @@ For simpler components, the root slot is often filled by the native HTML element For example, the [Button's](/joy-ui/react-button/) root slot is a ` - ); + return ; } diff --git a/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md b/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md index 73865901116ff9..3910203fb7248b 100644 --- a/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md +++ b/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md @@ -28,7 +28,6 @@ For simpler components, the root slot is often filled by the native HTML element For example, the [Button's](/joy-ui/react-button/) root slot is a `; + return ( + + ); } diff --git a/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx b/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx index 7d715d2347fa71..d3199709507c20 100644 --- a/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx +++ b/docs/data/joy/guides/overriding-component-structure/OverridingRootSlot.tsx @@ -2,5 +2,14 @@ import * as React from 'react'; import Button from '@mui/joy/Button'; export default function DivButton() { - return ; + return ( + + ); } diff --git a/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md b/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md index 371d0d1e6d5a4a..667f7f7035295b 100644 --- a/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md +++ b/docs/data/joy/guides/overriding-component-structure/overriding-component-structure.md @@ -16,14 +16,13 @@ All components contain a root slot that defines their primary node in the DOM tr All _non-utility_ Joy UI components accept two props for overriding their rendered HTML structure: - `component`—to override the root slot -- `slots`—to override any interior slots (when present) as well as the root +- `slots`—to replace any interior slots (when present) as well as the root Additionally, you can pass custom props to interior slots using `slotProps`. ## The root slot -The root slot represents the component's outermost element. -For simpler components, the root slot is often filled by the native HTML element that the component is intended to replace. +The root slot represents the component's outermost element. It is filled by a styled component with an appropriate HTML element. For example, the [Button's](/joy-ui/react-button/) root slot is a `