Skip to content

Commit

Permalink
Add choose() directive (#2341)
Browse files Browse the repository at this point in the history
  • Loading branch information
justinfagnani committed Dec 8, 2021
1 parent fcc2b3d commit 1d563e8
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/plenty-planes-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'lit': minor
'lit-html': minor
---

Add choose() directive
4 changes: 4 additions & 0 deletions packages/lit-html/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
"development": "./development/directives/cache.js",
"default": "./directives/cache.js"
},
"./directives/choose.js": {
"development": "./development/directives/choose.js",
"default": "./directives/choose.js"
},
"./directives/class-map.js": {
"development": "./development/directives/class-map.js",
"default": "./directives/class-map.js"
Expand Down
1 change: 1 addition & 0 deletions packages/lit-html/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const defaultConfig = (options = {}) =>
'directives/async-append',
'directives/async-replace',
'directives/cache',
'directives/choose',
'directives/class-map',
'directives/guard',
'directives/if-defined',
Expand Down
45 changes: 45 additions & 0 deletions packages/lit-html/src/directives/choose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/

/**
* Chooses and evaluates a template function from a list based on matching
* the given `value` to a case.
*
* Cases are structured as `[caseValue, func]`. `value` is matched to
* `caseValue` by strict equality. The first match is selected. Case values
* can be of any type including primitives, objects, and symbols.
*
* This is similar to a switch statement, but as an expression and without
* fallthrough.
*
* @example
*
* ```ts
* render() {
* return html`
* ${choose(this.section, [
* ['home', () => <h1>Home</h1>]
* ['about', () => <h1>About</h1>]
* ],
* () => html`<h1>Error</h1>)}
* `;
* }
* ```
*/
export const choose = <T, V>(
value: T,
cases: Array<[T, () => V]>,
defaultCase?: () => V
) => {
for (const c of cases) {
const caseValue = c[0];
if (caseValue === value) {
const fn = c[1];
return fn();
}
}
return defaultCase?.();
};
48 changes: 48 additions & 0 deletions packages/lit-html/src/test/directives/choose_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
import {choose} from '../../directives/choose.js';
import {assert} from '@esm-bundle/chai';

suite('choose', () => {
test('no cases', () => {
assert.strictEqual(choose(1, []), undefined);
});

test('matching cases', () => {
assert.strictEqual(choose(1, [[1, () => 'A']]), 'A');
assert.strictEqual(
choose(2, [
[1, () => 'A'],
[2, () => 'B'],
]),
'B'
);

const a = {};
const b = {};
assert.strictEqual(
choose(b, [
[a, () => 'A'],
[b, () => 'B'],
]),
'B'
);
});

test('default case', () => {
assert.strictEqual(
choose(
3,
[
[1, () => 'A'],
[2, () => 'B'],
],
() => 'C'
),
'C'
);
});
});
3 changes: 3 additions & 0 deletions packages/lit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"./directives/cache.js": {
"default": "./directives/cache.js"
},
"./directives/choose.js": {
"default": "./directives/cache.js"
},
"./directives/class-map.js": {
"default": "./directives/class-map.js"
},
Expand Down
1 change: 1 addition & 0 deletions packages/lit/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default litProdConfig({
'directives/async-append',
'directives/async-replace',
'directives/cache',
'directives/choose',
'directives/class-map',
'directives/guard',
'directives/if-defined',
Expand Down
7 changes: 7 additions & 0 deletions packages/lit/src/directives/choose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/

export * from 'lit-html/directives/choose.js';

0 comments on commit 1d563e8

Please sign in to comment.