ember-source 7.3.0-alpha.5 → 7.4.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-metadata.json +3 -3
- package/dist/dev/packages/@ember/-internals/deprecations/index.js +9 -0
- package/dist/dev/packages/@ember/-internals/glimmer/index.js +7 -7
- package/dist/dev/packages/@ember/-internals/routing/index.js +2 -2
- package/dist/dev/packages/@ember/-internals/runtime/index.js +1 -1
- package/dist/dev/packages/@ember/-internals/runtime/lib/ext/rsvp.js +1 -1
- package/dist/dev/packages/@ember/-internals/runtime/lib/mixins/action_handler.js +4 -0
- package/dist/dev/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +3 -0
- package/dist/dev/packages/@ember/-internals/views/lib/mixins/action_support.js +2 -0
- package/dist/dev/packages/@ember/application/index.js +3 -3
- package/dist/dev/packages/@ember/application/instance.js +9 -9
- package/dist/dev/packages/@ember/component/helper.js +2 -2
- package/dist/dev/packages/@ember/component/index.js +3 -3
- package/dist/dev/packages/@ember/engine/index.js +3 -3
- package/dist/dev/packages/@ember/engine/instance.js +1 -1
- package/dist/dev/packages/@ember/helper/index.js +1132 -79
- package/dist/dev/packages/@ember/modifier/on.js +1 -1
- package/dist/dev/packages/@ember/object/compat.js +0 -32
- package/dist/dev/packages/@ember/renderer/index.js +1 -1
- package/dist/dev/packages/@ember/routing/-internals.js +2 -2
- package/dist/dev/packages/@ember/routing/index.js +11 -28
- package/dist/dev/packages/@ember/routing/lib/utils.js +2 -2
- package/dist/dev/packages/@ember/routing/route.js +2 -2
- package/dist/dev/packages/@ember/routing/router-service.js +9 -9
- package/dist/dev/packages/@ember/routing/router.js +2 -2
- package/dist/dev/packages/@ember/template-compiler/lib/compile-options.js +3 -3
- package/dist/dev/packages/@ember/template-compiler/lib/template.js +2 -2
- package/dist/dev/packages/@ember/template-factory/index.js +1 -1
- package/dist/dev/packages/@glimmer/opcode-compiler/index.js +2 -2
- package/dist/dev/packages/@glimmer/program/index.js +3 -3
- package/dist/dev/packages/@glimmer/runtime/index.js +7 -7
- package/dist/dev/packages/@glimmer/wire-format/index.js +2 -5
- package/dist/dev/packages/ember/version.js +1 -1
- package/dist/dev/packages/ember-template-compiler/index.js +2 -2
- package/dist/dev/packages/router_js/index.js +2 -2
- package/dist/dev/packages/rsvp/index.js +1 -2281
- package/dist/dev/packages/shared-chunks/{arguments-CDkbOqTS.js → arguments-DniR8eF2.js} +5 -18
- package/dist/dev/packages/shared-chunks/{compiler-QUSl_urU.js → compiler-BHFFl-fv.js} +1 -1
- package/dist/dev/packages/shared-chunks/{curly-BbL6STF2.js → curly-BCD_vyHq.js} +1 -1
- package/dist/dev/packages/shared-chunks/{element-BYLB-q7a.js → element-Cgoi4ldD.js} +0 -24
- package/dist/dev/packages/shared-chunks/get-zsePWrJL.js +40 -0
- package/dist/dev/packages/shared-chunks/hash-BFu91gtE.js +57 -0
- package/dist/dev/packages/shared-chunks/{index-DaFzpTIE.js → index-BYUSIu_W.js} +3 -3
- package/dist/dev/packages/shared-chunks/{index-Czn34wUZ.js → index-Bv9SQpEx.js} +218 -78
- package/dist/dev/packages/shared-chunks/{invoke-d9sqa50M.js → invoke-CgF42joE.js} +1 -1
- package/dist/dev/packages/shared-chunks/{not-DYh6AY9Z.js → not-0cVb-rLf.js} +1 -1
- package/dist/dev/packages/shared-chunks/{on-DlF0Wy7P.js → on-CVIjn2C-.js} +22 -11
- package/dist/dev/packages/shared-chunks/{opcodes-CplRyHl_.js → opcodes-DDajoGhq.js} +0 -4
- package/dist/dev/packages/shared-chunks/{outlet-B4qORyui.js → outlet-BO5-QFmm.js} +3 -3
- package/dist/dev/packages/shared-chunks/{program-context-Dq8xN2HI.js → program-context-BBB1Ga5h.js} +2 -2
- package/dist/dev/packages/shared-chunks/{render-CtH73XOv.js → render-D_Rawf-r.js} +2 -2
- package/dist/{prod/packages/shared-chunks/rsvp.es-DR7yS7qg.js → dev/packages/shared-chunks/rsvp-aLN_pQtn.js} +152 -148
- package/dist/dev/packages/shared-chunks/{setup-registry-h519ZsHS.js → setup-registry-Ci8Af2Bz.js} +35 -13
- package/dist/{prod/packages/shared-chunks/syscall-ops-CN7STuUn.js → dev/packages/shared-chunks/syscall-ops-CkPT1Kfx.js} +1 -2
- package/dist/dev/packages/shared-chunks/{textarea-DEvw4ezm.js → textarea-DvS6Xmdh.js} +3 -23
- package/dist/dev/packages/shared-chunks/{unique-id-DQOhouG1.js → unique-id-Csxuh1I7.js} +0 -4
- package/dist/dev/packages/shared-chunks/{unrecognized-url-error-B8loxkay.js → unrecognized-url-error-cXUp-SK3.js} +1 -1
- package/dist/prod/packages/@ember/-internals/deprecations/index.js +9 -0
- package/dist/prod/packages/@ember/-internals/glimmer/index.js +7 -7
- package/dist/prod/packages/@ember/-internals/routing/index.js +2 -2
- package/dist/prod/packages/@ember/-internals/runtime/index.js +1 -1
- package/dist/prod/packages/@ember/-internals/runtime/lib/ext/rsvp.js +1 -1
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/action_handler.js +4 -0
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +3 -0
- package/dist/prod/packages/@ember/-internals/views/lib/mixins/action_support.js +2 -0
- package/dist/prod/packages/@ember/application/index.js +3 -3
- package/dist/prod/packages/@ember/application/instance.js +9 -9
- package/dist/prod/packages/@ember/component/helper.js +2 -2
- package/dist/prod/packages/@ember/component/index.js +3 -3
- package/dist/prod/packages/@ember/engine/index.js +3 -3
- package/dist/prod/packages/@ember/engine/instance.js +1 -1
- package/dist/prod/packages/@ember/helper/index.js +1132 -79
- package/dist/prod/packages/@ember/modifier/on.js +1 -1
- package/dist/prod/packages/@ember/object/compat.js +0 -32
- package/dist/prod/packages/@ember/renderer/index.js +1 -1
- package/dist/prod/packages/@ember/routing/index.js +10 -27
- package/dist/prod/packages/@ember/routing/lib/utils.js +2 -2
- package/dist/prod/packages/@ember/routing/route.js +2 -2
- package/dist/prod/packages/@ember/routing/router-service.js +9 -9
- package/dist/prod/packages/@ember/routing/router.js +2 -2
- package/dist/prod/packages/@ember/template-compiler/lib/compile-options.js +3 -3
- package/dist/prod/packages/@ember/template-compiler/lib/template.js +2 -2
- package/dist/prod/packages/@ember/template-factory/index.js +1 -1
- package/dist/prod/packages/@glimmer/opcode-compiler/index.js +2 -2
- package/dist/prod/packages/@glimmer/program/index.js +3 -3
- package/dist/prod/packages/@glimmer/runtime/index.js +7 -7
- package/dist/prod/packages/@glimmer/wire-format/index.js +2 -5
- package/dist/prod/packages/ember/version.js +1 -1
- package/dist/prod/packages/ember-template-compiler/index.js +2 -2
- package/dist/prod/packages/router_js/index.js +2 -2
- package/dist/prod/packages/rsvp/index.js +1 -2281
- package/dist/prod/packages/shared-chunks/{arguments-BzAkZVBa.js → arguments-CCYATlEH.js} +1 -18
- package/dist/prod/packages/shared-chunks/{compiler-lBSssiWp.js → compiler-Wt5SWcrF.js} +1 -1
- package/dist/prod/packages/shared-chunks/{curly-CU2jYOtm.js → curly-CdvJuTyW.js} +1 -1
- package/dist/prod/packages/shared-chunks/{element-DgHdPZ8u.js → element-BmBjPjkQ.js} +0 -24
- package/dist/prod/packages/shared-chunks/get-CEjFJzGs.js +40 -0
- package/dist/prod/packages/shared-chunks/hash-BitfXhCx.js +57 -0
- package/dist/prod/packages/shared-chunks/{index-XmtQRWbX.js → index-D8cl-pfl.js} +218 -78
- package/dist/prod/packages/shared-chunks/{index-Bf53M8eS.js → index-kwuZeaNz.js} +3 -3
- package/dist/prod/packages/shared-chunks/{invoke-DhQ5QRp2.js → invoke-4JGJYH7Z.js} +1 -1
- package/dist/prod/packages/shared-chunks/{not-BOIVROuv.js → not-Dn5s9qVZ.js} +1 -1
- package/dist/prod/packages/shared-chunks/{on-BZHAxzdq.js → on-ov4KAucw.js} +22 -11
- package/dist/prod/packages/shared-chunks/{opcodes-CplRyHl_.js → opcodes-DDajoGhq.js} +0 -4
- package/dist/prod/packages/shared-chunks/{outlet-CsNMfeOj.js → outlet-BWnaVOrA.js} +3 -3
- package/dist/prod/packages/shared-chunks/{program-context-COSioH46.js → program-context-WVlzpPdi.js} +2 -2
- package/dist/prod/packages/shared-chunks/{render-Bf7GviCY.js → render-BAVl5E6X.js} +2 -2
- package/dist/{dev/packages/shared-chunks/rsvp.es-DR7yS7qg.js → prod/packages/shared-chunks/rsvp-aLN_pQtn.js} +152 -148
- package/dist/prod/packages/shared-chunks/{setup-registry-DFSQHIUs.js → setup-registry-DeyoFe6Q.js} +35 -13
- package/dist/{dev/packages/shared-chunks/syscall-ops-CN7STuUn.js → prod/packages/shared-chunks/syscall-ops-CkPT1Kfx.js} +1 -2
- package/dist/prod/packages/shared-chunks/{textarea-DMmdvgk2.js → textarea-B-sssXGa.js} +3 -23
- package/dist/prod/packages/shared-chunks/{unique-id-o2pS74go.js → unique-id-BJb1p8EG.js} +0 -4
- package/dist/prod/packages/shared-chunks/{unrecognized-url-error-jjQ-FqKB.js → unrecognized-url-error-xC654tCo.js} +1 -1
- package/docs/data.json +1237 -1395
- package/package.json +52 -47
- package/types/stable/@ember/-internals/deprecations/index.d.ts +6 -0
- package/types/stable/@ember/-internals/glimmer/index.d.ts +7 -380
- package/types/stable/@ember/-internals/glimmer/lib/component.d.ts +1 -1
- package/types/stable/@ember/-internals/glimmer/lib/helper.d.ts +2 -2
- package/types/stable/@ember/-internals/glimmer/lib/helpers/each-in.d.ts +196 -63
- package/types/stable/@ember/-internals/glimmer/lib/helpers/element.d.ts +0 -24
- package/types/stable/@ember/-internals/glimmer/lib/helpers/mut.d.ts +3 -2
- package/types/stable/@ember/-internals/glimmer/lib/helpers/readonly.d.ts +3 -1
- package/types/stable/@ember/-internals/glimmer/lib/helpers/unbound.d.ts +6 -2
- package/types/stable/@ember/-internals/glimmer/lib/helpers/unique-id.d.ts +0 -3
- package/types/stable/@ember/-internals/glimmer/lib/syntax/mount.d.ts +4 -2
- package/types/stable/@ember/-internals/glimmer/lib/syntax/outlet.d.ts +7 -2
- package/types/stable/@ember/helper/index.d.ts +1113 -73
- package/types/stable/@ember/object/compat.d.ts +0 -32
- package/types/stable/@ember/object/core.d.ts +1 -1
- package/types/stable/@ember/routing/router-service.d.ts +9 -9
- package/types/stable/@glimmer/interfaces/lib/compile/wire-format/api.d.ts +1 -9
- package/types/stable/@glimmer/interfaces/lib/compile/wire-format/opcodes.d.ts +0 -4
- package/types/stable/@glimmer/interfaces/lib/vm-opcodes.d.ts +0 -4
- package/types/stable/@glimmer/opcode-compiler/lib/opcode-builder/helpers/conditional.d.ts +1 -1
- package/types/stable/@glimmer/opcode-compiler/lib/syntax/statements.d.ts +1 -1
- package/types/stable/@glimmer/runtime/lib/helpers/array.d.ts +0 -33
- package/types/stable/@glimmer/runtime/lib/helpers/concat.d.ts +0 -25
- package/types/stable/@glimmer/runtime/lib/helpers/fn.d.ts +0 -70
- package/types/stable/@glimmer/runtime/lib/helpers/get.d.ts +0 -69
- package/types/stable/@glimmer/runtime/lib/helpers/hash.d.ts +0 -36
- package/types/stable/index.d.ts +0 -14
- package/dist/dev/packages/shared-chunks/get-6I3sjd-I.js +0 -135
- package/dist/dev/packages/shared-chunks/hash-6NDs_5_f.js +0 -198
- package/dist/prod/packages/shared-chunks/get-Dago5uGl.js +0 -135
- package/dist/prod/packages/shared-chunks/hash-gEXIsSO4.js +0 -198
- package/types/stable/@ember/-internals/glimmer/lib/helpers/array.d.ts +0 -43
- package/types/stable/@ember/-internals/glimmer/lib/helpers/component.d.ts +0 -93
- package/types/stable/@ember/-internals/glimmer/lib/helpers/concat.d.ts +0 -32
- package/types/stable/@ember/-internals/glimmer/lib/helpers/fn.d.ts +0 -77
- package/types/stable/@ember/-internals/glimmer/lib/helpers/get.d.ts +0 -94
- package/types/stable/@ember/-internals/glimmer/lib/helpers/hash.d.ts +0 -46
- package/types/stable/@ember/-internals/glimmer/lib/helpers/helper.d.ts +0 -43
- package/types/stable/@ember/-internals/glimmer/lib/helpers/if-unless.d.ts +0 -228
- package/types/stable/@ember/-internals/glimmer/lib/helpers/log.d.ts +0 -19
- package/types/stable/@ember/-internals/glimmer/lib/helpers/modifier.d.ts +0 -42
- package/types/stable/@ember/-internals/glimmer/lib/helpers/page-title.d.ts +0 -24
- package/types/stable/@ember/-internals/glimmer/lib/modifiers/on.d.ts +0 -95
- package/types/stable/@ember/-internals/glimmer/lib/syntax/in-element.d.ts +0 -49
- package/types/stable/@ember/-internals/glimmer/lib/syntax/let.d.ts +0 -43
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { b as setHelperManager$1 } from '../../shared-chunks/api-B_poQGXS.js';
|
|
2
2
|
import { i as helperCapabilities } from '../../shared-chunks/api-DlJKfm_f.js';
|
|
3
|
-
import { i as invokeHelper$1 } from '../../shared-chunks/invoke-
|
|
4
|
-
import { a as array$1, f as fn$1, h as hash$1 } from '../../shared-chunks/hash-
|
|
5
|
-
import { c as concat$1, g as get$1 } from '../../shared-chunks/get-
|
|
6
|
-
import { a as and$1, e as eq$1, g as gt$1, b as gte$1, l as lt$1, c as lte$1, n as neq$1, d as not$1, o as or$1 } from '../../shared-chunks/not-
|
|
7
|
-
import { e as element$1 } from '../../shared-chunks/element-
|
|
8
|
-
import { u as uniqueId$1 } from '../../shared-chunks/unique-id-
|
|
3
|
+
import { i as invokeHelper$1 } from '../../shared-chunks/invoke-4JGJYH7Z.js';
|
|
4
|
+
import { a as array$1, f as fn$1, h as hash$1 } from '../../shared-chunks/hash-BitfXhCx.js';
|
|
5
|
+
import { c as concat$1, g as get$1 } from '../../shared-chunks/get-CEjFJzGs.js';
|
|
6
|
+
import { a as and$1, e as eq$1, g as gt$1, b as gte$1, l as lt$1, c as lte$1, n as neq$1, d as not$1, o as or$1 } from '../../shared-chunks/not-Dn5s9qVZ.js';
|
|
7
|
+
import { e as element$1 } from '../../shared-chunks/element-BmBjPjkQ.js';
|
|
8
|
+
import { u as uniqueId$1 } from '../../shared-chunks/unique-id-BJb1p8EG.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
@module @ember/helper
|
|
@@ -56,11 +56,12 @@ import { u as uniqueId$1 } from '../../shared-chunks/unique-id-o2pS74go.js';
|
|
|
56
56
|
capability is enabled.
|
|
57
57
|
|
|
58
58
|
@method capabilities
|
|
59
|
-
@for @ember/helper
|
|
60
59
|
@static
|
|
60
|
+
@for @ember/helper
|
|
61
61
|
@param {String} managerApiVersion The version of capabilities that are being used
|
|
62
62
|
@param options The capabilities values
|
|
63
63
|
@return {Capabilities} The capabilities object instance
|
|
64
|
+
@since 3.23.0
|
|
64
65
|
@public
|
|
65
66
|
*/
|
|
66
67
|
const capabilities = helperCapabilities;
|
|
@@ -255,6 +256,7 @@ const capabilities = helperCapabilities;
|
|
|
255
256
|
@param {Function} factory A factory function which receives an optional owner, and returns a helper manager
|
|
256
257
|
@param {object} definition The definition to associate the manager factory with
|
|
257
258
|
@return {object} The definition passed into setHelperManager
|
|
259
|
+
@since 3.23.0
|
|
258
260
|
@public
|
|
259
261
|
*/
|
|
260
262
|
const setHelperManager = setHelperManager$1;
|
|
@@ -266,8 +268,7 @@ const setHelperManager = setHelperManager$1;
|
|
|
266
268
|
To access a helper's value you have to use `getValue` from
|
|
267
269
|
`@glimmer/tracking/primitives/cache`.
|
|
268
270
|
|
|
269
|
-
```js
|
|
270
|
-
// app/components/data-loader.js
|
|
271
|
+
```gjs {data-filename="app/components/data-loader.js"}
|
|
271
272
|
import Component from '@glimmer/component';
|
|
272
273
|
import { getValue } from '@glimmer/tracking/primitives/cache';
|
|
273
274
|
import Helper from '@ember/component/helper';
|
|
@@ -290,9 +291,10 @@ const setHelperManager = setHelperManager$1;
|
|
|
290
291
|
return getValue(this.plusOne);
|
|
291
292
|
}
|
|
292
293
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
294
|
+
|
|
295
|
+
<template>
|
|
296
|
+
{{this.value}}
|
|
297
|
+
</template>
|
|
296
298
|
```
|
|
297
299
|
|
|
298
300
|
It receives three arguments:
|
|
@@ -320,6 +322,7 @@ const setHelperManager = setHelperManager$1;
|
|
|
320
322
|
@param {object} definition The helper definition
|
|
321
323
|
@param {Function} computeArgs An optional function that produces args
|
|
322
324
|
@returns
|
|
325
|
+
@since 3.23.0
|
|
323
326
|
@public
|
|
324
327
|
*/
|
|
325
328
|
const invokeHelper = invokeHelper$1;
|
|
@@ -335,21 +338,42 @@ const invokeHelper = invokeHelper$1;
|
|
|
335
338
|
* Using the `{{hash}}` helper, you can pass objects directly from the template
|
|
336
339
|
* as an argument to your components.
|
|
337
340
|
*
|
|
338
|
-
* ```
|
|
341
|
+
* ```gjs
|
|
339
342
|
* <template>
|
|
340
343
|
* {{#each-in (hash givenName='Jen' familyName='Weber') as |key value|}}
|
|
341
344
|
* <p>{{key}}: {{value}}</p>
|
|
342
345
|
* {{/each-in}}
|
|
343
346
|
* </template>
|
|
344
347
|
* ```
|
|
348
|
+
*
|
|
349
|
+
*
|
|
350
|
+
* Note that the hash is an empty object with no prototype chain, therefore
|
|
351
|
+
* common methods like `toString` are not available in the resulting hash.
|
|
352
|
+
* If you need to use such a method, you can use the `call` or `apply`
|
|
353
|
+
* approach:
|
|
354
|
+
*
|
|
355
|
+
* ```js
|
|
356
|
+
* function toString(obj) {
|
|
357
|
+
* return Object.prototype.toString.apply(obj);
|
|
358
|
+
* }
|
|
359
|
+
* ```
|
|
360
|
+
* The `hash` helper is available as a keyword and does not need to be imported.
|
|
361
|
+
*
|
|
362
|
+
* @method hash
|
|
363
|
+
* @public
|
|
364
|
+
* @static
|
|
365
|
+
* @for Keywords
|
|
366
|
+
* @noimport
|
|
367
|
+
* @param {Object} options
|
|
368
|
+
* @return {Object} Hash
|
|
369
|
+
* @since 2.3.0
|
|
345
370
|
*/
|
|
346
371
|
const hash = hash$1;
|
|
347
372
|
/**
|
|
348
373
|
* Using the `{{array}}` helper, you can pass arrays directly from the template
|
|
349
374
|
* as an argument to your components.
|
|
350
375
|
*
|
|
351
|
-
* ```
|
|
352
|
-
*
|
|
376
|
+
* ```gjs
|
|
353
377
|
* <template>
|
|
354
378
|
* <ul>
|
|
355
379
|
* {{#each (array 'Tom Dale' 'Yehuda Katz' @anotherPerson) as |person|}}
|
|
@@ -358,25 +382,46 @@ const hash = hash$1;
|
|
|
358
382
|
* </ul>
|
|
359
383
|
* </template>
|
|
360
384
|
* ```
|
|
385
|
+
*
|
|
386
|
+
* The `array` helper is available as a keyword and does not need to be imported.
|
|
387
|
+
*
|
|
388
|
+
* @method array
|
|
389
|
+
* @public
|
|
390
|
+
* @static
|
|
391
|
+
* @for Keywords
|
|
392
|
+
* @noimport
|
|
393
|
+
* @param {Array} options
|
|
394
|
+
* @return {Array} Array
|
|
395
|
+
* @since 3.8.0
|
|
361
396
|
*/
|
|
362
397
|
const array = array$1;
|
|
363
398
|
/**
|
|
364
|
-
* The `{{concat}}` helper
|
|
365
|
-
* parameters to a component or helper as a single parameter in the format of a
|
|
366
|
-
* concatenated string.
|
|
399
|
+
* The `{{concat}}` helper Concatenates the given arguments into a string.
|
|
367
400
|
*
|
|
368
|
-
*
|
|
401
|
+
* Example:
|
|
369
402
|
*
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
403
|
+
```gjs
|
|
404
|
+
import { concat } from '@ember/helper';
|
|
405
|
+
|
|
406
|
+
<template>
|
|
407
|
+
{{yield (concat firstName " " lastName)}}
|
|
408
|
+
|
|
409
|
+
{{! would yield name="<first name value> <last name value>" to the component}}
|
|
410
|
+
</template>
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
or for angle bracket invocation, you actually don't need concat at all:
|
|
414
|
+
|
|
415
|
+
```handlebars
|
|
416
|
+
<SomeComponent @name="{{firstName}} {{lastName}}" />
|
|
417
|
+
```
|
|
377
418
|
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
419
|
+
* @method concat
|
|
420
|
+
* @for @ember/helper
|
|
421
|
+
* @exampleimport import { concat } from '@ember/helper';
|
|
422
|
+
* @public
|
|
423
|
+
* @static
|
|
424
|
+
* @since 1.13.0
|
|
380
425
|
*/
|
|
381
426
|
const concat = concat$1;
|
|
382
427
|
/**
|
|
@@ -386,7 +431,7 @@ const concat = concat$1;
|
|
|
386
431
|
*
|
|
387
432
|
* To access a property on an object with a string key:
|
|
388
433
|
*
|
|
389
|
-
* ```
|
|
434
|
+
* ```gjs
|
|
390
435
|
* import { get } from '@ember/helper';
|
|
391
436
|
*
|
|
392
437
|
* <template>
|
|
@@ -396,7 +441,7 @@ const concat = concat$1;
|
|
|
396
441
|
*
|
|
397
442
|
* To access the first element in an array:
|
|
398
443
|
*
|
|
399
|
-
* ```
|
|
444
|
+
* ```gjs
|
|
400
445
|
* import { get } from '@ember/helper';
|
|
401
446
|
*
|
|
402
447
|
* <template>
|
|
@@ -406,7 +451,7 @@ const concat = concat$1;
|
|
|
406
451
|
*
|
|
407
452
|
* To access a property on an object with a dynamic key:
|
|
408
453
|
*
|
|
409
|
-
* ```
|
|
454
|
+
* ```gjs
|
|
410
455
|
* import { get } from '@ember/helper';
|
|
411
456
|
*
|
|
412
457
|
* <template>
|
|
@@ -416,6 +461,13 @@ const concat = concat$1;
|
|
|
416
461
|
*
|
|
417
462
|
* This will display the result of `@foo.item1` when `index` is `1`, and
|
|
418
463
|
* `this.foo.item2` when `index` is `2`, etc.
|
|
464
|
+
*
|
|
465
|
+
* @method get
|
|
466
|
+
* @for @ember/helper
|
|
467
|
+
* @since 2.1.0
|
|
468
|
+
* @exampleimport import { get } from '@ember/helper';
|
|
469
|
+
* @public
|
|
470
|
+
* @static
|
|
419
471
|
*/
|
|
420
472
|
const get = get$1;
|
|
421
473
|
/**
|
|
@@ -423,9 +475,7 @@ const get = get$1;
|
|
|
423
475
|
* a new function that combines. This allows you to pass parameters along to
|
|
424
476
|
* functions in your templates:
|
|
425
477
|
*
|
|
426
|
-
* ```
|
|
427
|
-
* import { fn } from '@ember/helper';
|
|
428
|
-
*
|
|
478
|
+
* ```gjs
|
|
429
479
|
* function showAlert(message) {
|
|
430
480
|
* alert(`The message is: '${message}'`);
|
|
431
481
|
* }
|
|
@@ -436,98 +486,153 @@ const get = get$1;
|
|
|
436
486
|
* </button>
|
|
437
487
|
* </template>
|
|
438
488
|
* ```
|
|
489
|
+
*
|
|
490
|
+
* For example, if you have an `each` helper looping over a number of items, you
|
|
491
|
+
* may need to pass a function that expects to receive the item as an argument
|
|
492
|
+
* to a component invoked within the loop. Here's how you could use the `fn`
|
|
493
|
+
* helper to pass both the function and its arguments together:
|
|
494
|
+
*
|
|
495
|
+
* ```gjs {data-filename="app/components/items-listing.gjs"}
|
|
496
|
+
* <template>
|
|
497
|
+
* {{#each @items as |item|}}
|
|
498
|
+
* <DisplayItem @item=item @select={{fn this.handleSelected item}} />
|
|
499
|
+
* {{/each}}
|
|
500
|
+
* </template>
|
|
501
|
+
* ```
|
|
502
|
+
*
|
|
503
|
+
* ```gjs {data-filename="app/components/items-list.gjs"}
|
|
504
|
+
* import Component from '@glimmer/component';
|
|
505
|
+
* import { action } from '@ember/object';
|
|
506
|
+
*
|
|
507
|
+
* export default class ItemsList extends Component {
|
|
508
|
+
* @action
|
|
509
|
+
* handleSelected(item) {
|
|
510
|
+
* // ...snip...
|
|
511
|
+
* }
|
|
512
|
+
* }
|
|
513
|
+
* ```
|
|
514
|
+
*
|
|
515
|
+
* In this case the `DisplayItem` component will receive a normal function
|
|
516
|
+
* that it can invoke. When it invokes the function, the `handleSelected`
|
|
517
|
+
* function will receive the `item` and any arguments passed, thanks to the
|
|
518
|
+
* `fn` helper.
|
|
519
|
+
*
|
|
520
|
+
* Let's take a look at what that means in a couple circumstances:
|
|
521
|
+
*
|
|
522
|
+
* - When invoked as `this.args.select()` the `handleSelected` function will
|
|
523
|
+
* receive the `item` from the loop as its first and only argument.
|
|
524
|
+
* - When invoked as `this.args.select('foo')` the `handleSelected` function
|
|
525
|
+
* will receive the `item` from the loop as its first argument and the
|
|
526
|
+
* string `'foo'` as its second argument.
|
|
527
|
+
*
|
|
528
|
+
* See also [partial application](https://en.wikipedia.org/wiki/Partial_application).
|
|
529
|
+
*
|
|
530
|
+
* The `fn` helper is available as a keyword and does not need to be imported.
|
|
531
|
+
*
|
|
532
|
+
* @method fn
|
|
533
|
+
* @for Keywords
|
|
534
|
+
* @noimport
|
|
535
|
+
* @public
|
|
536
|
+
* @since 3.11.0
|
|
537
|
+
* @static
|
|
439
538
|
*/
|
|
440
539
|
const fn = fn$1;
|
|
441
540
|
/**
|
|
442
541
|
* The `{{gt}}` helper returns `true` if the first argument is greater than
|
|
443
542
|
* the second argument.
|
|
444
543
|
*
|
|
445
|
-
* ```
|
|
446
|
-
* import { gt } from '@ember/helper';
|
|
447
|
-
*
|
|
544
|
+
* ```gjs
|
|
448
545
|
* <template>
|
|
449
546
|
* {{if (gt @score 100) "High score!" "Keep trying"}}
|
|
450
547
|
* </template>
|
|
451
548
|
* ```
|
|
452
549
|
*
|
|
453
|
-
*
|
|
454
|
-
* does not need to be imported.
|
|
550
|
+
* The `gt` helper is available as a keyword and does not need to be imported.
|
|
455
551
|
*
|
|
456
552
|
* @method gt
|
|
457
553
|
* @param {number} left
|
|
458
554
|
* @param {number} right
|
|
459
555
|
* @return {boolean}
|
|
556
|
+
* @noimport
|
|
557
|
+
* @for Keywords
|
|
558
|
+
* @since 7.1.0
|
|
559
|
+
* @static
|
|
560
|
+
* @public
|
|
460
561
|
*/
|
|
461
562
|
const gt = gt$1;
|
|
462
563
|
/**
|
|
463
564
|
* The `{{gte}}` helper returns `true` if the first argument is greater than
|
|
464
565
|
* or equal to the second argument.
|
|
465
566
|
*
|
|
466
|
-
* ```
|
|
467
|
-
* import { gte } from '@ember/helper';
|
|
468
|
-
*
|
|
567
|
+
* ```gjs
|
|
469
568
|
* <template>
|
|
470
569
|
* {{if (gte @age 18) "Adult" "Minor"}}
|
|
471
570
|
* </template>
|
|
472
571
|
* ```
|
|
473
572
|
*
|
|
474
|
-
*
|
|
475
|
-
* does not need to be imported.
|
|
573
|
+
* The `gte` helper is available as a keyword and does not need to be imported.
|
|
476
574
|
*
|
|
477
575
|
* @method gte
|
|
478
576
|
* @param {number} left
|
|
479
577
|
* @param {number} right
|
|
480
578
|
* @return {boolean}
|
|
579
|
+
* @noimport
|
|
580
|
+
* @for Keywords
|
|
581
|
+
* @since 7.1.0
|
|
582
|
+
* @static
|
|
583
|
+
* @public
|
|
481
584
|
*/
|
|
482
585
|
const gte = gte$1;
|
|
483
586
|
/**
|
|
484
587
|
* The `{{lt}}` helper returns `true` if the first argument is less than
|
|
485
588
|
* the second argument.
|
|
486
589
|
*
|
|
487
|
-
* ```
|
|
488
|
-
* import { lt } from '@ember/helper';
|
|
489
|
-
*
|
|
590
|
+
* ```gjs
|
|
490
591
|
* <template>
|
|
491
592
|
* {{if (lt @temperature 0) "Freezing" "Above zero"}}
|
|
492
593
|
* </template>
|
|
493
594
|
* ```
|
|
494
595
|
*
|
|
495
|
-
*
|
|
496
|
-
* does not need to be imported.
|
|
596
|
+
* The `lt` helper is available as a keyword and does not need to be imported.
|
|
497
597
|
*
|
|
498
598
|
* @method lt
|
|
499
599
|
* @param {number} left
|
|
500
600
|
* @param {number} right
|
|
501
601
|
* @return {boolean}
|
|
602
|
+
* @noimport
|
|
603
|
+
* @for Keywords
|
|
604
|
+
* @since 7.1.0
|
|
605
|
+
* @static
|
|
606
|
+
* @public
|
|
502
607
|
*/
|
|
503
608
|
const lt = lt$1;
|
|
504
609
|
/**
|
|
505
610
|
* The `{{lte}}` helper returns `true` if the first argument is less than
|
|
506
611
|
* or equal to the second argument.
|
|
507
612
|
*
|
|
508
|
-
* ```
|
|
509
|
-
* import { lte } from '@ember/helper';
|
|
510
|
-
*
|
|
613
|
+
* ```gjs
|
|
511
614
|
* <template>
|
|
512
615
|
* {{if (lte @count 0) "Empty" "Has items"}}
|
|
513
616
|
* </template>
|
|
514
617
|
* ```
|
|
515
618
|
*
|
|
516
|
-
*
|
|
517
|
-
* does not need to be imported.
|
|
619
|
+
* The `lte` helper is available as a keyword and does not need to be imported.
|
|
518
620
|
*
|
|
519
621
|
* @method lte
|
|
520
622
|
* @param {number} left
|
|
521
623
|
* @param {number} right
|
|
522
624
|
* @return {boolean}
|
|
625
|
+
* @noimport
|
|
626
|
+
* @for Keywords
|
|
627
|
+
* @since 7.1.0
|
|
628
|
+
* @static
|
|
629
|
+
* @public
|
|
523
630
|
*/
|
|
524
631
|
const lte = lte$1;
|
|
525
632
|
/**
|
|
526
633
|
* The `element` helper lets you dynamically set the tag name of an element.
|
|
527
634
|
*
|
|
528
|
-
* ```
|
|
529
|
-
* import { element } from '@ember/helper';
|
|
530
|
-
*
|
|
635
|
+
* ```gjs
|
|
531
636
|
* <template>
|
|
532
637
|
* {{#let (element @tagName) as |Tag|}}
|
|
533
638
|
* <Tag class="my-element">Hello</Tag>
|
|
@@ -539,8 +644,15 @@ const lte = lte$1;
|
|
|
539
644
|
* When `@tagName` is an empty string, the block content is rendered without a
|
|
540
645
|
* wrapping element. When `@tagName` is `null` or `undefined`, nothing is rendered.
|
|
541
646
|
*
|
|
647
|
+
* The `element` helper is available as a keyword and does not need to be imported.
|
|
648
|
+
*
|
|
542
649
|
* @method element
|
|
543
650
|
* @param {string} tagName
|
|
651
|
+
* @noimport
|
|
652
|
+
* @for Keywords
|
|
653
|
+
* @since 7.1.0
|
|
654
|
+
* @static
|
|
655
|
+
* @public
|
|
544
656
|
*/
|
|
545
657
|
const element = element$1;
|
|
546
658
|
/**
|
|
@@ -550,7 +662,7 @@ const element = element$1;
|
|
|
550
662
|
* Each invocation of {{uniqueId}} will return a new, unique ID string.
|
|
551
663
|
* You can use the `let` helper to create an ID that can be reused within a template.
|
|
552
664
|
*
|
|
553
|
-
* ```
|
|
665
|
+
* ```gjs
|
|
554
666
|
* import { uniqueId } from '@ember/helper';
|
|
555
667
|
*
|
|
556
668
|
* <template>
|
|
@@ -560,48 +672,59 @@ const element = element$1;
|
|
|
560
672
|
* {{/let}}
|
|
561
673
|
* </template>
|
|
562
674
|
* ```
|
|
675
|
+
*
|
|
676
|
+
* @method uniqueId
|
|
677
|
+
* @for @ember/helper
|
|
678
|
+
* @public
|
|
679
|
+
* @static
|
|
680
|
+
* @exampleimport import { uniqueId } from '@ember/helper';
|
|
681
|
+
* @since 4.4.0
|
|
563
682
|
*/
|
|
564
683
|
const uniqueId = uniqueId$1;
|
|
565
684
|
/**
|
|
566
685
|
* The `{{eq}}` helper returns `true` if its two arguments are strictly equal
|
|
567
686
|
* (`===`). Takes exactly two arguments.
|
|
568
687
|
*
|
|
569
|
-
* ```
|
|
570
|
-
* import { eq } from '@ember/helper';
|
|
571
|
-
*
|
|
688
|
+
* ```gjs
|
|
572
689
|
* <template>
|
|
573
690
|
* {{if (eq @status "active") "Active" "Inactive"}}
|
|
574
691
|
* </template>
|
|
575
692
|
* ```
|
|
576
693
|
*
|
|
577
|
-
*
|
|
578
|
-
* does not need to be imported.
|
|
694
|
+
* The `eq` helper is available as a keyword and does not need to be imported.
|
|
579
695
|
*
|
|
580
696
|
* @method eq
|
|
581
697
|
* @param {unknown} left
|
|
582
698
|
* @param {unknown} right
|
|
583
699
|
* @return {boolean}
|
|
700
|
+
* @noimport
|
|
701
|
+
* @for Keywords
|
|
702
|
+
* @static
|
|
703
|
+
* @since 7.1.0
|
|
704
|
+
* @public
|
|
584
705
|
*/
|
|
585
706
|
const eq = eq$1;
|
|
586
707
|
/**
|
|
587
708
|
* The `{{neq}}` helper returns `true` if its two arguments are strictly
|
|
588
709
|
* not equal (`!==`). Takes exactly two arguments.
|
|
589
710
|
*
|
|
590
|
-
* ```
|
|
591
|
-
* import { neq } from '@ember/helper';
|
|
592
|
-
*
|
|
711
|
+
* ```gjs
|
|
593
712
|
* <template>
|
|
594
713
|
* {{if (neq @status "active") "Not active" "Active"}}
|
|
595
714
|
* </template>
|
|
596
715
|
* ```
|
|
597
716
|
*
|
|
598
|
-
*
|
|
599
|
-
* does not need to be imported.
|
|
717
|
+
* The `neq` helper is available as a keyword and does not need to be imported.
|
|
600
718
|
*
|
|
601
719
|
* @method neq
|
|
602
720
|
* @param {unknown} left
|
|
603
721
|
* @param {unknown} right
|
|
604
722
|
* @return {boolean}
|
|
723
|
+
* @for Keywords
|
|
724
|
+
* @noimport
|
|
725
|
+
* @static
|
|
726
|
+
* @since 7.1.0
|
|
727
|
+
* @public
|
|
605
728
|
*/
|
|
606
729
|
const neq = neq$1;
|
|
607
730
|
/**
|
|
@@ -609,20 +732,22 @@ const neq = neq$1;
|
|
|
609
732
|
* falsy value (using Handlebars truthiness) or the right-most value if all
|
|
610
733
|
* are truthy. Requires at least two arguments.
|
|
611
734
|
*
|
|
612
|
-
* ```
|
|
613
|
-
* import { and } from '@ember/helper';
|
|
614
|
-
*
|
|
735
|
+
* ```gjs
|
|
615
736
|
* <template>
|
|
616
737
|
* {{if (and @isAdmin @isLoggedIn) "Welcome, admin!" "Access denied"}}
|
|
617
738
|
* </template>
|
|
618
739
|
* ```
|
|
619
740
|
*
|
|
620
|
-
*
|
|
621
|
-
* does not need to be imported.
|
|
741
|
+
* The `and` helper is available as a keyword and does not need to be imported.
|
|
622
742
|
*
|
|
623
743
|
* @method and
|
|
624
744
|
* @param {unknown} args Two or more values to evaluate
|
|
625
745
|
* @return {unknown} The first falsy value or the last value
|
|
746
|
+
* @noimport
|
|
747
|
+
* @for Keywords
|
|
748
|
+
* @static
|
|
749
|
+
* @since 7.1.0
|
|
750
|
+
* @public
|
|
626
751
|
*/
|
|
627
752
|
const and = and$1;
|
|
628
753
|
/**
|
|
@@ -630,9 +755,7 @@ const and = and$1;
|
|
|
630
755
|
* truthy value (using Handlebars truthiness) or the right-most value if all
|
|
631
756
|
* are falsy. Requires at least two arguments.
|
|
632
757
|
*
|
|
633
|
-
* ```
|
|
634
|
-
* import { or } from '@ember/helper';
|
|
635
|
-
*
|
|
758
|
+
* ```gjs
|
|
636
759
|
* <template>
|
|
637
760
|
* {{if (or @hasAccess @isAdmin) "Welcome!" "No access"}}
|
|
638
761
|
* </template>
|
|
@@ -644,15 +767,18 @@ const and = and$1;
|
|
|
644
767
|
* @method or
|
|
645
768
|
* @param {unknown} args Two or more values to evaluate
|
|
646
769
|
* @return {unknown} The first truthy value or the last value
|
|
770
|
+
* @noimport
|
|
771
|
+
* @for Keywords
|
|
772
|
+
* @static
|
|
773
|
+
* @since 7.1.0
|
|
774
|
+
* @public
|
|
647
775
|
*/
|
|
648
776
|
const or = or$1;
|
|
649
777
|
/**
|
|
650
778
|
* The `{{not}}` helper returns the logical negation of its argument using
|
|
651
779
|
* Handlebars truthiness. Takes exactly one argument.
|
|
652
780
|
*
|
|
653
|
-
* ```
|
|
654
|
-
* import { not } from '@ember/helper';
|
|
655
|
-
*
|
|
781
|
+
* ```gjs
|
|
656
782
|
* <template>
|
|
657
783
|
* {{if (not @isDisabled) "Enabled" "Disabled"}}
|
|
658
784
|
* </template>
|
|
@@ -664,9 +790,936 @@ const or = or$1;
|
|
|
664
790
|
* @method not
|
|
665
791
|
* @param {unknown} value The value to negate
|
|
666
792
|
* @return {boolean}
|
|
793
|
+
* @for Keywords
|
|
794
|
+
* @noimport
|
|
795
|
+
* @static
|
|
796
|
+
* @since 7.1.0
|
|
797
|
+
* @public
|
|
667
798
|
*/
|
|
668
799
|
const not = not$1;
|
|
669
800
|
|
|
801
|
+
/**
|
|
802
|
+
`{{yield}}` denotes an area of a template that will be rendered inside
|
|
803
|
+
of another template.
|
|
804
|
+
|
|
805
|
+
### Use with `Component`
|
|
806
|
+
|
|
807
|
+
When designing components, `{{yield}}` is used to denote where, inside the component's
|
|
808
|
+
template, an optional block passed to the component should render:
|
|
809
|
+
|
|
810
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
811
|
+
import LabeledTextField from '../components/labeled-textfield';
|
|
812
|
+
|
|
813
|
+
<template>
|
|
814
|
+
<LabeledTextField @value={{@model.name}}>
|
|
815
|
+
First name:
|
|
816
|
+
</LabeledTextField>
|
|
817
|
+
</template>
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
```gjs {data-filename="app/components/labeled-textfield.gjs"}
|
|
821
|
+
import { Input } from '@ember/component';
|
|
822
|
+
|
|
823
|
+
<template>
|
|
824
|
+
<label>
|
|
825
|
+
{{yield}} <Input @value={{@value}} />
|
|
826
|
+
</label>
|
|
827
|
+
</template>
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
Result:
|
|
831
|
+
|
|
832
|
+
```html
|
|
833
|
+
<label>
|
|
834
|
+
First name: <input type="text" />
|
|
835
|
+
</label>
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
Additionally, you can `yield` properties into the context for use by the consumer:
|
|
839
|
+
|
|
840
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
841
|
+
import Component from '@glimmer/component';
|
|
842
|
+
import LabeledTextField from '../components/labeled-textfield';
|
|
843
|
+
|
|
844
|
+
export default class Application extends Component {
|
|
845
|
+
firstNameValidator = (value) => {
|
|
846
|
+
// validates
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
<template>
|
|
850
|
+
<LabeledTextField @value={{@model.validation}} @validator={{this.firstNameValidator}} as |validationError|>
|
|
851
|
+
{{#if validationError}}
|
|
852
|
+
<p class="error">{{validationError}}</p>
|
|
853
|
+
{{/if}}
|
|
854
|
+
First name:
|
|
855
|
+
</LabeledTextField>
|
|
856
|
+
</template>
|
|
857
|
+
}
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
```gjs {data-filename="app/components/labeled-textfield.gjs"}
|
|
861
|
+
import { Input } from '@ember/component';
|
|
862
|
+
|
|
863
|
+
<template>
|
|
864
|
+
<label>
|
|
865
|
+
{{yield this.validationError}} <Input @value={{@value}} />
|
|
866
|
+
</label>
|
|
867
|
+
</template>
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
Result:
|
|
871
|
+
|
|
872
|
+
```html
|
|
873
|
+
<label>
|
|
874
|
+
<p class="error">First Name must be at least 3 characters long.</p>
|
|
875
|
+
First name: <input type="text" />
|
|
876
|
+
</label>
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
`yield` can also be used with the `hash` helper:
|
|
880
|
+
|
|
881
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
882
|
+
import DateRanges from '../components/date-ranges';
|
|
883
|
+
|
|
884
|
+
<template>
|
|
885
|
+
<DateRanges @value={{@model.date}} as |range|>
|
|
886
|
+
Start date: {{range.start}}
|
|
887
|
+
End date: {{range.end}}
|
|
888
|
+
</DateRanges>
|
|
889
|
+
</template>
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
```gjs {data-filename="app/components/date-ranges.gjs"}
|
|
893
|
+
<template>
|
|
894
|
+
<div>
|
|
895
|
+
{{yield (hash start=@value.start end=@value.end)}}
|
|
896
|
+
</div>
|
|
897
|
+
</template>
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
Result:
|
|
901
|
+
|
|
902
|
+
```html
|
|
903
|
+
<div>
|
|
904
|
+
Start date: July 1st
|
|
905
|
+
End date: July 30th
|
|
906
|
+
</div>
|
|
907
|
+
```
|
|
908
|
+
|
|
909
|
+
Multiple values can be yielded as block params:
|
|
910
|
+
|
|
911
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
912
|
+
import Banner from '../components/banner';
|
|
913
|
+
|
|
914
|
+
<template>
|
|
915
|
+
<Banner @value={{@model}} as |title subtitle body|>
|
|
916
|
+
<h1>{{title}}</h1>
|
|
917
|
+
<h2>{{subtitle}}</h2>
|
|
918
|
+
{{body}}
|
|
919
|
+
</Banner>
|
|
920
|
+
</template>
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
```gjs {data-filename="app/components/banner.gjs"}
|
|
924
|
+
<template>
|
|
925
|
+
<div>
|
|
926
|
+
{{yield "Hello title" "hello subtitle" "body text"}}
|
|
927
|
+
</div>
|
|
928
|
+
</template>
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
Result:
|
|
932
|
+
|
|
933
|
+
```html
|
|
934
|
+
<div>
|
|
935
|
+
<h1>Hello title</h1>
|
|
936
|
+
<h2>hello subtitle</h2>
|
|
937
|
+
body text
|
|
938
|
+
</div>
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
However, it is preferred to use the hash helper, as this can prevent breaking changes to your component and also simplify the api for the component.
|
|
942
|
+
|
|
943
|
+
Multiple components can be yielded with the `hash` and `component` helper:
|
|
944
|
+
|
|
945
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
946
|
+
import Banner from '../components/banner';
|
|
947
|
+
|
|
948
|
+
<template>
|
|
949
|
+
<Banner @value={{@model}} as |banner|>
|
|
950
|
+
<banner.Title>Banner title</banner.Title>
|
|
951
|
+
<banner.Subtitle>Banner subtitle</banner.Subtitle>
|
|
952
|
+
<banner.Body>A load of body text</banner.Body>
|
|
953
|
+
</Banner>
|
|
954
|
+
</template>
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
```gjs {data-filename="app/components/banner.gjs"}
|
|
958
|
+
import Title from './banner/title';
|
|
959
|
+
import Subtitle from './banner/subtitle';
|
|
960
|
+
import Body from './banner/body';
|
|
961
|
+
|
|
962
|
+
export default class Banner extends Component {
|
|
963
|
+
Title = Title;
|
|
964
|
+
Subtitle = Subtitle;
|
|
965
|
+
Body = Body;
|
|
966
|
+
|
|
967
|
+
<template>
|
|
968
|
+
<div>
|
|
969
|
+
{{yield (hash
|
|
970
|
+
Title=this.Title
|
|
971
|
+
Subtitle=this.Subtitle
|
|
972
|
+
Body=(component this.Body defaultArg="some value")
|
|
973
|
+
)}}
|
|
974
|
+
</div>
|
|
975
|
+
</template>
|
|
976
|
+
}
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
Result:
|
|
980
|
+
|
|
981
|
+
```html
|
|
982
|
+
<div>
|
|
983
|
+
<h1>Banner title</h1>
|
|
984
|
+
<h2>Banner subtitle</h2>
|
|
985
|
+
A load of body text
|
|
986
|
+
</div>
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
A benefit of using this pattern is that the user of the component can change the order the components are displayed.
|
|
990
|
+
|
|
991
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
992
|
+
import Banner from '../components/banner';
|
|
993
|
+
|
|
994
|
+
<template>
|
|
995
|
+
<Banner @value={{@model}} as |banner|>
|
|
996
|
+
<banner.Subtitle>Banner subtitle</banner.Subtitle>
|
|
997
|
+
<banner.Title>Banner title</banner.Title>
|
|
998
|
+
<banner.Body>A load of body text</banner.Body>
|
|
999
|
+
</Banner>
|
|
1000
|
+
</template>
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
Result:
|
|
1004
|
+
|
|
1005
|
+
```html
|
|
1006
|
+
<div>
|
|
1007
|
+
<h2>Banner subtitle</h2>
|
|
1008
|
+
<h1>Banner title</h1>
|
|
1009
|
+
A load of body text
|
|
1010
|
+
</div>
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
Another benefit to using `yield` with the `hash` and `component` helper
|
|
1014
|
+
is you can pass attributes and arguments to these components:
|
|
1015
|
+
|
|
1016
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1017
|
+
import Banner from '../components/banner';
|
|
1018
|
+
|
|
1019
|
+
<template>
|
|
1020
|
+
<Banner @value={{@model}} as |banner|>
|
|
1021
|
+
<banner.Subtitle class="mb-1">Banner subtitle</banner.Subtitle>
|
|
1022
|
+
<banner.Title @variant="loud">Banner title</banner.Title>
|
|
1023
|
+
<banner.Body>A load of body text</banner.Body>
|
|
1024
|
+
</Banner>
|
|
1025
|
+
</template>
|
|
1026
|
+
```
|
|
1027
|
+
|
|
1028
|
+
```gjs {data-filename="app/components/banner/subtitle.gjs"}
|
|
1029
|
+
{{!-- note the use of ..attributes --}}
|
|
1030
|
+
<h2 ...attributes>
|
|
1031
|
+
{{yield}}
|
|
1032
|
+
</h2>
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
```gjs {data-filename="app/components/banner/title.gjs"}
|
|
1036
|
+
<template>
|
|
1037
|
+
{{#if (eq @variant "loud")}}
|
|
1038
|
+
<h1 class="loud">{{yield}}</h1>
|
|
1039
|
+
{{else}}
|
|
1040
|
+
<h1 class="quiet">{{yield}}</h1>
|
|
1041
|
+
{{/if}}
|
|
1042
|
+
</template>
|
|
1043
|
+
```
|
|
1044
|
+
|
|
1045
|
+
Result:
|
|
1046
|
+
|
|
1047
|
+
```html
|
|
1048
|
+
<div>
|
|
1049
|
+
<h2 class="mb-1">Banner subtitle</h2>
|
|
1050
|
+
<h1 class="loud">Banner title</h1>
|
|
1051
|
+
A load of body text
|
|
1052
|
+
</div>
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
`yield` is available as a keyword and does not need to be imported.
|
|
1056
|
+
|
|
1057
|
+
@method yield
|
|
1058
|
+
@param {Hash} options
|
|
1059
|
+
@return {String} HTML string
|
|
1060
|
+
@static
|
|
1061
|
+
@for Keywords
|
|
1062
|
+
@noimport
|
|
1063
|
+
@public
|
|
1064
|
+
*/
|
|
1065
|
+
|
|
1066
|
+
/**
|
|
1067
|
+
`{{(has-block)}}` indicates if the component was invoked with a block.
|
|
1068
|
+
|
|
1069
|
+
This component is invoked with a block:
|
|
1070
|
+
|
|
1071
|
+
```handlebars
|
|
1072
|
+
<MyComponent>
|
|
1073
|
+
Hi Jen!
|
|
1074
|
+
</MyComponent>
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
This component is invoked without a block:
|
|
1078
|
+
|
|
1079
|
+
```handlebars
|
|
1080
|
+
<MyComponent />
|
|
1081
|
+
```
|
|
1082
|
+
|
|
1083
|
+
This is useful when you want to create a component that can optionally take a block
|
|
1084
|
+
and then render a default template when it is not invoked with a block.
|
|
1085
|
+
|
|
1086
|
+
```gjs {data-filename="app/components/my-component.gjs"}
|
|
1087
|
+
<template>
|
|
1088
|
+
{{#if (has-block)}}
|
|
1089
|
+
Welcome {{yield}}, we are happy you're here!
|
|
1090
|
+
{{else}}
|
|
1091
|
+
Hey you! You're great!
|
|
1092
|
+
{{/if}}
|
|
1093
|
+
</template>
|
|
1094
|
+
```
|
|
1095
|
+
|
|
1096
|
+
`has-block` is available as a keyword and does not need to be imported.
|
|
1097
|
+
|
|
1098
|
+
@method has-block
|
|
1099
|
+
@param {String} blockName the name of the block. The name is either "main" or "inverse" (though only curly components support inverse) or the name given to a named block.
|
|
1100
|
+
@return {Boolean} `true` if the component was invoked with a block
|
|
1101
|
+
@static
|
|
1102
|
+
@for Keywords
|
|
1103
|
+
@noimport
|
|
1104
|
+
@public
|
|
1105
|
+
*/
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
`{{(has-block-params)}}` indicates if the component was invoked with block params.
|
|
1109
|
+
|
|
1110
|
+
This component is invoked with block params:
|
|
1111
|
+
|
|
1112
|
+
```handlebars
|
|
1113
|
+
<MyComponent as |favoriteFlavor|>
|
|
1114
|
+
Hi Jen!
|
|
1115
|
+
</MyComponent>
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
And without block params:
|
|
1119
|
+
|
|
1120
|
+
```handlebars
|
|
1121
|
+
<MyComponent>
|
|
1122
|
+
Hi Jen!
|
|
1123
|
+
</MyComponent>
|
|
1124
|
+
```
|
|
1125
|
+
|
|
1126
|
+
This is useful when you want to create a component that can render itself
|
|
1127
|
+
differently when it is not invoked with block params.
|
|
1128
|
+
|
|
1129
|
+
```gjs {data-filename="app/components/my-component.gjs"}
|
|
1130
|
+
<template>
|
|
1131
|
+
{{#if (has-block-params)}}
|
|
1132
|
+
Welcome {{yield this.favoriteFlavor}}, we're happy you're here and hope you
|
|
1133
|
+
enjoy your favorite ice cream flavor.
|
|
1134
|
+
{{else}}
|
|
1135
|
+
Welcome {{yield}}, we're happy you're here, but we're unsure what
|
|
1136
|
+
flavor ice cream you would enjoy.
|
|
1137
|
+
{{/if}}
|
|
1138
|
+
</template>
|
|
1139
|
+
```
|
|
1140
|
+
|
|
1141
|
+
@method has-block-params
|
|
1142
|
+
@static
|
|
1143
|
+
@for Keywords
|
|
1144
|
+
@noimport
|
|
1145
|
+
@param {String} blockName the name of the block. The name is either "main" or "inverse" (though only curly components support inverse) or the name given to a named block.
|
|
1146
|
+
@return {Boolean} `true` if the component was invoked with block params
|
|
1147
|
+
@public
|
|
1148
|
+
*/
|
|
1149
|
+
|
|
1150
|
+
/**
|
|
1151
|
+
Execute the `debugger` statement in the current template's context.
|
|
1152
|
+
|
|
1153
|
+
```handlebars
|
|
1154
|
+
{{debugger}}
|
|
1155
|
+
```
|
|
1156
|
+
|
|
1157
|
+
When using the debugger helper you will have access to a `get` function. This
|
|
1158
|
+
function retrieves values available in the context of the template.
|
|
1159
|
+
For example, if you're wondering why a value `{{foo}}` isn't rendering as
|
|
1160
|
+
expected within a template, you could place a `{{debugger}}` statement and,
|
|
1161
|
+
when the `debugger;` breakpoint is hit, you can attempt to retrieve this value:
|
|
1162
|
+
|
|
1163
|
+
```
|
|
1164
|
+
> get('foo')
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
`get` is also aware of keywords. So in this situation
|
|
1168
|
+
|
|
1169
|
+
```handlebars
|
|
1170
|
+
{{#each this.items as |item|}}
|
|
1171
|
+
{{debugger}}
|
|
1172
|
+
{{/each}}
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
You'll be able to get values from the current item:
|
|
1176
|
+
|
|
1177
|
+
```
|
|
1178
|
+
> get('item.name')
|
|
1179
|
+
```
|
|
1180
|
+
|
|
1181
|
+
You can also access the context of the view to make sure it is the object that
|
|
1182
|
+
you expect:
|
|
1183
|
+
|
|
1184
|
+
```
|
|
1185
|
+
> context
|
|
1186
|
+
```
|
|
1187
|
+
|
|
1188
|
+
@method debugger
|
|
1189
|
+
@static
|
|
1190
|
+
@for Keywords
|
|
1191
|
+
@noimport
|
|
1192
|
+
@public
|
|
1193
|
+
*/
|
|
1194
|
+
|
|
1195
|
+
/**
|
|
1196
|
+
The `component` helper is used to package a Component with initial arguments.
|
|
1197
|
+
The included arguments can then be merged during the final invocation.
|
|
1198
|
+
|
|
1199
|
+
See [Component](/ember/release/modules/@glimmer%2Fcomponent/) for
|
|
1200
|
+
additional information on how a `Component` functions.
|
|
1201
|
+
|
|
1202
|
+
This is similar to the concept of Partial Application.
|
|
1203
|
+
|
|
1204
|
+
For example, given a `FullName` component:
|
|
1205
|
+
|
|
1206
|
+
```gjs {data-filename="app/components/full-name.gjs"}
|
|
1207
|
+
import MyInputComponent from './my-input-component';
|
|
1208
|
+
|
|
1209
|
+
<template>
|
|
1210
|
+
{{yield (component MyInputComponent value=@model.name placeholder="Username")}}
|
|
1211
|
+
</template>
|
|
1212
|
+
```
|
|
1213
|
+
|
|
1214
|
+
The yielded component can be invoked by the calling component.
|
|
1215
|
+
See the following snippet:
|
|
1216
|
+
|
|
1217
|
+
```gjs {data-filename="app/components/person-form.gjs"}
|
|
1218
|
+
import FullName from './full-name';
|
|
1219
|
+
|
|
1220
|
+
<template>
|
|
1221
|
+
<FullName @model={{@model}} as |Field|>
|
|
1222
|
+
<Field />
|
|
1223
|
+
</FullName>
|
|
1224
|
+
</template>
|
|
1225
|
+
```
|
|
1226
|
+
|
|
1227
|
+
Which will output an input whose value is already bound to `@model.name` and `placeholder`
|
|
1228
|
+
is "Username".
|
|
1229
|
+
|
|
1230
|
+
Any arguments passed at the invocation site of the component will override those applied via
|
|
1231
|
+
the `component` helper. For example, if the invocation site of the component is:
|
|
1232
|
+
|
|
1233
|
+
```gjs {data-filename="app/components/person-form.gjs"}
|
|
1234
|
+
import FullName from './full-name';
|
|
1235
|
+
|
|
1236
|
+
<template>
|
|
1237
|
+
<FullName @model={{@model}} as |Field|>
|
|
1238
|
+
<Field @placeholder="Your name" />
|
|
1239
|
+
</FullName>
|
|
1240
|
+
</template>
|
|
1241
|
+
```
|
|
1242
|
+
|
|
1243
|
+
The output will be an input whose value is bound to `@model.name` and `placeholder`
|
|
1244
|
+
is "Your name".
|
|
1245
|
+
|
|
1246
|
+
The `component` helper is built-in and does not need to be imported.
|
|
1247
|
+
|
|
1248
|
+
Prior to Strict Mode aka "Template Tag" or gjs, the component helper was also used to invoke
|
|
1249
|
+
components dynamically. This is no longer necessary, and they can be directly invoked, as above.
|
|
1250
|
+
|
|
1251
|
+
### Dynamic Component Invocation
|
|
1252
|
+
|
|
1253
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1254
|
+
import Component from '@glimmer/component';
|
|
1255
|
+
import { tracked } from '@glimmer/tracking';
|
|
1256
|
+
import { component } from '@ember/helper';
|
|
1257
|
+
import LiveUpdatingChart from '../components/live-updating-chart';
|
|
1258
|
+
import MarketCloseSummary from '../components/market-close-summary';
|
|
1259
|
+
|
|
1260
|
+
export default class Application extends Component {
|
|
1261
|
+
@tracked isMarketOpen = false;
|
|
1262
|
+
|
|
1263
|
+
get infographicComponent() {
|
|
1264
|
+
return this.isMarketOpen ? LiveUpdatingChart : MarketCloseSummary;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
<template>
|
|
1268
|
+
{{!-- The component can be invoked directly --}}
|
|
1269
|
+
<this.infographicComponent />
|
|
1270
|
+
|
|
1271
|
+
{{!-- The component helper here is no longer necessary --}}
|
|
1272
|
+
{{component this.infographicComponentName}}
|
|
1273
|
+
</template>
|
|
1274
|
+
}
|
|
1275
|
+
```
|
|
1276
|
+
|
|
1277
|
+
@method component
|
|
1278
|
+
@since 1.11.0
|
|
1279
|
+
@static
|
|
1280
|
+
@for Keywords
|
|
1281
|
+
@noimport
|
|
1282
|
+
@public
|
|
1283
|
+
*/
|
|
1284
|
+
|
|
1285
|
+
/**
|
|
1286
|
+
Use the `{{helper}}` helper to create contextual helper so
|
|
1287
|
+
that it can be passed around as first-class values in templates.
|
|
1288
|
+
|
|
1289
|
+
```handlebars
|
|
1290
|
+
{{#let (helper "join-words" "foo" "bar" separator=" ") as |foo-bar|}}
|
|
1291
|
+
|
|
1292
|
+
{{!-- this is equivalent to invoking `{{join-words "foo" "bar" separator=" "}}` --}}
|
|
1293
|
+
{{foo-bar}}
|
|
1294
|
+
|
|
1295
|
+
{{!-- this will pass the helper itself into the component, instead of invoking it now --}}
|
|
1296
|
+
<MyComponent @helper={{helper foo-bar "baz"}} />
|
|
1297
|
+
|
|
1298
|
+
{{!-- this will yield the helper itself ("contextual helper"), instead of invoking it now --}}
|
|
1299
|
+
{{yield foo-bar}}
|
|
1300
|
+
{{/let}}
|
|
1301
|
+
```
|
|
1302
|
+
|
|
1303
|
+
### Arguments
|
|
1304
|
+
|
|
1305
|
+
The `{{helper}}` helper works similarly to the [`{{component}}`](./component?anchor=component) and
|
|
1306
|
+
[`{{modifier}}`](./modifier?anchor=modifier) helper:
|
|
1307
|
+
|
|
1308
|
+
* When passed a string (e.g. `(helper "foo")`) as the first argument,
|
|
1309
|
+
it will produce an opaque, internal "helper definition" object
|
|
1310
|
+
that can be passed around and invoked elsewhere.
|
|
1311
|
+
|
|
1312
|
+
* Any additional positional and/or named arguments (a.k.a. params and hash)
|
|
1313
|
+
will be stored ("curried") inside the definition object, such that, when invoked,
|
|
1314
|
+
these arguments will be passed along to the referenced helper.
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
@method helper
|
|
1318
|
+
@static
|
|
1319
|
+
@for Keywords
|
|
1320
|
+
@noimport
|
|
1321
|
+
@public
|
|
1322
|
+
@since 3.27.0
|
|
1323
|
+
*/
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
The `if` helper allows you to conditionally render one of two branches,
|
|
1327
|
+
depending on the "truthiness" of a property.
|
|
1328
|
+
For example the following values are all falsey: `false`, `undefined`, `null`, `""`, `0`, `NaN` or an empty array.
|
|
1329
|
+
|
|
1330
|
+
This helper has two forms, block and inline.
|
|
1331
|
+
|
|
1332
|
+
## Block form
|
|
1333
|
+
|
|
1334
|
+
You can use the block form of `if` to conditionally render a section of the template.
|
|
1335
|
+
|
|
1336
|
+
To use it, pass the conditional value to the `if` helper,
|
|
1337
|
+
using the block form to wrap the section of template you want to conditionally render.
|
|
1338
|
+
Like so:
|
|
1339
|
+
|
|
1340
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1341
|
+
import Weather from '../components/weather';
|
|
1342
|
+
|
|
1343
|
+
<template>
|
|
1344
|
+
<Weather />
|
|
1345
|
+
</template>
|
|
1346
|
+
```
|
|
1347
|
+
|
|
1348
|
+
```gjs {data-filename="app/components/weather.gjs"}
|
|
1349
|
+
<template>
|
|
1350
|
+
{{! will not render because greeting is undefined}}
|
|
1351
|
+
{{#if @isRaining}}
|
|
1352
|
+
Yes, grab an umbrella!
|
|
1353
|
+
{{/if}}
|
|
1354
|
+
</template>
|
|
1355
|
+
```
|
|
1356
|
+
|
|
1357
|
+
You can also define what to show if the property is falsey by using
|
|
1358
|
+
the `else` helper.
|
|
1359
|
+
|
|
1360
|
+
```gjs {data-filename="app/components/weather.gjs"}
|
|
1361
|
+
<template>
|
|
1362
|
+
{{#if @isRaining}}
|
|
1363
|
+
Yes, grab an umbrella!
|
|
1364
|
+
{{else}}
|
|
1365
|
+
No, it's lovely outside!
|
|
1366
|
+
{{/if}}
|
|
1367
|
+
</template>
|
|
1368
|
+
```
|
|
1369
|
+
|
|
1370
|
+
You are also able to combine `else` and `if` helpers to create more complex
|
|
1371
|
+
conditional logic.
|
|
1372
|
+
|
|
1373
|
+
For the following template:
|
|
1374
|
+
|
|
1375
|
+
```gjs {data-filename="app/components/weather.gjs"}
|
|
1376
|
+
<template>
|
|
1377
|
+
{{#if @isRaining}}
|
|
1378
|
+
Yes, grab an umbrella!
|
|
1379
|
+
{{else if @isCold}}
|
|
1380
|
+
Grab a coat, it's chilly!
|
|
1381
|
+
{{else}}
|
|
1382
|
+
No, it's lovely outside!
|
|
1383
|
+
{{/if}}
|
|
1384
|
+
</template>
|
|
1385
|
+
```
|
|
1386
|
+
|
|
1387
|
+
If you call it by saying `isCold` is true:
|
|
1388
|
+
|
|
1389
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1390
|
+
import Weather from '../components/weather';
|
|
1391
|
+
|
|
1392
|
+
<template>
|
|
1393
|
+
<Weather @isCold={{true}} />
|
|
1394
|
+
</template>
|
|
1395
|
+
```
|
|
1396
|
+
|
|
1397
|
+
Then `Grab a coat, it's chilly!` will be rendered.
|
|
1398
|
+
|
|
1399
|
+
## Inline form
|
|
1400
|
+
|
|
1401
|
+
The inline `if` helper conditionally renders a single property or string.
|
|
1402
|
+
|
|
1403
|
+
In this form, the `if` helper receives three arguments, the conditional value,
|
|
1404
|
+
the value to render when truthy, and the value to render when falsey.
|
|
1405
|
+
|
|
1406
|
+
For example, if `useLongGreeting` is truthy, the following:
|
|
1407
|
+
|
|
1408
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1409
|
+
import Greeting from '../components/greeting';
|
|
1410
|
+
|
|
1411
|
+
<template>
|
|
1412
|
+
<Greeting @useLongGreeting={{true}} />
|
|
1413
|
+
<template>
|
|
1414
|
+
```
|
|
1415
|
+
|
|
1416
|
+
```gjs {data-filename="app/components/greeting.gjs"}
|
|
1417
|
+
<template>
|
|
1418
|
+
{{if @useLongGreeting "Hello" "Hi"}} Alex
|
|
1419
|
+
<template>
|
|
1420
|
+
```
|
|
1421
|
+
|
|
1422
|
+
Will render:
|
|
1423
|
+
|
|
1424
|
+
```html
|
|
1425
|
+
Hello Alex
|
|
1426
|
+
```
|
|
1427
|
+
|
|
1428
|
+
One detail to keep in mind is that both branches of the `if` helper will be evaluated,
|
|
1429
|
+
so if you have `{{if condition "foo" (expensive-operation "bar")`,
|
|
1430
|
+
`expensive-operation` will always calculate.
|
|
1431
|
+
|
|
1432
|
+
`if` is built-in and does not need to be imported.
|
|
1433
|
+
|
|
1434
|
+
@method if
|
|
1435
|
+
@static
|
|
1436
|
+
@for Keywords
|
|
1437
|
+
@noimport
|
|
1438
|
+
@public
|
|
1439
|
+
*/
|
|
1440
|
+
|
|
1441
|
+
/**
|
|
1442
|
+
The `unless` helper is the inverse of the `if` helper. It displays if a value
|
|
1443
|
+
is falsey ("not true" or "is false"). Example values that will display with
|
|
1444
|
+
`unless`: `false`, `undefined`, `null`, `""`, `0`, `NaN` or an empty array.
|
|
1445
|
+
|
|
1446
|
+
## Inline form
|
|
1447
|
+
|
|
1448
|
+
The inline `unless` helper conditionally renders a single property or string.
|
|
1449
|
+
This helper acts like a ternary operator. If the first property is falsy,
|
|
1450
|
+
the second argument will be displayed, otherwise, the third argument will be
|
|
1451
|
+
displayed
|
|
1452
|
+
|
|
1453
|
+
For example, if you pass a falsey `useLongGreeting` to the `Greeting` component:
|
|
1454
|
+
|
|
1455
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1456
|
+
import Greeting from '../components/greeting';
|
|
1457
|
+
|
|
1458
|
+
<template>
|
|
1459
|
+
<Greeting @useLongGreeting={{false}} />
|
|
1460
|
+
</template>
|
|
1461
|
+
```
|
|
1462
|
+
|
|
1463
|
+
```gjs {data-filename="app/components/greeting.gjs"}
|
|
1464
|
+
<template>
|
|
1465
|
+
{{unless @useLongGreeting "Hi" "Hello"}} Ben
|
|
1466
|
+
</template>
|
|
1467
|
+
```
|
|
1468
|
+
|
|
1469
|
+
Then it will display:
|
|
1470
|
+
|
|
1471
|
+
```html
|
|
1472
|
+
Hi Ben
|
|
1473
|
+
```
|
|
1474
|
+
|
|
1475
|
+
## Block form
|
|
1476
|
+
|
|
1477
|
+
Like the `if` helper, the `unless` helper also has a block form.
|
|
1478
|
+
|
|
1479
|
+
The following will not render anything:
|
|
1480
|
+
|
|
1481
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1482
|
+
import Greeting from '../components/greeting';
|
|
1483
|
+
|
|
1484
|
+
<template>
|
|
1485
|
+
<Greeting />
|
|
1486
|
+
</template>
|
|
1487
|
+
```
|
|
1488
|
+
|
|
1489
|
+
```gjs {data-filename="app/components/greeting.gjs"}
|
|
1490
|
+
<template>
|
|
1491
|
+
{{#unless @greeting}}
|
|
1492
|
+
No greeting was found. Why not set one?
|
|
1493
|
+
{{/unless}}
|
|
1494
|
+
</template>
|
|
1495
|
+
```
|
|
1496
|
+
|
|
1497
|
+
You can also use an `else` helper with the `unless` block. The
|
|
1498
|
+
`else` will display if the value is truthy.
|
|
1499
|
+
|
|
1500
|
+
If you have the following component:
|
|
1501
|
+
|
|
1502
|
+
```gjs {data-filename="app/components/logged-in.gjs"}
|
|
1503
|
+
<template>
|
|
1504
|
+
{{#unless @userData}}
|
|
1505
|
+
Please login.
|
|
1506
|
+
{{else}}
|
|
1507
|
+
Welcome back!
|
|
1508
|
+
{{/unless}}
|
|
1509
|
+
</template>
|
|
1510
|
+
```
|
|
1511
|
+
|
|
1512
|
+
Calling it with a truthy `userData`:
|
|
1513
|
+
|
|
1514
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1515
|
+
import LoggedIn from '../components/logged-in';
|
|
1516
|
+
|
|
1517
|
+
<template>
|
|
1518
|
+
<LoggedIn @userData={{hash username="Zoey"}} />
|
|
1519
|
+
</template>
|
|
1520
|
+
```
|
|
1521
|
+
|
|
1522
|
+
Will render:
|
|
1523
|
+
|
|
1524
|
+
```html
|
|
1525
|
+
Welcome back!
|
|
1526
|
+
```
|
|
1527
|
+
|
|
1528
|
+
and calling it with a falsey `userData`:
|
|
1529
|
+
|
|
1530
|
+
```gjs {data-filename="app/templates/application.gjs"}
|
|
1531
|
+
import LoggedIn from '../components/logged-in';
|
|
1532
|
+
|
|
1533
|
+
<template>
|
|
1534
|
+
<LoggedIn @userData={{false}} />
|
|
1535
|
+
</template>
|
|
1536
|
+
```
|
|
1537
|
+
|
|
1538
|
+
Will render:
|
|
1539
|
+
|
|
1540
|
+
```html
|
|
1541
|
+
Please login.
|
|
1542
|
+
```
|
|
1543
|
+
|
|
1544
|
+
`unless` is built-in and does not need to be imported.
|
|
1545
|
+
|
|
1546
|
+
@method unless
|
|
1547
|
+
@for Keywords
|
|
1548
|
+
@noimport
|
|
1549
|
+
@static
|
|
1550
|
+
@public
|
|
1551
|
+
*/
|
|
1552
|
+
|
|
1553
|
+
/**
|
|
1554
|
+
`log` allows you to output the value of variables in the current rendering
|
|
1555
|
+
context. `log` also accepts primitive types such as strings or numbers.
|
|
1556
|
+
|
|
1557
|
+
```handlebars
|
|
1558
|
+
{{log "myVariable:" myVariable }}
|
|
1559
|
+
```
|
|
1560
|
+
|
|
1561
|
+
`log` is built-in as a template keyword and does not need to be imported.
|
|
1562
|
+
|
|
1563
|
+
@method log
|
|
1564
|
+
@for Keywords
|
|
1565
|
+
@noimport
|
|
1566
|
+
@static
|
|
1567
|
+
@param {Array} params
|
|
1568
|
+
@public
|
|
1569
|
+
*/
|
|
1570
|
+
|
|
1571
|
+
/**
|
|
1572
|
+
Use the `{{modifier}}` helper to create contextual modifier so
|
|
1573
|
+
that it can be passed around as first-class values in templates.
|
|
1574
|
+
|
|
1575
|
+
```handlebars
|
|
1576
|
+
{{#let (modifier "click-outside" click=this.submit) as |on-click-outside|}}
|
|
1577
|
+
|
|
1578
|
+
{{!-- this is equivalent to `<MyComponent {{click-outside click=this.submit}} />` --}}
|
|
1579
|
+
<MyComponent {{on-click-outside}} />
|
|
1580
|
+
|
|
1581
|
+
{{!-- this will pass the modifier itself into the component, instead of invoking it now --}}
|
|
1582
|
+
<MyComponent @modifier={{modifier on-click-outside "extra" "args"}} />
|
|
1583
|
+
|
|
1584
|
+
{{!-- this will yield the modifier itself ("contextual modifier"), instead of invoking it now --}}
|
|
1585
|
+
{{yield on-click-outside}}
|
|
1586
|
+
{{/let}}
|
|
1587
|
+
```
|
|
1588
|
+
|
|
1589
|
+
### Arguments
|
|
1590
|
+
|
|
1591
|
+
The `{{modifier}}` helper works similarly to the [`{{component}}`](./component?anchor=component) and
|
|
1592
|
+
[`{{helper}}`](./helper?anchor=helper) helper:
|
|
1593
|
+
|
|
1594
|
+
* When passed a string (e.g. `(modifier "foo")`) as the first argument,
|
|
1595
|
+
it will produce an opaque, internal "modifier definition" object
|
|
1596
|
+
that can be passed around and invoked elsewhere.
|
|
1597
|
+
|
|
1598
|
+
* Any additional positional and/or named arguments (a.k.a. params and hash)
|
|
1599
|
+
will be stored ("curried") inside the definition object, such that, when invoked,
|
|
1600
|
+
these arguments will be passed along to the referenced modifier.
|
|
1601
|
+
|
|
1602
|
+
`modifier` is built-in as a template keyword and does not need to be imported.
|
|
1603
|
+
|
|
1604
|
+
@method modifier
|
|
1605
|
+
@for Keywords
|
|
1606
|
+
@static
|
|
1607
|
+
@public
|
|
1608
|
+
@since 3.27.0
|
|
1609
|
+
*/
|
|
1610
|
+
|
|
1611
|
+
/**
|
|
1612
|
+
`pageTitle` allows you to set the title of any page in your application and
|
|
1613
|
+
append additional titles for each route. For complete documentation, see
|
|
1614
|
+
https://github.com/ember-cli/ember-page-title.
|
|
1615
|
+
|
|
1616
|
+
```gjs
|
|
1617
|
+
import { pageTitle } from 'ember-page-title';
|
|
1618
|
+
|
|
1619
|
+
<template>
|
|
1620
|
+
{{pageTitle "My Page Title" }}
|
|
1621
|
+
</template>
|
|
1622
|
+
```
|
|
1623
|
+
|
|
1624
|
+
@method pageTitle
|
|
1625
|
+
@for External
|
|
1626
|
+
@param {String} param
|
|
1627
|
+
@static
|
|
1628
|
+
@public
|
|
1629
|
+
*/
|
|
1630
|
+
|
|
1631
|
+
/**
|
|
1632
|
+
The `let` helper receives one or more positional arguments and yields
|
|
1633
|
+
them out as block params.
|
|
1634
|
+
|
|
1635
|
+
This allows the developer to introduce shorter names for certain computations
|
|
1636
|
+
in the template.
|
|
1637
|
+
|
|
1638
|
+
This is especially useful if you are passing properties to a component
|
|
1639
|
+
that receives a lot of options and you want to clean up the invocation.
|
|
1640
|
+
|
|
1641
|
+
For the following example, the template receives a `post` object with
|
|
1642
|
+
`content` and `title` properties.
|
|
1643
|
+
|
|
1644
|
+
We are going to call the `my-post` component, passing a title which is
|
|
1645
|
+
the title of the post suffixed with the name of the blog, the content
|
|
1646
|
+
of the post, and a series of options defined in-place.
|
|
1647
|
+
|
|
1648
|
+
```handlebars
|
|
1649
|
+
{{#let
|
|
1650
|
+
(concat post.title ' | The Ember.js Blog')
|
|
1651
|
+
post.content
|
|
1652
|
+
(hash
|
|
1653
|
+
theme="high-contrast"
|
|
1654
|
+
enableComments=true
|
|
1655
|
+
)
|
|
1656
|
+
as |title content options|
|
|
1657
|
+
}}
|
|
1658
|
+
<MyPost @title={{title}} @content={{content}} @options={{options}} />
|
|
1659
|
+
{{/let}}
|
|
1660
|
+
```
|
|
1661
|
+
|
|
1662
|
+
`let` is built-in and does not need to be imported.
|
|
1663
|
+
|
|
1664
|
+
@method let
|
|
1665
|
+
@static
|
|
1666
|
+
@noimport
|
|
1667
|
+
@for Keywords
|
|
1668
|
+
@public
|
|
1669
|
+
*/
|
|
1670
|
+
|
|
1671
|
+
/**
|
|
1672
|
+
The `in-element` helper renders its block content outside of the regular flow,
|
|
1673
|
+
into a DOM element given by its `destinationElement` positional argument.
|
|
1674
|
+
|
|
1675
|
+
Common use cases - often referred to as "portals" or "wormholes" - are rendering
|
|
1676
|
+
dropdowns, modals or tooltips close to the root of the page to bypass CSS overflow
|
|
1677
|
+
rules, or to render content to parts of the page that are outside of the control
|
|
1678
|
+
of the Ember app itself (e.g. embedded into a static or server rendered HTML page).
|
|
1679
|
+
|
|
1680
|
+
```handlebars
|
|
1681
|
+
{{#in-element this.destinationElement}}
|
|
1682
|
+
<div>Some content</div>
|
|
1683
|
+
{{/in-element}}
|
|
1684
|
+
```
|
|
1685
|
+
|
|
1686
|
+
### Arguments
|
|
1687
|
+
|
|
1688
|
+
`{{in-element}}` requires a single positional argument:
|
|
1689
|
+
|
|
1690
|
+
- `destinationElement` -- the DOM element to render into. It must exist at the time
|
|
1691
|
+
of rendering.
|
|
1692
|
+
|
|
1693
|
+
It also supports an optional named argument:
|
|
1694
|
+
|
|
1695
|
+
- `insertBefore` -- by default the DOM element's content is replaced when used as
|
|
1696
|
+
`destinationElement`. Passing `null` to `insertBefore` changes the behaviour to
|
|
1697
|
+
append the block content to the end of any existing content. Any other value than
|
|
1698
|
+
`null` is currently not supported.
|
|
1699
|
+
|
|
1700
|
+
For example:
|
|
1701
|
+
|
|
1702
|
+
```handlebars
|
|
1703
|
+
{{#in-element this.destinationElement insertBefore=null}}
|
|
1704
|
+
<div>Some content</div>
|
|
1705
|
+
{{/in-element}}
|
|
1706
|
+
```
|
|
1707
|
+
|
|
1708
|
+
`in-element` is built-in and does not need to be imported.
|
|
1709
|
+
|
|
1710
|
+
@method in-element
|
|
1711
|
+
@for Keywords
|
|
1712
|
+
@param {Element} destinationElement the DOM element to render into. It must exist at the time
|
|
1713
|
+
of rendering.
|
|
1714
|
+
@param {Boolean} insertBefore named argument, by default the DOM element's content is replaced when used as
|
|
1715
|
+
`destinationElement`. Passing `null` to `insertBefore` changes the behaviour to
|
|
1716
|
+
append the block content to the end of any existing content. Any other value than
|
|
1717
|
+
`null` is currently not supported.
|
|
1718
|
+
@static
|
|
1719
|
+
@noimport
|
|
1720
|
+
@public
|
|
1721
|
+
*/
|
|
1722
|
+
|
|
670
1723
|
/* eslint-enable @typescript-eslint/no-empty-object-type */
|
|
671
1724
|
|
|
672
1725
|
export { and, array, capabilities, concat, element, eq, fn, get, gt, gte, hash, invokeHelper, lt, lte, neq, not, or, setHelperManager, uniqueId };
|