Initial commit

This commit is contained in:
Waylon Walker 2019-05-09 10:15:41 -05:00
commit 5a3bf52ebb
86 changed files with 2639 additions and 0 deletions

View file

@ -0,0 +1,13 @@
{
"paths": {
"source": "./src",
"compiled": "./lib"
},
"parts": [
{
"name": "part:@sanity/dashboard/widget/create",
"implements": "part:@sanity/dashboard/widget",
"path": "widget.js"
}
]
}

View file

@ -0,0 +1,40 @@
@import 'part:@sanity/base/theme/variables-style';
.root {
composes: container from "part:@sanity/dashboard/widget-styles";
}
.header {
composes: header from "part:@sanity/dashboard/widget-styles";
}
.title {
composes: title from "part:@sanity/dashboard/widget-styles";
}
.content {
display: grid;
padding: var(--small-padding);
grid-gap: var(--small-padding);
grid-template-columns: 1fr 1fr;
overflow-x: auto;
border-top: 1px solid var(--hairline-color);
@media (--screen-medium) {
grid-template-columns: 1fr 1fr 1fr 1fr;
}
}
.link {
composes: item from 'part:@sanity/base/theme/layout/selectable-style';
display: block;
border-radius: 2px;
padding: var(--small-padding);
text-decoration: none;
text-align: center;
box-sizing: border-box;
}
.iconWrapper {
font-size: 2em;
}

View file

@ -0,0 +1,39 @@
import {Link} from 'part:@sanity/base/router'
import FolderIcon from 'part:@sanity/base/folder-icon'
import FileIcon from 'part:@sanity/base/file-icon'
import React from 'react'
import styles from './StructureMenuWidget.css'
function getIconComponent (item) {
if (item.icon) return item.icon
if (!item.schemaType) return FileIcon
return item.schemaType.icon || FolderIcon
}
function StructureMenuWidget (props) {
return (
<div className={styles.root}>
<div className={styles.header}>
<h3 className={styles.title}>Edit your content</h3>
</div>
<div className={styles.content}>
{props.structure.items.map(item => {
const Icon = getIconComponent(item)
return (
<div key={item.id}>
<Link className={styles.link} href={`/desk/${item.id}`}>
<div className={styles.iconWrapper}>
<Icon />
</div>
<div>{item.title}</div>
</Link>
</div>
)
})}
</div>
</div>
)
}
export default StructureMenuWidget

View file

@ -0,0 +1 @@
export {default as StructureMenuWidget} from './StructureMenuWidget'

View file

@ -0,0 +1,99 @@
/* global __DEV__ */
import {defer, from as observableFrom, of as observableOf, throwError} from 'rxjs'
import {mergeMap} from 'rxjs/operators'
// eslint-disable-next-line import/no-commonjs
const {StructureBuilder} = require('@sanity/structure')
let prevStructureError = null
if (__DEV__) {
if (module.hot && module.hot.data) {
prevStructureError = module.hot.data.prevError
}
}
export function isSubscribable (thing) {
return thing && (typeof thing.then === 'function' || typeof thing.subscribe === 'function')
}
export function isStructure (structure) {
return (
structure &&
(typeof structure === 'function' ||
typeof structure.serialize !== 'function' ||
typeof structure.then !== 'function' ||
typeof structure.subscribe !== 'function' ||
typeof structure.type !== 'string')
)
}
export function serializeStructure (item, context, resolverArgs = []) {
// Lazy
if (typeof item === 'function') {
return serializeStructure(item(...resolverArgs), context, resolverArgs)
}
// Promise/observable returning a function, builder or plain JSON structure
if (isSubscribable(item)) {
return observableFrom(item).pipe(
mergeMap(val => serializeStructure(val, context, resolverArgs))
)
}
// Builder?
if (item && typeof item.serialize === 'function') {
return serializeStructure(item.serialize(context))
}
// Plain value?
return observableOf(item)
}
export function getDefaultStructure () {
const items = StructureBuilder.documentTypeListItems()
return StructureBuilder.list()
.id('__root__')
.title('Content')
.showIcons(items.some(item => item.getSchemaType().icon))
.items(items)
}
// We are lazy-requiring/resolving the structure inside of a function in order to catch errors
// on the root-level of the module. Any loading errors will be caught and emitted as errors
// eslint-disable-next-line complexity
export function loadStructure () {
let structure
try {
const mod = require('part:@sanity/desk-tool/structure?') || getDefaultStructure()
structure = mod && mod.__esModule ? mod.default : mod
// On invalid modules, when HMR kicks in, we sometimes get an empty object back when the
// source has changed without fixing the problem. In this case, keep showing the error
if (
__DEV__ &&
prevStructureError &&
structure &&
structure.constructor.name === 'Object' &&
Object.keys(structure).length === 0
) {
return throwError(prevStructureError)
}
prevStructureError = null
} catch (err) {
prevStructureError = err
return throwError(err)
}
if (!isStructure(structure)) {
return throwError(
new Error(
`Structure needs to export a function, an observable, a promise or a stucture builder, got ${typeof structure}`
)
)
}
// Defer to catch immediately thrown errors on serialization
return defer(() => serializeStructure(structure))
}

View file

@ -0,0 +1,11 @@
import {combineLatest} from 'rxjs'
import {map} from 'rxjs/operators'
import {loadStructure} from './lib/structure'
export function toPropsStream (props$) {
const structure$ = loadStructure()
return combineLatest(props$, structure$).pipe(
map(([props, structure]) => ({...props, structure}))
)
}

View file

@ -0,0 +1,10 @@
import {withPropsStream} from 'react-props-stream'
import {withRouterHOC} from 'part:@sanity/base/router'
import {StructureMenuWidget} from './components'
import {toPropsStream} from './props'
export default {
name: 'structure-menu',
component: withRouterHOC(withPropsStream(toPropsStream, StructureMenuWidget)),
layout: {width: 'full'}
}