A Practical Look into Guidewire’s Jutro Design System
What is Jutro by Guidewire?
Jutro is a design system and UI framework that empowers designers and developers in P&C insurance to build reusable, engaging, and configurable insurance applications. It is based on React, a JavaScript library for building user interfaces, created by Facebook. Jutro was announced in October 2020 at the Connections Reimagined event.
Component Based
Within Jutro, several pre-built components can be viewed via Storybook. This is handy for getting started, and customizations are easily handled with each component’s OOTB knobs (properties).
What isn’t immediately apparent is that in certain cases, the Jutro component doesn’t handle scenarios you may need and can be very difficult to override due to the component being locked down. In one case, we were trying to enable a seemingly simple feature for a dropdown where a letter could be typed, and the dropdown would navigate to that letter. Subsequent letters would further navigate the dropdown to the value closer to what was typed.
Example: Take a state dropdown. If I Type N, it should navigate to Nebraska, then e would stay on Nebraska, but v would navigate to Nevada. Once on that value, pressing Enter or tabbing out would set that value into the field.
This became impossible to override due to the nested layers within the Jutro component, so the feature was abandoned. A feature ticket was submitted to Guidewire, but I am not sure of the status of this feature.
Styling
You can often override the styling for a given component with the OOTB class overrides. But, depending on the component and the nesting levels, this can become somewhat cumbersome and difficult to override without an !important. You can often get what you want with the right specificity and component-level scss overrides. Still, we sometimes had to target .jut__ type classes and use !important, which is not recommended.
// Not Recommended
.jut__Button__outlined {
transition: all 0.3s ease 0s;
opacity: 1;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
padding: $btn-with-border-vert-padding $btn-hor-padding;
}
You should consider specifiers as your first option for drilling down, scoping the selector, and staying with more generic terms.
// Recommended using specificity
h2[class='policyChangeSubHeader'] {
margin-bottom: var(--GW-SPACING-4);
border-bottom: var(--GW-BORDER-WIDTH) solid var(--GW-BORDER-COLOR);
@include gw-breakpoint-down(phonewide) {
font-size: var(--GW-FONT-SIZE-H3);
}
}
The other thing to consider when overriding styles is using the OOTB –GW-XX variables if possible. This ensures standards are kept throughout the application and allows for easier global changes.
Composite components (aka layout components)
To maintain upgradeability when a customization exists outside of Jutro, it is best to create a composite component vs. a totally custom component. This ensures that as Jutro evolves, your component will get the benefits of the upgrade, in many cases, for free.
A composite component is a collection of OOTB Jutro components wrapped or grouped into a single reusable structure. It can be as few or as many Jutro components as needed, which, when used over separate pages, provides consistency in functionality and styling while maintaining upgradeability. Since Jutro also strictly adheres to WCAG accessibility standards, as long as you consider these requirements in your composite, your new component will leverage those standards.
A good example of this might be a Phone component, which shows three types of phone numbers based on what the user has supplied. Your component would be a makeup of 3 Jutro Input controls with some JSX to control visibility and read-only logic for home, work, and mobile.
Language & Translations
If you are fortunate enough to work on a multi-language project, there are some things to help identify items that are not translated properly.
The standard for translation keys is to use messages.js files, which are plain JavaScript. Within those files, they return JavaScript objects using defineMessages from the react-intl library.
Each item in the file has the format
mobilePhone: {
id: 'gw-pe-components-platform-react.PhoneDetails.Mobile Phone',
defaultMessage: 'Mobile Phone',
},
This is pretty standard… but these files don’t end up in the compiled language json file unless referenced within their corresponding JSX. You must import the file, otherwise, the webpack compiler doesn’t know about them. IMHO, this is a framework bug, but luckily there is a simple workaround.
import messages from './PhoneDetails.messages.js'
// IFF you do not need to refer to the file within your JSX,
// you can simply use this form
import './PhoneDetails.messages.js'
This takes care of the actual resource file, but what about the metadata file also pointing to this resource?
{
"id": "mobilePhone",
"type": "field",
"component": "Input",
"componentProps": {
"path": "cellNumber",
"readOnly": "true",
"label": {
"id": "gw-pe-components-platform-react.PhoneDetails.Mobile Phone",
"defaultMessage": "meta.Mobile Phone"
},
"contentContainerClassName": "mobilePhoneInputContainer"
}
},
If you put a defaultMessage into the metadata.json file, when the final screen is rendered, there is no way to tell if it is truly being translated because it will use the value from the metadata if it is not found in the actual translation file.
Instead, I prefer to use the input id (e.g. mobilePhone) as the defaultMessage prop. However, other developers prefer to find a specific resource by using the display text as the real string. In this case, we can simply add a prefix such as meta. in front of the text. By either using the id of the component, or prefixing with meta., you now have an obvious way of knowing whether something was properly translated.
Translations
This leads to the final item, which is the actual translation files themselves. When you build the portal, language files are created for you in the generated folder. In a perfect world, we would never need to check in the generated files but due to some issues with with how TeamCity works, we are not guaranteed to have these files built properly. So when checking in anything involving new translation keys, you must check in any and all language files, with their proper translations.
Example: en_CA.json and fr_CA.json
Summary
Using Jutro is a very beneficial way to quickly build UIs that will support upgrades and accessibility, but there are some gotchas to be aware of while on your journey.
Troy Stauffer
Senior Software Architect
Watch or read our other posts at Kimputing Blogs. You’ll find everything from Automated testing to CenterTest, Guidewire knowledge to general interest. We’re trying to help share our knowledge from decades of experience.