Skip to content

Theming Images

Jonathan Eiten edited this page Nov 17, 2018 · 5 revisions

As of v3.2.0, Hypergrid supports SVG images.

Contents

Abstract

  • Hypergrid can use SVG images as icons to be painted into the grid.
  • Hypergrid themes SVG image data along with the grid so a single set of icons can serve all themes.
  • Hypergrid optionally creates and maintains (i.e., themes) CSS rules using the same image data for use in DOM elements, such as in dashboards and grid cell editors.

Background

  • Hypergrid maintains a registry of images available for use as icons in grid cells. How the icons are referenced and used is entirely up to the cell renderer; the core Hypergrid engine doesn't reference these images.
  • The image registry is accessed require('fin-hypergrid/images') and has an add method for adding custom images and associating them with an image name. Up till now only PNG and JPEG images worked.
  • The image registry comes with a few images preinstalled. These are named for their intended usage. These images are subject to change. Some of them are crude and could benefit from an upgrade. The core engine only uses two of these, the checked and unchecked checkbox images.
  • The SimpleCell cell renderer (distributed as part of Hypergrid core) paints "registered" images into the canvas, referencing three properties for the registered image name. These properties are leftIcon, centerIcon, and rightIcon.
  • Hypergrid previously only applied themes to the grid itself. To use icons compatible with the new theme, it was necessary for the application layer to assign an alternate set of icons to images for each theme.

Adding and theming SVGs

The new approach is to create one set of icons with SVG and theme them by setting stroke and fill CSS style properties to colors from the theme object. The properties are typically set on the image's root <svg> element; however custom "prop setters" can set perform more complex operations on the image, including setting style.stroke and style.fill on any descendant node within the SVG node tree, or any node property, etc.

TL;DR You can now safely add SVG images for drawing icons in grid cells. Those images will now be automatically themed along with the grid (Hypergrid.applyTheme(theme)). A new option flags the added image to be maintained in parallel in a CSS class for use in DOM decoration around the grid or in grid cell editors (which are implemented in DOM, not canvas as with the grid); and that class will be themed along with the image when the grid is themed. See examples.

To use this new feature, read all of the following carefully:

  • Adding SVG images now paints correctly even when the image has no implicit size. Previously such images painted at their natural size (almost always much larger than intended) even when explictly sized. The work-around for this apparent browser bug is shown in the SimpleCell.js changes, in particular the explanatory note, important to know for custom cell renderer development.
  • SVG images found in the image registry are now themed along with the grid on calls to Hypergrid.applyTheme(theme) (or Hypergrid.theme = theme setter) which now call the new images.setTheme(theme) method. [Note that this methods sets the global theme used by all grid instances on the page. The instance version gridInstance.applyTheme(theme) (or gridInstance.theme = theme) does not call images.setTheme(theme) because we currently only have a single (global) image registry for all instances.]
  • SVG images added to the registry with the add(name, image) method are flagged as themeable (img.themeable = true) which makes them subject to theming by the new setTheme(theme) method which uses svg-themer to extract the original SVG markup, theme it, and re-inject it.
  • Note that your SVG should be appropriately sized before passing to images.add. Most SVGs are designed with a large viewport and that's how they'll display if they are not implicitly sized. You can also set the width and height props explicitly. (Remember that that you can only depend on cascading CSS rules to size it if it's actually in the DOM.)
  • Using an actual file URL as your image source is supported — although we recommend using data:image/svg+xml;base64,... source string so your app will have no external file dependencies.
  • The add method now accepts two additional parameters for a total of four parameters: function add(name, image, setSvgProps, styles) { ... } The last two parameters are new and are both optional.
    • setSvgProps — New optional 3rd parameter. Function to custom theme the SVG, if for example, you needed to set stroke and fill on descendant nodes, or needed to theme with more colors, etc. Click the link for more info. The default implementation for setSvgProps is is very simple. You can however override it with a custom implementation before calling add.
    • styles — New optional 4th parameter (or 3rd if setSvgProps parameter omitted). It creates CSS rule(s) which it places into a custom stylesheet. If given as true (or an empty array), it will create a single rule with a background-image property containing the image data in a CSS url(data:image/svg+xml) construct. The rule is named .hypergrid-background-image-name (where name is the name passed to add). If not empty, the array is a list of property names for which to create similar rules. The rules also contain width and height properties so you can create multiple "normalized" <div class="hypergrid-background-image-name"></div> elements for use in DOM (that all reference the same data), such as in cell editors. The conceit here is that this rule will get themed along with the SVG members of images.

Examples

Please see svg-themer for general information about theming SVG images and the optional setSvgProps prop setter functions.

[Need some examples of images.add and images.setTheme.]