added "File" Prop Type to core project
This commit is contained in:
parent
f94df690a2
commit
91b0ec5cfa
3 changed files with 74 additions and 3 deletions
|
@ -3,7 +3,7 @@ import Project from '@theatre/core/projects/Project'
|
||||||
import type {ISheet} from '@theatre/core/sheets/TheatreSheet'
|
import type {ISheet} from '@theatre/core/sheets/TheatreSheet'
|
||||||
|
|
||||||
import type {ProjectAddress} from '@theatre/shared/utils/addresses'
|
import type {ProjectAddress} from '@theatre/shared/utils/addresses'
|
||||||
import type {Asset} from '@theatre/shared/utils/assets'
|
import type {Asset, File} from '@theatre/shared/utils/assets'
|
||||||
import type {
|
import type {
|
||||||
ProjectId,
|
ProjectId,
|
||||||
SheetId,
|
SheetId,
|
||||||
|
@ -80,7 +80,7 @@ export interface IProject {
|
||||||
* @param asset - The asset to get the URL for
|
* @param asset - The asset to get the URL for
|
||||||
* @returns The URL for the asset, or `undefined` if the asset is not found
|
* @returns The URL for the asset, or `undefined` if the asset is not found
|
||||||
*/
|
*/
|
||||||
getAssetUrl(asset: Asset): string | undefined
|
getAssetUrl(asset: Asset | File): string | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TheatreProject implements IProject {
|
export default class TheatreProject implements IProject {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import type {
|
||||||
import {propTypeSymbol, sanitizeCompoundProps} from './internals'
|
import {propTypeSymbol, sanitizeCompoundProps} from './internals'
|
||||||
// eslint-disable-next-line unused-imports/no-unused-imports
|
// eslint-disable-next-line unused-imports/no-unused-imports
|
||||||
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
|
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
|
||||||
import type {Asset} from '@theatre/shared/utils/assets'
|
import type {Asset, File} from '@theatre/shared/utils/assets'
|
||||||
|
|
||||||
// Notes on naming:
|
// Notes on naming:
|
||||||
// As of now, prop types are either `simple` or `composite`.
|
// As of now, prop types are either `simple` or `composite`.
|
||||||
|
@ -138,6 +138,74 @@ export const compound = <Props extends UnknownShorthandCompoundProps>(
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A file prop type
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* Usage:
|
||||||
|
* ```ts
|
||||||
|
*
|
||||||
|
* // with a label:
|
||||||
|
* const obj = sheet.object('key', {
|
||||||
|
* url: t.file('My file.glb', {
|
||||||
|
* label: 'Model'
|
||||||
|
* })
|
||||||
|
* })
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param opts - Options (See usage examples)
|
||||||
|
*/
|
||||||
|
export const file = (
|
||||||
|
// The defaultValue parameter is a string for convenience, but it will be converted to an Asset object
|
||||||
|
defaultValue: File['id'],
|
||||||
|
opts: {
|
||||||
|
label?: string
|
||||||
|
interpolate?: Interpolator<File['id']>
|
||||||
|
} = {},
|
||||||
|
): PropTypeConfig_File => {
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
validateCommonOpts('t.file(defaultValue, opts)', opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
const interpolate: Interpolator<File> = (left, right, progression) => {
|
||||||
|
const stringInterpolate = opts.interpolate ?? leftInterpolate
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'file',
|
||||||
|
id: stringInterpolate(left.id, right.id, progression),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: 'file',
|
||||||
|
default: {type: 'file', id: defaultValue},
|
||||||
|
valueType: null as $IntentionalAny,
|
||||||
|
[propTypeSymbol]: 'TheatrePropType',
|
||||||
|
label: opts.label,
|
||||||
|
interpolate,
|
||||||
|
deserializeAndSanitize: _ensureFile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _ensureFile = (val: unknown): File | undefined => {
|
||||||
|
if (!val) return undefined
|
||||||
|
|
||||||
|
let valid = true
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof (val as $IntentionalAny).id !== 'string' &&
|
||||||
|
![null, undefined].includes((val as $IntentionalAny).id)
|
||||||
|
) {
|
||||||
|
valid = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((val as $IntentionalAny).type !== 'file') valid = false
|
||||||
|
|
||||||
|
if (!valid) return undefined
|
||||||
|
|
||||||
|
return val as File
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An image prop type
|
* An image prop type
|
||||||
*
|
*
|
||||||
|
@ -778,6 +846,7 @@ export interface PropTypeConfig_StringLiteral<T extends string>
|
||||||
export interface PropTypeConfig_Rgba extends ISimplePropType<'rgba', Rgba> {}
|
export interface PropTypeConfig_Rgba extends ISimplePropType<'rgba', Rgba> {}
|
||||||
|
|
||||||
export interface PropTypeConfig_Image extends ISimplePropType<'image', Asset> {}
|
export interface PropTypeConfig_Image extends ISimplePropType<'image', Asset> {}
|
||||||
|
export interface PropTypeConfig_File extends ISimplePropType<'file', File> {}
|
||||||
|
|
||||||
type DeepPartialCompound<Props extends UnknownValidCompoundProps> = {
|
type DeepPartialCompound<Props extends UnknownValidCompoundProps> = {
|
||||||
[K in keyof Props]?: DeepPartial<Props[K]>
|
[K in keyof Props]?: DeepPartial<Props[K]>
|
||||||
|
@ -812,6 +881,7 @@ export type PropTypeConfig_AllSimples =
|
||||||
| PropTypeConfig_StringLiteral<$IntentionalAny>
|
| PropTypeConfig_StringLiteral<$IntentionalAny>
|
||||||
| PropTypeConfig_Rgba
|
| PropTypeConfig_Rgba
|
||||||
| PropTypeConfig_Image
|
| PropTypeConfig_Image
|
||||||
|
| PropTypeConfig_File
|
||||||
|
|
||||||
export type PropTypeConfig =
|
export type PropTypeConfig =
|
||||||
| PropTypeConfig_AllSimples
|
| PropTypeConfig_AllSimples
|
||||||
|
|
|
@ -48,3 +48,4 @@ export function getAllPossibleAssetIDs(project: Project, type?: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Asset = {type: 'image'; id: string | undefined}
|
export type Asset = {type: 'image'; id: string | undefined}
|
||||||
|
export type File = {type: 'file'; id: string | undefined}
|
||||||
|
|
Loading…
Reference in a new issue