diff --git a/packages/dev/s2-docs/pages/react-aria/Button.mdx b/packages/dev/s2-docs/pages/react-aria/Button.mdx index adfb0be0c48..be228def8ca 100644 --- a/packages/dev/s2-docs/pages/react-aria/Button.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Button.mdx @@ -34,7 +34,7 @@ export const relatedPages = [{'title': 'useButton', 'url': 'https://react-spectr props={['variant', 'isPending', 'isDisabled']} initialProps={{children: 'Press me'}} type="tailwind" - files={["starters/tailwind/src/Button.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/Button.tsx"]} /> {/* + files={["starters/tailwind/src/Calendar.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/Checkbox.mdx b/packages/dev/s2-docs/pages/react-aria/Checkbox.mdx index b6b324bd59b..8a95dae82bd 100644 --- a/packages/dev/s2-docs/pages/react-aria/Checkbox.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Checkbox.mdx @@ -30,7 +30,7 @@ export const relatedPages = [{'title': 'useCheckbox', 'url': 'https://react-spec props={['children', 'isIndeterminate', 'isDisabled']} initialProps={{children: 'Remember me'}} type="tailwind" - files={["starters/tailwind/src/Checkbox.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/Checkbox.tsx"]} /> ## Selection diff --git a/packages/dev/s2-docs/pages/react-aria/ColorArea.mdx b/packages/dev/s2-docs/pages/react-aria/ColorArea.mdx index faca3a07e92..84045da46b0 100644 --- a/packages/dev/s2-docs/pages/react-aria/ColorArea.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ColorArea.mdx @@ -30,7 +30,7 @@ export const relatedPages = [{'title': 'useColorArea', 'url': 'https://react-spe props={['colorSpace', 'xChannel', 'yChannel', 'isDisabled']} initialProps={{defaultValue: 'hsl(0, 100%, 50%)'}} type="tailwind" - files={["starters/tailwind/src/ColorArea.tsx", "starters/tailwind/src/ColorThumb.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/ColorArea.tsx", "starters/tailwind/src/ColorThumb.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/ColorField.mdx b/packages/dev/s2-docs/pages/react-aria/ColorField.mdx index 188b81acbba..ff8079cbdc4 100644 --- a/packages/dev/s2-docs/pages/react-aria/ColorField.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ColorField.mdx @@ -31,7 +31,7 @@ export const relatedPages = [{'title': 'useColorField', 'url': 'https://react-sp props={['label', 'colorSpace', 'channel', 'description', 'isDisabled']} initialProps={{label: 'Color', defaultValue: '#ff0000', placeholder: 'Enter a color'}} type="tailwind" - files={["starters/tailwind/src/ColorField.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/ColorField.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/ColorPicker.mdx b/packages/dev/s2-docs/pages/react-aria/ColorPicker.mdx index 48a3782c621..5697e70a219 100644 --- a/packages/dev/s2-docs/pages/react-aria/ColorPicker.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ColorPicker.mdx @@ -30,7 +30,7 @@ export const relatedPages = [{'title': 'useColorPicker', 'url': 'https://react-s props={['label']} initialProps={{label: 'Fill', defaultValue: '#5100FF'}} type="tailwind" - files={["starters/tailwind/src/ColorPicker.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/ColorPicker.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/ColorSlider.mdx b/packages/dev/s2-docs/pages/react-aria/ColorSlider.mdx index 0fdd07abf66..5f46bb4afa7 100644 --- a/packages/dev/s2-docs/pages/react-aria/ColorSlider.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ColorSlider.mdx @@ -31,7 +31,7 @@ export const relatedPages = [{'title': 'useColorSlider', 'url': 'https://react-s props={['label', 'colorSpace', 'channel', 'orientation', 'isDisabled']} initialProps={{channel: 'hue', defaultValue: 'hsl(0, 100%, 50%)'}} type="tailwind" - files={["starters/tailwind/src/ColorSlider.tsx", "starters/tailwind/src/ColorThumb.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/ColorSlider.tsx", "starters/tailwind/src/ColorThumb.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/ColorSwatch.mdx b/packages/dev/s2-docs/pages/react-aria/ColorSwatch.mdx index a80791aba13..9ece1c24401 100644 --- a/packages/dev/s2-docs/pages/react-aria/ColorSwatch.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ColorSwatch.mdx @@ -30,7 +30,7 @@ export const relatedPages = [{'title': 'useColorSwatch', 'url': 'https://react-s props={[]} initialProps={{color: '#f00'}} type="tailwind" - files={["starters/tailwind/src/ColorSwatch.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/ColorSwatch.tsx"]} /> ## Accessibility diff --git a/packages/dev/s2-docs/pages/react-aria/ColorWheel.mdx b/packages/dev/s2-docs/pages/react-aria/ColorWheel.mdx index c74728a28d8..f64cb81dd6e 100644 --- a/packages/dev/s2-docs/pages/react-aria/ColorWheel.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ColorWheel.mdx @@ -28,7 +28,7 @@ export const relatedPages = [{'title': 'useColorWheel', 'url': 'https://react-sp links={docs.links} props={['isDisabled']} type="tailwind" - files={["starters/tailwind/src/ColorWheel.tsx", "starters/tailwind/src/ColorThumb.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/ColorWheel.tsx", "starters/tailwind/src/ColorThumb.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/DateField.mdx b/packages/dev/s2-docs/pages/react-aria/DateField.mdx index 8bca35de1ac..9a096bf5c72 100644 --- a/packages/dev/s2-docs/pages/react-aria/DateField.mdx +++ b/packages/dev/s2-docs/pages/react-aria/DateField.mdx @@ -31,7 +31,7 @@ export const relatedPages = [{'title': 'useDateField', 'url': 'https://react-spe props={['label', 'granularity', 'isDisabled']} initialProps={{label: 'Date'}} type="tailwind" - files={["starters/tailwind/src/DateField.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/DateField.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/Link.mdx b/packages/dev/s2-docs/pages/react-aria/Link.mdx index 2e9c5308a2c..a8592ce551c 100644 --- a/packages/dev/s2-docs/pages/react-aria/Link.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Link.mdx @@ -30,7 +30,7 @@ export const relatedPages = [{'title': 'useLink', 'url': 'https://react-spectrum props={['children', 'variant', 'isDisabled']} initialProps={{children: 'The missing link', href: 'https://www.imdb.com/title/tt6348138/', target: '_blank'}} type="tailwind" - files={["starters/tailwind/src/Link.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/Link.tsx"]} /> ## Events diff --git a/packages/dev/s2-docs/pages/react-aria/RangeCalendar.mdx b/packages/dev/s2-docs/pages/react-aria/RangeCalendar.mdx index c9407ede315..0967abe328d 100644 --- a/packages/dev/s2-docs/pages/react-aria/RangeCalendar.mdx +++ b/packages/dev/s2-docs/pages/react-aria/RangeCalendar.mdx @@ -29,7 +29,7 @@ export const relatedPages = [{'title': 'useRangeCalendar', 'url': 'https://react links={vanillaDocs.links} props={['isDisabled']} type="tailwind" - files={["starters/tailwind/src/RangeCalendar.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/RangeCalendar.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/SearchField.mdx b/packages/dev/s2-docs/pages/react-aria/SearchField.mdx index 325f2a2383a..ed5f120338e 100644 --- a/packages/dev/s2-docs/pages/react-aria/SearchField.mdx +++ b/packages/dev/s2-docs/pages/react-aria/SearchField.mdx @@ -31,7 +31,7 @@ export const relatedPages = [{'title': 'useSearchField', 'url': 'https://react-s props={['label', 'description', 'isDisabled']} initialProps={{label: 'Search', placeholder: 'Search documents'}} type="tailwind" - files={["starters/tailwind/src/SearchField.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/SearchField.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/Switch.mdx b/packages/dev/s2-docs/pages/react-aria/Switch.mdx index 16f0cfe7f79..fb452c06c5e 100644 --- a/packages/dev/s2-docs/pages/react-aria/Switch.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Switch.mdx @@ -30,7 +30,7 @@ export const relatedPages = [{'title': 'useSwitch', 'url': 'https://react-spectr props={['children', 'isDisabled']} initialProps={{children: 'Low power mode'}} type="tailwind" - files={["starters/tailwind/src/Switch.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/Switch.tsx"]} /> ## Selection diff --git a/packages/dev/s2-docs/pages/react-aria/TextField.mdx b/packages/dev/s2-docs/pages/react-aria/TextField.mdx index 27d21212395..bd2629eb852 100644 --- a/packages/dev/s2-docs/pages/react-aria/TextField.mdx +++ b/packages/dev/s2-docs/pages/react-aria/TextField.mdx @@ -31,7 +31,7 @@ export const relatedPages = [{'title': 'useTextField', 'url': 'https://react-spe props={['label', 'description', 'isReadOnly', 'isDisabled']} initialProps={{label: 'Name', placeholder: 'Enter your full name'}} type="tailwind" - files={["starters/tailwind/src/TextField.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/TextField.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/TimeField.mdx b/packages/dev/s2-docs/pages/react-aria/TimeField.mdx index 6e7d26c2138..5aa02dd2c3e 100644 --- a/packages/dev/s2-docs/pages/react-aria/TimeField.mdx +++ b/packages/dev/s2-docs/pages/react-aria/TimeField.mdx @@ -31,7 +31,7 @@ export const relatedPages = [{'title': 'useTimeField', 'url': 'https://react-spe props={['label', 'granularity', 'isDisabled']} initialProps={{label: 'Time'}} type="tailwind" - files={["starters/tailwind/src/TimeField.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/TimeField.tsx"]} /> ## Value diff --git a/packages/dev/s2-docs/pages/react-aria/ToggleButton.mdx b/packages/dev/s2-docs/pages/react-aria/ToggleButton.mdx index 2ea5a85350f..cf5048a5a03 100644 --- a/packages/dev/s2-docs/pages/react-aria/ToggleButton.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ToggleButton.mdx @@ -30,7 +30,7 @@ export const relatedPages = [{'title': 'useToggleButton', 'url': 'https://react- props={['isDisabled']} initialProps={{children: 'Pin'}} type="tailwind" - files={["starters/tailwind/src/ToggleButton.tsx", "starters/tailwind/src/index.css"]} /> + files={["starters/tailwind/src/ToggleButton.tsx"]} /> ## Selection diff --git a/packages/dev/s2-docs/pages/react-aria/ToggleButtonGroup.mdx b/packages/dev/s2-docs/pages/react-aria/ToggleButtonGroup.mdx index 520422fc1b2..a3115e6e4ae 100644 --- a/packages/dev/s2-docs/pages/react-aria/ToggleButtonGroup.mdx +++ b/packages/dev/s2-docs/pages/react-aria/ToggleButtonGroup.mdx @@ -25,7 +25,7 @@ export const relatedPages = [{'title': 'useToggleButtonGroup', 'url': 'https://r ``` - ```tsx render docs={docs.exports.ToggleButtonGroup} links={docs.links} props={['selectionMode', 'orientation', 'isDisabled']} initialProps={{'aria-label': 'Text style'}} type="tailwind" files={["starters/tailwind/src/ToggleButtonGroup.tsx", "starters/tailwind/src/index.css"]} + ```tsx render docs={docs.exports.ToggleButtonGroup} links={docs.links} props={['selectionMode', 'orientation', 'isDisabled']} initialProps={{'aria-label': 'Text style'}} type="tailwind" files={["starters/tailwind/src/ToggleButtonGroup.tsx"]} "use client"; import {ToggleButtonGroup} from 'tailwind-starter/ToggleButtonGroup'; import {ToggleButton} from 'tailwind-starter/ToggleButton'; diff --git a/packages/dev/s2-docs/pages/react-aria/examples/emoji-picker.mdx b/packages/dev/s2-docs/pages/react-aria/examples/emoji-picker.mdx index 71651f9095f..e0867069831 100644 --- a/packages/dev/s2-docs/pages/react-aria/examples/emoji-picker.mdx +++ b/packages/dev/s2-docs/pages/react-aria/examples/emoji-picker.mdx @@ -12,7 +12,7 @@ export const description = 'With autocomplete, virtualized scrolling, and keyboa An emoji picker with autocomplete, virtualized scrolling, and arrow key navigation. -```tsx render dir="react-aria/examples" files={['packages/dev/s2-docs/pages/react-aria/examples/EmojiPicker.css']} type="vanilla" expanded includeAllImports +```tsx render dir="react-aria/examples" files={['packages/dev/s2-docs/pages/react-aria/examples/EmojiPicker.css']} type="vanilla" expanded "use client"; import {Autocomplete, GridLayout, ListBox, ListBoxItem, Select, SelectValue, Size, useFilter, Virtualizer} from 'react-aria-components'; import {Button} from 'vanilla-starter/Button'; diff --git a/packages/dev/s2-docs/src/Code.tsx b/packages/dev/s2-docs/src/Code.tsx index b7759a1b9ab..68852870fc8 100644 --- a/packages/dev/s2-docs/src/Code.tsx +++ b/packages/dev/s2-docs/src/Code.tsx @@ -4,6 +4,7 @@ import {CodeProps} from './VisualExampleClient'; import {HastNode, HastTextNode, highlightHast, Language} from 'tree-sitter-highlight'; import React, {ReactNode} from 'react'; import {style, StyleString} from '@react-spectrum/s2/style' with {type: 'macro'}; +import {TabLink} from './FileTabs'; const property = style({color: 'indigo-1000'}); const fn = style({color: 'red-1000'}); @@ -239,6 +240,12 @@ function renderHast(node: HastNode | HastTextNode, key: string, links?: Links, i properties = {...properties, href: link}; } + // Link to imported files. + if (properties?.className === 'string' && typeof children === 'string' && /^['"]\.\//.test(children)) { + tagName = TabLink; + properties = {...properties, name: children.slice(3, -1)}; + } + if (tagName === 'span' && !className) { return children; } diff --git a/packages/dev/s2-docs/src/CodeBlock.tsx b/packages/dev/s2-docs/src/CodeBlock.tsx index 41105ac7069..4e7973e1a2b 100644 --- a/packages/dev/s2-docs/src/CodeBlock.tsx +++ b/packages/dev/s2-docs/src/CodeBlock.tsx @@ -1,16 +1,16 @@ // @ts-ignore import assets from 'url:../pages/**/*.{png,jpg,svg}' with {env: 'react-client'}; -import {cache, ReactNode} from 'react'; +import {cache, ReactElement, ReactNode} from 'react'; import {Code, ICodeProps} from './Code'; import {CodePlatter, FileProvider, Pre} from './CodePlatter'; import {ExampleOutput} from './ExampleOutput'; -import {ExpandableCode} from './ExpandableCode'; +import {ExpandableCode, ExpandableCodeProvider} from './ExpandableCode'; +import {FileTabs} from './FileTabs'; import {findPackageJSON} from 'module'; import fs from 'fs'; import {highlight, Language} from 'tree-sitter-highlight'; import path from 'path'; import {style} from '@react-spectrum/s2/style' with {type: 'macro'}; -import {Tab, TabList, TabPanel, Tabs} from '@react-spectrum/s2'; import {VisualExample, VisualExampleProps} from './VisualExample'; const example = style({ @@ -59,11 +59,10 @@ interface CodeBlockProps extends VisualExampleProps { files?: string[], expanded?: boolean, hidden?: boolean, - includeAllImports?: boolean, showCoachMark?: boolean } -export function CodeBlock({render, children, dir, files, expanded, hidden, includeAllImports, ...props}: CodeBlockProps) { +export function CodeBlock({render, children, dir, files, expanded, hidden, ...props}: CodeBlockProps) { if (hidden) { return null; } @@ -116,7 +115,8 @@ export function CodeBlock({render, children, dir, files, expanded, hidden, inclu
{files ? {content} @@ -161,21 +161,44 @@ function TruncatedCode({children, maxLines = 6, ...props}: TruncatedCodeProps) { ); } -export function Files({children, files, type, defaultSelected, maxLines}: {children?: ReactNode, files: string[], type?: 'vanilla' | 'tailwind' | 's2', defaultSelected?: string, maxLines?: number}) { +interface FilesProps { + children?: ReactNode, + files: string[], + downloadFiles?: {[name: string]: string}, + type?: 'vanilla' | 'tailwind' | 's2', + defaultSelected?: string, + maxLines?: number +} + +export function Files({children, files, downloadFiles, type, defaultSelected, maxLines}: FilesProps) { + let fileMap: {[name: string]: ReactElement} = {}; + for (let file of files) { + fileMap[path.basename(file)] = ; + } + + let extraFiles: {[name: string]: ReactElement} = {}; + if (downloadFiles) { + for (let name in downloadFiles) { + if (!files[name]) { + extraFiles[name] = ( + + {downloadFiles[name]} + + ); + } + } + } + return ( - - - {children && Example} - {files.map(file => {path.basename(file)})} - - {children && {children}} - {files.map(file => )} - + + + {children} + + ); } diff --git a/packages/dev/s2-docs/src/ExpandableCode.tsx b/packages/dev/s2-docs/src/ExpandableCode.tsx index 53ae4d37fc3..2773eddf501 100644 --- a/packages/dev/s2-docs/src/ExpandableCode.tsx +++ b/packages/dev/s2-docs/src/ExpandableCode.tsx @@ -2,7 +2,7 @@ import {ActionButton} from '@react-spectrum/s2'; import {flushSync} from 'react-dom'; -import React, {CSSProperties, ReactNode, useRef, useState} from 'react'; +import React, {createContext, CSSProperties, ReactNode, useContext, useRef, useState} from 'react'; import {style} from '@react-spectrum/s2/style' with {type: 'macro'}; const example = style({ @@ -46,8 +46,22 @@ const expandWrapper = style({ paddingY: 8 }); -export function ExpandableCode({children, hasHighlightedLine}: {children: ReactNode, hasHighlightedLine?: boolean}) { +type ExpandableCodeContextValue = [boolean, (v: boolean) => void] | null; +const ExpandableCodeContext = createContext(null); + +export function ExpandableCodeProvider({children}) { let [isExpanded, setExpanded] = useState(false); + return ( + + {children} + + ); +} + +export function ExpandableCode({children, hasHighlightedLine}: {children: ReactNode, hasHighlightedLine?: boolean}) { + let state = useState(false); + let ctx = useContext(ExpandableCodeContext); + let [isExpanded, setExpanded] = ctx || state; let ref = useRef(null); let mask: string | undefined; let padding: string | undefined; diff --git a/packages/dev/s2-docs/src/FileTabs.tsx b/packages/dev/s2-docs/src/FileTabs.tsx new file mode 100644 index 00000000000..d64d101aecb --- /dev/null +++ b/packages/dev/s2-docs/src/FileTabs.tsx @@ -0,0 +1,69 @@ +'use client'; + +import {CodeLink} from './Link'; +import {createContext, ReactElement, ReactNode, useContext, useState} from 'react'; +import {Key, Tab, TabList, TabPanel, Tabs} from '@react-spectrum/s2'; +import {style} from '@react-spectrum/s2/style' with {type: 'macro'}; + +interface FileTabsProps { + children?: ReactNode, + files: {[name: string]: ReactElement}, + extraFiles?: {[name: string]: ReactElement}, + defaultSelectedKey?: Key +} + +const FileTabsContext = createContext<((tab: Key) => void) | null>(null); + +export function FileTabs({children, files, extraFiles, defaultSelectedKey}: FileTabsProps) { + let [tabs, setTabs] = useState(files); + let [selectedKey, setSelectedKey] = useState(defaultSelectedKey || Object.keys(files)[0]); + let onFileClick = (key: Key) => { + let file: Key | null = null; + for (let k of [key, key + '.tsx', key + '.ts', key + '.js']) { + if (k in files || (extraFiles && k in extraFiles)) { + file = k; + break; + } + } + + if (file) { + setSelectedKey(file); + if (!tabs[file] && extraFiles?.[file]) { + setTabs({...tabs, [file]: extraFiles[file]}); + } + } + }; + + return ( + + + + {children && Example} + {Object.keys(tabs).map(file => {file})} + + {children && {children}} + {Object.entries(tabs).map(([name, file]) => {file})} + + + ); +} + +export function TabLink({name, ...props}) { + let onFileClick = useContext(FileTabsContext); + if (!onFileClick) { + return ; + } + + return ( + { + onFileClick(name); + }} /> + ); +} diff --git a/packages/dev/s2-docs/src/Link.tsx b/packages/dev/s2-docs/src/Link.tsx index ff65db5cb15..53f77133cbe 100644 --- a/packages/dev/s2-docs/src/Link.tsx +++ b/packages/dev/s2-docs/src/Link.tsx @@ -45,7 +45,7 @@ export function ColorLink({type, ...props}: RACLinkProps & {type?: 'keyword' | ' } export function CodeLink(props: RACLinkProps) { - return ({textDecorationStyle: isHovered ? 'solid' : 'dotted'})} />; + return ({cursor: 'pointer', textDecoration: isHovered ? 'underline solid' : 'underline dotted'})} />; } const titleLink = style({ diff --git a/packages/dev/s2-docs/src/VisualExample.tsx b/packages/dev/s2-docs/src/VisualExample.tsx index 0f32c3f5eeb..bb768d6ddc8 100644 --- a/packages/dev/s2-docs/src/VisualExample.tsx +++ b/packages/dev/s2-docs/src/VisualExample.tsx @@ -185,7 +185,7 @@ export function VisualExample({component, docs, links, importSource, props, init {Object.keys(controls).map(control => )}
- {files ? {output} : output} + {files ? {output} : output}