Wrote documentation for feature.ts

Also slightly cleaned up modifiers.tsx due to slightly new comment style
This commit is contained in:
thepaperpilot 2022-05-10 20:04:08 -05:00
parent 2ec1a03d8f
commit 521c0d1ea4
2 changed files with 56 additions and 12 deletions

View file

@ -2,46 +2,83 @@ import Decimal from "util/bignum";
import { DoNotCache } from "util/computed"; import { DoNotCache } from "util/computed";
import { CSSProperties, DefineComponent, isRef } from "vue"; import { CSSProperties, DefineComponent, isRef } from "vue";
/**
* A symbol to use as a key for a vue component a feature can be rendered with
* @see {@link VueFeature}
*/
export const Component = Symbol("Component"); export const Component = Symbol("Component");
/**
* A symbol to use as a key for a prop gathering function that a feature can use to send to its component
* @see {@link VueFeature}
*/
export const GatherProps = Symbol("GatherProps"); export const GatherProps = Symbol("GatherProps");
/**
* A type referring to a function that returns JSX and is marked that it shouldn't be wrapped in a ComputedRef
* @see {@link jsx}
*/
export type JSXFunction = (() => JSX.Element) & { [DoNotCache]: true }; export type JSXFunction = (() => JSX.Element) & { [DoNotCache]: true };
/**
* Any value that can be coerced into (or is) a vue component
*/
export type CoercableComponent = string | DefineComponent | JSXFunction; export type CoercableComponent = string | DefineComponent | JSXFunction;
/**
* Any value that can be passed into an HTML element's style attribute.
* Note that Profectus uses its own StyleValue and CSSProperties that are extended,
* in order to have additional properties added to them, such as variable CSS variables.
*/
export type StyleValue = string | CSSProperties | Array<string | CSSProperties>; export type StyleValue = string | CSSProperties | Array<string | CSSProperties>;
// TODO if importing .vue components in .tsx can become type safe, /** A type that refers to any vue component */
// this type can probably be safely removed
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export type GenericComponent = DefineComponent<any, any, any>; export type GenericComponent = DefineComponent<any, any, any>;
/** Utility type that is S, with any properties from T that aren't already present in S */
export type Replace<T, S> = S & Omit<T, keyof S>; export type Replace<T, S> = S & Omit<T, keyof S>;
/**
* Utility function for a function that returns an object of a given type,
* with "this" bound to what the type will eventually be processed into.
* Intended for making lazily evaluated objects.
*/
export type OptionsFunc<T, S = T, R = Record<string, unknown>> = () => T & ThisType<S> & Partial<R>; export type OptionsFunc<T, S = T, R = Record<string, unknown>> = () => T & ThisType<S> & Partial<R>;
let id = 0; let id = 0;
// Get a unique ID to allow a feature to be found for creating branches /**
// and any other uses requiring unique identifiers for each feature * Gets a unique ID to give to each feature, used for any sort of system that needs to identify
// IDs are gauranteed unique, but should not be saved as they are not * elements in the DOM rather than references to the feature itself. (For example, branches)
// guaranteed to be persistent through updates and such * IDs are guaranteed unique, but _NOT_ persistent - they likely will change between updates.
* @param prefix A string to prepend to the id to make it more readable in the inspector tools
*/
export function getUniqueID(prefix = "feature-"): string { export function getUniqueID(prefix = "feature-"): string {
return prefix + id++; return prefix + id++;
} }
/** Enum for what the visibility of a feature or component should be */
export enum Visibility { export enum Visibility {
/** The feature or component should be visible */
Visible, Visible,
/** The feature or component should not appear but still take up space */
Hidden, Hidden,
/** The feature or component should not appear not take up space */
None None
} }
/**
* Takes a function and marks it as JSX so it won't get auto-wrapped into a ComputedRef.
* The function may also return empty string as empty JSX tags cause issues.
*/
export function jsx(func: () => JSX.Element | ""): JSXFunction { export function jsx(func: () => JSX.Element | ""): JSXFunction {
(func as Partial<JSXFunction>)[DoNotCache] = true; (func as Partial<JSXFunction>)[DoNotCache] = true;
return func as JSXFunction; return func as JSXFunction;
} }
/** Utility function to convert a boolean value into a Visbility value */
export function showIf(condition: boolean, otherwise = Visibility.None): Visibility { export function showIf(condition: boolean, otherwise = Visibility.None): Visibility {
return condition ? Visibility.Visible : otherwise; return condition ? Visibility.Visible : otherwise;
} }
/** Utility function to set a property on an object if and only if it doesn't already exist */
export function setDefault<T, K extends keyof T>( export function setDefault<T, K extends keyof T>(
object: T, object: T,
key: K, key: K,
@ -52,6 +89,11 @@ export function setDefault<T, K extends keyof T>(
} }
} }
/**
* Traverses an object and returns all features of the given type(s)
* @param obj The object to traverse
* @param types The feature types that will be searched for
*/
export function findFeatures(obj: Record<string, unknown>, ...types: symbol[]): unknown[] { export function findFeatures(obj: Record<string, unknown>, ...types: symbol[]): unknown[] {
const objects: unknown[] = []; const objects: unknown[] = [];
const handleObject = (obj: Record<string, unknown>) => { const handleObject = (obj: Record<string, unknown>) => {
@ -71,6 +113,12 @@ export function findFeatures(obj: Record<string, unknown>, ...types: symbol[]):
return objects; return objects;
} }
/**
* Traverses an object and returns all features that are _not_ any of the given types.
* Features are any object with a "type" property that has a symbol value.
* @param obj The object to traverse
* @param types The feature types that will be skipped over
*/
export function excludeFeatures(obj: Record<string, unknown>, ...types: symbol[]): unknown[] { export function excludeFeatures(obj: Record<string, unknown>, ...types: symbol[]): unknown[] {
const objects: unknown[] = []; const objects: unknown[] = [];
const handleObject = (obj: Record<string, unknown>) => { const handleObject = (obj: Record<string, unknown>) => {

View file

@ -14,13 +14,9 @@ import { computed, unref } from "vue";
* {@link createModifierSection}. * {@link createModifierSection}.
*/ */
export interface Modifier { export interface Modifier {
/** /** Applies some operation on the input and returns the result. */
* Applies some operation on the input and returns the result.
*/
apply: (gain: DecimalSource) => DecimalSource; apply: (gain: DecimalSource) => DecimalSource;
/** /** Reverses the operation applied by the apply property. Required by some features. */
* Reverses the operation applied by the apply property. Required by some features.
*/
revert?: (gain: DecimalSource) => DecimalSource; revert?: (gain: DecimalSource) => DecimalSource;
/** /**
* Whether or not this modifier should be considered enabled. * Whether or not this modifier should be considered enabled.