/** @jsx jsx */
import { jsx } from '@emotion/core';
import PropTypes from 'prop-types';
import VisuallyHidden from '@reach/visually-hidden';
import sortBy from 'sort-by';
import { formatBytes } from '../utils/format.js';
import { DirectoryIcon, CodeFileIcon } from './Icons.js';
const linkStyle = {
color: '#0076ff',
textDecoration: 'none',
':hover': {
textDecoration: 'underline'
}
};
const tableCellStyle = {
paddingTop: 6,
paddingRight: 3,
paddingBottom: 6,
paddingLeft: 3,
borderTop: '1px solid #eaecef'
};
const iconCellStyle = {
...tableCellStyle,
color: '#424242',
width: 17,
paddingRight: 2,
paddingLeft: 10,
'@media (max-width: 700px)': {
paddingLeft: 20
}
};
const typeCellStyle = {
...tableCellStyle,
textAlign: 'right',
paddingRight: 10,
'@media (max-width: 700px)': {
paddingRight: 20
}
};
function getRelName(path, base) {
return path.substr(base.length > 1 ? base.length + 1 : 1);
}
export default function DirectoryViewer({ path, details: entries }) {
const rows = [];
if (path !== '/') {
rows.push(
|
..
|
|
|
);
}
const { subdirs, files } = Object.keys(entries).reduce(
(memo, key) => {
const { subdirs, files } = memo;
const entry = entries[key];
if (entry.type === 'directory') {
subdirs.push(entry);
} else if (entry.type === 'file') {
files.push(entry);
}
return memo;
},
{ subdirs: [], files: [] }
);
subdirs.sort(sortBy('path')).forEach(({ path: dirname }) => {
const relName = getRelName(dirname, path);
const href = relName + '/';
rows.push(
|
{relName}
|
- |
- |
);
});
files
.sort(sortBy('path'))
.forEach(({ path: filename, size, contentType }) => {
const relName = getRelName(filename, path);
const href = relName;
rows.push(
|
{relName}
|
{formatBytes(size)} |
{contentType} |
);
});
return (
Icon
|
Name
|
Size
|
Content Type
|
{rows}
);
}
if (process.env.NODE_ENV !== 'production') {
DirectoryViewer.propTypes = {
path: PropTypes.string.isRequired,
details: PropTypes.objectOf(
PropTypes.shape({
path: PropTypes.string.isRequired,
type: PropTypes.oneOf(['directory', 'file']).isRequired,
contentType: PropTypes.string, // file only
integrity: PropTypes.string, // file only
size: PropTypes.number // file only
})
).isRequired
};
}