diff --git a/beta/src/components/Breadcrumbs.tsx b/beta/src/components/Breadcrumbs.tsx index beed182a4..9bd630b12 100644 --- a/beta/src/components/Breadcrumbs.tsx +++ b/beta/src/components/Breadcrumbs.tsx @@ -10,7 +10,7 @@ function Breadcrumbs() { const {breadcrumbs} = useRouteMeta(); if (!breadcrumbs) return null; return ( -
+
{breadcrumbs.map( (crumb, i) => crumb.path && ( diff --git a/beta/src/components/MDX/ConsoleBlock.tsx b/beta/src/components/MDX/ConsoleBlock.tsx index a5e68cead..2ec393f03 100644 --- a/beta/src/components/MDX/ConsoleBlock.tsx +++ b/beta/src/components/MDX/ConsoleBlock.tsx @@ -58,7 +58,8 @@ function ConsoleBlock({level = 'error', children}: ConsoleBlockProps) { className={cn( 'flex px-4 pt-4 pb-6 items-center content-center font-mono text-code rounded-b-md', { - 'bg-red-30 text-red-40 bg-opacity-10': level === 'error', + 'bg-red-30 text-red-50 dark:text-red-30 bg-opacity-5': + level === 'error', 'bg-yellow-5 text-yellow-50': level === 'warning', 'bg-gray-5 text-secondary dark:text-secondary-dark': level === 'info', diff --git a/beta/src/components/MDX/Sandpack/Console.tsx b/beta/src/components/MDX/Sandpack/Console.tsx index 375a92f0b..23194c870 100644 --- a/beta/src/components/MDX/Sandpack/Console.tsx +++ b/beta/src/components/MDX/Sandpack/Console.tsx @@ -109,6 +109,9 @@ export const SandpackConsole = ({visible}: {visible: boolean}) => { setLogs((prev) => { const newLogs = message.log .filter((consoleData) => { + if (!consoleData.method) { + return false; + } if ( typeof consoleData.data[0] === 'string' && consoleData.data[0].indexOf('The above error occurred') !== -1 diff --git a/beta/src/components/MDX/Sandpack/SandpackRoot.tsx b/beta/src/components/MDX/Sandpack/SandpackRoot.tsx index cb5d50963..4b3f41527 100644 --- a/beta/src/components/MDX/Sandpack/SandpackRoot.tsx +++ b/beta/src/components/MDX/Sandpack/SandpackRoot.tsx @@ -74,7 +74,7 @@ function SandpackRoot(props: SandpackProps) { files['/styles.css'] = { code: [sandboxStyle, files['/styles.css']?.code ?? ''].join('\n\n'), - hidden: true, + hidden: !files['/styles.css']?.visible, }; return ( diff --git a/beta/src/content/apis/react-dom/components/common.md b/beta/src/content/apis/react-dom/components/common.md new file mode 100644 index 000000000..15311754c --- /dev/null +++ b/beta/src/content/apis/react-dom/components/common.md @@ -0,0 +1,1180 @@ +--- +title: "Common components (e.g.
)" +--- + + + +All built-in browser components, such as [`
`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div), support some common props and events. + + + + + +--- + +## Usage {/*usage*/} + +### Applying CSS styles {/*applying-css-styles*/} + +In React, you specify a CSS class with [`className`.](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) It works like the `class` attribute in HTML: + +```js + +``` + +Then you write the CSS rules for it in a separate CSS file: + +```css +/* In your CSS */ +.avatar { + border-radius: 50%; +} +``` + +React does not prescribe how you add CSS files. In the simplest case, you'll add a [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link) tag to your HTML. If you use a build tool or a framework, consult its documentation to learn how to add a CSS file to your project. + +Sometimes, the style values depend on data. Use the `style` attribute to pass some styles dynamically: + +```js {3-6} + +``` + + +In the above example, `style={{}}` is not a special syntax, but a regular `{}` object inside the `style={ }` [JSX curly braces.](/learn/javascript-in-jsx-with-curly-braces) We recommend to only use the `style` attribute when your styles depend on JavaScript variables. + + + +```js App.js +import Avatar from './Avatar.js'; + +const user = { + name: 'Hedy Lamarr', + imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg', + imageSize: 90, +}; + +export default function App() { + return ; +} +``` + +```js Avatar.js active +export default function Avatar({ user }) { + return ( + {'Photo + ); +} +``` + +```css styles.css +.avatar { + border-radius: 50%; +} +``` + + + + + +#### How to apply multiple CSS classes conditionally? {/*how-to-apply-multiple-css-classes-conditionally*/} + +To apply CSS classes conditionally, you need to produce the `className` string yourself using JavaScript. + +For example, `className={'row ' + (isSelected ? 'selected': '')}` will produce either `className="row"` or `className="row selected"` depending on whether `isSelected` is `true`. + +To make this more readable, you can use a tiny helper library like [`classnames`:](https://github.com/JedWatson/classnames) + +```js +import cn from 'classnames'; + +function Row({ isSelected }) { + return ( +
+ ... +
+ ); +} +``` + +It is especially convenient if you have multiple conditional classes: + +```js +import cn from 'classnames'; + +function Row({ isSelected, size }) { + return ( +
+ ... +
+ ); +} +``` + +
+ +--- + +### Manipulating a DOM node with a ref {/*manipulating-a-dom-node-with-a-ref*/} + +Sometimes, you'll need to get the browser DOM node associated with a tag in JSX. For example, if you want to focus an `` when a button is clicked, you need to call [`focus()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on the browser `` DOM node. + +To obtain the browser DOM node for a tag, [declare a ref](/apis/react/useRef) and pass it as the `ref` attribute to that tag: + +```js {7} +import { useRef } from 'react'; + +export default function Form() { + const inputRef = useRef(null); + // ... + return ( + + // ... +``` + +React will put the DOM node into `inputRef.current` after it's been rendered to the screen. + + + +```js +import { useRef } from 'react'; + +export default function Form() { + const inputRef = useRef(null); + + function handleClick() { + inputRef.current.focus(); + } + + return ( + <> + + + + ); +} +``` + + + +Read more about [manipulating DOM with refs](/learn/manipulating-the-dom-with-refs) and [check out more examples.](/apis/react/useRef#examples-dom) + +For more advanced use cases, the `ref` attribute also accepts a [callback function.](#ref-callback) + +--- + +### Dangerously setting the inner HTML {/*dangerously-setting-the-inner-html*/} + +You can pass a raw HTML string to an element like so: + +```js +const markup = { __html: '

some raw html

' }; +return
; +``` + +**This is dangerous. As with the underlying DOM [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) property, you must exercise extreme caution! Unless the markup is coming from a completely trusted source, it is trivial to introduce an [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) vulnerability this way.** + +For example, if you use a Markdown library that converts Markdown to HTML, you trust that its parser doesn't contain bugs, and the user only sees their own input, you can display the resulting HTML like this: + + + +```js +import { useState } from 'react'; +import MarkdownPreview from './MarkdownPreview.js'; + +export default function MarkdownEditor() { + const [postContent, setPostContent] = useState('_Hello,_ **Markdown**!'); + return ( + <> +