Skip to content

Latest commit

 

History

History
316 lines (257 loc) · 13.6 KB

2.0.0.md

File metadata and controls

316 lines (257 loc) · 13.6 KB

2.0.0

Lots of big, juicy, modernising changes here. Make sure you at least read the migration guide.

Contents:

Major New Features

  • Scala 3 support

  • React Hooks (doc)

  • React 17

    • Contexts now have optional displayNames. You can optionally specify it on creation via React.createContext(displayName, defaultValue). You can also read it via .displayName.
    • Add disableRemotePlayback HTML attribute
    • Add enterKeyHint HTML attribute
  • Effect generalisation:

    • You can now provide any kind of supported effect in place of just Callback(To) in many cases. Eg. you can now pass an AsyncCallback to an event handler without converting it to a Callback.
    • Additional effect types can be used by including the appropriate module; no imports required. Eg. if you include the Cats Effect extension module you can pass an IO directly to scalajs-react.
    • The default effect types are now configurable. Default effect types are used when scalajs-react provides you with effect values. Eg. calling .props from BackendScope used to be hardcoded to return a CallbackTo[Props] because CallbackTo used to be hardcoded as the default sync effect type.
      • If you use the core module then everything will be the same as it was with Callback(To) and AsyncCallback being the default sync and async effect types respectively.
      • If you use the new core-bundle-cats_effect module instead of core, then Cats Effects' SyncIO and IO types will be the default sync and async effect types respectively.
    • The Callback(To), AsyncCallback, CallbackOption classes are now optional. If you use a different core bundle (eg. core-bundle-cats_effect instead of core) then classes like CallbackTo wont even be on the classpath unless you explicitly add the callback module.
  • Modularity. There are now many more modules (i.e. Maven artifacts) that are smaller and more pluggable, for increased flexibility. For example, the React Scala.JS facades now live in their own modules without any other scalajs-react specific functionality. (doc)

  • Global settings have been fixed and revamped. See the new guide here. This allows you to produce different dev and prod builds without making code changes.

Minor New Features

  • Add support for Monocle v3

  • Add Router DSL to handle repeated query params like ?a=1&a=2:

    • queryToSeq which gives you a Seq[(String, String)]
    • queryToMultimap which gives you a Map[String, Seq[String]
  • Add to object Callback:

    • def runAll(callbacks: CallbackTo[Any]*): Callback -- Any exceptions get a printStackTrace and are then discarded, and the next callback run.
  • Add to object CallbackTo:

    • def fromJsFn[A](f: js.Function0[A]): CallbackTo[A]
  • Add to Callback{,To} instances:

    • def reset: Callback -- If this completes successfully, discard the result. If any exception occurs, call printStackTrace and continue.
  • Add to AsyncCallback instances:

    • def reset: AsyncCallback[Unit] -- If this completes successfully, discard the result. If any exception occurs, call printStackTrace and continue.
  • New extension method showDom(): String available on mounted components given import japgolly.scalajs.react.test._ and/or import japgolly.scalajs.react.test.ReactTestUtil._

Removals

  • Dropped support for Scala 2.12
  • Dropped support for Scala.JS 0.6.x
  • Dropped Scalaz support. The following modules are no longer available:
    • ext-monocle (deprecated version of ext-monocle-scalaz)
    • ext-monocle-scalaz
    • ext-scalaz72
  • Removed state monad support (ReactS, ReactST, etc)
  • Removed code deprecated in 1.5.x
  • Removed scala-collection-compat as a dependency
  • Removed CallbackKleisli
  • Removed .namespace from VDOM tags - it's an ancient legacy artifact that is no longer used

Changes: Backwards-Incompatible

  • If you used to just add the extra module to your sbt's libraryDependencies and rely on core being included as a transitive dependency, it will no longer work. Explicitly add the core to your libraryDependencies.

  • In ReactTestUtils, act and actAsync now return the argument's value after it's executed

  • RouterCtl#onLinkClick now returns a Option[Callback] instead of a CallbackOption[Unit]. If necessary, wrap in CallbackOption.optionCallback to convert back to CallbackOption[Unit], or .getOrEmpty to turn into a Callback.

  • traverse and sequence methods in Callback, CallbackTo, AsyncCallback, CallbackOption now require an Iterable instead of an IterableOnce

  • Backwards-incompatible module changes:

    Old Module Name New Module Name
    ext-cats core-ext-cats
    ext-cats-effect core-ext-cats_effect
    ext-monocle Discontinued
    ext-monocle-cats extra-ext-monocle2
    ext-monocle-scalaz Discontinued
    ext-scalaz72 Discontinued
  • -Xelide-below no longer used. There are a few runtime checks that scalajs-react performs in a few places (currently js component wrapping, router construction). Previously you could disable and remove these from your JS output by specifying -Xelide-below ASSERTION as a scalac flag. Scala 3 doesn't support elision and it's too obscure a feature anyway so as of this version, scalajs-react runtime assertions will always appear in development mode (fastOptJS) and will be removed in production mode (fullOptJS).

  • Upgraded the Cats Effect to v3

  • The SVG attribute colorProfile is now colorProfileAttr

Changes: Backwards-Compatible

  • ReactTestUtils:

    • render methods now call act() under the hood
    • with*Render* methods that take a (f: M => A) can now also take
      • (f: (Element, M) => A)
      • withParent(f: Element => A)
  • Reusability derivation now also includes a reference-equality check by default. If the reference-equality check fails, then it falls back to a content-based check.

  • VdomNode instances now have a renderIntoDOM method (just like VdomElement)

  • Make covariant:

    • AsyncCallback
    • AsyncCallback.Forked
    • CallbackTo
    • CallbackOption
  • Add withFilter to Callback(To) and AsyncCallback

  • Bug fixes:

    • ScalaFnComponents now use VdomNodes instead of VdomElements
    • ForwardRefs now use VdomNodes instead of VdomElements
    • Input to AsyncCallback.traverse et al should only be evaluated once per callback invocation
    • Input to CallbackOption.traverse et al should only be evaluated once per callback invocation
  • Avoid boxing in React.Context and getSnapshotBeforeUpdate

  • Px[A]#extract now takes an implicit Px.Extract[A](Px[A] => A) argument instead of being a macro. If you're using this exotic feature, you can now provide your own Px.Extract typeclass instances.

  • Backwards-compatible dependency upgrades:

    • cats to 2.6.1
    • monocle (v2) to 2.1.0
    • scala to 2.13.6
    • scala.js to 1.5.1
    • sourcecode to 0.2.7

Changes: Auto-Migratable

You can run the script in the Migration section at the bottom of the page to automatically perform these changes.

  • If you use any of the Router DSL .addCondition methods and provide a Page => CallbackTo[Boolean], you'll now need to add a By suffix (eg. addConditionBy).

  • Renamed

    • CatsReactReactCats
    • MonocleReactReactMonocle
    • In ReactTestUtils:
      • withNewBodyElementAsyncCallbackwithNewBodyElementAsync
      • withNewDocumentElementAsyncCallbackwithNewDocumentElementAsync
      • withRenderedAsyncCallbackwithRenderedAsync
      • withRenderedIntoBodyAsyncCallbackwithRenderedIntoBodyAsync
      • withRenderedIntoDocumentAsyncCallbackwithRenderedIntoDocumentAsync
  • Renamed (with old names still in place but deprecated)

    • AsyncCallback.{byName ⇒ suspend}
    • Callback.{byName ⇒ suspend}
    • CallbackTo.{byName ⇒ suspend}
    • CallbackOption.{liftOption ⇒ option}
    • CallbackOption.{liftOptionCallback ⇒ optionCallback}
    • CallbackOption.{liftOptionLike ⇒ maybe}
    • CallbackOption.{liftOptionLikeCallback ⇒ maybeCallback}
    • CallbackOption.{liftValue ⇒ delay}
    • CallbackOption.liftCallback(callback) ⇒ callback.toCBO
    • CallbackOption(callback) ⇒ callback.asCBO
    • JsFnComponent.fromScala.{byName ⇒ delay}
    • Reusability.{byName ⇒ suspend}
  • Renamed any vdom method names from `kebab-case` to camelCase

Migration

  1. Make sure to read the Changes: Backwards-Incompatible section above.

  2. Run this:

    find . -type f -name '*.scala' -exec perl -pi -e '
      s/\b(AsyncCallback[ .]+)byName\b/\1suspend/g;
      s/\b(Callback[ .]+)byName\b/\1suspend/g;
      s/\b(CallbackTo[ .]+)byName\b/\1suspend/g;
      s/\b(CallbackOption[ .]+)liftOption\b/\1option/g;
      s/\b(CallbackOption[ .]+)liftOptionCallback\b/\1optionCallback/g;
      s/\b(CallbackOption[ .]+)liftOptionLike\b/\1maybe/g;
      s/\b(CallbackOption[ .]+)liftOptionLikeCallback\b/\1maybeCallback/g;
      s/\b(CallbackOption[ .]+)liftValue\b/\1delay/g;
      s/\bCallbackOption *\( *([a-zA-Z_](?:[a-zA-Z0-9_. ]*[a-zA-Z0-9_])?) *\)/\1.asCBO/g;
      s/\bCallbackOption[ .]+liftCallback *\( *([a-zA-Z_](?:[a-zA-Z0-9_. ]*[a-zA-Z0-9_])?) *\)/\1.toCBO/g;
      s/\b(JsFnComponent[ .]+fromScala[ .]+)byName\b/\1delay/g;
      s/\b(Reusability[ .]+)byName\b/\1suspend/g;
      s/\bMonocleReact\b/ReactMonocle/g;
      s/\bCatsReact\b/ReactCats/g;
      s/\b(withNewBodyElementAsync)Callback\b/\1/g;
      s/\b(withNewDocumentElementAsync)Callback\b/\1/g;
      s/\b(withRenderedAsync)Callback\b/\1/g;
      s/\b(withRenderedIntoBodyAsync)Callback\b/\1/g;
      s/\b(withRenderedIntoDocumentAsync)Callback\b/\1/g;
      s/\bnew OnUnmount.Backend\b/OnUnmount()/g;
      s/\b(addCondition(?:With(?:Optional)?Fallback)?)( *\( *[a-zA-Z_][a-zA-Z0-9_]* +=>)/\1By\2/g;
      s/`all-scroll`/allScroll/g;
      s/`bidi-override`/bidiOverride/g;
      s/`border-box`/borderBox/g;
      s/`break-all`/breakAll/g;
      s/`break-word`/breakWord/g;
      s/`cjk-decimal`/cjkDecimal/g;
      s/`col-resize`/colResize/g;
      s/`color-profile`/colorProfile/g;
      s/`content-box`/contentBox/g;
      s/`context-menu`/contextMenu/g;
      s/`decimal-leading-zero`/decimalLeadingZero/g;
      s/`e-resize`/eResize/g;
      s/`ew-resize`/ewResize/g;
      s/`font-face-format`/fontFaceFormat/g;
      s/`font-face-name`/fontFaceName/g;
      s/`font-face-src`/fontFaceSrc/g;
      s/`font-face-uri`/fontFaceUri/g;
      s/`font-face`/fontFace/g;
      s/`hiragana-iroha`/hiraganaIroha/g;
      s/`inline-block`/inlineBlock/g;
      s/`inline-flex`/inlineFlex/g;
      s/`inline-table`/inlineTable/g;
      s/`katakana-iroha`/katakanaIroha/g;
      s/`keep-all`/keepAll/g;
      s/`line-through`/lineThrough/g;
      s/`list-item`/listItem/g;
      s/`lower-alpha`/lowerAlpha/g;
      s/`lower-greek`/lowerGreek/g;
      s/`lower-latin`/lowerLatin/g;
      s/`lower-roman`/lowerRoman/g;
      s/`missing-glyph`/missingGlyph/g;
      s/`n-resize`/nResize/g;
      s/`ne-resize`/neResize/g;
      s/`nesw-resize`/neswResize/g;
      s/`no-drop`/noDrop/g;
      s/`not-allowed`/notAllowed/g;
      s/`ns-resize`/nsResize/g;
      s/`nw-resize`/nwResize/g;
      s/`nwse-resize`/nwseResize/g;
      s/`padding-box`/paddingBox/g;
      s/`pre-line`/preLine/g;
      s/`pre-wrap`/preWrap/g;
      s/`preserve-3d`/preserve3d/g;
      s/`row-resize`/rowResize/g;
      s/`s-resize`/sResize/g;
      s/`se-resize`/seResize/g;
      s/`sw-resize`/swResize/g;
      s/`table-caption`/tableCaption/g;
      s/`table-cell`/tableCell/g;
      s/`table-column-group`/tableColumnGroup/g;
      s/`table-column`/tableColumn/g;
      s/`table-footer-group`/tableFooterGroup/g;
      s/`table-header-group`/tableHeaderGroup/g;
      s/`table-row-group`/tableRowGroup/g;
      s/`table-row`/tableRow/g;
      s/`text-bottom`/textBottom/g;
      s/`text-top`/textTop/g;
      s/`under left`/underLeft/g;
      s/`under right`/underRight/g;
      s/`upper-alpha`/upperAlpha/g;
      s/`upper-latin`/upperLatin/g;
      s/`upper-roman`/upperRoman/g;
      s/`vertical-text`/verticalText/g;
      s/`w-resize`/wResize/g;
      s/`x-large`/xLarge/g;
      s/`x-small`/xSmall/g;
      s/`xx-large`/xxLarge/g;
      s/`xx-small`/xxSmall/g;
      s/`zoom-in`/zoomIn/g;
      s/`zoom-out`/zoomOut/g;
    ' {} +

Thanks

A lot of this was kindly sponsored by Gemini/NOIRLab/AURA. Huge thanks to @cquiroz for making this possible, and to @rpiaggio for the awesome ideas that helped guide design.

We all want features like Scala 3 support but in reality it's a ton of work to implement. It's not very feasible for an OSS maintainer to do literally months of full-time work for free. On behalf of myself and the scalajs-react community, thank you so much for sponsoring this huge effort!