-
38ff738: Allow specifying an alternative event target with event-target
This now allows specifying an alternative event target via the new
event-target
property. You can use it like this:import sheet, { mount } from "https://cdn.corset.dev/v2"; mount( document, class { onpopstate(ev) { console.log( `location: ${document.location}, state: ${JSON.stringify( event.state )}` ); } bind() { return sheet` #app { event: popstate ${this.onpopstate}; event-target: popstate ${window}; } `; } } );
In the above we are able to use a selector to listen to the popstate event that is on the window object.
This can also be used with any object that follows the EventTarget interface:
import sheet, { mount } from "https://cdn.corset.dev/v2"; let target = new EventTarget(); // Now this can be shared around mount( document, class { bind() { return sheet` #app { event: foo ${() => console.log("foo event occurred!")}; event-target: foo ${target}; } some-custom-element { prop: events ${target}; } `; } } );
-
38ff738: Allow specifying an alternative event target with event-target
This now allows specifying an alternative event target via the new
event-target
property. You can use it like this:import sheet, { mount } from "https://cdn.corset.dev/v2"; mount( document, class { onpopstate(ev) { console.log( `location: ${document.location}, state: ${JSON.stringify( event.state )}` ); } bind() { return sheet` #app { event: popstate ${this.onpopstate}; event-target: popstate ${window}; } `; } } );
In the above we are able to use a selector to listen to the popstate event that is on the window object.
This can also be used with any object that follows the EventTarget interface:
import sheet, { mount } from "https://cdn.corset.dev/v2"; let target = new EventTarget(); // Now this can be shared around mount( document, class { bind() { return sheet` #app { event: foo ${() => console.log("foo event occurred!")}; event-target: foo ${target}; } some-custom-element { prop: events ${target}; } `; } } );
- 9730a91: Target the root element via :scope
-
c3aaec0: Allow multiple store-set within a rule
#app { store-root: app; store-set: app first "Wilbur"; store-set: app last "Phillips"; --full-name: store-get(app, first) " " store-get(app, last); text: var(--full-name); }
-
8573803: Allow multiple store-root on an element
You can now set multiple stores on an element:
#app { store-root: one, two; store-set: one name "Matthew"; store-set: two name "Wilbur"; }
- 8750545: var should recompute when child compute is dirty
- 5d68c7e: Prevent unnecessary function calls when a var is undefined
- 3efbd6a: Update when pushing to an empty array using longhand each
- ef19155: Allow using SVG templates
-
c39d80e: Consolidate data properties
This consolidates data attributes, grouping them by type, so that you might have:
<div data-corset-props="--one --two --three"></div>
Instead of:
<div data-corset-prop-one data-corset-prop-two data-corset-prop-three></div>
This means less clutter in the DOM.
In addition to
data-corset-props
there is alsodata-corset-stores
for stores anddata-corset-scope
for each scope values (item and index).
- cf4ca7a: Ensure changes in list update
- 23b5605: Fix to allow each to be used with attr
-
25e06c5: Multi-binding properties are now additive
In Corset 2.0, multi-binding properties are now additive. That means if you use the
class-toggle
,each
,prop
,data
, orattr
properties, the values you set will be added to the element, but will not remove previous values added.In Corset 1.0 these multi-binding properties were destructive. This meant if you did:
#app { class-toggle: one true; } #app { class-toggle: two true; }
Only the
two
class would be on the element. In Corset 2.0 bothone
andtwo
will be set.To allow you to remove previous bindings, Corset 2.0 has new
revert-sheet
andall
keywords. To remove previous bindings, as in above, you would now do:#app { class-toggle: one true; } #app { class-toggle: all revert-sheet, two true; }
Using
all
selects all active bindings for that property.Due to the change in making multi-binding properties be additive, there is no longer a need for keyed property access, and it has thereby been removed. This aligns Corset syntax with CSS.
In the future no new syntax not supported by CSS will be added to Corset.
-
0e4c74b: Removes keyed properties and makes properties default additive
- 8abb1ee: Child behaviors now cause the parent to rebind
- 06bd259: Allow the :root selector for targeting the root element
- 5d3b461: Fixes bugs based on vars not being resolvable
- b76dfa5: On conflict between attach-template and text, former wins
- 921c26e: Allows a ShadowRoot to be a root element of a sheet
- 76b0c7a: Allow mount() to take a ShadowRoot
- de0927e: Fix bug with attach-template and vars
- 80fd8bf: When a data prop changes, rebind the sheet
- 5d3b461: Fixes bugs based on vars not being resolvable
- b76dfa5: On conflict between attach-template and text, former wins
- 8abb1ee: Child behaviors now cause the parent to rebind
- de0927e: Fix bug with attach-template and vars
- 80fd8bf: When a data prop changes, rebind the sheet
- 06bd259: Allow the :root selector for targeting the root element
- 76b0c7a: Allow mount() to take a ShadowRoot
- 921c26e: Allows a ShadowRoot to be a root element of a sheet
- 0e4c74b: Removes keyed properties and makes properties default additive
- 3f62eae: Fixes typecheck errors
- 37fa1ef: Fixes the package.json main
-
35f6cea: 1.0 Release
The first major release of Corset establishes the current featureset as the stable APIs to build upon.
No new features in this release, just closing off what was build in 0.8 and 0.9.
-
fb1a0cf: Adds
createStore
to the function contextThis is a new function
creatStore(): Store
, provided to functions, that allow them to create new stores that are scoped to the sheet they are called within.This is meant to allow custom functions to asynchronously change values and have that reflect in bindings.
- 021d7ed: Fixes stores not being available when vars are set
- 68913f7: Ensure that setting a store causes invalidation
-
b91646e: Adds support for Stores
This change adds a new feature "stores". A store is a Map that can be created in any scope within a sheet. The Map will be shared within JS inside of a behavior. It can be passed to child behaviors (through inputProperties) and when a child behavior modifies it, it will rebind() the parent behavior as well.
- b939766: Fixes inputProperties types on the Map
- 0b06f3b: Improved TypeScript typings
- d3a2c5c: Fixes numbers in selectors
- 7ddfe4d: Fixes arrays being joined in the text property
- 95e3c2e: Updated CI to deploy v0 redirect
- b216c53: Final change for the CDN symlink feature
- ab2ecd4: [email protected]
- f4b90a6: [email protected]
- 51ffe8f: [email protected]
- 48da0e7: [email protected]
- 3832860: [email protected]
- 4e70b71: Support for multiple entrypoints
- 040c860: Update for more robust semver CDN support
- d32acba: Use cdn-spooky-deploy-action 3.5
- 2e1f297: Use the CDN's new semver URL
- 115a71f: Swaps the order of the context and props args in registerCustomFunction to match registerBehavior
-
15b70f6: Replace wrap/wrapAsync with rebind
This is a breaking change which removes wrap and wrapAsync with a new
rebind
function. Just call rebind any time state has change that necessitates callingbind()
to get new values. -
f0594ca: Changes bind() to pass the
this
forward
- 60e1b7b: Adds the wrapAsync method to the behavior context
- 5280f3c: Adds a wrap function for wrapping callbacks in behaviors
-
5071384: # New mount API
This change implements a new mount API, a breaking change.
The old signature:
mount(root, state => { return sheet` `; }
Is replace with a class rather than a proxy-based callback function. This should allow higher-level abstractions to be built on top without the magic of the proxy implementation.
mount( root, class { bind() { return sheet` `; } } );
The API asks for a bind method on the passed in class that returns a sheet.
Additionally you can probably
static inputProperties
which will give you a map of (custom) properties. This is for the next change...The old
mount
property is replaced withbehavior
.mount()
is a function passed to behavior. You can mount multiple behaviors on teh same element:class One { bind() {} } class Two { bind() {} } mount( root, class { bind() { return sheet` #app { behavior: mount(${One}), mount(${Two}); } `; } } );
Normal comma-separated rules applied. Additionally you can provide
inputProperties
and receive a map like so:class One { static inputProperties = ["--foo"]; constructor(props) { this.initial = props.get("--foo"); } bind(props) { return sheet` #thing { text: ${this.initial + "-" + props.get("--foo")} } `; } } mount( root, class { bind() { return sheet` #app { behavior: mount(${One}); } `; } } );
-
3ccb517: Adds support for longhand properties for events
This adds the following longhand syntaxes for events:
let controller = new AbortController(); sheet` button { event-listener[click]: ${cb}; event-capture[click]: false; event-once[click]: false; event-passive[click]: false; event-signal[click]: ${controller.signal}; } `;
-
31bd7cc: Keyed properties, comma-separated lists, and more
- Multi-binding properties now need to separate each binding with a comma:
#app { class-toggle: one ${true}, two ${two}; }
- Multi-binding properties now will invalidate any others that were previous applied.
- The 3rd signature for
get()
has been removed. This is the signature that automatically looks for theitem()
within an each clause. This might be replaced byitem(name
) in the future.
-
Keyed properties - All multi-binding properties can instead by used with their key being placed in the property name like so:
input { attr[placeholder]: "Enter your email"; } #app { class-toggle[darkmode]: ${true}; }
-
var()
now expands when it contains a list, like in CSS.#app { --opts: type "text"; } input { attr: var(--opts); }
-
Custom properties can contain space-separated lists (as shown above).
-
The
attr
property is now a shorthand forattr-value
andattr-toggle
.app { attr[name]: "password" ${true}; } /** Is exactly equivalent to */ app { attr-value[name]: "password"; attr-toggle[name]: ${true}; } /** But the second argument is optional in attr and defaults to true */ app { attr[name]: "password"; }
-
The new
registerCustomFunction
API allows you to define a custom function in JavaScript with access to input properties, the element being bounded to, and more.
import sheet, { registerCustomFunction } from "corset"; registerCustomFunction( "--add-two", class { static inputProperties = ["--start"]; call([a, b], _ctx, props) { return a + b + props.get("--start"); } } ); mount( document, () => sheet` #app { --start: 2; text: --add-two(${1}, ${2}); } ` );
Some features discussed didn't make it in, but could come relatively soon:
- There is no built-in
true
andfalse
yet. Instead continue using a JS insertion${true}
. - There is no built-in number types yet.
- Space-separated lists do not work within functions yet (except through a
var()
). - No
initial
yet. - No change to the
mount()
API.
- Multi-binding properties now need to separate each binding with a comma:
-
582546b: Makes the identifiers true and false be recognized as booleans
- 59a963d: Fix for unbinding events using keyed syntax
- 59a963d: Fix for unbinding events using keyed syntax
-
31bd7cc: Keyed properties, comma-separated lists, and more
- Multi-binding properties now need to separate each binding with a comma:
#app { class-toggle: one ${true}, two ${two}; }
- Multi-binding properties now will invalidate any others that were previous applied.
- The 3rd signature for
get()
has been removed. This is the signature that automatically looks for theitem()
within an each clause. This might be replaced byitem(name
) in the future.
-
Keyed properties - All multi-binding properties can instead by used with their key being placed in the property name like so:
input { attr[placeholder]: "Enter your email"; } #app { class-toggle[darkmode]: ${true}; }
-
var()
now expands when it contains a list, like in CSS.#app { --opts: type "text"; } input { attr: var(--opts); }
-
Custom properties can contain space-separated lists (as shown above).
-
The
attr
property is now a shorthand forattr-value
andattr-toggle
.app { attr[name]: "password" ${true}; } /** Is exactly equivalent to */ app { attr-value[name]: "password"; attr-toggle[name]: ${true}; } /** But the second argument is optional in attr and defaults to true */ app { attr[name]: "password"; }
-
The new
registerCustomFunction
API allows you to define a custom function in JavaScript with access to input properties, the element being bounded to, and more.
import sheet, { registerCustomFunction } from "corset"; registerCustomFunction( "--add-two", class { static inputProperties = ["--start"]; call([a, b], _ctx, props) { return a + b + props.get("--start"); } } ); mount( document, () => sheet` #app { --start: 2; text: --add-two(${1}, ${2}); } ` );
Some features discussed didn't make it in, but could come relatively soon:
- There is no built-in
true
andfalse
yet. Instead continue using a JS insertion${true}
. - There is no built-in number types yet.
- Space-separated lists do not work within functions yet (except through a
var()
). - No
initial
yet. - No change to the
mount()
API.
- Multi-binding properties now need to separate each binding with a comma:
- f218cae: Allows custom properties to be called as functions
- fe97d6e: Provide compressed wasm on the CDN
- 61f0e61: Removes dead code for old each-scope/index props
- d653759: Adds mount function and property