8 Work with Oracle JET Web Components
Oracle JET Web Components are reusable pieces of user interface code that you can embed as custom HTML elements. Web Components can contain Oracle JET components, other Web Components, HTML, JavaScript, and CSS. You can create your own Web Component or add one to your page.
Design Custom Web Components
Oracle JET Web Components are custom components that include multiple component types. Web components that you create can be used in your app or they can be uploaded to Oracle Component Exchange to share with other developers.
The variety of component types supported by Oracle JET and Oracle Component Exchange are:
- Standalone Web Components are classic UI components with some kind of UI along with a defined set of properties, methods, events and slots. They can represent everything from a simple better-button type of widget all the way to a super complex whole page component such as a calendar.
- Pack components, also called a JET Pack, represents a versioned stripe of related components designed to be used together. When consumers pick up a component that is a member of a JET Pack they associate their app with the version of the pack as a whole, not the individual components within it. The JET Pack simplifies the setup of such projects and the dependency management as a whole.
- Resource components are re-usable libraries of assets used by Web Components contained in JET Packs. Resource components typically contain things like shared images, resource bundles, utility classes and so forth. A resource component has no hard and fast predefined structure so can contain anything that you want. However, it does not itself provide any UI components. Instead conventional standalone components would depend on one of these for shared resources. We only expect resource components to be used in concert with JET Packs.
- Reference components define a look-up reference to third party code. As such, reference components are a pointer to that code either as a NPM module and/or as a CDN location. Reference components don't actually include the third party libraries, they just point to it.
You can create standalone Web Components to support your specific app needs. You can also create sets of Web Components that you intend to be used together and assemble those in a JET Pack, or pack component type. The pack component contains the Web Components and configuration files that define the version stripe of each component in the pack. When Web Components are part of a pack, changes to their definition file are required to differentiate them from the same component used as a standalone component.
Tip:
When you assemble components into a small number of packs, from the consumer's point of view, it makes path setup and dependency management much simpler.
You can enhance JET Pack components by using resource components when you have re-usable libraries of assets that are themselves not specifically UI components. The resource component structure is flexible so you add anything that you want, such as shared images, resource bundles, utility classes and so forth.
If you need to reference third-party code in a Web Component, you can create a reference component. The reference component doesn't include any third-party libraries, but it can define a pointer to that code either as a NPM module and/or as a CDN location. Although it is possible to embed third party library code into the packaged distribution of a given component, by separating it out you get two particular benefits:
-
The dependency is clear and declared up front. This is an important consideration for organizations that care about third party liability and license usage. It also makes reacting to security vulnerabilities in third party code much easier.
-
You can maximize re-use of these libraries - particularly with common libraries, such as moment.js.
The only component type that is not allowed in packs are reference components.
When creating JET Packs it is important to think about how their components can evolve over time in relation to the consuming apps. A common mistake is to start out syncing the component version numbers to the version number of the primary consuming app. This relationship can break down, however, for example when a breaking API change in one of your components forces a major version change which now takes you out of sync. The best practice is to adopt Semantic Versioning (SemVer) of components from the start and not to sync versions with the consuming app. Take the time to understand how SemVer works, particularly in relation to re-release versions. For more information, see Version Numbering Standards.
You should maintain the source code for your component sets separately from the apps that will consume them. Remember that components will evolve over time at a separate rate from the consuming app so having the source code decoupled into a separate source code project and repository makes a huge amount of sense.
The recommended project layout for your component source project is based on the default project layout created by Oracle JET CLI tooling. The JET CLI supports the creation of TypeScript components as well as standard ES6 based components. If you follow adhere to the project layout generated by JET tooling, then you derive the following tooling benefits:
-
Automatic creation of the correct requireJS path mappings for your components and their upstream dependencies when testing within the context of this component source project
-
Support for live editing when using the
ojet serve
command (both JS and TS components) -
Auto transpilation of Typescript based components to ES6
-
Automatic creation of both debug and minified components by the
ojet build
command -
Automatic creation of component bundles for JET Packs where bundling is specified
-
Ability to directly publish to the Component Exchange using the
ojet publish
component command -
Ability to directly package your components into distributable zip files using the
ojet package
component command
About Web Components
Oracle JET Web Components are packaged as standalone modules that your app can load using RequireJS. The framework supplies APIs that you can use to register Web Components. Knockout currently provides one and two way data binding, template markup, and Web Component activation.
If you are new to Web Components and would like to learn more, visit this Oracle Blogs page for a series of articles that will introduce you to important concepts: https://blogs.oracle.com/groundside/cca.
Web Component Architecture
The following image shows a high-level view of the JET Web Component architecture. In this example, an Oracle JET app is consuming the Web Component, but you can add Web Components to other JavaScript or Oracle apps where supported.
Web Components contain:
-
A custom DOM element: Named element that functions as a HTML element.
<my-web-component attribute1="value1" attribute2="value2" ...> </my-web-component>
-
Web Component binding definition: Knockout expression for setting Web Component attributes.
<my-web-component attribute1="value1" attribute2="[[value2]]" attribute3="{{value3}}"> </my-web-component>
attribute1
’s value can be a primitive JavaScript type (boolean, number, string) or a JSON object,attribute2
’s value uses one way data binding, andattribute3
‘s value uses a two way binding. One way bindings on Web Components specify that the expression will not update the app’s ViewModel if the value changes. In two way bindings, the expression will update and the value written back to the app’s ViewModel.In the following code sample, the Web Component is declared with three attributes:
type
,data
, andaxis-labels
.<my-chart type=bubble data="[[salesData]]" axis-labels={{showAxisLabels}} ... </my-chart>
Because the
salesData
expression is declared using one way binding ([[salesData]]
), it will not be written back to if thedata
property is updated by the Web Component's ViewModel. Thedata
property will contain the current value, but thesalesData
expression will not be updated. Alternatively, if theaxisLabels
property is updated by the ViewModel, both theaxisLabel
property and the{{showAxisLabels}}
expression will contain the updated value. -
Metadata: Data provided in JSON format which defines the Web Component’s required properties:
name
,version
, andjetVersion
. Metadata may also define optional properties, includingdescription
,displayName
,dependencies
,icon
,methods
,events
, andslots
.Web Components support both runtime and design time metadata. Design time metadata isn’t required at runtime and is useful for design time tools and property editors. Design time tools can define tools-specific metadata extensions to the Web Component’s metadata. For any tool-specific metadata extensions, refer to the documentation for that specific tool. For additional information about metadata properties, see Composite in the API documentation.
The following sample shows some of the available metadata fields with descriptions of their content and whether they are not used at run time. Required metadata are highlighted in bold.
{ "name": "The component tag name", "version": "The component version. Note that changes to the metadata even for minor updates like updating the jetVersion should result in at least a minor Web Component version change, e.g. 1.0.0 -> 1.0.1.", "jetVersion": "The semantic version of the supported JET version(s). Web Component authors should not specify a semantic version range that includes unreleased JET major versions as major releases may contain non backwards compatible changes. Authors should instead recertify Web Components with each major release and update the component metadata or release a new version that is compatible with the new release changes.", "description": "A high-level description for the component. Not used at run time.", "displayName": "A user friendly, translatable name of the component. Not used at run time.", "properties": { "property1": { "description": "A description for the property. Not used at run time.", "displayName": "A user friendly, translatable name of the property. Not used at run time.", "readOnly": "Boolean that determines whether a property can be updated outside of the ViewModel. False by default.", "type": "The type of the property, following Google's Closure Compiler syntax.", "value": "Object containing an optional default value for a property.", "writeback": "Boolean that determines whether an expression bound to this property should be written back to. False by default.", "enumValues": "An optional array of valid enum values for a string property. An error is thrown if a property value does not match one of the provided enumValues.", "properties": "A nested properties object for complex properties. Subproperties exposed using nested properties objects in the metadata can be set using dot notation in the attribute. See the Subproperties section for more details on working with subproperties." }, "property2": { ... contents omitted } }, "methods": { "method1": { "description": "A description for the method. Not used at run time.", "displayName": "A user friendly, translatable name of the method. Not used at run time.", "internalName": "An optional ViewModel method name that is different from, but maps to this method.", "params": "An array of objects describing the method parameter . Not used at run time.", "return": "The return type of the method, following Closure Compiler syntax. Not used at run time." }, "method2": { ... contents omitted } }, "events": { "event1": { "bubbles": "Boolean that indicates whether the event bubbles up through the DOM or not. Defaults to false. Not used at run time.", "cancelable": "Boolean that Indicates whether the event is cancelable or not. Defaults to false. Not used at run time.", "description": "A description for the event. Not used at run time.", "displayName": "A user friendly, translatable name of the method. Not used at run time.", "detail": { "field name": "Describes the properties available on the event's detail property which contains data passed when initializing the event. Not used at run time." } }, "event2": { ... contents omitted } }, "slots": { "slot1": { "description": "A description for the slot. Not used at run time.", "displayName": "A user friendly, translatable name of the method. Not used at run time." } } }
-
HTML markup: (Required) Contains the View definition which describes how to render the Web Component. The Web Component's View has access to several
$
variables along with any public variables defined in the Web Component's ViewModel. Some of the variables that can be used in the Web Component's View are:Variables Description $properties
A map of the Web Component's current property values $slotCounts
A map of slot names containing a number of associated child nodes assigned to that slot $unique
A unique string value provided for every component instance that can be used for unique ID generation $uniqueId
The ID of the Web Component, if specified. Otherwise, it is the same as unique $props
Deprecated since 5.0.0, use $properties
instead$slotNodeCounts
Deprecated since 5.0.0, use $slotCounts
instead -
JavaScript: Optional script for defining the ViewModel and custom events.
The ViewModel is also where you define callbacks for various stages of the Web Component’s lifecycle. Web Components support the following optional lifecycle methods:
activated (context)
,connected (context)
,bindingsApplied (context)
,propertyChanged (context)
, anddisconnected (element)
. For more information on lifecycle methods, see Composite - Lifecycle. -
CSS: Optional styling for the Web Component.
CSS is not scoped to Web Components, and you must define styles appropriately.
-
SCSS: Optional files containing Sass variables to generate the Web Component’s CSS.
If you’re defining only a few styles for your component, then adding the CSS manually may be sufficient. However, there may be use cases where you want to use Sass variables to generate the CSS. In those cases, create and place the SCSS files in the Web Component’s folder and use the tooling to add node-sass to your app. See Step 8 - Creating Web Components.
Important:
You must add the Sass files manually to the Web Component’s folder. The tooling will compile any Sass files if they exist, but it will not create them for you.
Web Component Files
Web Components can contain CSS, HTML, JavaScript, and metadata files that you can modify according to your app requirements.
You can create a Web Component manually by creating a folder and adding
the required files within the folder. You can also create a Web Component by using
the Oracle JET CLI command ojet create component
<component-name>
that automatically generates the Web
Component folder with the required files for your app.
When you create a Web Component manually, place the Web Component files
in a folder with the same name as the Web Component tag. Typically, you place the
folder within your app in a jet-composites
folder:
app-path/jet-composites/my-web-component/
.
You can also place your Web Component in a different file location or reference a Web Component on a different server using RequireJS path mapping. For examples, see Composite - Packaging and Registration.
-
my-web-component—view.html
: view template -
my-web-component—viewModel.js
: ViewModel -
component.json
: metadata -
my-web-component-styles.css
: CSS styling -
my-web-component-styles.scss
: Sass variables to generate CSS for Web Components -
loader.js
: RequireJS module defining the dependencies for its metadata, View, ViewModel, and CSS This file should also include the Web Component registration.
Web Component Slotting
Slots are used as placeholders in a Web Component that users can fill in with their markup. Slot is defined in the component JSON file of your Web Component.
Use slotting to add child components (which can also be Web Components) that get slotted into specified locations within the Web Component's View markup. The following example contains a portion of the View markup for a Web Component named demo-columns.
<div class="oj-flex oj-flex-item-pad">
<div role="group" :aria-label="[[$properties.headers[0]]]"
class="oj-flex-item demo-columns-col-a oj-flex oj-sm-flex-direction-column oj-sm-align-items-center">
<h3>
<oj-bind-text value="[[$properties.headers[0]]]"></oj-bind-text>
</h3>
<oj-bind-slot name="columnA">
</oj-bind-slot>
</div>
... content omitted
</div>
In this example, the demo-columns Web Component defines an
oj-bind-slot
named columnA
. As shown below, a
developer can specify a child component with a slot named columnA
when adding the demo-columns Web Component to the page.
<demo-columns id="composite-container" headers='["Sales", "Human Resources", "Support"]'>
<!-- ko foreach: sales -->
<demo-card slot="columnA" name="[[name]]" work-title="[[title]]"></demo-card>
<!-- /ko -->
... contents omitted
</demo-columns>
Web Component Template Slots
You can define placeholders in your template using template slots that can be filled with any markup fragment you want when the template element is used within a markup of your component.
When you need to reuse a stamped template with varying data, you can use a template slot to expose the additional data from the component's binding context.
You can define placeholders in your template using template slots that can be filled with any markup fragment you want when the template element is used within a markup of your component. When you need to reuse a stamped template with varying data, you can use a template slot to expose the additional data from the component's binding context.
Template slots for Web Components are used to define additional binding
contexts for a slotted content within an app. To declaratively define a template slot, use
the oj-bind-template-slot
element in the Web Component's View markup for
the slot that contains a stamped template DOM. The oj-bind-template-slot
element is similar to the oj-bind-slot
element, but its slotted content
should be wrapped inside a template
element within the app DOM.
In the below example, the demo-list Web Component defines an oj-bind-template-slot
named item
. This template slot provides the data
attribute that exposes additional properties to the template DOM and an data-oj-as
attribute that is used as an alias for the $current
variable. Note that the data-oj-as
attribute for template
element can be referenced only inside a default template.
<table>
<thead>
<tr>
<th>
<oj-bind-text value="[[$properties.header]]"></oj-bind-text>
</th>
</tr>
</thead>
<tbody>
<oj-bind-for-each data="{{$properties.data}}">
<template>
<tr>
<td>
<!-- Template slot for list items with default template and an optional alias -->
<oj-bind-template-slot name="item" data="{{'value': $current.data}}">
<!-- Default template -->
<template data-oj-as="listItem">
<span>
<oj-bind-text value='[[listItem.value]]'</oj-bind-text>
</span>
</template>
</oj-bind-template-slot>
</td>
</tr>
</template>
</oj-bind-for-each>
</tbody>
... contents omitted
</table>
The oj-bind-template-slot
children are resolved when the
Web Component View bindings are applied and are then resolved in the app's binding context
extended with additional properties provided by the Web Component. These additional
properties are available on the $current
variable in the app provided
template slot. The app can use an optional data-oj-as
attribute as an alias
in the template instead of the $current
variable. The following example
contains a portion of the app’s markup named demo-list.
<demo-list data="{{groceryList}}" header="Groceries">
<template slot="item" data-oj-as="groceryItem">
<oj-checkboxset>
<oj-option value="bought"><oj-bind-text value='[[groceryItem.value]]'></oj-bind-text></oj-option>
</oj-checkboxset>
</template>
... contents omitted
</demo-list>
The Oracle JET Cookbook at Web Component - Template Slots includes complete examples for using template slots. oj-bind-template-slot API documentation describes the attributes and other template slot properties.
Web Component Events
Oracle JET Web Components can fire automatic property changed events that are mapped to the properties defined in the component metadata. These components will also fire custom events for the events delared in the component metadata.
Web Components can internally listen to the automatically generated
propertyChanged
events that are mapped to the properties in the
component metadata using the propertyChanged
lifecycle method. For
example, a propertyChanged
event is fired when a property is
updated. This propertyChanged
event contains the following
properties:
-
property
: Name of the property that changed. -
value
: Current value of the property. -
previousValue
: Previous value of the property that changed. -
updatedFrom
: The location from where the property was updated. -
Subproperty
: An object holding information about the subproperty that changed.
When there is a need to declaratively define a custom event for a Web
Component, you must declare the event in the component's metadata file. These events
will only be fired if the code of the Web Component calls the
dispatchEvent()
method. The app can listen to these events by
declaring the event listener attributes and property setters. These event listeners
can be added declaratively or programmatically.
For the declarative specification of event listeners, use the
on-[event-name]
syntax for the attributes. For example,
on-click
, on-value-changed
, and so on.
<oj-element-name value="{{currentValue}}" on-value-changed="{{valueChangedListener}}"></oj-element-name>
The programmatic specification of event listeners may use the DOM
addEventListener
mechanism or by using the custom element
property.
The DOM addEventListener
mechanism uses the
elementName.addEventListener
method. For example:
elementName.addEventListener("valueChanged", function(event) {...});
The custom element property uses the
elementName.onEventName
syntax for the property setter. For
example:
elementName.onValueChanged = function(event) {...};
For more information, see the Web Components - Events and Listeners API documentation.
Web Component Examples
Web Components can contain slots, data binding, template slots, nested Web Components, and events. You can use the examples provided in the Oracle JET Cookbook for these Web Component features.
The Oracle JET Cookbook contains complete examples for creating basic and advanced Web Components. You can also find examples that use slotting and data binding. For details, see Web Component - Basic.
For additional information about Web Component fields and methods, see Composite in the API documentation.
Best Practices for Web Component Creation
Best practices for creating Oracle JET Web Components include required and recommended patterns, configuration, coding practices, version numbering, and styling standards. Follow best practices to ensure interoperability with other Web Components and consuming frameworks.
Recommended Standard Patterns and Coding Practices
Recommended patterns and coding practices for Oracle JET Web Components include standards for configuration, versioning, coding, and archival.
Component Versioning
Your Web Component must be assigned a version number in semantic version format.
When assigning and incrementing the version number associated with your components, be sure to follow semantic version rules and update Major, Minor and Patch version numbers appropriately. By doing so, component consumers will have a clear understanding about the compatibility and costs of migrating between different versions of your component.
To assign a version number to your Web Component, see About semantic versioning.
JET Version Compatibility
You must use the semantic version rules to specify thejetVersion
of the supported JET version(s). Web Component authors should
not specify a semantic version range that includes unreleased JET major versions as major
releases may contain non backwards compatible changes. Authors should instead recertify Web
Components with each major release and update the component metadata or release a new version
that is compatible with the new release changes.
Translatable Resources
Developers who want to localize Web Component translatable resources now get a
resource bundle (template) when they create their Web Component. These components should use
the standard Oracle JET mechanism using the ojL10n requireJS
plugin. You
must store the translation bundles in the
webcomponentname/resources/nls
subdirectory that is a peer to the
webcomponentname/resources/nls/root
subdirectory with the
resource strings for your Web Component’s folder. You can declare the languages and locales
that you support in the Web Component metadata.
Peer-to-Peer Communication
Components must prefer a shared observable provided by the consumer over any kind of secret signaling mechanism when you are dealing with a complex integration. For example, a filter component and a data display component. By using a shared observable you can pre-seed and programmatically interact with the components through the filter.
Alternatively, you can use events and public methods based on one of the following approaches being used:
-
A hierarchical relationship between the source and receiver of the event.
-
The identity of the source being passed to the receiver.
Note that in some runtime platforms, the developer doing the wiring may not have access to component IDs to pass the relevant identity.
-
Listeners attached by components at the document level.
In this case, you are responsible for the cleanup of those listeners, management of duplicates, and so on. Also, such listeners should preferably be based on Web Component events, not common events such as click, which might be overridden by intermediate nodes.
Note:
Under the web-component standards (shadow DOM), events will be re-targeted as they transition the boundary between the component and the consuming view. That is, the apparent identity of the raising element might be changed, particularly in the case of Nested Web Component architecture where the event would get tagged with the element representing the outer Web Component rather than the inner Web Component. Therefore, you should not rely on theevent.target
attribute to identify the Web Component source when
listening at the document level. Instead, the event.deepPath
attribute can
be used to understand the actual origin of the event.
Access to External Data
Web Components do not permit the usage of the knockout binding hierarchy to obtain data from outside the Web Component context, for example, $root
, $parent[1]
, and so on. All data transfer in and out of the component must be through the formal properties, methods, and events.
Object Scope
All properties and functions of Web Components should be confined to the scope of the view model. No window or global scope objects should be created. Similarly, the existence of window scope objects should not be assumed by the Web Component author. If a consumer Web Component defined externally at window or global level is required for read or write then that component must be passed in by the consuming view model through a formal property. Even if a well known global reference is needed from outside of the component, it should be formally injected using the require define()
function and declared as a dependency in the Web Component metadata.
External References
If a Web Component must reference an external component, it should be part of the formal API of the component. The formal API passes the component reference through a property. For example, to allow the registration of a listener, the Web Component code requires a component reference defined externally. You must not allow Web Components to obtain IDs from hard-coded values, global storage, or walking the DOM.
Subcomponent IDs
Within the framework if any component needs a specific ID, use context.unique
or context.uniqueId
value to generate the ID. This ID is unique within the context of the page.
ID Storage
Any generated IDs should not be stored across invocation, such as in local storage or in cookies. The context.unique
value for a particular Web Component may change each time a particular view is executed.
LocalStorage
It is difficult to consistently identify a unique instance of a Web Component within an app. So, it is advised not to allow a Web Component to utilize the local storage of a browser for persisting information that is specific to an instance of that Web Component. However, if the app provides a unique key through the public properties of the component you can then identify the unique instance of the component.
Additionally, do not use local storage as a secret signaling mechanism between composites. You cannot assure the availability of the capability and so it is recommended to exchange information through a shared JavaScript object or events as part of the public API for the component(s).
String Overrides
Web Components will often contain string resources internally to service their default needs for UI and messages. However, sometimes you may want to allow the consumer to override these strings. To do this, expose a property for this purpose on the component. By convention such a property would be called translations
, and within it you can have sub-properties for each translatable string that relates to a required property on the component, for example requiredHint
, requiredMessageSummary
, and so on. These properties can then be set on the component tag using sub-property references. For example:
"properties" : {
"translations": {
"description": "Property to allow override of default messages",
"writeback" : false,
"properties" : {
"requiredHint": {
"description": "Change the text of the required hint",
"type": "string"
},
"requiredMessageSummary": {
"description": "...",
"type": "string"
},
"requiredMessageDetail": {
"description": "...",
"type": "string"
}
}
}
}
}
Logging
Use Logger
to write log messages from your code in preference to
console.log()
. The Web Components should respect the logging level of the
consuming app and not change it. You should ideally prefix all log messages emitted from the
component with an identification of the source Web Component. As a preference, you can use
the Web Component name. The components should not override the writer defined by the
consuming app.
Expensive Initialization
Web Components should carry out minimum work inside the constructor function. Expensive initialization should be deferred to the activated
lifecycle method or later. The constructor of a Web Component is invoked even if the component is not actually added to the visible DOM. For example, if a constructor is invoked within a Knockout if
block. The further lifecycle phases will only occur when the component is actually needed.
Service Classes
The use of global service classes, that is functionality shared across multiple Web Components, can constitute an invisible contract that the consumer of your Web Component has to know about. To avoid this, we recommend:
-
Create the service as a module that every Web Component can explicitly set it as
require()
block, thus removing the need for the consumer to do this elsewhere. -
Consider the timing issues that might occur if your service class needs some time to initialize, for example fetching data from a remote service. In such cases, you should be returning promises to the service object so that the components can safely avoid trying to use the information before it is actually available.
Using ojModule
If you use ojModule
in a Web Component and plan to distribute the
Web Component outside of your app, you must take additional steps to ensure that the
contained ojModule
could be loaded from the location relative to the
location of the Web Component. Unless the View and ViewModel instances are being passed to
ojModule
directly, you will need to provide the require function instance
and the relative paths for views and view models. The require function instance should be
obtained by the component loader module by specifying require
as a
dependency.
<div data-bind="ojModule: {require: {instance: require_instance, viewPath: "path_to_Web_Component_Views", modelPath: "path_to_cWeb_Component_ViewModels"}}"></div>
require Option | Type | Description |
---|---|---|
|
Function |
Function defining the require instance |
|
String |
String containing the path to the Web Component’s Views |
|
String |
String containing the path to the Web Component’s ViewModels |
For additional information about working with ojModule
, see
ojModule.
Archiving Web Components for Distribution
If you want to create a zip file for packaging, create an archive with the same name as the component itself. You may add version-identifying suffixes to the zip file name for operational reasons. The Web Component artifacts must be placed in the root of the zip file, and there should be no intermediate directory structure before reaching the files.
Using Lifecycle Methods
If a ViewModel is provided for a Web Component, the following optional callback methods can be defined on its ViewModel that will be called at each stage of the Web Component's lifecycle. Some of the callback methods that can be used are listed below:
-
activated(context)
: Invoked after the ViewModel is initialized. -
connected(context)
: Invoked after the View is first inserted into the DOM and then each time the Web Component is reconnected to the DOM after being disconnected. -
bindingsApplied(context)
: Invoked after the bindings are applied on the View. -
propertyChanged(context)
: Invoked when properties are updated before the[property]Changed
event is fired. -
disconnected(element)
: Invoked when this Web Component is disconnected from the DOM.
For additional information on Web Component lifecycle methods, see Composite - Lifecycle.
Template Aliasing
JET components that support inline templates can now use an optional
data-oj-as
attribute to provide template specific aliases for
$current
variable at the app level. In the instances where the component
must support multiple template slots as in the case of chart and table components, a single
alias may not be sufficient. In such cases, you can use an
optional data-oj-as
attribute on the template element. For more
information on the usage of this optional attribute with template slots, see oj-bind-template-slot API documentation.
CSS and Theming Standards
Oracle JET Web Components should comply with all recommended styling standards to ensure interoperability with other Web Components and consuming apps.
For information on the generic best practices for using CSS and Themes, see Best Practices for Using CSS and Themes.
Standard | Details | Example |
---|---|---|
Prevent flash of unstyled content |
Oracle JET will add the Note that this is an element selector, and there should not be a dot (.) before |
|
Add scoping |
Use an element selector to minimize the chance that one of your classes is used by someone outside of your component and becomes dependent on your internal implementation. In the example to the right, if someone tries to apply the class |
IMPORTANT: If your component also includes a dialog, then when displayed, that dialog will be attached to the main document DOM tree and will not be a child of your component. Therefore, if you define a style to apply to a dialog defined by your component, you cannot scope it to the component name as that's not the actual container for the dialog when displayed. To resolve, use the component name as the prefix instead:
|
Avoid element styling |
The app will often style HTML tag elements like headers, links, and so on. In order to blend in with the app, avoid styling these elements in your Web Component. |
|
Version Numbering Standards
All types of Web Components, including standalone, JET Pack, and Resource components, require a version number and that number should adhere to a semantic versioning (SemVer) scheme that ensures a standard for development teams to follow similar to the approach adopted by Oracle JET release versioning.
Reference components are a slightly special case as the version of the reference component will always match the version of the NPM library that it references.
All other Web Component types, rely on semantic versioning to designate a version of the component. Semantic versioning defines a version number which has three primary segments and an optional fourth segment. The first three segments are defined as MAJOR.MINOR.PATCH with these meanings:
-
MAJOR version when you make incompatible API changes
-
MINOR version when you add functionality in a backward compatible manner
-
PATCH version when you make backward compatible bug fixes
Note:
For background on semantic versioning, visit https://semver.org.
When defining a version number for your Web Component, you must define all three of these core segments:
1.0.0
Additionally after the PATCH version, you can append an optional extension segment which can consist of two additional pieces of information:
-
A segment delimited by a leading hyphen which allows you to assign a pre-release version
-
A purely informational segment preceded by a plus sign (+) that you might use to hold a GIT commit hash or other control information. This segment plays no part in the comparison of component versions.
Here's an example of a fully-defined version number for a pre-release version of a component:
1.0.1-beta.1+332
In this case beta.1
is a pre-release indicator and 332
is a build number.
The change in version number for a Web Component should indicate to consumers the risk level of consuming that new version. Consumers should know that they can drop in a new MINOR or PATCH release of your components without needing to revise their code. If you make changes to the Web Component source code that forces the consuming app to do more than just refresh the Web Component's directory or change a CDN reference, then you should revise the MAJOR version to indicate this.
The Web Component metadata file component.json
lets you define the supported version of Oracle JET that the component can work with. This is the jetVersion
attribute which can be set to a specific version or version range, as defined by npm-semver. For example, the jetVersion
attribute will be set to one of the following:
-
Preferred: All MINOR and PATCH versions from the specified version forward until there is a change in MAJOR release number. For example:
"jetVersion:: "^9.1.0"
, , which indicates support for that release and all subsequent MINOR and PATCH versions, up to (but not including) the next MAJOR release and it is equivalent to">=9.1.0 <10.0.0"
. -
The exact semantic version of exact version of Oracle JET that the Web Component supports. For example:
"jetVersion" : "9.1.0"
, which implies that this Web Component supports only Oracle JET 9.1.0. -
All PATCH versions of Oracle JET within a specific MAJOR.MINOR release. For example:
"jetVersion" : "9.0.x"
, which implies that this Web Component supports every release of JET between JET 9.0.0 and JET 9.1.0 (but specifically not JET 9.1.0 itself). -
A specific range of Oracle JET versions. For example:
"jetVersion" : "9.0.0 -9.1.0"
, which implies that this Web Component supports every release of JET between JET 9.0.0 and JET 9.1.0 inclusive (so not including, for example, JET 9.2.0 or JET 8.0.0).
Tip:
The Oracle JET recommended format is the first case defined similar to "^9.1.0"
. Given that JET itself follows the semantic versioning rules, changes that occur in MINOR or PATCH versions ought not break your Web Component source code. This also means that you don't have to release an update to all your Web Components for every MINOR release of Oracle JET (unless you choose to make use of a new feature).
Note:
For background on npm-semver, visit npm documentation at this web site https://docs.npmjs.com/about-semantic-versioning.
In the case of JET Packs, you should pay attention to the dependencies
attribute in the component.json
file located in the pack. You should strive to require the various components bundled into the pack to be consumed together, and as such, you should define such dependencies with absolute version matches rather than version ranges to indicate this. For example, in this case the demo-memory-game component at version 1.0.2
will only expect to host a demo-memory-card at exactly version 1.0.2
.
{
"name": "demo-memory-game",
"version": "1.0.2",
"type": "pack",
"displayName": "JET Memory Game",
"description": "A memory game element with a configurable card set and attempt counter.",
"dependencies": {
"demo-memory-card": "1.0.2"
}
}
Create Web Components
Oracle JET supports a variety of custom Web Component component types. You can create standalone Web Components or you can create sets of Web Components that you intend to be used together and you can then assemble those in a JET Pack, or pack component type. You can enhance JET Packs by creating resource components when you have re-usable libraries of assets that are themselves not specifically UI components. And, if you need to reference third-party code in a standalone component, you can create reference components to define pointers to that code.
Create Standalone Web Components
Use the Oracle JET command-line interface (CLI) to create an Oracle JET Web Component template implemented as JavaScript or TypeScript that you can populate with content. If you’re not using the tooling, you can add the Web Component files and folders manually to your Oracle JET app.
The following image shows a simple Web Component named demo-card
that displays contact cards with the contact’s name and image if available. When the user selects the card, the content flips to show additional detail about the contact.
The procedure below lists the high level steps to create a Web Component using this demo-card
component as an example. Portions of the code are omitted for the sake of brevity, but you can find the complete example at Web
Component - Basic. You can also download the demo files by clicking the download button () in the cookbook.
Before you begin:
- Familiarize yourself with the steps to install the Oracle JET CLI, see Install Oracle JET Tooling.
- Familiarize yourself with the steps to add a Web Component to an Oracle JET app using the Oracle JET CLI, see Understand the Web App Workflow.
- Familiarize yourself with the list of reserved names for a Web Component that are not available for use, see valid custom element name.
-
Familiarize yourself with the list of existing Web Component properties, events, and methods, see HTMLElement properties, event listeners, and methods.
-
Familiarize yourself with the list of global attributes and events, see Global attributes.
To create a Web Component:
For help with markdown, refer to GitHub documentation.
For the complete code of the demo-card Web Component CSS styles, see
demo-card-styles.css
in the Web
Component - Basic cookbook sample.
For information on adding Web Component metadata that defines methods and events, see the Web Component - Events cookbook sample.
Create JET Packs
Create JET Packs to simplify project management for consumers who might pick up a component that is related to one or more components. You may require specific versions of the referenced components for individual JET Packs.
Fundamentally, the JET Pack is a library of related Web Components that does not directly include those assets, but is as an index to a particular versioned stripe of components.
Note:
Note there is one exception to the pack as a reference mechanism for related components. A pack might include one or more RequireJS bundle files which package up optimized forms of the component set into a small number of physical downloads. This, however, is always in addition to the actual components being available as independent entities in Oracle Component Exchange.
The components referenced by the JET Pack are intended to be used together and their usage is restricted by individual component version. Thus, the JET Pack that you create will tie very specific versions of each component into a relationship with very specific, fixed versions of the other components in the same set. Thus, a JET Pack itself has a "version stripe" which determines the specific components that users import into their apps. Since the version number of individual components may vary, the JET Pack guarantees the consumer associates their app with the version of the pack as a whole, and not with the individual components contained by the pack.
For details about versioning JET Packs, see Version Numbering Standards.
Create Resource Components for JET Packs
Create a resource component when you want to reuse assets across web components that you assemble into JET Packs. The resource component can be reused by multiple JET Packs.
When dealing with complex sets of components you may find that it makes sense to share certain assets between multiple components. In such cases, the components can all be included into a single JET Pack and then a resource component can be added to the pack in order to hold the shared assets. There is no constraint on what can be stored in a pack, typically it may expose shared JavaScript, CSS, and JSON files and images. Note that third party libraries should generally be referenced from a reference component and should not be included into a resource component.
You don't need any tools to create the resource component. You will need to create a folder in a convenient location. This folder will ultimately be zipped to create the distributable resource component. Internally this folder can then hold any content in any structure that you desire.
To create a resource component:
Create Reference Components for Web Components
Create a reference component when you need to obtain a pointer to third-party libraries for use by Web Components.
Create the Reference Component
You don't need any tools to create the reference component. You will need to create a folder in a convenient location where you will define metadata for the reference component in the component.json
file. This folder will ultimately be zipped to create the distributable reference component.
Reference components are generally standalone, so the component.json
file you create must not be contained within a JET Pack.
To create a reference component:
Consume the Reference Component
When your Web Components need access to the third party library defined in one of these reference components, you use the dependency attribute metadata in the component.json
to point to either an explicit version of the reference component or you can specify a semantic range. Here's a simple example of a component that consumes two such reference components at specific versions:
{
"name":"calendar",
"pack":"oj-sample",
"displayName": "JET Calendar",
"description": "FullCalendar wrapper with Accessibility added.",
"version": "1.0.2",
"jetVersion": "^9.0.0",
"dependencies": {
"oj-ref-moment":"2.24.0",
"oj-ref-fullcalendar":"3.9.0"
},
...
When the above component is added to an Oracle JET or Oracle Visual Builder project this dependency information will be used to create the correct RequireJS paths for the third party libraries pointed to be the reference component.
For more information about semantic version usage, see Version Numbering Standards.
Alternatively, when you install a Web Component that depends on a reference component and you use Oracle JET CLI, the tooling will automatically do an npm install for you so that the libraries are local. However, with the same component used in Oracle Visual Builder, a CDN location must be used and therefore the reference component must exist on the CDN in order to be used in Visual Builder.
Theme Web Components
Oracle JET Web Components may need to inherit styling from consuming app, such as the background color, where the color style is themeable. Web Components may also enable theming so the consuming app can customize the provided styles. You can add theming support to your Web Component, and you can define CSS variables to support customization of your component's look and feel.
About Web Component Theming
When you theme Web Components you work with SASS partial files to define the style classes and expose the styles through CSS variables, by using the JET Tooling to derive optimized CSS.
It is not always necessary to theme custom components and component packs that you create. In many cases you may not need to enable custom theming. For example, when you only need to wrap some core JET components with no additional user interface, no theming is needed. As these two use cases suggest, it depends how you expect your components to be used in the consuming app.
-
Theme-enable the custom component, or component pack, when the component needs to inherit styling from the consuming app, such as the background color that color style must be themeable in your component.
-
Theme-enable the custom component, or component pack, when the component defines its own style class and that style needs to be themeable in the consuming app for customization.
Oracle JET relies on CSS variables to theme apps. The use of CSS variables to theme your Web Component supports easy integration into a consuming app. To streamline the theming process and support the generation of optimised stylesheets, your Web Component relies on SASS partial files and SCSS processing.
After you create the Web Component, you run the ojet add theming
command to install support for scss processing into the base app where you will add the
component. Then you can use the ojet create
component command to add
your component to the jet-composites
folder. The new component project
will contain a themes folder and three subfolders:
base
,redwood
, and stable
containing SASS partials files, as follows:
-
base folder - contains the base SASS partial file, where you define the style classes for the component that are common across themes. The style classes reference CSS variables, the values of which are generally provided by the theme specific SASS partial file.
-
redwood folder - contains the theme-specific SASS partial file for the Redwood theme, where you define style settings for the component, specifically you use it to set any CSS variable values that the theme variant needs to set on the base
_myComponent.scss
partial file. The Redwood theme implements the look and feel for Oracle apps, future changes will be made to address Oracle's requirements. -
stable folder - contains the theme-specific SASS partial file for the Stable theme, where you define style settings for the component, specifically you use it to set any CSS variable values that the theme variant needs to set on the base
_myComponent.scss
partial file. The Stable theme is recommended as the base theme for custom themes if you want to reduce the likelihood that future theme updates affect your custom theme.
The SASS partials split between these folders supports the separation of the core style definitions from the variable driven theme-specific definitions. This structure allows you to define multiple themes but in practice is not a requirement for JET web apps, where the Redwood theme runs across platforms and environments, such as iOS on a mobile device or Windows on a desktop machine.
In addition to the generated theme folders, each component also has an SCSS file (ie, myComponent-styles.scss
) at the root of the component folder that the JET Tooling processes to generate the final CSS from the theme SASS partials. The root .scss
file contains a single line:
@import "themes/redwood/_myComponent.scss";
Guidelines for Web Component Theming
JET relies on the use of CSS variables as the primary vehicle for theming, which allows even a single supported theme configuration to adapt to the requirements of the consuming app.
When theming the Web Component observe the following considerations to guide the process.
- The goal should be to make your themed Web Component work out of the box for most cases and still allow the component to be themeable by a consuming app. Maintain a single default theme across your entire set of components.
- While a Web Component must provide a single default theme that works out of the box, you may choose to define the settings for multiple themes within the component. Note that only one theme can be active and surfaced for the component for direct runtime use.
- Document the supported themes in the readme file for the component or pack. This
information, combined with component metadata that you supply in
component.json
, specify the contract that the consuming app must fulfill. - Use CSS variables to externalize anything that you want to make configurable within a theme. This supports component-instance style overrides where needed and also simplifies the creation of custom themes for the component.
- Inherit as much information as possible from the core JET Redwood theme, for example
color ramps and sizing. This ensures that the Web Component's theming harmonizes
with all of the core JET components present in the app and that your component will
be able to adapt well to a custom theme. Where possible, use the
oj-flex
classes supplied by JET or other public layout styles to manage layout. This will ensure that the finer attributes of theming, such as padding, are consistent. - CSS usage should be optimized to allow consolidation at the JET Pack level or the app level. The use of CSS variables supports CSS consolidation.
If your themed component is configured through CSS variables so that the consuming
app may override at the app or instance level, then add those variables to a section
called Theming in the component README.md
and document what they do and
what they should be set to. Once documented in this way, the variables become a formal
part of the component API and you should follow the normal semver rules when it comes to
making changes. A change to the default theme should be classed as a MAJOR version
number change in semantic version number.
Theme a Web Component
You can use Oracle JET Tooling to theme-enable a custom Web Components project and work with CSS variables to theme custom components that you add to the project.
You enable theming of a new Web Components project, or JET Pack project, by using the JET Tooling to add theming support to the containing project. The tooling adds SASS partials files used to streamline the CSS generation process and is a prerequisite step to creating a custom component or pack to support modifications to the base theme.
After you theme-enable your containing project by running the ojet add
theming
command at the project root, new custom components that you create in the
project will contain a themes
folder with subfolders that each contain a
single SASS partials file that you will modify:
/<componentName>/themes/base/_<componentName>.sccs
defines your custom styling for the component that you want to remain common across themes. The styling portions that need to change with theme variations will be injected via CSS variable values and come from either the base JET theme or from the component theme-specific settings./<componentName>/themes/redwood/_<componentName>.sccs
contains the theme-specific settings for the component. Specifically, in this file you can specify any CSS variable values that a custom theme based on the Redwood theme needs to set on the base partials./<componentName>/themes/stable/_<componentName>.sccs
contains the theme-specific settings for the component. Specifically, in this file you can specify any CSS variable values that a custom theme based on the Stable theme needs to set on the base partials.
Additionally, any custom component in a theme-enabled project will also contain a <componentName>.scss
SASS file in the component's root folder. This file serves to import the CSS file that the JET build process generates from the SASS partials files.
Note:
A CSS build error may result if a pack or component is created before running ojet add theming
. The add theming
command enables SCSS compilation to generate the CSS. Be sure to run add theming
before creating the pack or component.
Before you begin:
- Refer to the JET CSS Variables section of the JET API reference doc for an overview of the CSS variables and values to use when directly defining custom selectors of the web component.
- View the CSS Variables section in the Oracle JET Cookbook for examples of CSS variable usages.
- Optionally, download and install the CSS Variable Theme Builder - Instruction Tab app when you want to learn about the available CSS variables in this interactive demo app. Follow the instructions online to modify the theme definition files to learn how CSS variable overrides change the demo tool UI.
To add theming support and theme a component:
Consolidate CSS for JET Packs
You can consolidate the stylesheets of custom components in a JET Pack to a single CSS file.
When you add custom Web Components to a JET Pack, initially, each component provides it's own CSS file. Although this approach works, it's optimal in a production app to reduce the number of physical roundtrips to the server and take full advantage of browser caching and the CDN. To reduce the number of roundtrips, you can enable loading from a single CSS file through the use of a shared Resource component that you add to the pack.
Before you begin:
- Create a Resource component with a working folder
common
and itscomponent.json
file, as described in Create Resource Components for JET Packs.
To create a single shared CSS file in a pack:
Optimize CSS to Allow Consuming Apps to Provide Styles
You can optimize the loading of component styles in the theme CSS for the consuming app.
To support downstream usages of the themed component, the Web Component needs to establish a contract for what the component needs. The developer who consumes your themed custom component into their app should be able to incorporate the styles unchanged and, optionally, perform a CSS optimization to enable loading from a single CSS file.
To enable these usages you must establish a contract that the downstream developer can observe when adding your component to their app.
To define and support the contract, you decorate the custom component with metadata
that specifies the theme SCSS partials that the component exposes, and you modify
the default loader script for the component CSS to specify the CSS requireJS plugin
with the configurable ojcss
plugin.
Before you begin:
- Set up the consolidation of component stylesheets with the aid of a Resource component you create at the pack level, as described in Consolidate CSS for JET Packs.
To define a theme-consuming contract for the component:
Incorporate Themed Components into a Consuming App
You can override CSS variables in a properly themed Web Component by making changes to the style classes in your consuming app's theme.
For example, if your app's custom theme alters the default Redwood theme color ramp, you want to ensure that the same colors are inherited by the themeable custom components that you add to your app. This process of overriding the CSS variables of the custom component by the consuming app requires that you incorporate the partials supplied by each component that you want to consume. This process is statically defined and therefore you will need to re-perform this whenever you add a new component that requires theming into the consuming app.
Note that you also can use this process when you do not need to make changes to the underlying Redwood theme and only want to optimize the number of CSS files by consolidating both the core Redwood styles, plus the extra styles defined for the custom components you will use.
Before you begin:
- Create a working project that you will use to carry out the theme creation
process.
ojet create redwood-plus-theme-source --template=basic
In this example, the working project is named
redwood-plus-theme-source
. - Add theming support to the project and create the custom
theme.
ojet add theming ojet create theme redwood-plus --basetheme=redwood
In this example, the theme name
redwood-plus
distinguishes the custom theme from the out-of-the-boxredwood
theme name. Note that JET, as of release 11.0.0, supports another out-of-the-box theme (stable
) that is less likely to be affected by future changes to the out-of-the-boxredwood
theme. Choosestable
as the--basetheme
argument value if the consuming app uses a theme based on thestable
theme. - When working with Oracle Component Exchange to add Web Components, set up
access to Component
Exchange.
ojet configure --exchange-url=https://xxxxx-cloud01.developer.ocp.oraclecloud.com/xxxxx-cloud01/s/xxxxx-cloud01_sharedcomponentcatalog_8325/compcatalog/0.2.0
-
Add the components that you want to include into your theme. This process will download the components into the
/jet_components
cache folder in the root of your theme source project.You can add the components one by one:
ojet add component oj-sample-metric@^4.0.0
Or, you can add an entire pack at once.
ojet add pack oj-sample@^4.0.0
In this example, the component name and pack name are reused from the examples shown in the previous topics in this section.
Note when adding the components or packs, you should specify the versions that you need. Similar to the way you would use the core JET theme, you can expect to rebuild and regenerate the theme if there is a change in the major version number of the component or pack.
To incorporate themeable components into the custom theme:
Test Web Components
Test Oracle JET Web Components using your favorite testing tools for client-side JavaScript apps.
Regardless of the test method you choose, be sure that your tests fully exercise the Web Component’s:
-
ViewModel (if it exists)
Ideally, your test results should be verifiable via code coverage numbers.
-
HTML view
Be sure to include any DOM branches that might be conditionally rendered, and test all slots with and without default content.
-
Properties and property values
-
Events
-
Methods
-
Accessibility
-
Security
For additional information about testing Oracle JET apps, see Test Oracle JET Apps.
Add Web Components to Your Page
To use an Oracle JET Web Component, you must register the Web Component’s loader file in your app and you must also include the Web Component element in the app’s HTML. You can add any supporting CSS or files as needed.
Build Web Components
You can build your Oracle JET Web Component to optimize the files and to generate a minified folder of the component that can be shared with the consumers.
When your Web Component is configured and is ready to be used in different apps, you can build the Web Components of the type: standalone Web Component, JET Pack, and Resource component. Building these components using JET tooling generates a minified content with the optimized component files. This minified version of the component can be easily shared with the consumers for use. For example, you would build the component before publishing it to Oracle Component Exchange. To build the Web Component, use the following command from the root folder of the JET app containing the component:
ojet build component my-web-component-name
For example, if your Web Component name is demo-card-example
, use the following
command:
ojet build component demo-card-example
For a JET Pack, specify the pack name.
ojet build component my-pack-name
Note that the building individual components within the pack is not supported, and the whole pack must be built at once.
This command creates a /min
folder in the web/js/jet-composites/demo-card-example/x.x.x
directory of your Oracle JET web app, where x.x.x
is the version number
of the component. The /min
folder contains the minified (release)
version of your Web Component files.
Reference component do not require minification or bundling and therefore do not need to be built.
When you build Web Components:
-
If your JET app contains more than one component, you can build the containing JET app to build and optimize all components together. The
build component
command with the component name provides the capability to build a single component. -
You can optionally use the
--release
flag with the build command, but it is not necessary since thebuild
command generates both the debug and minified version of the component. -
You can optionally use the
--optimize=none
flags with thebuild
command when you want to generate compiled output that is more readable and suitable for debugging. The component'sloader.js
file will contain the minified app source, but content readability is improved, as line breaks and white space will be preserved from the original source.
Generate API Documentation for VComponent-based Web Components
The Oracle JET CLI includes a command (ojet add docgen
) that
you can use to assist with the generation of API documentation for the VComponent-based web
components (VComponent) that you develop.
When you run the command from the root of your project, the JSDoc NPM package
is installed and an apidoc_template
directory is added to the
src
directory of your project. The apidoc_template
directory contains the following files that you can customize with appropriate titles,
subtitles, and footer information, such as copyright information, for the API reference
documentation that you'll subsequently generate for your VComponent(s).
footer.html
header.html
main.html
You write comments in the source file of your VComponent, as in the following example:
import { ExtendGlobalProps, registerCustomElement } from "ojs/ojvcomponent";
. . .
type Props = Readonly<{
message?: string;
address?: string;
}>;
/**
*
* @ojmetadata version "1.0.0"
* @ojmetadata displayName "A user friendly, translatable name of the component"
* @ojmetadata description "<p>Write a description here.</p>
<p>Use HTML tags to put in new paragraphs</p>
<ul>
<li>Bullet list item 1</li>
<li>Bullet list item 2</li></ul>
* <p>Everything before the closing quote is rendered</p>
* "
*
*/
function StandaloneVcompFuncImpl({ address = "Redwood shores",
message = "Hello from standalone-vcomp-func" }: Props) {
return (
<div>
. . .
</div>
);
}
Once you have completed documenting your VComponent’s API in the source
file, you run the build
command for your component or the JET Pack, if
the component is part of a JET pack (ojet build component
component-name
or ojet build component
jet-pack-name
) to generate API reference doc in the appRootDir/web/js/jet-composites/component-or-pack-name/vcomponent-version/docs
directory.
The following /docs
directory listing shows the files that
the Oracle JET CLI generates for a standalone VComponent. You can’t generate the API
documentation by building the Oracle JET app that contains the component. You have to
build the individual VComponent or the JET Pack that contains VComponents. Note too that
you can’t generate API doc for CCA-based web components using the Oracle JET CLI
ojet add docgen
command.
appRootDir/web/js/jet-composites/standalone-vcomp-func/1.0.0/docs
| index.html
| jsDocMd.json
| standalone-vcomp-func.html
| standalone.StandaloneVcompFunc.html
|
+---scripts
| | deprecated.js
| |
| \---prettify
| Apache-License-2.0.txt
| lang-css.js
| prettify.js
|
\---styles
| jsdoc-default.css
| prettify-jsdoc.css
| prettify-tomorrow.css
|
\---images
bookmark.png
linesarrowup.png
linesarrowup_blue.png
linesarrowup_hov.png
linesarrowup_white.png
oracle_logo_sm.png
One final thing to note is that if you want to include an alternative logo and/or CSS
styles to change the appearance of the generated API doc, you update the content in the
following directory
appRootDir/node_modules/@oracle/oraclejet/dist/jsdoc/static/styles/
.
Package Web Components
You can create a sharable zip file archive of the minified Oracle JET Web Component from the Command-Line Interface.
jet-composites
subfolder of the app's
/web
. After you build a standalone Web Component or a Resource
component, you use the JET tooling to run the package
command and
create a zip file that contains the Web Component compiled and minified
source.ojet package component my-web-component-name
/jet-composites/<packName>
subfolder contains nested
component folders and the tooling ensures that each component has its own zip
file.ojet package pack my-JET-Pack-name
The package
command packages the component's minified source from
the /web/js/jet-composites
directory and
makes it available as a zip file in a /dist
folder at the root of the
containing app. This zip file will contain both the specified component and a minified
version of that component in a /min
subfolder.
Reference components do not require minification or bundling and therefore do not need to be built. You can archive the Reference component by creating a simple zip archive of the component's folder.
The zip archive of the packaged component is suitable to share, for example, on
Oracle Component Exchange, as described in Publish Web Components to Oracle Component Exchange. To help organize components that you
want to publish, the JET tooling appends the value of the version
property from the component.json
file for the JET pack and the
individual components to the generated zip in the dist
folder. Assume,
for example, that you have a component pack, my-component-pack
, that
has a version
value of 1.0.0
and the indiviudal
components (my-widget-1
, and so on) within the pack also have version
values of 1.0.0
, then the zip file names for the generated files will
be as follows:
appRootDir/dist/
my-web-component-name_1-0-0.zip
my-component-pack_1-0-0.zip
my-component-pack-my-widget-1_1-0-0.zip
my-component-pack-my-widget-2_1-0-0.zip
my-component-pack-my-widget-3_1-0-0.zip
You can also generate an archive file when you want to upload the component to a CDN. In the CDN case, additional steps are required before you can share the component, as described in Upload and Consume Web Components on a CDN.
Create a Project to Host a Shared Oracle Component Exchange
When you want to store and share Web Components across machines for re-use by other developers, you can use a Component Exchange that you create in Oracle Visual Builder Studio.
When you want to share Web Components, you generally need to set up a dedicated project to specifically host a Shared Exchange. Although every project within Oracle Visual Builder Studio has a private Component Exchange instance, the Shared Exchange makes uploaded components accessible to other developers. You can use the same project in your Shared Exchange to host the source code repository of your components.
To create the Shared Exchange:
Publish Web Components to Oracle Component Exchange
When you want to store and share Web Components across machines for re-use by other developers, you can use the Oracle JET CLI (Command-Line Interface) to configure access to a Shared Component Exchange defined in Oracle Visual Builder Studio and then publish components to a public project.
When you want to share Web Components, you can use Oracle JET CLI to configure access
to a Shared Component Exchange by supplying the URL to the target
Component Exchange. Once you have configured the JET tooling for a
specific Component Exchange, you can run the publish
component
command in the JET CLI to upload
specified components. Users with access rights can use the CLI to
search the Component Exchange for components by keyword and add
components to their web app project.
Before you begin:
-
Create a project in a Shared Component Exchange, as described in Create a Project to Host a Shared Oracle Component Exchange.
-
Share the project with all users who will need to access components by adding them as members to the project, as described in Create a Project to Host a Shared Oracle Component Exchange. Users will need to create their own user name and password to access the Shared Component Exchange.
To publish components to a Shared Component Exchange:
search exchange
command with a keyword, such as
the component name. Additionally, you can add components to your web app by
running the add component
command for the configured
Component Exchange. For more information, use ojet help
in
the JET CLI.
Upload and Consume Web Components on a CDN
You can package a Web Component to make it available on a Content Delivery Network (CDN) and you can reuse the component in your app.
You can include the CDN location of the component in the component metadata as
defined in the component's component.json
file. By doing this, tools such as
Oracle JET tooling and Oracle Visual Builder will be able to point to the CDN location when
you build your apps in release mode.
CDN information is encoded by using the paths
attribute in the component.json
file. A typical example looks similar to this.
{
"name": “demo-samplecomponent",
"displayName": “Sample component",
"version": "1.0.0",
"paths": {
"cdn": {
"min": "https://static.example.com/cdn/jet/components/demo-samplecomponent/1.0.0/min",
"debug": "https://static.example.com/cdn/jet/components/demo-samplecomponent/1.0.0"
}
},
...
The following notes apply to the paths
attribute that you specify:
-
The exact CDN root location will depend on your CDN provider, and it is the final part of the location that is needed.
-
The location has a folder with the same name as the component (in this example
demo-samplecomponent
) followed by the version number of the component (1.0.0
). As you release new versions of the component, you will create a new version-number folder under the component root. -
You can provide both a
min
anddebug
path for the component, where thedebug
path is optional.
To prepare for CDN distribution, package the component by running the
package component
command in the Oracle JET Command-Line Interface. This
will produce a zip file with the same name as the component (for example,
demo-samplecomponent.zip
) in the /dist
folder of the
containing Oracle JET app. This zip file will contain both the specified component and a
minified version of that component in a /min
subfolder.
Unpack the zip file that you created under the /<component-name>/<version>
folder for your CDN as identified in the component.json
file.
After a component is available on a CDN, you can then use it in your JET app by
pointing the requireJS path for the component to the CDN location that you identified for the
component. If you use Oracle JET tooling, this will be done for you; however, if you need to
define the requireJS paths manually, such a mapping will look similar to this in
main.js
file:
requirejs.config(
{
baseUrl: 'js',
paths:
{
'demo-samplecomponent': '"https://static.example.com/cdn/jet/components/demo-samplecomponent/1.0.0/min',
...
References to the component can be made using the path <component-name>/loader
.