Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update README to reflect latest state #45

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 39 additions & 163 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,42 @@
ember-template-imports
==============================================================================

This addon provides a number of different formats for using template imports
within Ember!
# ember-template-imports

## aka First-Class Component Templates

This addon began as a testing ground for various "template import" syntaxes,
but has essentially evolved to implement the
[First-Class Component Templates RFC](https://rfcs.emberjs.com/id/0779-first-class-component-templates/),
which introduces `<template>` tags as a format for making component templates
first-class participants in JavaScript and TypeScript with
[strict mode](https://rfcs.emberjs.com/id/0496-handlebars-strict-mode/)
template semantics. The `<template>` syntax is made available to
JavaScript and TypeScript files with the `.gjs` and `.gts` extensions, respectively.
Comment on lines +5 to +12
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This addon implements the [First-Class Component Templates
RFC](https://rfcs.emberjs.com/id/0779-first-class-component-templates/), which
introduces `<template>` tags as a format for making component templates
first-class participants in JavaScript and TypeScript with [strict
mode](https://rfcs.emberjs.com/id/0496-handlebars-strict-mode/) template
semantics.

It also serves as a home for other syntaxes built on the same underlying primitives in Ember, including using `hbs` tagged template literal strings to create templates in JS. Although these are not the ultimate design for First-Class Component Templates, they remain supported for the transition period.


First-class component templates address a number of pain points in today’s component
authoring world, and provide a number of new capabilities to Ember and Glimmer users:

- accessing local JavaScript values with no ceremony and no backing class, enabling much
easier use of existing JavaScript ecosystem tools, including especially styling
libraries—standard [CSS Modules](https://github.com/css-modules/css-modules)
will “just work,” for example
- authoring more than one component in a single file, where colocation makes sense—and
thereby providing more control over a component’s public API
- likewise authoring locally-scoped helpers, modifiers, and other JavaScript functionality

Here is an example of a `.gjs` / `.gts` component file, which demonstrates how other
components (e.g. `MyComponent`) can be imported using JS/TS `import` syntax, and then
rendered within the embedded `<template>` tag:
Comment on lines +14 to +27
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not hard-wrap, please!

Suggested change
First-class component templates address a number of pain points in today’s component
authoring world, and provide a number of new capabilities to Ember and Glimmer users:
- accessing local JavaScript values with no ceremony and no backing class, enabling much
easier use of existing JavaScript ecosystem tools, including especially styling
libraries—standard [CSS Modules](https://github.com/css-modules/css-modules)
will “just work,” for example
- authoring more than one component in a single file, where colocation makes sense—and
thereby providing more control over a component’s public API
- likewise authoring locally-scoped helpers, modifiers, and other JavaScript functionality
Here is an example of a `.gjs` / `.gts` component file, which demonstrates how other
components (e.g. `MyComponent`) can be imported using JS/TS `import` syntax, and then
rendered within the embedded `<template>` tag:
First-class component templates address a number of pain points in today’s component authoring world, and provide a number of new capabilities to Ember and Glimmer users:
- accessing local JavaScript values with no ceremony and no backing class, enabling much easier use of existing JavaScript ecosystem tools, including especially styling libraries—standard [CSS Modules](https://github.com/css-modules/css-modules) will “just work,” for example
- authoring more than one component in a single file, where colocation makes sense—and thereby providing more control over a component’s public API
- likewise authoring locally-scoped helpers, modifiers, and other JavaScript functionality
Here is an example of a `.gjs` / `.gts` component file, which demonstrates how other components (e.g. `MyComponent`) can be imported using JS/TS `import` syntax, and then rendered within the embedded `<template>` tag:


```js
import MyComponent from './my-component';

<template>
<p>
Rendering MyComponent below:
</p>
<MyComponent/>
</template>
```

Template imports are an upcoming feature in Ember. Like Glimmer components, the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with removing this particular section, but let's leave the sections after it.

primitive APIs for supporting imports were built before we decided on a final
format for their high level usage. There are a number of different ideas for how
we can integrate imports with templates, and the idea behind this addon is that
it can be a test bed for them all. This way, we can share common tooling between
solutions, and work together as a community as we explore the design space.

So far, this addon supports two different potential formats:

- Template tags, embedded in `.gjs` files

```js
import MyComponent from './my-component';

<template>
<MyComponent/>
</template>
```

- Template literals, similar to the existing `hbs` helper in tests:

```js
import { hbs } from 'ember-template-imports';
import MyComponent from './my-component';

export default hbs`
<MyComponent/>
`;
```

For the previous version of this addon, see [this repository](https://github.com/patricklx/ember-template-imports).
And huge thanks to @patricklx for his contributions here!

## Using Template Tags and `.gjs` Files

Template tags are a new syntax introduced in `.gjs`, a new file format that is
Expand Down Expand Up @@ -150,124 +142,6 @@ export default class Hello {
}
```

## Using Template Literals with `hbs`

Template literals are an existing JavaScript syntax that has been repurposed to
define Ember templates. This syntax can be used in standard JavaScript files to
define templates for Ember components.

```js
// components/hello.js
import { hbs } from 'ember-template-imports';

export default hbs`
<span>Hello, {{@name}}!</span>
`;
```

This example defines a template-only component, which is the default export of
`hello.js`. You would be able to use this component in another component
like so:

```js
// components/hello-world.js
import { hbs } from 'ember-template-imports';
import Hello from './hello';

export default hbs`
<Hello @name="world" />
`;
```
In addition, you can define template-only components and assign them to
variables, allowing you to export components with named exports:

```js
import { hbs } from 'ember-template-imports';

export const First = hbs`First`;

export const Second = hbs`Second`;

export const Third = hbs`Third`;
```

This also allows you to create components that are only used locally, in the
same file:

```js
import { hbs } from 'ember-template-imports';

const Option = hbs`
<option selected={{@selected}} value={{@value}}>
{{or @title @value}}
</option>
`;

export const CustomSelect = hbs`
<select>
{{#each @options as |option|}}
<Option
@value={{option.value}}
@selected={{eq option @selectedOption}}
/>
{{/each}}
</select>
`;
```

Helpers and modifiers can also be defined in the same file as your components,
making them very flexible:

```js
import { hbs } from 'ember-template-imports';
import { helper } from '@ember/component/helper';
import { modifier } from 'ember-modifier';

const plusOne = helper(([num]) => num + 1);

const setScrollPosition = modifier((element, [position]) => {
element.scrollTop = position
});

hbs`
<div class="scroll-container" {{setScrollPosition @scrollPos}}>
{{#each @items as |item index|}}
Item #{{plusOne index}}: {{item}}
{{/each}}
</div>
`;
```

Finally, to associate a template with a class-based component, you can assign
the template to the `static template` property of the class:

```js
// components/hello.js
import Component from '@glimmer/component';
import { hbs } from 'ember-template-imports';

export default class Hello extends Component {
name = 'world';

static template = hbs`
<span>Hello, {{this.name}}!</span>
`;
}
```

This template literal syntax has a few key differences and restrictions from
standard JS template literal syntax:

- Using template interpolations (`${}`) is disallowed. You cannot embed dynamic
values in templates, they must be statically analyzable and compilable.
- Templates are able to reference all variables that are in scope where they are
defined. This is unlike normal template literals, which require you to
interpolate a value using `${}` to reference and use it.
- The `static template` property of class components does not exist directly on
the class. It is compiled away, and so it cannot be directly referenced or
dynamically modified/assigned.


## Reference: built-in helpers, modifiers, components

As implemented as part of the [Strict Mode Templates RFC][rfc-496], the built in
Expand All @@ -285,30 +159,32 @@ helpers, modifiers and components are available for import:

[rfc-496]: https://github.com/emberjs/rfcs/pull/496

Compatibility
------------------------------------------------------------------------------
## Compatibility

* Ember.js v3.27 or above
* Ember CLI v2.13 or above
* `ember-cli-htmlbars` 6.0 or above
* Node.js v12 or above

## Status / Stability

Installation
------------------------------------------------------------------------------
There some remaining issues regarding Prettier, ESLint, and ember-template-lint support;
please see [this issue](https://github.com/ember-template-imports/ember-template-imports/issues/35)
for more information.

## Installation

```
ember install ember-template-imports
```

Editor Integrations
------------------------------------------------------------------------------
## Editor Integrations

To get syntax highlighting inside embedded templates and support for the GJS
file extension, you may need to configure your editor.

### Visual Studio Code
The [vscode-glimmer](https://marketplace.visualstudio.com/items?itemName=chiragpat.vscode-glimmer) plugin handles syntax highlighting for both proposed formats.
The [vscode-glimmer](https://marketplace.visualstudio.com/items?itemName=chiragpat.vscode-glimmer) plugin handles syntax highlighting for `.gjs` and `.gts` files.

### Neovim

Expand Down