Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/6.x/docs/components/FAB/FAB.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import ExtendsLink from '@docs/components/ExtendsLink.tsx';
import ThemeColorsTable from '@docs/components/ThemeColorsTable.tsx';
import ScreenshotTabs from '@docs/components/ScreenshotTabs.tsx';
import ExtendedExample from '@docs/components/ExtendedExample.tsx';
import { FABVariantsExample, FABSizesExample } from '@docs/components/FABExample.tsx';

A floating action button represents the primary action on a screen.



<span />

<ScreenshotTabs screenshotData={{"all variants":"screenshots/fab-1.png","all sizes":"screenshots/fab-2.png","all modes":"screenshots/fab-4.png","with label":"screenshots/fab-3.png"}}/>

<FABVariantsExample />
<FABSizesExample />

## Usage
```js
Expand Down
3 changes: 3 additions & 0 deletions docs/6.x/docs/components/FAB/FABExtended.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ExtendsLink from '@docs/components/ExtendsLink.tsx';
import ThemeColorsTable from '@docs/components/ThemeColorsTable.tsx';
import ScreenshotTabs from '@docs/components/ScreenshotTabs.tsx';
import ExtendedExample from '@docs/components/ExtendedExample.tsx';
import { FABExtendedExample } from '@docs/components/FABExample.tsx';

An extended floating action button represents the primary action on a screen
and shows a label next to the icon. Animates between expanded (icon + label)
Expand All @@ -16,6 +17,8 @@ and collapsed (icon only) states.

<span />

<FABExtendedExample />

## Usage
```js
import * as React from 'react';
Expand Down
7 changes: 5 additions & 2 deletions docs/6.x/docs/components/Switch/Switch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import ExtendsLink from '@docs/components/ExtendsLink.tsx';
import ThemeColorsTable from '@docs/components/ThemeColorsTable.tsx';
import ScreenshotTabs from '@docs/components/ScreenshotTabs.tsx';
import ExtendedExample from '@docs/components/ExtendedExample.tsx';
import { SwitchStatesExample, SwitchDisabledExample, SwitchIconsExample } from '@docs/components/SwitchExample.tsx';

Material 3 toggle between two mutually exclusive states (on / off).



<span />

<ScreenshotTabs screenshotData={{"Android (enabled)":"screenshots/switch-enabled.android.png","Android (disabled)":"screenshots/switch-disabled.android.png","iOS (enabled)":"screenshots/switch-enabled.ios.png","iOS (disabled)":"screenshots/switch-disabled.ios.png"}}/>

<SwitchStatesExample />
<SwitchDisabledExample />
<SwitchIconsExample />

## Usage
```js
Expand Down
31 changes: 28 additions & 3 deletions docs/component-docs-plugin/generatePageMDX.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,27 @@ function generateThemeColors(
`;
}

type LiveExampleData = {
module: string;
exports: string[];
};

function generateLiveExamplesImport(liveExample: LiveExampleData | undefined) {
if (!liveExample) {
return '';
}

return `\nimport { ${liveExample.exports.join(', ')} } from '${liveExample.module}';`;
}

function generateLiveExamples(liveExample: LiveExampleData | undefined) {
if (!liveExample) {
return '';
}

return `\n\n${liveExample.exports.map((name) => `<${name} />`).join('\n')}`;
}

function generateScreenshots(screenshotData: string | undefined) {
if (!screenshotData) {
return `<span />`;
Expand Down Expand Up @@ -224,8 +245,12 @@ export default function generatePageMDX(doc: ComponentDoc, link: string) {
const summary = summaryMatch ? summaryMatch[1] : '';
const usage = description.replace(summary, '');

const liveExample = customFields.liveExamples[doc.title];
const themeColorsData = JSON.stringify(customFields.themeColors[doc.title]);
const screenshotData = JSON.stringify(customFields.screenshots[doc.title]);
// Live examples supersede screenshots, so a component never shows both.
const screenshotData = liveExample
? undefined
: JSON.stringify(customFields.screenshots[doc.title]);
const extendedExamplesData = JSON.stringify(
customFields.extendedExamples[doc.title]
);
Expand All @@ -241,11 +266,11 @@ import PropTable from '@docs/components/PropTable.tsx';
import ExtendsLink from '@docs/components/ExtendsLink.tsx';
import ThemeColorsTable from '@docs/components/ThemeColorsTable.tsx';
import ScreenshotTabs from '@docs/components/ScreenshotTabs.tsx';
import ExtendedExample from '@docs/components/ExtendedExample.tsx';
import ExtendedExample from '@docs/components/ExtendedExample.tsx';${generateLiveExamplesImport(liveExample)}

${summary}

${generateScreenshots(screenshotData)}
${generateScreenshots(screenshotData)}${generateLiveExamples(liveExample)}

${generateExtendedExamples(usage, extendedExamplesData)}

Expand Down
3 changes: 3 additions & 0 deletions docs/component-docs.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url';

import { extendedExamples } from './src/data/extendedExamples.ts';
import { liveExamples, type LiveExample } from './src/data/liveExamples.ts';
import { screenshots } from './src/data/screenshots.ts';
import { themeColors } from './src/data/themeColors.ts';

Expand All @@ -19,6 +20,7 @@ type ComponentDocsConfig = {
themeColors: Record<string, unknown>;
screenshots: Record<string, unknown>;
extendedExamples: Record<string, unknown>;
liveExamples: Record<string, LiveExample>;
};
};

Expand Down Expand Up @@ -163,6 +165,7 @@ const componentDocsConfig: ComponentDocsConfig = {
themeColors,
screenshots,
extendedExamples,
liveExamples,
},
};

Expand Down
65 changes: 65 additions & 0 deletions docs/src/components/FABExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import * as React from 'react';

import { FAB, type FABSize, type FABVariant } from 'react-native-paper';

import InteractiveExample, { ExampleRow, Labelled } from './InteractiveExample';

const VARIANTS: FABVariant[] = [
'primary',
'secondary',
'tertiary',
'tonalPrimary',
'tonalSecondary',
'tonalTertiary',
];

const SIZES: FABSize[] = ['default', 'medium', 'large'];

export const FABVariantsExample = () => (
<InteractiveExample title="Variants">
<ExampleRow>
{VARIANTS.map((variant) => (
<Labelled key={variant} label={variant}>
<FAB
icon="pencil"
variant={variant}
onPress={() => {}}
aria-label={`${variant} floating action button`}
/>
</Labelled>
))}
</ExampleRow>
</InteractiveExample>
);

export const FABSizesExample = () => (
<InteractiveExample title="Sizes">
<ExampleRow>
{SIZES.map((size) => (
<Labelled key={size} label={size}>
<FAB
icon="pencil"
size={size}
onPress={() => {}}
aria-label={`${size} floating action button`}
/>
</Labelled>
))}
</ExampleRow>
</InteractiveExample>
);

export const FABExtendedExample = () => {
const [expanded, setExpanded] = React.useState(true);

return (
<InteractiveExample title="Extended">
<FAB.Extended
icon="plus"
label="New message"
expanded={expanded}
onPress={() => setExpanded((value) => !value)}
/>
</InteractiveExample>
);
};
79 changes: 79 additions & 0 deletions docs/src/components/InteractiveExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import * as React from 'react';
import { StyleSheet, View } from 'react-native';

import { DarkTheme, LightTheme, Provider, Text } from 'react-native-paper';

import { useColorMode } from './theme-common';

/**
* Row of demo variations, wrapping on narrow viewports.
*/
export const ExampleRow = ({ children }: React.PropsWithChildren) => (
<View style={styles.row}>{children}</View>
);

/**
* A single demo variation captioned with the prop value it illustrates.
*/
export const Labelled = ({
label,
children,
}: React.PropsWithChildren<{ label: string }>) => (
<View style={styles.item}>
{children}
<Text style={styles.itemLabel}>{label}</Text>
</View>
);

type InteractiveExampleProps = React.PropsWithChildren<{
/**
* Short caption rendered above the live preview, describing what the
* example demonstrates.
*/
title?: string;
}>;

/**
* Shared shell for live component demos embedded in the docs.
*
* The Paper theme follows the active docs color mode so demos match the
* surrounding page.
*/
const InteractiveExample = ({ title, children }: InteractiveExampleProps) => {
const isDarkTheme = useColorMode().colorMode === 'dark';

return (
<Provider theme={isDarkTheme ? DarkTheme : LightTheme}>
<figure className="paper-interactive-example">
{title ? (
<figcaption className="paper-interactive-example__title">
{title}
</figcaption>
) : null}
<View style={styles.content}>{children}</View>
</figure>
</Provider>
);
};

const styles = StyleSheet.create({
content: {
alignItems: 'flex-start',
},
row: {
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'center',
gap: 24,
},
item: {
alignItems: 'center',
gap: 8,
},
itemLabel: {
fontSize: 12,
opacity: 0.7,
},
});

export default InteractiveExample;
66 changes: 66 additions & 0 deletions docs/src/components/SwitchExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as React from 'react';

import { Switch } from 'react-native-paper';

import InteractiveExample, { ExampleRow, Labelled } from './InteractiveExample';

export const SwitchStatesExample = () => {
const [on, setOn] = React.useState(true);
const [off, setOff] = React.useState(false);

return (
<InteractiveExample title="Enabled">
<ExampleRow>
<Labelled label="selected">
<Switch value={on} onValueChange={setOn} aria-label="Selected" />
</Labelled>
<Labelled label="unselected">
<Switch value={off} onValueChange={setOff} aria-label="Unselected" />
</Labelled>
</ExampleRow>
</InteractiveExample>
);
};

export const SwitchDisabledExample = () => (
<InteractiveExample title="Disabled">
<ExampleRow>
<Labelled label="selected">
<Switch value disabled aria-label="Disabled and selected" />
</Labelled>
<Labelled label="unselected">
<Switch value={false} disabled aria-label="Disabled and unselected" />
</Labelled>
</ExampleRow>
</InteractiveExample>
);

export const SwitchIconsExample = () => {
const [on, setOn] = React.useState(true);
const [off, setOff] = React.useState(false);

return (
<InteractiveExample title="With icons in the handle">
<ExampleRow>
<Labelled label="selected">
<Switch
value={on}
onValueChange={setOn}
checkedIcon="check"
uncheckedIcon="close"
aria-label="Selected with icon"
/>
</Labelled>
<Labelled label="unselected">
<Switch
value={off}
onValueChange={setOff}
checkedIcon="check"
uncheckedIcon="close"
aria-label="Unselected with icon"
/>
</Labelled>
</ExampleRow>
</InteractiveExample>
);
};
16 changes: 16 additions & 0 deletions docs/src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -1286,3 +1286,19 @@ html:not(.dark) .paper-version-selector-menu {
padding: 18px;
}
}

.paper-interactive-example {
margin: 16px 0 24px;
padding: 24px;
border: 1px solid var(--rp-c-divider, rgba(148, 163, 184, 0.24));
border-radius: 16px;
background: var(--rp-c-bg-soft, rgba(148, 163, 184, 0.06));
overflow-x: auto;
}

.paper-interactive-example__title {
margin-bottom: 16px;
color: var(--rp-c-text-2);
font-size: 13px;
font-weight: 600;
}
25 changes: 25 additions & 0 deletions docs/src/data/liveExamples.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export type LiveExample = {
/** Module specifier the examples are imported from. */
module: string;
/** Named exports rendered, in order, under the page summary. */
exports: string[];
};

export const liveExamples: Record<string, LiveExample> = {
FAB: {
module: '@docs/components/FABExample.tsx',
exports: ['FABVariantsExample', 'FABSizesExample'],
},
Extended: {
module: '@docs/components/FABExample.tsx',
exports: ['FABExtendedExample'],
},
Switch: {
module: '@docs/components/SwitchExample.tsx',
exports: [
'SwitchStatesExample',
'SwitchDisabledExample',
'SwitchIconsExample',
],
},
};
Loading