All Versions
Latest Version
Avg Release Cycle
63 days
Latest Release

Changelog History
Page 1

  • v0.10.3 Changes

    September 01, 2020
    • ๐Ÿ†• New: Airstream v0.10.1, see Airstream changelog
    • ๐Ÿ†• New: Easily toggle composite attr values
      • e.g. cls.toggle("class1") := true and cls.toggle("class1") <-- $bool
    • ๐Ÿ†• New: Easily remove composite attr values: cls.remove("class1")
    • ๐Ÿ†• New: Another cls.set method with varargs (same for other composite attrs)
    • ๐Ÿ†• New: Add pointer events to Laminar (thanks, @doofin!)
    • API: Make separator field on CompositeAttr public

    ๐Ÿ†• News:


    Laminar & Airstream development is sponsored by people like you.

    GOLD sponsors supporting this release: โœจ Iurii Malchenko

    ๐Ÿ‘ Thank you for supporting me! โค๏ธ

  • v0.10.2 Changes

    August 01, 2020
    • ๐Ÿ†• New: Support custom CSS props (for Web Components)
      • No change to Laminar API, but we're using a different method of setting and unsetting all CSS props under the hood.
    • New: Upgrade Scala DOM Types to v0.10.1
      • Adds slot attribute (for Web Components)

  • v0.10.1 Changes

    August 01, 2020
    • ๐Ÿ†• New: eventProp --> var alias for eventProp --> var.writer

  • v0.10.0 Changes

    August 01, 2020
    • โฌ†๏ธ Build: Upgrade Airstream to v0.10.0: changelog

  • v0.9.2 Changes

    July 01, 2020
    • ๐Ÿ†• New: Airstream v0.9.2, fixes throttle and adds a few convenience methods, see Airstream changelog.
    • ๐Ÿ†• New: onMountUnmountCallbackWithState which is like onMountUnmountCallback but can remember user-defined state and provide it to the unmount callback.
    • ๐Ÿ†• New: observable --> var alias for observable --> var.writer
    • ๐Ÿ†• New: FormElement type alias

  • v0.9.1 Changes

    May 01, 2020
    • ๐Ÿ›  Fix: Remove one of the conflicting amend methods (#54)
      • This change should be almost always source-compatible so no changes required.
    • ๐Ÿ†• New: nbsp character now available for convenience
    • ๐Ÿ†• New: emptyMod now available (a universal Modifier that does nothing)

    ๐Ÿ†• News:

  • v0.9.0 Changes

    April 01, 2020
    • โฌ†๏ธ Build: Upgrade Scala DOM Types to v0.10.0: changelog
      • A few naming changes to attributes and tags
      • This also bumps scala-js-dom to v1.0.0
    • โฌ†๏ธ Build: Upgrade Airstream to v0.9.0: changelog
    • API: ReactiveElement.amend() returns this now
    • ๐Ÿ›  Fix: Incorrect SVG composite attributes types

    ๐Ÿ†• News:

    • Check out yurique/scala-js-laminar-starter.g8, a new giter8 template that sets up a full stack application with Laminar on the frontend, and uses a plain webpack config instead of scalajs-bundler.

  • v0.8.0 Changes

    March 01, 2020

    ๐Ÿš€ This release is a significant improvement to both usability and safety of Laminar. We overhauled the lifecycle event system, and reworked how Laminar makes use of Airstream ownership, fixing longstanding design flaws in the process. We also simplified many things e.g. we eliminated the whole Scala DOM Builder layer. Below is a comprehensive list of changes with migration tips sprinkled throughout.

    • โž• Addons
      • New: Waypoint โ€“ efficient URL router for Laminar
    • ๐Ÿ“š Documentation
      • The entire documentation was of course updated for v0.8.0. For those already familiar with Laminar v0.7 API, the following sections contain new or significantly updated conceptual material:
      • Manual Application
      • Reusing Elements
      • Efficiency
      • Binding Observables
      • Ownership
      • Memory Management
      • Element Lifecycle Hooks
      • See also the Changelog for Airstream v0.8.0, and the new Dynamic Ownership section in Airstream docs.
      • New blog post expanding on the rationale behind Laminar: My Four Year Quest For Perfect Scala.js UI Development
    • ๐Ÿ†• New: Ownership & Lifecycle Events overhaul
      • This is the flagship feature of this release.
      • Ownership
      • Laminar now uses Airstream's new DynamicOwner and DynamicSubscription features: ReactiveElement subscriptions are now activated every time the element is mounted, not when it is first created. This solves a long standing design flaw (#33).
      • You can now re-mount previously unmounted elements: their subscriptions will be re-created and will work again.
      • Lifecycle Event system
      • Eliminate mountEvents and parentChangeEvents streams, maybeParentSignal signal, MountEvent type, and all related machinery
      • New: onMountCallback / onMountBind / onMountInsert / onUnmountCallback / onMountUnmountCallback modifiers
      • Mount events are now propagated differently down the tree, which has minor timing differences:
        • Order of unmount events changed between child / parent components. If a subtree is being unmounted, the unmount hooks on children will fire before they fire on their parents.
        • Previously mount events had to wait for the current Airstream Transaction to finish when propagating to child nodes (similar to how EventBus always emits events in a new Transaction). This is not the case anymore. In practical terms this is unlikely to affect you, except that it fixes #47.
      • Migration: Read the new docs and choose an appropriate onMount* hook instead of the old streams. Don't rush to use onMountCallback, check out all of the hooks first.
    • ๐Ÿ”€ API: Merge EventPropEmitter and EventPropSetter into EventPropBinder)
      • Unlike the old EventPropSetter, EventPropBinder adds and removes event listeners on mount, not on instantiation. This should not be a problem as event listeners generally don't fire on detached nodes in the first place.
      • Migration: Replace usages of EventPropEmitter with EventPropBinder. If you were using EventPropEmitter as an EventPropTransformation, those methods will not be available anymore as EventPropBinder does not extend EventPropTransformation, so you will need to rewrite those calls differently, more manually. This usage wasn't explicitly documented, so I hope no one actually runs into this.
    • API: RootNode no longer automatically mounts itself when the provided containerElement is itself unmounted.
      • This improves ease of integration if you want to e.g. render a Laminar element in a React component.
      • Migration: this probably does not affect you. If it does, you'll need to call rootNode.mount() when appropriate. See the new "What Is Mounting?" section in docs.
    • API: Replace ReactiveEventProp.config(useCapture: Boolean) with EventPropTransformation.useCapture and EventPropTransformation.useBubbleMode
      • Migration example: onClick.config(useCapture = true) --> onClick.useCapture
      • Practically this means that you can set useCapture anywhere you have an EventPropTransformation, not just where you have the original ReactiveEventProp
    • API: New modifier subtypes: Setter, Binder and Inserter (old Setter renamed to KeySetter)
      • The behaviour is the same except for subscription lifecycle as explained in ownership, but you need to know the distinction between the new types to use the new lifecycle hooks.
    • API: Eliminate dependency on Scala DOM Builder
      • DOM Builder is capable of supporting different DOM backends and even JVM rendering. We have no plans to use either of these in Laminar, so the indirection required by these abstractions is not pulling its weight.
      • DomApi
      • Remove the old DomApi trait and companion object.
        • Combine domapi.*Api traits into a single DomApi object
        • Use the new DomApi object directly instead of passing implicit domapi.*Api parameters.
      • Move Setter and EventPropSetter into Laminar, simplify type signatures and rename to KeySetter and EventPropBinder
      • Merge into relevant Laminar subtypes: Node -> ReactiveNode (add Ref type param), Comment -> ReactiveComment, Text -> TextNode, ParentNode -> ParentNode, ChildNode -> ChildNode, Root -> RootNode, TagSyntax -> HtmlTag & SvgTag
      • Merge EventfulNode trait into ReactiveElement (split members between the trait and the companion object)
      • Change type of maybeEventListeners to have List instead of mutable.Buffer, it was never intended to be mutable
      • Migration: If you reference any of the affected types directly, you will need to import them from Laminar, or use their corresponding Laminar replacements listed above. Other than that, everything should just work.
    • API: Limit access / hide / obscure
      • Hide willSetParent and setParent methods. Use Laminar's ParentNode.appendChild(parent, childNode) or similar.
      • Move appendChild and other similar methods from ParentNode instance to companion object.
      • Those low-level methods are still available to you as a user, but generally you should avoid them in favor of a reactive approach (various <-- and --> methods).
      • ReactiveElement.maybeChildren is not mutable anymore (was never intended to be)
      • subscribe* methods renamed and moved to ReactiveElement companion object
      • Migration: use the new observable --> observer modifier, or the new onMount* hooks, and/or the new element.amend method.
      • Make sure to document nodeToInserter @nc
    • ๐Ÿšฆ API: eliminate auxiliary syntax myElement <-- child <-- childSignal
      • Use the new amend method instead: myElement.amend(child <-- childSignal)
    • ๐Ÿšš API: Remove ChildNode.isParentMounted method. Use a similar ChildNode.isNodeMounted instead.
    • ๐Ÿ“ฆ API: Move ChildrenCommand out of the poorly named collection package
    • API: Rename types: ReactiveHtmlBuilders -> HtmlBuilders, ReactiveSvgBuilders -> SvgBuilders, ReactiveRoot -> RootNode, ReactiveComment -> CommentNode, ReactiveText -> TextNode, ReactiveChildNode -> ChildNode
    • ๐Ÿ†• New: EventPropTransformation), works the same as ReactiveEventProp), returning a stream of events
      • Example: div(...).events(onClick.useCapture.preventDefault)
      • Useful to combine with the new observable --> observer method.
    • ๐Ÿ†• New: element.amend method
    • ๐Ÿ†• New: onMountFocus modifier - focus an element every time it's mounted
    • API: New alias for inContext: forthis
    • API: ReactiveElement and other node types that take type params now have type Base defined on their companion objects containing the most generic version of that type, e.g. ReactiveElement[dom.Element] for ReactiveElement.
    • ๐Ÿš€ Build: Note that this release is version 0.8.0, not 0.8 as I would have named it before.

  • v0.7.2 Changes

    December 01, 2019
    • ๐Ÿ— Build: Scala 2.13 support