Code Monkey home page Code Monkey logo

ember-command's Introduction

Commands for Ember

Implementation of the Command design pattern from C-Q-S for ember.

  • Commands are a primitives to be passed around
  • Commands are just functions
  • Commands are composable of many functions (but stays a function)
  • Commands can have/be a link (but stays a function)
  • Use commands with (fn) and enjoy partial applications (because it stayed a function)

What you'll get:

  • A Command class to extend from for your implementation
  • A LinkCommand as syntactic sugar for creating a link (through ember-link)
  • A @command decorator to connect your component with your command
  • A <CommandElement> component as your building block to attach your command to the UI
  • The <CommandElement> will accept a Command, an @action or a (link)
  • The <CommandElement> will render the correct HTML element to take care of accessibility

Documentation

Read the Documentation

Installation

Install ember-command with:

ember install ember-command

Usage

The idea for ember-command is clearly to separate your business logic from your UI by offering a couple of mechanics to do that.

Actions

Write an action that invokes a service within a single file component.

import { action } from 'ember-command';
import { on } from '@ember/modifier';

const inc = action(({ services }) => () => {
  services.counter.inc();
});

const Counter = <template>
  <button type="button" {{(inc)}}>+</button>
</template>

export default Counter;

Composing

Compose various commands together to form a primitive that can be passed around. This works well in combination with ember-link.

Let's make a link and add tracking to it:

import { command, action, CommandElement } from 'ember-command';
import { link } from 'ember-link';

const track = action(({ services }) => (event: string) => {
  services.tracking.track(event);
});

const HomeLink = <template>
  <CommandElement @command={{command 
    (fn (track) "go home")
    (link "application")
  }}>Home</CommandElement>
</template>

export default HomeLink;

Contributing

See the Contributing guide for details.

License

This project is licensed under the MIT License.

ember-command's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

sergeastapov

ember-command's Issues

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • Pin dependencies (@gossi/config-eslint, @gossi/config-prettier, @gossi/config-template-lint, @typescript-eslint/eslint-plugin, @typescript-eslint/parser, ember-template-lint, eslint, eslint-plugin-ember, prettier)
  • Pin dependencies (@types/qunit, @types/rsvp, @types/sinon)
  • Pin dependencies (concurrently, ember-qunit, ember-source-channel-url, ember-try, qunit, qunit-dom)
  • Update dependency @glint/core to ^1.4.0
  • Update dependency @glint/environment-ember-loose to ^1.4.0
  • Update dependency @glint/environment-ember-template-imports to v1.4.0
  • Update dependency @glint/template to ^1.4.0
  • Update dependency ember-cli-typescript to ^5.3.0
  • Update dependency ember-sinon-qunit to ^7.4.0
  • Update dependency release-it to ^16.3.0
  • Update dependency typescript to ^5.4.3
  • Update dependency webpack to ^5.91.0
  • Update pnpm to v8.15.6
  • Update Framework Dependencies (major) (@embroider/addon-dev, ember-resolver, ember-source)
  • Update Lint Dependencies (major) (@typescript-eslint/eslint-plugin, @typescript-eslint/parser, ember-template-lint, eslint-plugin-ember)
  • Update Node.js to v20
  • Update Testing Dependencies (major) (concurrently, ember-qunit, ember-try, qunit-dom)
  • Update actions/configure-pages action to v5
  • Update actions/deploy-pages action to v4
  • Update actions/upload-pages-artifact action to v3
  • Update dependency @types/sinon to v17
  • Update dependency ember-cli to v5
  • Update dependency ember-cli-babel to v8
  • Update dependency ember-concurrency to v4
  • Update dependency ember-template-imports to v4
  • Update dependency release-it to v17
  • Update dependency rollup to v4
  • Update dependency sinon to v17
  • Lock file maintenance
  • ๐Ÿ” Create all rate-limited PRs at once ๐Ÿ”

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/ci.yml
  • wyvox/action v1
  • wyvox/action v1
  • wyvox/action v1
  • wyvox/action v1
  • wyvox/action v1
  • wyvox/action v1
  • wyvox/action v1
  • wyvox/action v1
.github/workflows/docs.yml
  • wyvox/action v1
  • actions/configure-pages v3
  • actions/upload-pages-artifact v1
  • actions/deploy-pages v2
.github/workflows/release.yml
  • wyvox/action v1
npm
ember-command/package.json
  • @embroider/addon-shim ^1.8.6
  • @embroider/macros ^1.11.1
  • ember-sweet-owner ^0.2.0
  • @babel/core ^7.22.9
  • @babel/eslint-parser ^7.22.9
  • @babel/plugin-proposal-class-properties ^7.18.6
  • @babel/plugin-proposal-decorators ^7.22.7
  • @babel/preset-typescript ^7.22.5
  • @babel/runtime ^7.22.6
  • @ember/test-helpers ^3.2.0
  • @embroider/addon-dev ^3.2.0
  • @glimmer/component ^1.1.2
  • @glimmer/interfaces ^0.84.3
  • @glimmer/manager ^0.84.3
  • @glint/core ^1.0.2
  • @glint/environment-ember-loose ^1.0.2
  • @glint/environment-ember-template-imports ^1.0.2
  • @glint/template ^1.0.2
  • @gossi/config-eslint ^0.6.0
  • @gossi/config-prettier ^0.6.0
  • @gossi/config-template-lint ^0.6.0
  • @rollup/plugin-babel ^6.0.3
  • @rollup/plugin-node-resolve ^15.1.0
  • @rollup/plugin-typescript ^11.1.2
  • @release-it-plugins/lerna-changelog ^6.0.0
  • @tsconfig/ember ^3.0.0
  • @types/rsvp ^4.0.4
  • @typescript-eslint/eslint-plugin ^5.62.0
  • @typescript-eslint/parser ^5.62.0
  • concurrently ^8.2.0
  • ember-element-helper ^0.8.2
  • ember-link ^3.1.0
  • ember-source ~4.12.3
  • ember-template-lint ^5.11.2
  • ember-template-imports ^3.4.2
  • eslint ^8.48.0
  • eslint-plugin-ember ^11.11.1
  • prettier ^3.0.3
  • release-it ^16.2.1
  • rollup ^3.26.3
  • rollup-plugin-glimmer-template-tag ^0.4.1
  • typedoc ^0.25.7
  • typedoc-plugin-markdown ^4.0.0-next.43
  • typedoc-vitepress-theme ^1.0.0-next.7
  • typescript ^5.1.6
  • webpack ^5.88.2
  • @ember/test-helpers >=2.9.0
  • @glimmer/component ^1.1.2
  • ember-element-helper >=0.8.2
  • ember-link >=1.3.1
package.json
  • concurrently ^7.6.0
  • vitepress ^1.0.0-rc.20
  • node 18.17.1
  • pnpm 8.8.0
test-app/package.json
  • @babel/core ^7.22.9
  • @ember/optional-features ^2.0.0
  • @ember/string ^3.1.1
  • @ember/test-helpers ^3.2.0
  • @embroider/test-setup ^3.0.1
  • @embroider/webpack ^3.1.4
  • @embroider/compat ^3.2.0
  • @embroider/macros ^1.11.1
  • @glimmer/component ^1.1.2
  • @glimmer/tracking ^1.1.2
  • @glint/core ^1.0.2
  • @glint/template ^1.0.2
  • @glint/environment-ember-loose ^1.0.2
  • @glint/environment-ember-template-imports 1.0.2
  • @gossi/config-eslint ^0.6.0
  • @gossi/config-prettier ^0.6.0
  • @gossi/config-template-lint ^0.6.0
  • @tsconfig/ember ^3.0.0
  • @types/qunit ^2.19.6
  • @types/sinon ^10.0.15
  • @typescript-eslint/eslint-plugin ^5.62.0
  • @typescript-eslint/parser ^5.62.0
  • broccoli-asset-rev ^3.0.0
  • concurrently ^8.2.0
  • ember-auto-import ^2.6.3
  • ember-cli ~4.12.0
  • ember-cli-babel ^7.26.11
  • ember-cli-dependency-checker ^3.3.2
  • ember-cli-htmlbars ^6.2.0
  • ember-cli-inject-live-reload ^2.1.0
  • ember-cli-sri ^2.1.1
  • ember-cli-typescript ^5.2.1
  • ember-concurrency ^3.1.0
  • ember-disable-prototype-extensions ^1.1.3
  • ember-element-helper ^0.8.2
  • ember-link ^3.1.0
  • ember-load-initializers ^2.1.2
  • ember-qunit ^7.0.0
  • ember-resolver ^10.1.1
  • ember-sinon-qunit ^7.1.4
  • ember-source ~4.12.3
  • ember-source-channel-url ^3.0.0
  • ember-template-imports ^3.4.2
  • ember-template-lint ^5.11.2
  • ember-try ^2.0.0
  • eslint ^8.48.0
  • eslint-plugin-ember ^11.11.1
  • loader.js ^4.7.0
  • pnpm-sync-dependencies-meta-injected ^0.0.9
  • prettier ^3.0.3
  • qunit ^2.19.4
  • qunit-dom ^2.0.0
  • sinon ^15.2.0
  • typescript ^5.1.6
  • webpack ^5.88.2

  • Check this box to trigger a request for Renovate to run again on this repository

allow getters to make commands conditionally

allow this:

class Component {
  @command
  get myCommand() {
    if (someCond) {
      return [commandA, commandB];
    }
  }
}

at the moment, the @command decorator doesn't understand getters.

Add API Documentation

As part of #31 it was tried to add API docs (similar to ember-link) but typedoc cannot understand gts files and pointing it at dts files output of glint didn't create the expected output.

This needs some revisiting. Probably could be a package in ember that extracts APIs into a common format, that can be rendered by various tools. Ideally a format already in use.

Putting a TestLink into a `@command` will cause the tests to not prevent the transition

Simply:

<MyComponent @link={{link ...}}/>

inside the component:

export default class MyComponent extends Component {
  @command
  go = commandFor([
    this.args.link,
    this.somethingElse
  ]);
}

and then writing tests for this:

test('it can follow the link', function () {
  this.link = linkFor('somewhere');
  this.link.onTransitionTo = () => assert.step('link clicked');

  await render(hbs`<MyComponent @link={{this.link}}/>`);

  await click(...);

  assert.verifySteps(['link clicked']);
});

the click() will actually make the link to be transitioned and not prevented.

Accept `(set)` helper

Adding a "command" in template-only form with just (set) will break further execution. So let's accept it.

LinkCommand to accept a Link instance

Allow this to work:

class MyComponent extends Component {
  link = this.linkMananger.createLink({...});

  @command = commandFor([new LinkCommand(this.link)]);
}

which would enable this:

{{! invocation }}
<MyComponent @link={{link "..."}}/>
{{! template.hbs

<Button @push={{this.go}}>let's go</Button>

and

interface Args {
  link: Link;
}

class MyComponent extends Component<Args> {
  @command
  go = commandFor([
    new LinkCommand(this.args.link),
    new OtherCommand()
  ]);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.