@nestechnology/turas-design-system v1.1.202401171-beta
turas-design-system npm package
Introduction
The npm package contains CSS and script intended for use by a Turas application,
and designed to work with markup emitted by Tag Helpers in the NES.Turas.DesignSystem NuGet package
.
Azure DevOps pipelines are set up to publish turas-design-system
to the public npmjs.com
registry, scoped to the nestechnology
npm organisation.
Packages will be available here: https://www.npmjs.com/package/@nestechnology/turas-design-system.
Dependencies
If you inspect the package.json
file, the dependencies
entry lists the other npm packages that are required
by the Turas Design System to be present, such as bootstrap
, jquery
and datatables.net
.
You must ensure that files from Turas Design System and its dependencies are located in the relevant locations
within wwwroot
.
If you have opted to call AddTurasDesignSystem
in your app startup code, CSS and script references will be injected
into the page automatically. The files it references must be in your project in those locations.
Otherwise, you can add your own CSS and script references and have more control over where the dependencies are located.
Font Awesome
Each Turas application should have its own Font Awesome Kit ID. The UX team can assist in obtaining one if you do not have one already.
If you have opted to call AddTurasDesignSystem
in your app startup code and supplied a Font Awesome Kit ID, a reference will be injected into the page automatically
to fetch the Font Awesome Kit from https://kit.fontawesome.com/{KitID}.js
, with a fallback URL of wwwroot/lib/font-awesome-kit/font-awesome-kit.js
.
Once you have a Kit ID, you should ensure that you have manually downloaded the Kit from the relevant URL and placed it in the above path in wwwroot
.
Otherwise, your app will not work correctly offline as it will not be able to reach the Font Awesome URL and have no local fallback file.
Importing the package
As a developer of a Turas application, you have different options for importing the package and its dependencies.
LibMan
If you are using Visual Studio, the easiest way to import client-side dependencies is to use
Microsoft Library Manager, aka LibMan. This can be accessed by right-clicking wwwroot
and selecting
Add > Client-side Library
.
The dialog allows you to select the desired version of an npm package, and optionally pick specific files in the
package, to be downloaded to the specified place in your project (usually under wwwroot\lib\<package_name>
.
The dialog stores the package information in the libman.json
file. You can edit this file by hand, and Visual Studio
will automatically update the files in your project.
This approach can be used to obtain the turas-design-system
npm package, but it does not automatically fetch
the dependencies. So you must also ensure that the dependencies from the package.json
within turas-design-system
are added to libman.json
, such as bootstrap
and jquery
, taking care to reference the same versions as in package.json
.
NOTE LibMan offers several providers to choose from, the recommended provider is jsDelivr.
npm
Instead of using LibMan, you can use npm to fetch the turas-design-system
npm package and its dependencies.
The upside is that, unlike LibMan, npm will automatically fetch the dependencies such as bootstrap
.
The downsides are that you must have node and npm installed on your machine, and the packages are downloaded
to the node_modules
folder rather than wwwroot
, so you must take extra steps to copy the files into wwwroot
for use in your web app. This may involve setting up Gulp tasks in a gulpfile.json
.
Other
There are other npm package managers available, such as yarn and pnpm.
Initialisation
Included in the turas-design-system.init.js
file is a document ready handler which calls TurasDesignSystem.Initialise(document)
.
If your application uses the NES.Turas.DesignSystem NuGet package
and calls AddTurasDesignSystem
then by default it injects
a reference to that file into the body
element.
If you have disabled auto-inject or auto-initialise in the call to AddTurasDesignSystem
and you do not use <turas-scripts initialise/>
,
or if your application does not call that method or use the package, then you should call TurasDesignSystem.Initialise(document)
manually.
If your application performs partial refreshes by injecting HTML into the page (e.g. fetched via Ajax) then you should call
TurasDesignSystem.Initialise
passing the root element of the refreshed content.
If you have code you want to be executed once the Turas Design System has finished initialising, you can call e.g.
TurasDesignSystem.PostInitialise(document, customPostInitFunction);
. When the customPostInitFunction
is invoked, it is passed
the jQuery-wrapped container as the only argument (so in this case it will be passed $(document)
).
The customPostInitFunction
callback can be an asynchronous function; it is await
ed when invoked by TurasDesignSystem.Initialise
.
If you have multiple post-initialise functions to register, you can call PostInitialise
multiple times. The functions
will be invoked in the order they were registered.
Using the Turas Design System components
FileUploadComponent
A sample file upload component using the tag helper provided by the NES.Turas.DesignSystem NuGet package
could look like this, configured to upload a single file immediately with Ajax:
<turas-file-upload file-upload-component-id="FileUploadComponent1"
asp-for="ImmediateUploadedFile"
filename="UploadedFilename"
file-type="UploadedFileType"
file-size="UploadedFileSize"
download-url="UploadedFileDownloadUrl"
view-url="UploadedFileViewUrl"
accept="@Model.FileAccept"
max-file-size-mb="20"
immediate-upload-url="/forms/UploadSingleFile">
<turas-file-action state="NES.Turas.DesignSystem.Enums.FileUploadState.Complete">
<button type="button" custom-file-delete><i class="fa-regular fa-trash-can"></i>Delete</button>
</turas-file-action>
</turas-file-upload>
To obtain a reference to the FileUploadComponent
API in your script:
var fileUploadComponent = new TurasDesignSystem.FileUploadComponent($("#FileUploadComponent1"));
The supplied element must be a .fileUploadComponent
(or a descendant of one) that was generated by the Turas Design System.
If a descendant element is supplied, the closest .fileUploadComponent
is located and initialised.
If the constructor was previously called for that .fileUploadComponent
, the same reference is returned.
The API exposes functions to let you attach event handlers or a custom upload implementation:
OnUploadReady
OnUploadComplete
OnError
UploadFile
The SetDefaults
API lets you set global defaults that apply to all FileUploadComponents
that are subsequently created:
// Register a default file upload handler, replacing the built-in default which is to use an XMLHttpRequest. You may decide to use fetch or jQuery Ajax instead for example.
// Register a default error handler for file uploads, replacing the built-in default which is to display a bootstrap modal.
TurasDesignSystem.SetDefaults({
FileUploadHandler: async function (file, url, method, $uploadContainer) {
console.log("custom upload handler fills the progress bar immediately and returns fake info");
this.SetUploadProgress($uploadContainer, 123456, 123456);
var fakeResponse = { filename: "foo.pdf", fileType: "application/pdf", fileSize: 123456, downloadUrl: "/foo/download", viewUrl: "/foo/view" };
return { response: JSON.stringify(fakeResponse), status: 200, cancelled: false };
},
FileUploadError: (event, eventData) => alert(eventData.message)
});
If you are calling SetDefaults
, you should do so before any calls to new TurasDesignSystem.FileUploadComponent(...)
,
as the settings will not apply to any components created earlier.
DataGridComponent
A sample data grid component using the tag helper provided by the NES.Turas.DesignSystem NuGet package
could look like this:
<turas-data-grid grid-id="PersonGrid" asp-for="PersonGrid" row-id="PersonGrid.Row.RowId" camel-case>
<turas-data-grid-column asp-for="PersonGrid.Row.Name" span="4" sortable />
<turas-data-grid-column asp-for="PersonGrid.Row.DateOfBirth" span="2" sortable />
<turas-data-grid-column asp-for="PersonGrid.Row.Job" span="4" sortable />
</turas-data-grid>
To obtain a reference to the DataGridComponent
API in your script:
var personGridComponent = new TurasDesignSystem.DataGridComponent($("#PersonGrid"));
The supplied element must be a .dataGridComponent
(or a descendant of one) that was generated by the Turas Design System.
If a descendant element is supplied, the closest .dataGridComponent
is located and initialised.
If the constructor was previously called for that .dataGridComponent
, the same reference is returned.
If you wish to customise a particular DataGridComponent
, you may pass an options object when the constructor is first invoked.
var personGridOptions = {
BuildGridDataFetchOption: () => customGridDataFetchOptions,
RenderCell: customRenderCellFunction
};
var personGridComponent = new TurasDesignSystem.DataGridComponent($("#PersonGrid"), personGridOptions);
A custom error handler can be attached:
const replacesDefaultHandler = true;
personGridComponent.OnError(function(event, eventData) {
this.$component.find(".dataTables_processing").hide();
alert(eventData.message);
}, replacesDefaultHandler);
The DataGridComponent
relies on the datatables.net npm package. To obtain a reference to the underlying datatables
API:
var dataTableApi = personGridComponent.dataTable;
The SetDefaults
API lets you set global defaults that apply to all DataGridComponents
that are subsequently created:
// Register default grid data fetch options
// Register a default RenderCell implementation
// Register a default error handler, replacing the built-in default which is to display a Bootstrap modal.
TurasDesignSystem.SetDefaults({
GridDataFetch: () => customGridDataFetchOptions,
GridRenderCell: customRenderCellFunction,
GridError: function(event, eventData) { this.$component.find(".dataTables_processing").hide(); alert(eventData.message); },
});
If you are calling SetDefaults
, you should do so before any calls to new TurasDesignSystem.DataGridComponent(...)
,
as the settings will not apply to any components created earlier.
File download modals
When the Turas Design System has been initialised, a spinner modal is available for display when a file download is in progress.
The modal is wired up to be displayed automatically when an anchor tag with both download
and turas-file
attributes is clicked:
<a href="/download-file" download turas-file>Download the file</a>
With those attributes present, the Turas Design System will:
- Automatically display the spinner modal.
- Set a
turasFileDownload
cookie with a 10 minute expiry. - Start a timer to poll every second to check that the cookie still exists.
- If the cookie does not exist, or if a
turasFileDownloadError
cookie exists, hide the spinner modal. - If a
turasFileDownloadError
cookie exists, show a file download error modal.
Note: This approach relies on the server clearing the turasFileDownload
cookie before returning the file response,
and setting the turasFileDownloadError
if a file could not be sent in the response. If the server has not been configured
to do this, then do not set the turas-file
attribute on the anchors.
To show and hide the modal manually:
var modal = TurasDesignSystem.ShowFileDownloadModal();
// ...
modal.hide();
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
5 months ago
5 months ago
8 months ago
9 months ago
9 months ago
9 months ago
6 months ago
6 months ago
9 months ago
7 months ago
10 months ago
9 months ago
10 months ago
9 months ago
10 months ago
8 months ago
9 months ago
8 months ago
8 months ago
9 months ago
8 months ago
9 months ago
8 months ago
9 months ago
9 months ago
7 months ago
7 months ago
8 months ago
10 months ago
8 months ago
9 months ago
5 months ago
10 months ago
9 months ago
7 months ago
5 months ago
9 months ago
8 months ago
8 months ago
7 months ago
8 months ago
8 months ago
9 months ago
7 months ago
8 months ago
8 months ago
8 months ago
9 months ago
8 months ago
8 months ago
9 months ago
9 months ago
8 months ago
9 months ago
10 months ago
8 months ago
8 months ago
8 months ago
9 months ago
10 months ago
9 months ago
10 months ago
7 months ago
7 months ago
8 months ago
9 months ago
10 months ago
7 months ago
9 months ago
9 months ago
5 months ago
10 months ago
8 months ago
8 months ago
9 months ago
7 months ago
9 months ago
10 months ago
9 months ago
7 months ago
8 months ago
9 months ago
8 months ago
9 months ago
9 months ago
9 months ago
9 months ago
10 months ago
7 months ago
9 months ago
10 months ago
8 months ago
9 months ago
8 months ago
8 months ago
9 months ago
6 months ago
9 months ago
6 months ago
10 months ago
9 months ago
7 months ago
8 months ago
9 months ago
9 months ago
9 months ago
8 months ago
8 months ago
9 months ago
7 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
8 months ago
8 months ago
6 months ago
8 months ago
8 months ago
7 months ago
8 months ago
8 months ago
8 months ago
9 months ago
9 months ago
9 months ago
9 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago