expo-router
Version:
Expo Router is a file-based router for React Native and web applications.
217 lines (216 loc) • 8.16 kB
JavaScript
// Copyright © 2024 650 Industries.
'use client';
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNavOptions = getNavOptions;
exports.Sitemap = Sitemap;
const react_1 = __importDefault(require("react"));
const react_native_1 = require("react-native");
const react_native_safe_area_context_1 = require("react-native-safe-area-context");
const Pressable_1 = require("./Pressable");
const useSitemap_1 = require("./useSitemap");
const Link_1 = require("../link/Link");
const statusbar_1 = require("../utils/statusbar");
const INDENT = 20;
function getNavOptions() {
return {
title: 'sitemap',
presentation: 'modal',
headerLargeTitle: false,
headerTitleStyle: {
color: 'white',
},
headerTintColor: 'white',
headerLargeTitleStyle: {
color: 'white',
},
headerStyle: {
backgroundColor: 'black',
// @ts-expect-error: mistyped
borderBottomColor: '#323232',
},
header: () => {
const WrapperElement = react_native_1.Platform.OS === 'android' ? react_native_safe_area_context_1.SafeAreaView : react_native_1.View;
return (<WrapperElement style={styles.header}>
<react_native_1.View style={styles.headerContent}>
<react_native_1.View style={styles.headerIcon}>
<SitemapIcon />
</react_native_1.View>
<react_native_1.Text role="heading" aria-level={1} style={styles.title}>
Sitemap
</react_native_1.Text>
</react_native_1.View>
</WrapperElement>);
},
};
}
function Sitemap() {
const sitemap = (0, useSitemap_1.useSitemap)();
const children = react_1.default.useMemo(() => sitemap?.children.filter(({ isInternal }) => !isInternal) ?? [], [sitemap]);
return (<react_native_1.View style={styles.container}>
{statusbar_1.canOverrideStatusBarBehavior && <react_native_1.StatusBar barStyle="light-content"/>}
<react_native_1.ScrollView contentContainerStyle={styles.scroll}>
{children.map((child) => (<react_native_1.View testID="sitemap-item-container" key={child.contextKey} style={styles.itemContainer}>
<SitemapItem node={child}/>
</react_native_1.View>))}
</react_native_1.ScrollView>
</react_native_1.View>);
}
function SitemapItem({ node, level = 0 }) {
const isLayout = react_1.default.useMemo(() => node.children.length > 0 || node.contextKey.match(/_layout\.[jt]sx?$/), [node]);
const info = node.isInitial ? 'Initial' : node.isGenerated ? 'Generated' : '';
if (isLayout) {
return <LayoutSitemapItem node={node} level={level} info={info}/>;
}
return <StandardSitemapItem node={node} level={level} info={info}/>;
}
function LayoutSitemapItem({ node, level, info }) {
const [isCollapsed, setIsCollapsed] = react_1.default.useState(true);
return (<>
<SitemapItemPressable style={{ opacity: 0.4 }} leftIcon={<PkgIcon />} rightIcon={<ArrowIcon rotation={isCollapsed ? 0 : 180}/>} filename={node.filename} level={level} info={info} onPress={() => setIsCollapsed((prev) => !prev)}/>
{!isCollapsed &&
node.children.map((child) => (<SitemapItem key={child.contextKey} node={child} level={level + (node.isGenerated ? 0 : 1)}/>))}
</>);
}
function StandardSitemapItem({ node, info, level }) {
return (<Link_1.Link accessibilityLabel={node.contextKey} href={node.href} asChild
// Ensure we replace the history so you can't go back to this page.
replace>
<SitemapItemPressable leftIcon={<FileIcon />} rightIcon={<ForwardIcon />} filename={node.filename} level={level} info={info}/>
</Link_1.Link>);
}
function SitemapItemPressable({ style, leftIcon, rightIcon, filename, level, info, ...pressableProps }) {
return (<Pressable_1.Pressable {...pressableProps}>
{({ pressed, hovered }) => (<react_native_1.View testID="sitemap-item" style={[
styles.itemPressable,
{
paddingLeft: INDENT + level * INDENT,
backgroundColor: hovered ? '#202425' : 'transparent',
},
pressed && { backgroundColor: '#26292b' },
style,
]}>
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center' }}>
{leftIcon}
<react_native_1.Text style={styles.filename}>{filename}</react_native_1.Text>
</react_native_1.View>
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center' }}>
{!!info && <react_native_1.Text style={[styles.virtual, { marginRight: 8 }]}>{info}</react_native_1.Text>}
{rightIcon}
</react_native_1.View>
</react_native_1.View>)}
</Pressable_1.Pressable>);
}
function FileIcon() {
return <react_native_1.Image style={styles.image} source={require('expo-router/assets/file.png')}/>;
}
function PkgIcon() {
return <react_native_1.Image style={styles.image} source={require('expo-router/assets/pkg.png')}/>;
}
function ForwardIcon() {
return <react_native_1.Image style={styles.image} source={require('expo-router/assets/forward.png')}/>;
}
function SitemapIcon() {
return <react_native_1.Image style={styles.image} source={require('expo-router/assets/sitemap.png')}/>;
}
function ArrowIcon({ rotation = 0 }) {
return (<react_native_1.Image style={[
styles.image,
{
transform: [{ rotate: `${rotation}deg` }],
},
]} source={require('expo-router/assets/arrow_down.png')}/>);
}
const styles = react_native_1.StyleSheet.create({
container: {
backgroundColor: 'black',
flex: 1,
alignItems: 'stretch',
},
header: {
backgroundColor: '#151718',
paddingVertical: 16,
borderBottomWidth: 1,
borderColor: '#313538',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 3,
},
shadowOpacity: 0.33,
shadowRadius: 3,
elevation: 8,
},
headerContent: {
flexDirection: 'row',
alignItems: 'center',
gap: 14,
paddingHorizontal: '5%',
...react_native_1.Platform.select({
web: {
width: '100%',
maxWidth: 960,
marginHorizontal: 'auto',
},
}),
},
title: {
color: 'white',
fontSize: 28,
fontWeight: 'bold',
},
scroll: {
paddingHorizontal: '5%',
paddingVertical: 16,
...react_native_1.Platform.select({
ios: {
paddingBottom: 24,
},
web: {
width: '100%',
maxWidth: 960,
marginHorizontal: 'auto',
paddingBottom: 24,
},
default: {
paddingBottom: 12,
},
}),
},
itemContainer: {
borderWidth: 1,
borderColor: '#313538',
backgroundColor: '#151718',
borderRadius: 12,
marginBottom: 12,
overflow: 'hidden',
},
itemPressable: {
paddingHorizontal: INDENT,
paddingVertical: 16,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
...react_native_1.Platform.select({
web: {
transitionDuration: '100ms',
},
}),
},
filename: { color: 'white', fontSize: 20, marginLeft: 12 },
virtual: { textAlign: 'right', color: 'white' },
image: { width: 24, height: 24, resizeMode: 'contain', opacity: 0.6 },
headerIcon: {
width: 40,
height: 40,
backgroundColor: '#202425',
borderRadius: 8,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
});
//# sourceMappingURL=Sitemap.js.map
;