The v2 release is a complete re-write of react-md to address the majority of problems encountered while using v1. Unfortunately, this took a lot longer than I had hoped since I ended up using this project to learn Typescript as well as the new React hooks API. Even though there are some missing components from v1, I think the new functionality outweighs it and the components are scoped for a later release.
Before starting the migration to v2, I highly recommend reviewing the [Working with v1] guide and reviewing the following missing functionality:
get*Style
, get*ClassName
, etc)BottomNavigation
component has not been added to the initial v2 release.
This component might be added at a later time, but the new @react-md/app-bar package
should be able to solve a decent amount of use cases.DatePicker
and TimePicker
components have not been added to the
initial v2 release. These two components will definitely be added in a later
release, but require a lot more time to implement since dates are hard and
I want to create all the sub-components in a reusable and exportable way for
additional customization.FileUpload
component since it didn't feel extremely useful since
it didn't actually upload a file to a servermini
variants for the Drawer
/NavigationDrawer
components have not
yet been implemented in the new Layout
component.MenuTab
component due to never really working correctly and the
new @react-md/tabs package should allow for a much better user experience and
customization.ListItemControl
component since it was implemented pretty badly.
The new @react-md/list and @react-md/form packages should allow for this to be re-implemented in
your app fairly easily though.TablePagination
and TableCardHeader
components since I wasn't
sure how helpful they were and didn't really work. The new @react-md/table styling
behavior and customization should allow for a custom implementation fairly
easily though.EditDialogColumn
, SelectFieldColumn
, *Column
components from
the @react-md/table package since they aren't really needed anymore. Form elements
should be renderable within tables without the weird hacks these components
were implementing.Version
component since it was probably only ever used by the
documentation site.This release focused on updating react-md
to be as customizable as possible by
exporting a lot more low-level components, hooks, and utils that were used
internally. Something that I noticed from the v1 release is that if something
was not easily customizable or specific components were not public, it was
easier to actually write your own version of that component. This was a
major flaw and caused lots of problems especially since the majority of the
functionality behind these components were not reusable. The new components and
hooks should be able to help for these use cases but the down side is that
you'll still need to create a custom implementation for common patterns
throughout your app because some patterns seem repetitive.
Note: Upgrading to v2 of
react-md
does not require you to also use Typescript even though it is highly recommended to do so. You can still usereact-md
with JavaScript as you have done before, but all the examples and documentation will be written with Typescript.
v1.1.0
was the first react-md
release to add support for Typescript but unfortunately
the type definitions were
not that great because I did not
fully understand Typescript and kept getting out of sync or forgotten. Since
Typescript is becoming the new trend for web development with additional tooling
and editor integrations, it seemed like a good time to finally start learning
Typescript and re-write react-md
to use it natively.
One of the biggest pros for rewriting to Typescript is that now all the
documentation around Component props, hooks, or utils can now be viewed within
your editor or IDE if it supports the "Go to Definition"
functionality due to
being compiled with the *.d.ts
files now. In addition, the type definitions
should never be out of sync and should be much more strictly typed than before
since the entire library has been written in Typescript.
That being said, there are a few type definitions that could still be improved in v2 especially around generics and Records so any suggestions or PRs are welcomed.
In v1, the Drawer
and NavigationDrawer
components were used to be able to
determine the current app size using the static methods: getCurrentMedia
and
matchesMedia
. This meant that the only way to determine the current
application size through media queries was to either:
Drawer
or NavigationDrawer
components and hook into the
onMediaTypeChange
callback propDrawer.getCurrentMedia
/NavigationDrawer.getCurrentMedia
static methodsThis solution was pretty terrible and lead to confusion, out-of-sync behavior, and bugs.
Starting with v2 these issues should be resolved due to React implementing the new Context API along with the new AppSizeListener component and media query SCSS mixins.
The new AppSizeListener
component should be mounted once near the root of
your app which will initialize multiple resize and media query event listeners
to determine what size your app is currently being rendered while the
useAppSize
hook allows access to the current size.
Check out the AppSizeListener example for more details and a live demo.
In addition to the new component and hook, react-md
now provides a few utility
SCSS mixins for applying styles at different media query sizes:
There are also a few media query components which can be used to conditionally render components based on the current application site. Check out the Media Query Components example for some more information.
Since this release dropped IE 11 support, all the dynamic theming is done
through Custom CSS Properties (CSS Variables) with the new theme SCSS
functions and mixins. The root @react-md/theme package now provides a new background
and surface
color variable to use along with a lot of other themeable values
while the other packages will provide themeable variables for colors, margin,
and padding. The new theme API allows you to easily modify existing themes
without all the boilerplate and "hacks" from the v1 release. Here is a quick
example:
.custom-theme--v1 {
// create smaller icon buttons
.md-btn--icon {
height: 1rem;
font-size: 1rem;
width: 1rem;
}
// updating icon spacing
.md-icon-text {
$new-spacing: 0.5rem;
&:first-child {
padding-right: $new-spacing;
}
&:last-child {
padding-left: $new-spacing;
}
}
// change theme colors
@include react-md-theme-colors($md-orange-500, $md-purple-a-200);
}
// in v2
.custom-theme--v2 {
@include rmd-button-theme-update-var(icon-size, 1rem);
@include rmd-icon-theme-update-var(text-spacing, 0.5rem);
@include rmd-theme-update-var(primary, $rmd-orange-500);
@include rmd-theme-update-var(secondary, $rmd-purple-a-200);
}
You can also reference the current theme values as a value or CSS Variable:
.custom-class {
// use current background-color
@include rmd-theme(background-color, background);
// use the current primary text color on the current background color
@include rmd-theme(color, text-primary-on-background);
// use the current primary theme color as a border color (for some reason)
@include rmd-theme(border-color, primary): ;
// add 1rem to the current CSS Variable value for the icon text spacing
padding: calc(#{rmd-icon-theme-var(text-spacing)} + 1rem);
}
The new theme API is pretty powerful and allows for a lot of new customization
without needing to modify the react-md
internals and remembering specific
class names. Please check out the creating dynamic themes documentation for
more information.
Disclaimer: This new theme API was heavily inspired by the material components web library.
This release added a bunch of new utility functions and mixins to add additional styling throughout your app for common use cases such as:
Check out the SassDoc pages for additional documentation and examples for common mixins:
The default styles from react-md
will now attempt to automatically fix
contrast ratio issues between foreground and background colors using the new
rmd-theme-tone function. This appears to work for a great amount of use cases,
but it is still recommended to verify colors meet the recommended contrast ratio
for accessibility. You can check out the Theme Builder for a few examples of
contrast ratio issues by playing with the theme colors.
Every SCSS variable is now automatically compiled with its default value and
written to a dist/scssVariables.js
file for each package as a record of
variable names as keys and the default compiled value as the value. This allows
you to get access to each variable name as well as all the themeable CSS
Variables in JavaScript.
For example, if you want to get all the available material design colors from the theme package, you can use the following code:
import scssVariables from "@react-md/theme/dist/scssVariables";
// get all the colors from the color palette
// only the color variables in this package will not be prefixed
// with rmd-theme
const colorKeys = Object.keys(scssVariables).filter(
(name) => !/^rmd-theme/.test(name)
);
Note: This will be strictly typed for Typescript users as well.
To be honest, I had no idea what I was doing with typography in v1 (I
still don't really understand typography) and defaulted to modifying the
default tags with react-md
typography styles:
<h1> - <h6>
<p>
<caption>
<input>
<textarea>
<button>
Starting with v2, react-md
will provide a much simpler
CSS reset and not apply
any typography to html tags. In addition, the default typography styles can be
overridden or merged with new styles using the
$rmd-typography-styles variable.
The new @react-md/typography package also exports two new components for general text
styling and reusable typography mixins.
A user interaction state is the feedback presented to the user when one of the following actions happens:
v1 of react-md
had a very "noisy" implementation of this with the
ripple/ink effect
which caused a 300ms animation each time the user interacted with a focusable
element. This was okay for the tap and click behaviors but extremely obnoxious
for keyboard users especially when tabbing through elements quickly.
In addition there would sometimes be :hover
styles applied accidentally after
a user touches an element on mobile since touch events also trigger the :hover
state. The rewrite for v2 has solved these issues by introducing interaction
states, providing mixins to dynamically apply styles based on an interaction
state, and providing a new keyboard focus state.
The @react-md/utils package provides an InteractionModeListener
that is bundled into
the Configuration
component in the @react-md/layout package that helps determine which
interaction mode the user is currently using. This can be used along with the
following mixins for dynamically applying styles based on an interaction mode:
In addition, a new @react-md/states package has been added that implements the new
behavior for the ink/ripple effect that will now only trigger after a click
event instead of focus. The focus state has been drastically simplified to add
blue box-shadow
and sometimes add a slight background color change while
keyboard focused. The new interaction states can be implemented for any
non-react-md component as well with the following mixins:
The v1 release of react-md
implemented some accessibility features and
keyboard movement but the majority of the behavior was incorrect and caused more
issues than it tried to solve. v2 is still not 100% perfect due to how
differently screen readers behave, but should now follow the specs outlined on
the WIA-ARIA Best Practices
website. Due to these fixes a lot of components will now correctly require an
aria-label
or aria-labelledby
prop which only required an id
before.
The new keyboard movement behavior is drastically different now since components
now correctly follow the recommendations outlined in the WIA-ARIA Best practices
website. A new feature that is introduced in v2 is the ability to
"type-to-focus" elements in some complex components. The user can now focus a
component like the Tree
or DropdownMenu
and type letters to match the first
child that starts with those letters. In addition, lot of work has been made
into ensuring that keyboard focus is no longer lost while navigating between
temporary elements like menus and dialogs and implementing the new
aria-activedescendant
movement when needed to keep focus on the correct
components. It is highly recommended to check out the AutoComplete,
DropdownMenu, and Tree components since the changes should be extremely
noticeable and a few of the demos showcase this functionality.
Finally, the accessibility helpers have been created as reusable hooks in the @react-md/utils package so that non react-md components can implement this functionality as well.
document.querySelector
string.FocusContainer
that just
provides a onKeyDown
event handler for maintaining focus within a container.aria-activedescendant
focus
pattern which maintains focus on the "root" elementonKeyDown
event handler.useFocusMovement
and useActiveDescendantMovement
to provide keyboard
movement and optional search functionality.react-md
will now automatically update the provided styles when a parent
element (normally the root <html>
) for dir="rtl"
to support right to left
languages. The following properties will be automatically inversed:
margin-left
margin-right
padding-left
padding-right
left
right
Since it might be required to update non-react-md components with these styles, the @react-md/utils package also exports the following mixins to implement this behavior:
The documentation site allows for a live preview for this functionality! If you are on desktop, click the right to left toggle button in the main header. If you are on mobile, click the kebab menu in the main header and then click the toggle right to left option.
This feature is enabled by default starting with v2 but can be disabled by updating the rmd-utils-enable-rtl variable:
$rmd-utils-enable-rtl: false;
@import "react-md/dist/react-md";
v2 of react-md heavily uses the Context API to implement different features and configuration for things such as:
react-md
theme
for different componentsCheck out the @react-md/layout package for more information since it provides a
Configuration
component that combines all of these context providers into a
single component.
In order to allow more customization and reconfigurability within react-md, more low level components are now exported as well as moving some functionality within hooks.
Since it can be difficult to remember all the icon names or even mistyping a
font icon name, react-md@v2
now provides every material icon as a FontIcon
and SVGIcon
implementation. At the time of writing these release notes, there
are 932 icons available which means 1864 icon components. Check out the
@react-md/material-icons package for more info and previewing every icon.
Since v2 of react-md
ended up being a complete re-write, I wanted to create a
way to be able to slowly update existing apps from v1 to v2 without forcing an
immediate re-write. Related components will now be grouped and published
together using the @react-md
scope as well as the "root" react-md
package
that exports everything like normal. If you are completely new to react-md
, I
recommend just installing react-md
while apps that are migrating should use
the scoped packages.
Please see the scoped packages documentation for a more in-depth write up.
The documentation site has been re-written to use NextJS instead of the extremely outdated custom implementation with different webpack configs. This should hopefully allow contributors to get started more quickly and apply changes as needed. Each page should now also provide a table of contents to be able to quickly navigate to a specific heading, demo, documentation, etc. There are also some other small other documentation improvements that will be outlined below.
Note: The search behavior needs to be fixed since it was hacked together in about 20 minutes. You should be able to find the majority of components other than the grid components. These can be found in the @react-md/utils package as
GridList
andGrid
.
After reviewing feedback about the v1 documentation site, the main problem areas were:
To solve the first two issues, a custom
sandbox generator script
was created that resolves every
dependency and file name
for each demo and generates a
sandbox json file.
This allows for the new and improved
DemoSandbox
to render all the files for a demo as well as dynamically creating an editable
code sandbox using the
codesandbox define API. Each
demo will now have a button to preview the code in the new DemoSandbox
, create
an editable sandbox with CodeSandbox, and a directly
link to the source code within GitHub to help show the full context of the
demos. In addition, each demo was updated to hopefully be a lot less complex
than some that appeared in v1.
The third issue was solved by re-writing the sassdoc generator script to hackily force compile the scss variable. Now if a variable references another SCSS variable, the default compiled value can be viewed by enabling the "Default Compiled Value" switch for that variable. Check out the $rmd-alert-theme-values variable for a quick example.
The forth issue has not been solved completely, but there is now a new solution in place by being able to render examples a bit easier within SassDoc and showing the compiled value. The rmd-utils-rtl mixin has a pretty good example to reference for this functionality.
The last issue about missing information for the example has hopefully been solved by the new writing patterns throughout the documentation site. Each example should now have a bit more information about the components being used along with some background information about what the demo is trying to accomplish. Documentation is difficult so please provide feedback for what has been helpful and what has not.
The v2 release has decreased the UMD bundle size by 12.35%
while the CSS
bundles have increased by 18.56% - 18.75%
:
v1 size
The gzipped UMD bundle size is:
- dist/v1/umd/react-md.min.js 98.68 KB
The min and max gzipped CSS bundle sizes are:
- dist/v1/css/react-md.yellow-red.min.css 13.2 KB
- dist/v1/css/react-md.blue_grey-deep_purple.min.css 13.23 KB
v2 size
The gzipped UMD bundle size is:
- dist/umd/react-md.production.min.js 86.49 KB
- dist/umd/react-md-with-font-icons.production.min.js 196.05 KB
- dist/umd/react-md-with-svg-icons.production.min.js 196.03 KB
The min and max gzipped CSS bundle sizes are:
- dist/css/react-md.grey-deep_orange-200-light.min.css 15.65 KB
- dist/css/react-md.indigo-blue-400-dark.min.css 15.71 KB
In addition, v2 should have finally solved the code splitting issue that
existing in v1 and produce an even smaller bundle if every feature within
react-md
is not used.
This should be the main highlights for the v2 release. If you are interested in an in-depth package-by-package update and changelog, you can view one of the following changelogs: