JET Core Pack
Oracle® JavaScript Extension Toolkit (JET)
18.0.0
G12199-01
Overview
JET Core Pack is a new distribution of the JET User Interface(UI) components, written entirely using the VComponent API and the JET Virtual DOM architecture.
These components will have a DOM element prefix of oj-c-* instead of the existing oj-* prefix used in Legacy JET.
By providing a completely new set of components, we can maintain backward compatibility with existing applications where developers can use both Core Pack and Legacy components side by side. All components continue to be written to meet the Redwood Design System specifications, so they will look and interact in the same manor. These new componens are written using the VComponent API, and Preact as the underlying implementation. This will provide a large performance benefit over the existing Legcy components and should improve overall application performance as more of the components become available and are used.
Installation
The JET Core Pack is included in all JET distributions starting with JET v13.0.0. Starting with JET v14.0.0 it will also be available as it's own NPM module. If you are migrating an existing project to JET v14.0.0 or higher, you can add the JET Core Pack component package to your application by following the commands (run these from the root of your project).
- npm install @oracle/oraclejet-core-pack --save
- As part of the JET v14 Migration, you should have already updated your path-mapping.json file, which will include entries for the new oj-c prefix.
- You will also find as part of your JET v14 migration, that a new CSS file is being linked to in the head of the index.html file of your application.
<link rel="stylesheet" href="css/theme-redwood/14.0.0/web/theme.css" id="themestyle" />
"paths": {
"ojs/*": [
"./node_modules/@oracle/oraclejet/dist/types/*"
],
"@oracle/oraclejet-preact/*": [
"./node_modules/@oracle/oraclejet-preact/*"
],
"oj-c/*": [
"./node_modules/@oracle/oraclejet-core-pack/oj-c/types/*"
],
"preact": [
"./node_modules/@oracle/oraclejet/dist/js/libs/preact"
]
}
Differences from Legacy Components
These components will have a DOM element prefix of oj-c-* instead of the existing oj-* prefix used in Legacy JET.
By providing a completely new set of components, we can maintain backward compatibility with existing applications where developers can use by Core Pack and Legacy components side by side. All components continue to be written to meet the Redwood Design System specifications, so they will look and interact in the same manor. These new componens are written using the VComponent API, and Preact as the underlying implementation. This will provide a large performance benefit over the existing Legcy components and should improve overall application performance as more of the components become available and are used.
Benefits of Core Pack Components
Performance is the main reason to migrate to the new component set. The use of Preact and Virtual DOM as the implementation for these components, provides improvements in component rendering times, and in some cases, significant improvements.
Note: The use of the Core Pack components by themselves will improve the rendering times of the application, but it will not fix or change any performance issues that may be caused by backend or architectural issues of the application.
Limitations of Core Pack Components
Core Pack only supports the Redwood theme at this time. Stable and custom themes will be supported in the future. The Alta theme is deprecated, and will not be supported in core pack.
Migration to Core Pack Components
Migration Basics
Before migrating run the JET Audits and fix any issues before proceeding. Running audits will catch many issues including deprecated APIs, and deprecated APIs will not be available in Core Pack components.
Visual Builder does not yet support Core Pack, it will begin providing the new Core Pack component set in a future release. Migration tools will eventually be provided in visual builder
If you are using the CLI migration tools will eventually be provided, but for now you must migrate by hand. The legacy component API doc will have a migration section, for example here's the oj-button migration section.
CSS
In some components CSS will no longer work as expected. Let’s take oj-action-card and oj-c-action-card as an example, if I set the following CSS on the two elements I get different behavior
- style="border-radius: 30px" changes the visible border on oj-action-card, but not on oj-c-action-card
- style="padding: 30px" puts the padding inside the border on oj-action-card, but outside the border on oj-c-action-card
No Refresh Method
Certain legacy JET components supported the .refresh() method as a way to notify the component that its children or slots have changed. Because in Core Pack we have largely moved away from defining component behavior via DOM children, .refresh() will not be implemented by Core Pack components. For cases where you need to change a component’s slots after the component has been created, use oj-bind-if as shown in the example below:
<oj-bind-if test="[[ showIcon ]]">
<oj-c-button label="Text">
<span slot="startIcon" class="oj-ux-ico-delete-circle"></span>
</oj-c-button>
</oj-bind-if>
<oj-bind-if test="[[ !showIcon ]]">
<oj-c-button label="Text"></oj-c-button>
</oj-bind-if>
Translations
In legacy JET we expose many/all translations per instance, but the majority of translations should be changed only at the app level, not the instance level. Many translation props have therefore been deprecated in legacy JET. The per instance translations that do remain are top level props in Core Pack components, for example translations.required.message-detail
on <oj-input-number>
has changed to required-message-detail
on <oj-c-input-number>
.
Zero Margins
Whitespace should be owned by the parent container. For example in <oj-c-button>
the button code is responsible for controlling the whitespace between the icon and the text, the icon passed in should not have a margin. In order to enforce this whitespace contract the Core Pack components use CSS to remove margins from direct children.
Internationalization
Make sure you are correctly internationalizing and Localizing your application or you may see issues after migrating to core pack.
Data Driven Components
Some components that used to take children in legacy are data-driven in the core pack. These include
- Components that took oj-option children in legacy (like oj-menu, oj-buttonset-one, oj-buttonset-many, oj-radioset, oj-checkboxset)
- Tab bar and navigation list
For example, in oj-checkboxset you add oj-option children, but in oj-c-checkboxset, you use the options prop.
For background, some legacy components use DOM elements for configuration purposes. For example, the set of items in an oj-checkboxset can be configured by specifying an oj-option child for each item:
<oj-checkboxset>
<oj-option value="first">Item One</oj-option>
<oj-option value="second">Item Two</oj-option>
</oj-checkboxset>
While this is a convenient way to specify items in cases where the data is static, this API design can can be seriously problematic for dynamic cases. The crux of the problem is that we have multiple parties contending for control of the child DOM. For example, while from the application’s (or Knockout/Preact’s) view, the expectation is that the oj-option elements are children of the oj-checkboxset, the component has other ideas. After rendering, we end up with a more complicated DOM structure, eg:
<oj-checkboxset>
<span>
<span>
<input type="checkbox" value="first">
</span>
<label>
<span>
<oj-option value="first">Item One</oj-option>
</span>
</label>
</span>
<span>
<span>
<input type="checkbox" value="second">
</span>
<label>
<span>
<oj-option value="first">Item Two</oj-option>
</span>
</label>
</span>
</oj-checkboxset>
Note that the <oj-option> elements have been relocated such that they are no longer direct children of the <oj-checkboxset>. This can confuse the binding provider (Knockout/Preact) and complicates life for the application developer that wants to later mutate the set of available items.
For Core Pack components, we have decided to avoid this dilemma by switching to a new approach: rather than configuring components via child elements, we are adopting a property-centric solution. For example, the options in oj-c-checkboxset are specified via the "options" property:
<oj-c-checkboxset options="[[options]]">
Where the available options are specified via an array, eg:
this.options = [
{ value: "first", label: "Item One" },
{ value: "second", label: "Item Two" },
]
In cases where the set of available items needs to be modified, this can be done by updating the options property with a new array.
With this new array/property-centric approach there is no confusion/contention over DOM ownership.
One other small benefit is that we expect that this approach will be slightly more efficient.