- Add support for React 18 (PR #665)
- Add syntactic sugar for capture phase handlers, such as 'onKeyDownCapture' (PR #695)
- Correctly handle
@reactcomponents with achildren: Seq[ReactElement]prop (PR #721)
- Includes the core set of changes required to make Slinky work well with Next.js (including module splitting). The Slinky docs site now is built with Next.js! (PR #588)
- Slinky now requires Scala.js 1.9.0 or higher, but libraries published against older versions of Slinky should continue to work (PR #588)
- The interface to
createPortalhas changed, but libraries should not be affected since this is typically intended for end-users (PR #594)
- Fix stale version of components being rendered when hot reloading is used with module splitting (PR #588)
- Add support for the
keyparameter ofcreatePortal(PR #594) - Allow the
cxandcySVG attributes to be assigned toStrings instead of justDouble(PR #617)
v0.7.2 (replaced v0.7.1)
- Inline functional component creation to improve stack traces (PR #551)
- Fix issue with readers not being available in dev mode on Scala 3 (PR #552)
- Fix CI issues with publishing to Maven Central and JetBrains Marketplace
- Added preliminary Scala 3 support (PR #494)
- no
@react/Props-applysugar - expected to require
-source:3.0-migrationand produce warnings - may not encode the same props in the same way as Scala 2 version due to different encoder generation mechanism.
- no
- Dropped Scala.js 0.6 and upgraded 1.x line to 1.6.0 to simplify building with Scala 3 (PR #494)
- Updated scalajs-dom to v2.0.0 which is cross-published for Scala 3 (PR #511)
- Support returning
js.Functionas the cleanup handler for effect hooks (PR #525) - Support using
React.memoon a component created withReact.forwardRef(PR #530) - Support the dependencies parameter of
useImperativeHandle(PR #531)
- Bring back the missing
ddanddttags (PR #477) - Allow the
Propstype in an@reactcomponent to have its own annotations (PR #476) - Support the
readOnlyattribute ontextareaelements (PR #492) - Remove an extra
printlnin an element conversion (PR #507)
- The IntelliJ support plugin has now been extracted into an independent plugin on the JetBrains Marketplace, making installation much more consistent
- Add support for native
useWindowDimensionshook (PR #422)
- Add missing inherited props to native
FlatListcomponent (PR #422)
- Updated
scalajs-domto 1.0.0 (PR #362) - Add facades for the
React.Profilercomponent (PR #372) - Add facades for the
actfuncion inreact-test-renderer(PR #376)
- Fix compilation errors on Scala 2.13 when
Anyis involved inProps/Statetypes (PR #388) - Allow exporting external component definitions as instances of
ReactComponentClass(PR #377) - Update prop type definitions for the React Native
Imagecomponent to support local images (PR #411)
- Due to the update of scalajs-dom to 1.0.0 a support for
ddanddttags has been dropped.
- Add docs for the new Electron app template (PR #339)
- Fix crashes with class components when emitting ES2015 code (PR #335)
- Support hot reloading when using Scala.js 1.0 (PR #336)
- Correct props type definition for the React Native
FlatListcomponent (PR #352)
- Add slinky-react-router and slinky-history as separate subprojects, to provide interfaces to react-router and the html5 history api (PR #305)
- Add apply method for constructing CustomTag and CustomAttributes (PR #318)
- Rewrite the class component logic to patch the component definition once to handle JS data instead of on every initialization (PR #321)
- Add ARIA role attribute (PR #309)
- Support className and role attributes for SVG (PR #314)
- Add novalidate attribute to form (PR #315)
- Fix types for the useCallback hook and fix its reference equality behavior (PR #302)
- Use js.Object instead of js.Dynamics on attribute style (PR #322)
- Add missing inherited props to native ScrollView component (PR #326)
- Fix project build in Windows OS and add automated testing in Windows to CI workflow. You can now build Slinky and run tests in Windows (PR #308)
- Improve experience using
ReactElements within first-order types such as Map and List (PR #285) - Support React Native's Keyboard API (PR #293)
- Fix crashes when calling
setStateon a component withPropsset to some subtype ofFunction1(PR #295) - Support
useCallbackwith a function that takes arguments (PR #290) - Fix false warnings on
@reactclasses if-Ywarn-value-discardscalac option was used (PR #296) - Update the IntelliJ support plugin to be compatible with IntelliJ 2019.2 (PR #297)
- Support optional attributes, see the docs for more details (PR #275)
- Slinky now has full support for Scala 2.13 (PR #269)
- Improve error messages when an
@react classextends the wrong supertype (PR #277) - Add shortcut
applyfor@reactfunctional components to mirror class components (PR #278)
- Allow
SetStateHookCallbackto be used as plain functions through an implicit conversion (PR #268) - Allow
React.memoto specify a custom compare function (PR #260) - New facades for React Native:
SafeAreaView,TouchableHighlight,TouchableOpacity, andPlatform(PR #214)
- Allow
componentdefined in a functional component to have any access control (PR #262) - Fix incorrect typing of
SyntheticMouseEvent.clientX(PR #261)
- Casting the
targetproperty of event objects is no longer needed! Now all event handlers are statically typed based on the tag they are being placed on (PR #243) - Support React Hooks for functional components, see the docs for more details (PR #227)
- Add support for writing functional components, see the docs for more details (PR #217)
- Slinky docs have moved to a new domain, slinky.dev!
- The tags API has seen some major changes, please take a look at the separate section below for more details (PR #243)
- Half-built components and tags, which have some props provided but have not yet been converted to a
ReactElement, cannot be reused. Doing this will result in a runtime exception pointing out where the reuse occured (PR #253) - Components using the static lifecycle functions
getDerivedStateFromPropsandgetDerivedStateFromErrormust now override the functions with aval(PR #248) - The
React.forwardReffunction now takes aFunctionalComponentTakingRef, which can be creating by creating a functional component that takes an additional ref parameter:FunctionalComponent((props, ref) => ...)(PR #227) - The
ReactReftype is no longer variant in its type parameters to increase type safety (PR #227) - Components will no longer have their
displayNamewhen built infullOptJSmode, this results in a ~2.5% decrease in bundle size and matches behavior with JS where names are obfuscated in production builds (PR #217) - The
Optionwriter now emitsnullinstead ofjs.undefinedfor a value ofNone(PR #247)
- Make the static lifecycle functions
getDerivedStateFromPropsandgetDerivedStateFromErrorwork correctly infullOptJSmode (PR #248) - Fix issues around state not updating when setting an
OptiontoNonein hot reloading mode (PR #247) - Handle
nullreturn values in derived state functions to not update the state (PR #249) - Fix the
js.|reader/writer implementations to work correctly infullOptJSmode (PR #248) - Support autoComplete attr for input and form elements (PR #225)
- Fix capitalization of
rowSpan/colSpanattribute (used to berowspan/colspan) (PR #224)
This release includes a major rewrite of the tags API that eliminates the need to cast the target value of event handlers and improves typesafety by more closely matching the official React API. As a result of these changes, event handlers defined in separate methods or code abstracting over tags may not initially compile with this new version.
Event handlers in previous versions of Slinky were functions from a DOM event type to Unit. In React, events are normalized into SyntheticEvents that provide a common subset of the events generated in different browsers. In this version of Slinky, event handlers have been changed to all be functions from a synthetic event type (one of SyntheticEvent[TargetDOMType, UnderlyingDOMEventType], SyntheticMouseEvent[TargetDOMType], SyntheticTouchEvent[TargetDOMType], etc based on the event being listened to) to Unit.
This means that explicit references to the DOM event type will no longer compile and will need to be replaced by an appropriate synthetic event type with a TargetDOMType that matches the DOM type of the tag the listener is being placed on. This change ensures that the properties available on event objects at compile time match those generated by React.
In previous versions of Slinky, passing in attributes required the first attribute to be passed separately from the varargs parameter containing the rest of the attributes. In this version, the API for constructing tags has changed from apply taking either (firstTag: AttrPair[...], otherTags: AttrPair[...]*) or ReactElement* to just a single method taking (mods: TagMod[...]*) with conversions from AttrPair and ReactElement to this type.
So code that passed in generated attributes like:
div(firstAttr, restAttrs: _*)will now need to be replaced by
div(allAttrs: _*)Similarly, in components that previously took in AttrPair and ReactElement separately, this can now be simplified to just take TagMods.
- Slinky support for Scala 2.13 is now built with 2.13.0-M5 (PR #202)
- Add support for
getDerivedStateFromErrorfrom React 16.6 (PR #206) - Add support for the
Suspensecomponent from React 16.6 (PR #216) - Use default parameters to fill in missing props on exported components (PR #221)
- Fix compile errors when overriding the
PropsorStatetype (PR #220) - Update library injector setup to support IntelliJ 2018.3 and newer (PR #219)
- Fix runtime crash when
initialState()is defined with the extra parentheses (PR #218) - Fix compilation errors in generating
Reader/Writerwhen private objects are involved (PR #205)
- Support reading and writing
scala.Array(PR #187) - Support the
defaultValueattribute for specifying a default form value without overriding user inputs (PR #186)
- Prevent crashes with components that store an
Optionof an opaque type in theirState(PR #198) - Fix
ComponentWrappers not picking up manually defined Reader/Writers for theStatetype (PR #190) - Fix how the IntelliJ extensions handles components that have a
childrenprop but no other props (PR #189) - Fix errors when using the
@reactmacro annotation withComponent/StatelessComponentimported locally (PR #188) - Fix the
valueattribute not being available on theselectandtextareatags (PR #177) - Bump Scala version to 2.12.7 and SBT/plugin versions as well (PR #176)
- Slinky now supports Scala 2.13.0-M4 (PR #153)!
- Magnolia has been replaced with a custom implementation tuned for Slinky, resulting in smaller bundles and faster compilation (PR #159, PR #159)
- Readers and writers for props are no longer needed for hot-reloading components, resulting in up to 2x drops in bundle size in
fastOptJSmode (PR #162) - React element construction is now more aggressively inlined, resulting in smaller bundle sizes (5% drop in the docs project) (PR #156)
- Switch from React VR package to React 360 (PR #141)
- Scalameta is no longer used for the
@reactmacro, and Macro Paradise is used instead. See the docs for updated installation instructions for adding the Macro Paradise compiler plugin (PR #132) @reactcomponents taking achildrenprop now generate anapplymethod with the children moved to a curried parameter to better match JSX (PR #161)- React VR components are no longer supported, the
slinky-vrmodule now points to React 360 (PR #141) ReactComponentClassnow takes a type parameter of thePropstype to improve type safety with higher-order components. Existing uses can be safely replaced withReactComponentClass[_](PR #157)- Interop with Scala.js React now requires using the explicit conversions
.toSlinkyand.toScalaJSReact(PR #151)
- Support pointer events that were added in React 16.4 (PR #149)
- Bump Scala.js React version for interop to 1.2.0 (PR #148)
- Fix errors in Reader/Writer provider macros with Scala versions > 2.12.4 (PR #147)
- Support storing any type as a default context value (PR #136)
- Set sourcemaps to use GitHub URLs so that they load in other apps (PR #143)
- Fix bug with
shouldComponentUpdatenot being registered correctly on the component (PR #135)
- Fix exception when hot-reloading Slinky components (PR #134)
- Slinky now has support for React 16.3 features
- Use the new Context API with a statically-typed interface (PR #125)
- Use the new Ref API with a statically-typed interface as well! (PR #126)
- Transition to the new React lifecycle with support for getSnapshotBeforeUpdate (PR #129)
- Use the getDerivedStateFromProps API by defining it inside
ComponentWrapperor the companion object of an annotated component (PR #130) - Use the
React.forwardRefAPI to create new components that forward their refs to children (PR #127) - Use the
StrictModecomponent to enable more runtime checks on your components (PR #128)
- Slinky now has support for React Native, available in the
slinky-nativemodule. Try it out with create-react-native-scala-app - Slinky now has support for React VR, available in the
slinky-vrmodule. Try it out with create-react-vr-scala-app - Want to write fancier unit tests for your Slinky app? Slinky now comes with an interface for
react-test-renderer, available under theslinky-testrenderermodule. (PR #119)
- The
ErrorBoundarytrait has been removed, because it is no longer needed to implement an error boundary component - The
DefinitionBaseclass now takes an additional type parameterSnapshot, for use with the new snapshot-based lifecycle API - The
BuildingComponentcase class has been simplified into a regular class, so thenewkeyword is now required when creating instances - The
Reactobject has been refactored to take regular Scala types instead of JS types, so any dependency on the original JS types (js.FunctionN) will not work
- The
@reactmacro now produces nicer APIs for external components that have default values for all props parameters. (PR #119) - Add more variations for
ExternalComponentthat support providing a statically-typed interface for the component instance:ExternalComponentWithRefType,ExternalComponentWithAttributesWithRefType,ExternalComponentNoPropsWithRefType,ExternalComponentNoPropsWithAttributesWithRefType(PR #119) - Bring back the
WithRawtrait, which makes it possible to access the original object of a read value (PR #122) - Fix exceptions when declaring custom tags and attributes in a component class (PR #118)
- Fix exceptions when reading the null-prototype in Node.js (PR #121)
- Improve support for creating custom tags and attributes (see docs for details) (PR #116)
- Fix compilation errors when using an
Optionof a component instance in a tag tree (PR #111) - Reduce warnings for unused imports when using the
@reactmacro annotation (PR #112)
- Slinky now has full support for React 16 features such as fragments, portals, and streaming server-side-rendering
- The tag API has been remodeled to be more efficient and flexible (see https://slinky.shadaj.me/docs/abstracting-over-tags/)
- The
@reactmacro annotation is now compatible with many more use cases, such as pulling values from a companion object, and has improved support in IntelliJ
- BREAKING!: The package
me.shadaj.slinkyhas been renamed toslinky(PR #103) - BREAKING: Stateless components that use the
@reactmacro annotation must extend theStatelessComponentclass instead of justComponent(PR #69) - BREAKING: Callbacks passed to
setStateare now Scala functions, so there is no need to force implicit conversions (PR #71) - BREAKING: The tag construction flow now requires attributes to come before children. In addition, an empty list of attributes is no longer allowed. When generating tags with dynamic attributes, you will now need to construct the tag as
tag(attrs.head, attrs.tail: _*)to satisfy this requirement (PR #73) - Add support for portal elements, which were introduced in React 16 (PR #65)
- Greatly improve IntelliJ support for Slinky with special macro annotation behavior (PR #69)
- Add an alternative
applymethod to eliminate compiler warnings when using propless components (PR #70) - Add better error message when
@reactannotation is used on a component with noPropstype declaration (PR #72) - Better support for converting Slinky types to scalajs-react types when an implicit conversion to
ReactElementis needed (PR #73) - Large performance gains in tag construction, with over 5x improvements for some components! (PR #73)
- Add missing global HTML attributes:
spellCheck,contentEditable, andtabIndex(PR #77) - Fix compilation errors when trying to use findDOMNode and passing in an annotated component (PR #78)
- Add no-callback forceUpdate and make it available in annotated components (PR #78)
- Fix bugs involving using companion object values from a
@reactannotated component (PR #80) - Add a
*tag for external components that can take any attribute (PR #81) - Add support for error boundaries, which were added in React 16 (PR #82)
- Add support for all
ReactElementtypes introduced in React 16, such as numbers and booleans (PR #83) - Add remaining methods from ReactDOMServer, including those introduced in React 16 (PR #84)
- Add the custom
onattribute for AMP pages, introduced in React 16 (PR #85) - Add facade for
React.Children, including a new typeReactChildrenforprops.children(PR #86) - Add facade for
ReactDOM.unmountComponentAtNode(PR #88) - Fix mapping of undefined values in a case class. Such values now do not become a property in the written object (PR #95)
- Add readers for
js.Array[T](PR #100) - Add common supertype
Tagfor all tag elements to allow abstracting over them (PR #101) - Add common supertype
Attrwith the typeclasssupports[Tag]to allow abstracting over supported attributes (seeTagTestfor example) (PR #101)
- BREAKING: Instead of taking key and refs as additional parameters next to props, they are now taken in through the methods
withKeyandwithRef(components and external components only) - BREAKING: Introduce the experimental macro annotation
@reactto simplify component and external component creation with auto-generated companion object for a component class (or external component object). This is a major change to how applications with Slinky are written, so please see the notes at the end of the changelog (PR #29)- BREAKING: This change also renames the
Componentclass toComponentWrapper. TheComponentclass is now used for the@reactannotation.
- BREAKING: This change also renames the
- BREAKING: Rename
ExternalComponentWithTagModstoExternalComponentWithAttributesand take attributes as a curried parameter instead of an extra parameter afterProps(PR #26) - BREAKING: Introduce
ExternalComponentNoPropsandExternalComponentNoPropsWithAttributesfor cases where an external component takes no props (PR #58) - BREAKING: Slinky now expects that the
-P:scalajs:sjsDefinedByDefaultcompiler option is enabled in the@reactmacro annotation [] - Have mouse attributes such as
onMouseDowntake aMouseEventinstead of just anEvent(PR #27) - Add support for generating
ReaderandWriterfor sealed traits, value classes, and case objects (through a Magnolia upgrade) (PR #45) - Fix bug with hot loading not updating instances of readers and writers (PR #49)
- Fix bug with hot loading using the wrong proxy component when there are multiple components classes in the tree (PR #50)
- Add support for reading and writing js.Dynamic (and anything that extends js.Any) (PR #51)
- Add support for reading and writing union types (js.|) (PR #52)
- Slinky's implementation of mapping Scala types to JS types is now available as a separate module
slinky-readwrite(PR #54) - Improve type safety of ExternalComponentWithAttributes by restricting the type parameter to tag types (PR #55)
One of Slinky's main goals is to have React components written in Scala look very similar to ES6. In version 0.1.x, Slinky required
extra boilerplate for defining an object that contained apply methods and then creating a Def inner class that contained the actual component logic.
This version includes the @react macro annotation, which makes it possible to directly write the class containing component logic and have Slinky generate
the companion object for constructing component instances. The macro annotation also now generates special apply methods when your Props is a case class
so that constructing Scala components looks more similar to JSX, with the Props values directly taken as parameters of the apply.
Note that the macro annotation is experimental and not required. To use the original component style simply replace the extends Component with extends ComponentWrapper and your
components should continue to function as they did before.
As an example of migrating an existing component to the new macro annotation style, take a simple component that displays a header:
import me.shadaj.slinky.core.WrapperComponent
import me.shadaj.slinky.web.html._
object HelloMessage extends WrapperComponent {
case class Props(name: String)
type State = Unit
@ScalaJSDefined
class Def(jsProps: js.Object) extends Definition(jsProps) {
def render() = {
div(s"Hello ${props.name}")
}
}
}to use the new macro annotation style, we essentially extract out the definition class, move the Props and State types into the class, and extend Component instead of Definition:
import me.shadaj.core.{Component, react}
import me.shadaj.slinky.web.html._
@react class HelloMessage extends Component {
case class Props(name: String)
type State = Unit
def render() = {
div(s"Hello ${props.name}")
}
}If we want to use this component, we now have a new option for constructing it directly passing in the Props values
HelloMessage(HelloMessage.Props("Shadaj")) // old style
HelloMessage("Shadaj") // now possible!
HelloMessage(name = "Shadaj") // now possible, closest to JSXThe @react annotation is also available for external components. For external components, the annotation generates the new apply method style in the same style as Scala components.
import me.shadaj.slinky.core.annotations.react
import me.shadaj.slinky.core.ExternalComponent
@react object React3 extends ExternalComponent {
case class Props(mainCamera: String, width: Int, height: Int,
onAnimate: Option[() => Unit] = None, alpha: Boolean = false)
override val component: js.Object = js.Dynamic.global.React3.asInstanceOf[js.Object]
}this makes it possible to construct the external component as
React3(mainCamera = "camera", width = 800, height = 800)- Have ExternalComponentsWithTagMods take the tag type as a type parameter instead of an abstract type (PR #19)
- Added support for reading and writing values of type
js.UndefOr[T](PR #18) - Components and external components with a
Propstype ofUnitcan now be constructed without any parameters, instead of having to pass in()as props (PR #12) - Boolean attributes, such as
disabled, can now be used without specifying a value to closer match JSX. For example, a disabled input can now be constructed asinput(disabled)without providing the:= true(PR #14)
- Initial release