ractive v0.10.0 Release Notes
-
2018-04-05
๐ฅ Breaking changes
resolveInstanceMembers
now defaults tofalse
to avoid foot maimings associated with common instance member names and ambiguous references.- Template positions are now stored in the
q
member rather than thep
member to avoid accidental overlap with partials. - The stringy syntax for computed properties has changed to plain old expression syntax. This means that
${length} * ${width}
as a computation is now justlength * width
, which is hopefully a little less surprising given${interpolator}
syntax in template strings. - '.' in computation keypaths must now be escaped if they're meant to be part of a single key, as you can now add computations below the root level.
- Checking that a value exists at some keypath in the data will no longer exclude the root prototypes (
Object
,Function
,Array
) because doing so creates issues when dealing withObject.create(null)
. If you keep your references unambiguous, this shouldn't cause any issues. - Aliases now take precedent over properties from contexts above their alias defintions. This means that
{{#with { foo: 10 } }}{{#with 42 as foo}}{{foo}}{{/with}}{{/with}}
results in42
rather than10
, which makes it now behave in a slightly less surprising way. polyfills.js
is no longer included in the build, as it was just an empty placeholder since the handful of polyfills that were in it were included in the main build.- The context pop reference prefix
^^/
now correctly handles{{#each}}
blocks such that^^/ === ../../
from immediately within the block body. This is because^^/
is supposed to jump explicit contexts and not just implicit contexts as provided by each iteration.
๐ New features (experimental, feedback welcome!)
- There is now an
allowExpressions
parser and init option that disables the parsing of expressions when passed toparse
or an instance with an unparsed template and disables the evaluation of expessions when passed to an instance. See #3000 for more info. {{#await some.promise}}promise is pending{{then value}}{{value}} is the result{{catch e}}error is {{e}}{{else}}some.promise is undefined{{/await}}
. In other words, we snagged the await block from Svelte.- Computations can now be added on the fly using
ractive.compute(keypath, computation)
, wherecomputation
is a string, function, or computation descriptor. - Computations can now be added to nested keypaths, and those keypaths may also be wildcards. To add an area to all
boxes
with alength
andwidth
, you canractive.compute('boxes.*.area', 'length * width')
. - There's a new
helpers
registry that can be used to store a flat map of helper functions (or bits of data) that will be checked first when resolving ambiguos references that don't resolve in the immediate context. This is also more or less cribbed from Svelte.' - Ractive now has a more universal plugin format that delegates to the appropriate registries but also has an opportunity to do more than just add to registries, like install new methods on prototypes, add observers and events listeners, and extend or replace CSS defintions.
Ractive.use(...plugins)
,Component.use(...plugins)
, andractive.use(...plugins)
and the equivalentextend
andinit
paramsuse: [...plugins]
take plugins in the form({ Ractive, instance, proto }) => {}
, whereRactive
is always the rootRactive
constructor,instance
is the component constructor for components and instance for instances, andproto
is the component prototype for components and instance for instances. - Event directives now support initialization arguments in the form of
on-event(init, args)="handler"
, where the custom event plugin is called asevent(node, fire, init, args)
. This has a number of uses, including allowing long-throw events to provide feedback in the form of bindings and allowing filtering of key and or mouse events based on button or modifier key status. - You can add globally managed CSS to Ractive with
Ractive.addCSS(id, css)
, which is particularly useful for some types of plugins. You can check to see if global styles are already applied withRactive.hasCSS(id)
becauseaddCSS
will throw if you try to install the same styles twice. Thecss
may be a string or a function that takes CSS data and returns a string, in which case it will be automatically recomputed when any variables it uses from the data are changed. - A component's CSS is now exposed on the constructor as the writable
css
property. Changing a component'scss
property will also update its styles included in the Ractive-managed style tag. - There's a new special reference,
@last
to get the index of the last iteration of an{{#each}}
, which is particularly useful when iteration object values. - The
preserveWhitespace
option has been extended to also take a map of elements in which to preserve whitespace. - Reference expressions can now use an array member to expand to an arbitrary keypath e.g.
some[ ['extra', 'keys', 'here'] ]
is equivalent tosome.extra.keys.here
, but the array can be another reference that updates the target model dynamically. - You can now specify aliases to
@index
,@key
,@keypath
, and@rootpath
as additional aliases in an{{#each}}
block e.g.{{#each items as item, @index as index, @keypath as path}}...{{/each}}
. - The
as
in aliases is now optional so{{#each items as item, @index as index}}
is equivalent to{{#each items item, @index index}}
. - You can now instruct an
{{#each}}
block shuffle itself when it updates rather than simply allowing the data to update in children to match any keypath changes. This means that you can now achieve shuffling with a computed expression that correctly transitions elements in and out of the DOM. This is done with a special aliasshuffle
for the{{#each}}
block, which may be eithertrue
or a keypath as a string e.g.{{#each items, true as shuffle}}
or{{#each items, 'some.path' as shuffle}}
. - You can also instruct an
{{#each}}
block with a computed value to map its iteration contexts back to a source model using thesource
special alias, which should be set to underlying source of the computation e.g.{{#each compute(some(items)), items as source}}
. Source contexts are determined using theindexOf
method of the source array with the values from the computed array. - You can now specify a context for a yield rather than aliases if that better suites your usecase e.g.
{{#each things}}{{yield with .}}{{/each}}
. This makes the immediate context within the yieldthings.${index}
, and the outer context can still be accessed with^^/
.
- There is now an
๐ Bug fixes
- Some corner cases causing context leaks from a template into a component have been plugged.
Other changes
- Ractive now uses prettier to make keeping the code style consistent easier, which will hopefully also make contributions easier.