-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Modernize components and prepare for v2 (#61)
* Add type declarations for public APIs * Clean up `implementationMap` inconsistencies * Modernize Exclaim components * Officially deprecate `unwrap` * Modernize playground-app Exclaim implementations * Modernize playground-app itself * Update README and GLOSSARY * Add v1 -> v2 migration notes to the README * Turn on `embroider-optimized`? * Don't rely on `@cached` * Re-add missing `Environment` type * Ensure whitespace is always trimmed * Add undeclared `@glimmer` dependencies
- Loading branch information
Showing
74 changed files
with
743 additions
and
634 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { ComponentLike } from '@glint/template'; | ||
import { ComponentSpec, ImplementationMap } from '../index'; | ||
|
||
declare const ExclaimUi: ComponentLike<{ | ||
Args: { | ||
/** | ||
* A spec for an Exclaim UI. | ||
*/ | ||
ui: unknown; | ||
|
||
/** | ||
* A mapping of names to implementations for use by `$component` | ||
* and `$helper` in the given UI spec. | ||
*/ | ||
implementationMap: ImplementationMap; | ||
|
||
/** | ||
* The backing data that any `$bind` in the UI spec will be bound | ||
* to. This value will also be directly available as `@env` to all | ||
* components rendered in this UI. | ||
*/ | ||
env?: unknown; | ||
|
||
/** | ||
* A callback that will be invoked when the given path in the | ||
* environment has changed because a `$bind` value was written. | ||
*/ | ||
onChange?: (envPath: string) => void; | ||
|
||
/** | ||
* Set this flag `true` to use `computed`-based reactivity for managings | ||
* bindings and helpers within this UI. When `false` or unset, native | ||
* getters and setters will be used instead. | ||
*/ | ||
useClassicReactivity?: boolean; | ||
|
||
/** | ||
* An optional component that, if provided, will be invoked around each | ||
* component in this UI. | ||
*/ | ||
wrapper?: ComponentLike<{ | ||
Args: { | ||
/** The {@link ComponentSpec} being wrapped. */ | ||
componentSpec: ComponentSpec; | ||
|
||
/** The resolved config object the wrapped component will receive. */ | ||
config: unknown; | ||
|
||
/** The env object the wrapped component will receive. */ | ||
env: unknown; | ||
}; | ||
Blocks: { | ||
default: []; | ||
}; | ||
}>; | ||
}; | ||
|
||
Blocks: { | ||
/** | ||
* If an error is encountered when processing the given UI spec, it | ||
* will be yielded to the default block. | ||
*/ | ||
default: [error: unknown]; | ||
}; | ||
}>; | ||
|
||
export default ExclaimUi; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { ComponentLike } from '@glint/template'; | ||
|
||
declare const Env: unique symbol; | ||
|
||
/** A marker type for objects that are operating as an Exclaim environment. */ | ||
export type Environment<T> = T & Record<typeof Env, undefined>; | ||
|
||
/** | ||
* Returns the environment and source path within it where the field at | ||
* the path on the given object originates, if known. | ||
*/ | ||
export function resolveEnvPath( | ||
object: unknown, | ||
path: string, | ||
): string | undefined; | ||
|
||
/** The data defining a helper in an {@link ImplementationMap} */ | ||
export type HelperImplementation = { | ||
helper: (...args: Array<never>) => unknown; | ||
shorthandProperty?: string; | ||
meta?: unknown; | ||
}; | ||
|
||
/** The data defining a component in an {@link ImplementationMap} */ | ||
export type ComponentImplementation = { | ||
component: ComponentLike<unknown>; | ||
shorthandProperty?: string; | ||
meta?: unknown; | ||
}; | ||
|
||
/** | ||
* A mapping of names that can be used in a UI spec with `$helper` | ||
* or `$component` to the runtime implementation that should be invoked | ||
* when that name is encountered. | ||
*/ | ||
export type ImplementationMap<Names extends string = string> = Record< | ||
Names, | ||
HelperImplementation | ComponentImplementation | ||
>; | ||
|
||
/** Represents a `$component` object in a UI spec. */ | ||
export class ComponentSpec { | ||
readonly component: ComponentLike<unknown>; | ||
readonly config: unknown; | ||
readonly meta: unknown; | ||
|
||
resolveConfig(env: Environment<unknown>): unknown; | ||
} | ||
|
||
/** Represents a `$helper` object in a UI spec. */ | ||
export class HelperSpec { | ||
readonly helper: (...args: Array<never>) => unknown; | ||
readonly config: unknown; | ||
readonly meta: unknown; | ||
readonly bindings: Array<unknown>; | ||
|
||
invoke(env: Environment<unknown>): unknown; | ||
} | ||
|
||
/** | ||
* @deprecated This function is now a no-op and should no longer be used. | ||
*/ | ||
export function unwrap<T>(value: T): T; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { ExclaimUi } from './components/exclaim-ui'; | ||
|
||
export default interface ExclaimTemplateRegistry { | ||
ExclaimUi: typeof ExclaimUi; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,22 @@ | ||
{{#component | ||
@wrapper | ||
componentSpec=@componentSpec | ||
env=this.effectiveEnv | ||
config=this.resolvedConfig | ||
}} | ||
{{#component | ||
@componentSpec.component | ||
config=this.resolvedConfig | ||
env=this.effectiveEnv | ||
as |componentSpec overrideEnv| | ||
~}} | ||
<ExclaimComponent | ||
<@wrapper | ||
@componentSpec={{@componentSpec}} | ||
@env={{this.componentData.env}} | ||
@config={{this.componentData.config}} | ||
> | ||
{{~null~}} | ||
<@componentSpec.component | ||
@config={{this.componentData.config}} | ||
@env={{this.componentData.env}} | ||
as |componentSpec additionalEnvData| | ||
> | ||
{{~null~}} | ||
<ExclaimComponent | ||
@componentSpec={{componentSpec}} | ||
@env={{this.effectiveEnv}} | ||
@overrideEnv={{overrideEnv}} | ||
@env={{this.componentData.env}} | ||
@additionalEnvData={{additionalEnvData}} | ||
@wrapper={{@wrapper}} | ||
/> | ||
{{~/component}} | ||
{{/component}} | ||
{{~null~}} | ||
</@componentSpec.component> | ||
{{~null~}} | ||
</@wrapper> |
Oops, something went wrong.