Peek Theme Documentation¶

The main aim of the Peek application is to display and transmit data.
What is Peek¶
Peek is a semi distributed pluggable python platform.
Plugins are installed across the peek services and communicate with other plugins to retrieve, transmit, store or display data.
Peek provides a platform for Python similar to the functionality JBOSS provides for JAVA. (Or at least that is in the intention, it’s early days)
The Big Bang¶
Peek was created and is maintained by Synerty to be a distributed, pluggable python platform that provides many of the core services needed for enterprise applications.
We wanted to integrate smaller pieces of code, that can leverage different existing boilerplate code which the platform provides. For example, services for parallel processing or services for business integrations.
The Peek Platform allows developers to better write and integrate smaller units of code.
Synerty uses the Peek platform to provide scalable enterprise grade applications to the power utilities sector.
Bootstrap¶
The scss for the peek app is based upon bootstrap. For more detail to bootstrap documentation please visit BootStrap.
The bootstrap classes that are related to the layouts will only work on HTML, not NativeScript. Therefore the theme will avoid selecting by bootstrap classes that are related to layouts.
The looks and feel classes are to be used. These will need to be styled from scratch for NativeScript.
The scss will be structured in such a way to ignore hierarchy and tag selection.
Note
NativeScript does not use Bootstrap for layout.
NativeScript User Interface¶
The user interface of NativeScript mobile apps consists of pages. Typically, the design of the user interface is developed and stored in XML files, styling is done via CSS and the business logic is developed and stored in JavaScript or TypeScript files.
Style Guide¶
Design Objective¶
The objective of this project is to stylise the existing layout to make it very impressive without changing the HTML / javascript of a page to a large extent. The job mainly involves CSS/SCSS upgrade to the base Bootstrap theme.
This app will be viewed predominately during the day. The design and layout must be clear to read in very bright sunlight.

Design Overview¶

Design requirements¶
- Data must be
- Readable in daylight
- Without transparent backgrounds
- Large icons with text in the icons on home page
- Home page icons need to be more like apple icons
- Home page design must be impressive
- All screens do not need to have the same background
- Other screens must have static background to avoid distractions
- Use Nodal background as used in Peek App Branding
- Each icon on the home screen represents and App / Plugin and the background image for each App can change when a user clicks into it, hence having its own subtle branding but still share allot of common elements in the entire app.
Design restrictions¶
- Design must not be dark or have a dark background
Colours¶
A primary colour refers to a colour that appears most frequently in your app.
A secondary colour refers to a colour used to accent key parts of your UI.
The primary and secondary colours have been selected to ensure sufficient colour contrast between elements so that all users can see and use the app.
Primary Colour (Brand)¶
A primary colour is the color displayed most frequently across your app’s screens and components. It can also be used to accent elements, if you don’t have a secondary color.
To create contrast between elements, you can use lighter or darker tones of your primary color. The contrast between lighter and darker tones helps show division between surfaces, such as between the status bar and a toolbar.

Secondary Colour¶
A secondary colour is used to accent select parts of your UI. It can be complementary or analogous to your primary colour, but it should not simply be a light or dark variation of your primary colour. It should contrast with elements that surround it and be applied sparingly as an accent.
Secondary colours are best used for:
- Buttons, floating action buttons, and button text
- Text fields, cursors, and text selection
- Progress bars
- Selection controls, buttons, and sliders
- Links
- Headlines

Typography¶
Colours and Contrast¶
A text colour that is too similar to the background colour is hard to read. Text with too much contrast can also be hard to read. This is especially true of light-coloured text against dark backgrounds.
Text on the primary, primary-dark, secondary or secondary-dark will be coloured white #ffffff
.
As a general rule of thumb in the Peek application text displaying data is coloured black #000000
to draw focus, text displaying information is coloured secondary-dark #707070
to avoid taking away
focus from the displayed data.
Layout¶
Peek plugins can consist of the following:
- Navigation Section, located at the top of the screen. Within the Navigation Section Navigation buttons are grouped together and located on the left of the screen. Action buttons are grouped located to the right of the screen. Previous and Next buttons are grouped with and located to the right of the action buttons.
- Mobile Dialog Section, appears from the top of the screen and the navigation section should be hidden while the Mobile Dialog Section is active.
- Information Section, the landing screen of a plugin used to describe and display required information on opening the plugin such as active user.
- Details Section, presents data (text, numbers, images, or other data) of importance.
- Tables Section, best suited when there’s logical relationships among text, numbers, images, or other data exist in two dimensions (vertical and horizontal).
The Peek plugin contents will always be display between the header at the top and footer at the bottom.
Note
Customising plugins layout outside of the guides directions is up to the developer.
Platform¶
Design conventions can differ from platform to platform. These differences in convention can affect the user’s ability to understand the UI or complete certain tasks.
Peek is to be designed to function identically across all platforms.
Devices¶
The application has been developed for screens of a resolution greater than, 1136 x 640 pixels. This is the iPhone 5 resolution.
Note
The application will function on devices with lower resolution but may not display correctly.
Tabs Section¶
The Tabs Section is positioned below the Title Bar, below the Navigation Section, above the plugin screen and contains buttons that route to other tab contents toggling the data presented.
The sample below shows an example of tab navigation of the inbox plugin. The ‘Inbox’ is presented as the active tab and the ‘Activity’ is presented as the inactive tab.

The Tabs Section serves as screen content control.
If a Tabs Section is required it is constructed by the plugin screen.
The buttons remain a fixed size throughout a responsive lifecycle. The buttons are sized around the text they contain. The active tab button uses the primary colour styling and is slightly taller than the selectable inactive tab button.
Note
The buttons require a different theme to the Title Bar and generic peek theme buttons.
Classes¶
The .peek-tabs-section
class contains the looks classes specific to the
Tabs Section.
.peek-tabs-section { /* Contains the Tabs Section attributes */ ... .btn-group { /* Contains the attributes unique to the Tabs Section */ .tabs-section-btn { /* Contains the Button attributes unique to the Tabs Section */ ... } .tabs-section-btn.active { /* Contains the Button attributes for the active tab unique to the Tabs Section */ ... } .tabs-section-btn-divider { /* Contains the button divider attributes unique to the Tabs Section */ ... } .tabs-section-btn-disabled { /* Contains the button disabled attributes unique to the Tabs Section */ ... } } } .peek-tabs-bar-padding { /* Provides padding for the screen under the Tabs Section */ ... }
SCSS Files¶
The Tabs Section style classes are found in the
_tabs_section.scss
.
The Tabs Section HTML layout classes are found in the
_tabs_section.web.scss
.
The Tabs Section NativeScript layout classes are found in the
_tabs_section.ns.scss
.
HTML¶
The peek-tabs-section
is to be included before the code of the plugin screen
requiring Tabs.
The tabs-section-btn-divider
and tabs-section-btn-disabled
classes are not required in the Web app.
Their attributes are handled by pseudo-selectors of tabs-section-btn
.
<div class="peek-tabs-section"> <div class="btn-group" role="group"> <Button class="tabs-section-btn" [class.active]="barIndex == 0" (click)="barIndex = 0"> Inbox </Button> <Button class="tabs-section-btn" [class.active]="barIndex == 1" (click)="barIndex = 1"> Activity </Button> </div> </div>
NativeScript¶
The peek-tabs-section
is to be included before the code of the plugin screen
requiring Tabs.
The tabs-section-btn-divider
and tabs-section-btn-disabled
classes are required in the
NativeScript app. Pseudo-selectors applied in the SCSS are not supported by NativeScript.
tabs-section-btn-divider
will set the right side border of the button.
tabs-section-btn-disabled
applies the disabled styling.
<StackLayout class="peek-tabs-section"> <GridLayout class="btn-group" rows="auto" columns="auto, auto, *"> <Button row="0" col="0" class="tabs-section-btn" [class.active]="barIndex == 0" text="Inbox" (tap)="barIndex = 0"></Button> <Button row="0" col="1" class="tabs-section-btn" [class.active]="barIndex == 1" text="Activity" (tap)="barIndex = 1"></Button> </GridLayout> </StackLayout>
Mobile Dialog Section¶
The Mobile Dialog Section presents inputs and/or options to the Peek app user. It can involve a select drop down with a confirm and cancel buttons as per the example below.

The input types can be customised by the developer depending on the plugin requirements.
Uses:
- List Selection
- Text Input
- File Select
- Action Confirm
Any plugin screen dialog will be able to use the .mobile-dialog
attributes.
Classes¶
The .mobile-dialog
class contain the classes specific to a Mobile Dialog Section.
.mobile-dialog {
/* Contains the Mobile Dialog Section looks classes unique for mobile devices */
...
.dialog-label {
/*
Contains the label attributes unique to the Mobile Dialog Section
*/
...
}
.dialog-selector {
/*
Contains the selector attributes unique to the Mobile Dialog Section
*/
...
}
.dialog-btn-block {
/*
Contains the btn block attributes unique to the Dialog Mobile Section
*/
...
}
.dialog-action-btn-group {
/*
Contains the action button group attributes unique to the Dialog Mobile
Section
*/
...
}
.dialog-action-btn {
/*
Contains the action button attributes unique to the Mobile Dialog Section
*/
...
}
}
SCSS Files¶
The Mobile Dialog Section style classes are found in the
_mobile_dialog_section.scss
.
The Mobile Dialog Section HTML layout classes are found in the
_mobile_dialog_section.web.scss
.
The Mobile Dialog Section NativeScript layout classes are found in the
_mobile_dialog_section.ns.scss
.
HTML¶
The Mobile Dialog Section uses Bootstraps Forms.
Refer to the Forms for more information about creating Forms using Bootstrap.
Below is the HTML code extract op-confirm.component shown in the image at the top of, Mobile Dialog Section:
<div class="mobile-dialog" [@dialogAnimation]="dialogAnimationState"
(@dialogAnimation.done)="animationDone($event)">
<div class="container-fluid">
<div class="form-group">
<div class="dialog-label"
for="operationDate">Operation Date / Time :
</div>
<input id="operationDate" class="dialog-selector form-control"
[(ngModel)]="inputData.operationDate" ng2-datetime-picker
close-on-select="false"
date-format="DD-MMM-YYYY HH:mm"/>
</div>
<div class="form-group">
<div class="dialog-label text-muted">Request Further Instructions :
<button class="dialog-action-btn btn-sm"
(click)="inputData.requestFurtherInstructions=!inputData.requestFurtherInstructions"
[class.btn-success]="inputData.requestFurtherInstructions"
type="button">{{inputData.requestFurtherInstructions ? "Yes" :
"No"}}
</button>
</div>
</div>
<!--BEGIN HANDBACK DIALOG -->
<div class="btn-group pull-right">
<Button class="dialog-action-btn" (click)="webConfirmClicked()">
{{inputData.actionName}}
</Button>
<Button class="dialog-action-btn" (click)="cancelClicked(false)">Cancel
</Button>
</div>
</div>
</div>
NativeScript¶
The Mobile Dialog Section uses the NativeScript recursive layout system.
The StackLayout defines the horizontal groups of GridLayout Content is placed in the GridLayout that is the immediate child of the StackLayout.
Refer to the ListPicker for more information about using NativeScript ListPicker.
Below is the NativeScript code extract op-confirm.component:
<StackLayout class="mobile-dialog">
<StackLayout class="input-field" horizontalAlignment="stretch">
<GridLayout rows="auto, auto" columns="auto, auto">
<Label row="0" col="0" colspan="2"
class="dialog-label" text="Operation Date / Time :"></Label>
<!--<GridLayout columns="*,*" rows="auto">-->
<DatePicker class="dialog-selector" row="1" col="0" #datePicker
(loaded)="nsConfigureDate(datePicker)"
(dateChange)="nsDateChanged($event)">
</DatePicker>
<TimePicker class="dialog-selector" row="1" col="1" #timePicker
(loaded)="nsConfigureTime(timePicker)"
(timeChange)="nsTimeChanged($event)">
</TimePicker>
</GridLayout>
<!--</GridLayout>-->
<WrapLayout>
<Label class="dialog-label"
text="Request Further Instructions : " textWrap="true"
></Label>
<Switch #furtherInstruct
[checked]="inputData.requestFurtherInstructions"
(checkedChange)="inputData.requestFurtherInstructions = furtherInstruct.checked"
></Switch>
</WrapLayout>
</StackLayout>
<GridLayout columns="*,*" rows="auto">
<Button class="dialog-action-btn" col="0" [text]="inputData.actionName"
(tap)="nsConfirmClicked()"></Button>
<Button class="dialog-action-btn" col="1" text="Cancel"
(tap)="cancelClicked(true)"></Button>
</GridLayout>
</StackLayout>
Information Section¶
The Information Section shows useful plugin related descriptions, information and / or instructions. This can include data from other plugins.
Ideally the Information Section is used as the landing page before presenting the plugin screens. It could be used throughout a plugin if required.

The Information Section should provide the Peek App user any relevant information needed to use a plugin.
Uses:
- Initial landing page
- Sub section landing page (instructions for part of a plugin that may function differently)
Any plugin Screen will be able to use the .peek-information-section
attributes.
Classes¶
The .peek-information-section
class contain the classes specific to a Information
Section.
.peek-information-section {
/*
Contains the Information Section classes
*/
...
.information-section-icon {
/*
Contains the icon attributes unique to the peek-information-section class
*/
...
}
.information-section-title {
/*
Contains the title attributes unique to the peek-information-section class
*/
...
}
}
SCSS Files¶
The Information style classes are found in the _information_section.scss
.
The Information Section HTML layout classes are found in the
_information_section.web.scss
.
The Information Section NativeScript layout classes are found in the
_information_section.ns.scss
.
HTML¶
<div class="peek-information-section">
<div class="information-section-title">Welcome to Field Switching</div>
<img class="information-section-icon"
src="/assets/peek_plugin_pof_field_switching/plugin_icon.png">
<div class="p">Peek Field Switching allows field engineers working on the
electricity network to electronically
<ul>
<li>View switching instructions</li>
<li>Receive instructions from the control room</li>
<li>And field confirm field switching operations</li>
</ul>
</div>
<hr>
<div class="information-section-title">Logged in as {{userDetails.displayName}}
</div>
</div>
NativeScript¶
<StackLayout class="peek-information-section">
<Image class="information-section-icon"
src="~/assets/peek_plugin_pof_field_switching/plugin_icon.png"></Image>
<label class="information-section-title"
text="Welcome to Field Switching"></label>
<label class="p"></label>
<label class="p"
textwrap="true"
text="Peek Field Switching allows field engineers working on the electricity network to electronically:"></label>
<label class="p"></label>
<label class="p" text="* View switching instructions"></label>
<label class="p" text="* Receive instructions from the control room"></label>
<label class="p" text="* And field confirm field switching operations"></label>
<label class="p"></label>
<label class="information-section-title"
text="Logged in as {{userDetails.displayName}}"></label>
</StackLayout>
Details Section¶
The Details Section presents data (text, numbers, images, or other data) of importance to the Peek app user. It involves enumerating important characteristics, emphasizing significant figures and identifying important features of data.

Ideally this section will be configured to present only required data to the user reducing the need for the Peek app user scrolling / filtering through unnecessary data. Prioritises information by providing focus to the values.
Uses:
- Instructions
- Itinerary
- Form Data (displaying not editing)
Any plugin Screen will be able to use the .peek-details-section
attributes.
Classes¶
The .peek-details-section
class contain the classes specific to a Details
Section.
.peek-details-section {
/* Contains the Details Section looks classes */
...
.details-section-title {
/*
Contains the title attributes unique to the Details Section
this text will have the text-muted effect
*/
...
}
.details-section-value {
/*
Contains the value attributes unique to the Details Section
text to have the focus of attention
*/
...
.multiline {
/*
For HTML.
This class is to be used for multi-line support.
Whitespace is preserved by the browser. Text will wrap when
necessary, and on line breaks. Must be in a span
*/
...
}
.editable {
/*
Contains the editable attributes of one line of text unique to the .details-section-value class
*/
...
}
//Select lists
...
}
//Single line inputs
...
}
//Multi line inputs
...
}
.editable-md {
/*
Contains the editable attributes of two lines of text unique to the .details-section-value class
*/
...
}
.editable-lg {
/*
Contains the editable attributes of three lines of text unique to the .details-section-value class
*/
...
}
}
.details-section-btn {
/*
Contains the generic button attributes unique to the .peek-details-section class
*/
...
}
.btn-group {
.details-section-btn {
/*
Contains the generic button attributes inside a .btn-group unique to the .peek-details-section class
*/
...
}
.details-section-btn.active {
/*
Contains the Button attributes for the active button unique to the Details Section
*/
...
}
.details-section-btn-divider-left {
/*
Contains the button divider attributes inside a .btn-group unique to the .peek-details-section class
*/
...
}
}
.details-section-btn-disabled {
/*
Contains the button disabled attributes .peek-details-section class
*/
}
}
SCSS Files¶
The Details style classes are found in the
_details_section.scss
.
The Details Section HTML layout classes are found in the
_details_section.web.scss
.
The Details Section NativeScript layout classes are found in the
_details_section.ns.scss
.
HTML¶
The Details Section uses Bootstraps Grid System.
A Container contains row’s. Row create horizontal groups of columns, rows are made up of 12 columns. Content is placed in columns and only column’s can be immediate children of row’s.
Refer to the Grid System for more information about creating page layouts using the Bootstrap grid system.
Below is the HTML code extract of three rows:
<div class="peek-nav-bar-padding peek-details-section">
<div class="container-fluid">
<!--Displayed form data -->
<div class="row">
<div class="col-xs-6">
<div class="details-section-title">
Control Engineer
</div>
<div class="details-section-value">
{{job.activeControlEngineer}}
</div>
</div>
<div class="col-xs-6">
<div class="details-section-title">
Field State
</div>
<div class="details-section-value">
{{job.fieldStatus.niceName}}
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-xs-12">
<div class="details-section-title">
Name
</div>
<div class="details-section-value">
{{job.jobName}}
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-xs-12">
<div class="details-section-title">Work Description</div>
<div class="details-section-value">
<span class="multiline">{{job.workSummary}}</span>
</div>
</div>
</div>
<hr>
NativeScript¶
The Details Section uses the NativeScript recursive layout system.
The StackLayout defines the horizontal groups of GridLayout Content is placed in the GridLayout that is the immediate child of the StackLayout.
Below is the NativeScript code extract of two rows from the screenshot in the beginning of the Details Section:
<StackLayout class="peek-details-section">
<GridLayout rows="auto, auto" columns="*, *">
<!-- Column 1 -->
<Label row="0" col="0" class="details-section-title"
text="Control Engineer"></Label>
<Label row="1" col="0" class="details-section-value" textWrap="true"
[text]="job.activeControlEngineer"></Label>
<!-- Column 2 -->
<Label row="0" col="1" class="details-section-title"
text="Field State"></Label>
<Label row="1" col="1" class="details-section-value"
[text]="job.fieldStatus.niceName"></Label>
</GridLayout>
<!-- Spacer -->
<Label class="h3" text=""></Label>
<!--<hr>-->
<GridLayout rows="auto, auto" columns="*">
<Label row="0" col="0" class="details-section-title" text="Name"></Label>
<Label row="1" col="0" class="details-section-value" textWrap="true"
[text]="job.jobName"></Label>
</GridLayout>
<!-- Spacer -->
<Label class="h3" text=""></Label>
<!--<hr>-->
Tables Section¶
The Tables Section is best suited when there’s logical relationships among text, numbers, images, or other data exist in two dimensions (vertical and horizontal). These relationships are represented in columns and rows, and the columns and rows must be recognizable in order for the logical relationships to be perceived.
Useful for viewing detailed data and precise values, good for comparing individual values.

The objective of this technique is to present tabular information in a way that preserves relationships within the information.
- Filter or sort data
- Show exact data
- Visualise single or two dimensional data.
Any plugin Screen will be able to use the .peek-tables-section
attributes.
Classes¶
The .peek-tables-section
class contain the classes specific to a Tables
Section.
.peek-tables-section{
/* Contains the Tables Section classes */
...
.table{
/* Contains the table attributes unique to the Tables Section */
...
}
.tr{
/* Contains the table row attributes unique to the .table class */
...
}
.th{
/* Contains the table head cell attributes unique to the .table class */
...
}
.td{
/* Contains the table row cell attributes unique to the .table class */
...
}
.bg-odd {
/*
Applies the table even rows background theme
This class also exists inside the .bg-... classes found in :ref:`other_useful_styles`.
*/
...
}
}
SCSS Files¶
The Tables style classes are found in the
_tables_section.scss
.
The Tables Section HTML layout classes are found in the
_tables_section.web.scss
.
The Tables Section NativeScript layout classes are found in the
_tables_section.ns.scss
.
HTML¶
The Tables Section uses Bootstraps Tables.
Below is the HTML code extract of table header and two rows from Tables Section:
<div class="peek-tables-section">
<table class="table">
<thead>
<tr class="tr">
<th class="th">ID</th>
<th class="th">Name</th>
<th class="th">Scheduled Date</th>
<th class="th">Status</th>
</tr>
</thead>
<tbody>
<tr class="tr"
*ngFor="let item of incidents; odd as odd"
[class.bg-primary]="item.fieldStatus.isActive"
[class.bg-warning]="item.fieldStatus.isDispatched"
[class.bg-success]="item.fieldStatus.isAccepted"
(click)="jobClicked(item)">
<td class="td"
[class.bg-odd]="odd" [class.bg-even]="even">
{{item.jobNumber}}
</td>
<td class="td"
[class.bg-odd]="odd" [class.bg-even]="even">
{{item.jobName}}
</td>
<td class="td"
[class.bg-odd]="odd" [class.bg-even]="even">
{{item.scheduledDate
| date:'HH:mm EE dd-MMM'}}
</td>
<td class="td"
[class.bg-odd]="odd" [class.bg-even]="even">
{{item.fieldStatus.niceName}}
</td>
</tr>
</tbody>
</table>
</div>
NativeScript¶
The Tables Section uses Listview.
Below is the NativeScript code extract of table header and two rows from Tables Section:
<StackLayout class="peek-tables-section">
<StackLayout class="table">
<GridLayout rows="auto" columns="2*, 3*, 2*">
<Label class="th" row="0" col="0" text="Job"></Label>
<Label class="th" row="0" col="1" text="Scheduled"></Label>
<Label class="th" row="0" col="2" text="Status"></Label>
</GridLayout>
<GridLayout rows="*" columns="*">
<ListView [items]="jobs">
<ng-template let-item="item" let-i="index" let-odd="odd" let-even="even">
<StackLayout
[class.bg-primary]="item.fieldStatus.isActive"
[class.bg-info]="item.fieldStatus.isAccepted"
[class.bg-success]="item.fieldStatus.isDispatched"
(tap)="jobClicked(item)">
<GridLayout rows="2*,2*,*" columns="2*, 3*, 2*"
class="tr"
[class.bg-odd]="odd" [class.bg-even]="even">
<!-- Details -->
<Label row="0" col="0"
class="td"
[text]="item.jobNumber"></Label>
<Label row="0" col="1"
class="td"
[text]="item.scheduledDate | date:'HH:mm EE dd-MMM'"></Label>
<Label row="0" col="2"
class="td"
[text]="item.fieldStatus.niceName"></Label>
<!-- Description -->
<Label row="1" col="0" colSpan="3"
class="td"
[text]="item.jobName" textWrap="true"></Label>
</GridLayout>
</StackLayout>
</ng-template>
</ListView>
</GridLayout>
</StackLayout>
</StackLayout>
Note
For the ListView to fill the screen space it is required to be the child of a GridLayout. Star mode for GridLayout row and column means that child ListView will expand to fill the gap left from other elements in the screen.
Other Useful Styles¶
Peek Theme is applied to bootstrap and some newly created classes as not all Peek Plugins require specific style configurations.
Most of the Peek Plugin Screens will use the generic bootstrap classes.
These classes are available throughout Peek and attribute changes are found in
_bootstrap_adjustments.scss
.
Headings¶
Generic Headings 1 through to 6.
.h1 { /* Applies the heading theme */ ... } .h2 { /* Applies the heading theme */ ... } .h3 { /* Applies the heading theme */ ... } .h4 { /* Applies the heading theme */ ... } .h5 { /* Applies the heading theme */ ... } .h6 { /* Applies the heading theme */ ... }
Divider¶
The divider is styled as per the peek theme and can be used throughout the peek app.
The <hr> tag defines a thematic break in the HTML app.
The <StackLayout class=”hr”> element defines the thematic break in the NativeScript app.
.hr { /* Applies the line divider theme */ ... }
Contextual Backgrounds¶
Set the background of an element to any contextual class.
Bootstrap Contextual Backgrounds
NativeScript Contextual Colors
Note
- Only
bg-primary
andbg-danger
exist in the NativeScript - Styling Infrastructure. The other classes need their attributes created from scratch to function in NativeScript.
.bg-primary{
/* Applies the primary background theme */
...
}
.bg-success{
/* Applies the success background theme */
...
}
.bg-info{
/* Applies the info background theme */
...
}
.bg-warning{
/* Applies the warning background theme */
...
}
.bg-danger{
/* Applies the danger background theme */
...
}
Button¶
Generic Peek theme button.
.btn { /* Contains the generic button attributes */ ... }
For using Icons in buttons see Font Awesome Icons in Buttons
Contextual Buttons¶
Modify the button background colour and/or text colour of any button element.
NativeScript Contextual Colors
Note
These classes need their attributes created from scratch to function in NativeScript.
Contextual button classes:
.btn-primary {
/* Applies the primary button theme */
...
}
.btn-success {
/* Applies the success button theme */
...
}
.btn-info {
/* Applies the info button theme */
...
}
.btn-warning {
/* Applies the warning button theme */
...
}
.btn-danger {
/* Applies the danger button theme */
...
}
Font Awesome¶
The Peek Theme uses Font Awesome Icons. This guide explains how to use the font awesome icons for the Peek application in both NativeScript and Web.
Visit the Font Awesome Cheatsheet for icon names. These are reference names to the unicode.
WEB Syntax¶
To create the ‘unlink’ icon used in the title-bar:
This is the syntax used in angular:
<fa *ngIf="!vortexIsOnline"
name="unlink"
tooltip="Connection to server is offline">
</fa>
This is the result in the browser:
<fa name="unlink" tooltip="Connection to server is offline" ng-reflect-name="unlink">
<i aria-hidden="true" class="fa fa-unlink" ng-reflect-klass="fa fa-unlink" ng-reflect-ng-class=""></i>
</fa>
To create the ‘comment-o’ icon as used in the Peek Chat plugin:
This is the syntax used in angular:
<fa class="pl-inbox-icon"
*ngIf="task.isMessage() && !task.isCompleted()"
name="comment-o">
</fa>
This is the result in the browser:
<fa class="pl-inbox-icon" name="comment-o" ng-reflect-name="comment-o">
<i aria-hidden="true" class="fa fa-comment-o" ng-reflect-klass="fa fa-comment-o" ng-reflect-ng-class=""></i>
</fa>
Component Selectors¶
Selectors |
---|
<ng2-fa></ng2-fa> |
<fa></fa> |
<ng4-fa></ng4-fa> |
<ng-fa></ng-fa> |
Component Options¶
name | type | options | optional |
---|---|---|---|
name | String | F-A Icons | No |
size | String | lg, 2x, 3x, 4x, 5x | Yes |
fixed | Boolean | true | false | Yes |
animation | String | spin | pulse | Yes |
rotate | Number | String | 90 | 180 | 270 horizontal | vertical | Yes |
inverse | Boolean | true | false | Yes |
NativeScript Syntax¶
To create the ‘unlink’ icon used in the title-bar:
<Label *ngIf="!vortexIsOnline" class="fa" [text]="'fa-unlink' | fonticon"></Label>
To create the ‘comment-o’ icon as used in the Peek Chat plugin:
<Label row="0" col="0" *ngIf="item.isMessage() && !item.isCompleted()" class="pl-inbox-icon fa h2" [text]="'fa-comment-o' | fonticon"></Label>
Font Awesome Icons in Buttons¶
Web app example:
<button class="btn" (click)="editClicked()" *ngIf="!updateMode">
<fa name="pencil"></fa> Edit
</button>
NativeScript app example:
<Button class="btn fa"
text="{{'fa-pencil' | fonticon }} Edit"
(tap)="editClicked()"
*ngIf="!updateMode">
</Button>
Peek Screen Examples¶
This section describes the styling of the built in peek platform displays.
Title Bar¶

The Title Bar is fixed to the top of the screen.
The buttons remain a fixed size throughout a responsive lifecycle.
Plugins can add buttons after the “Home” button on the left, or on the right of the Title Bar.
The buttons on the right of the Title Bar will range from none to three.
The Title Bar will contain no more than four buttons.
The centralized title remains a single line and truncates a ...
if the line
exceeds the minimum screen width.
The title has a fixed width of 40px.
The Title Bar is unique, therefore the classes used will be specific for the Title Bar.
Classes¶
The .peek-title-bar
class contains the classes specific to the Title Bar.
.peek-title-bar{
/* Contains the Title Bar classes */
...
}
.title-bar-btn{
/* Contains the button attributes unique to the Title Bar */
...
}
.title-bar-title{
/* Contains the title attributes unique to the Title Bar */
...
}
}
.peek-page-contents{
/* Contains the padding to stop the screens being covered by the title-bar */
...
}
SCSS Files¶
The Title Bar style classes are found in the
_title_bar.scss
.
The Title Bar HTML layout classes are found in the
_title_bar.web.scss
.
The Title Bar NativeScript layout classes are found in the
_title_bar.ns.scss
.
HTML¶

<div class="peek-title-bar"
[class.bg-danger]="!vortexIsOnline">
<div class="btn-group pull-left"
role="group">
<button class="title-bar-btn"
[routerLink]="['/']">
Home
</button>
</div>
<div class="title-bar-title pull-left">
{{title}}
</div>
<div class="btn-group pull-right"
role="group">
<button class="title-bar-btn"
*ngFor="let link of rightLinks"
[routerLink]="[link.resourcePath]">
{{linkTitle(link)}}
</button>
</div>
</div>
NativeScript¶

<GridLayout class="peek-title-bar"
[class.bg-danger]="!vortexIsOnline"
rows="auto" columns="auto, *, auto">
<Button class="btn" col="0" row="0"
text="Home"
[nsRouterLink]="['/']">
</Button>
<Button class="btn"
*ngFor="let link of leftLinks"
col="0" row="0"
[text]="linkTitle(link)"
[nsRouterLink]="[link.resourcePath]">
</Button>
<Label class="title"
col="1" row="0"
[text]="title">
</Label>
<Button class="btn"
*ngFor="let link of rightLinks"
col="2" row="0"
[text]="linkTitle(link)"
[nsRouterLink]="[link.resourcePath]">
</Button>
</GridLayout>
Home Screen¶
The Home Screen is a unique screen in Peek that displays a link to available plugins that have front-ends.

Classes¶
The .peek-home-screen
class will contain the classes specific to the Home Screen.
.peek-home-screen{
/*
Contains the Home Screen classes
*/
...
.home-screen-icon{
/*
Contains the Button attributes unique to the Home Screen
Buttons responsively wrap
*/
...
}
.home-screen-image{
/*
Contains the Image attributes unique to the Home Screen
Strictly uses images
*/
...
}
.home-screen-title{
/* Contains the Button Title attributes unique to the Home Screen */
...
}
}
.peek-home-screen-background{
/*
Contains the Background attributes
Home Screen background is unique and different to other screens
Cannot use the body tag
*/
...
}
Background Image¶

SCSS Files¶
The Home Screen style classes are found in the
_home_screen.scss
.
The Home Screen HTML layout classes are found in the
_home_screen.web.scss
.
The Home Screen NativeScript layout classes are found in the
_home_screen.ns.scss
.
HTML¶
<div class="peek-home-screen">
<div class="container-fluid">
<div class="row">
<div class="title h3"
*ngIf="!appDetails.length">
No Plugins Installed
</div>
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2"
*ngFor="let app of appDetails">
<a class="home-screen-icon"
[routerLink]="[app.resourcePath]">
<img class="home-screen-image"
[src]="[app.pluginIconPath]">
<div class="home-screen-title">
{{app.title}}
</div>
</a>
</div>
</div>
</div>
</div>
NativeScript¶
<ScrollView class="peek-home-screen">
<WrapLayout>
<Label class="message"
*ngIf="!appDetails.length"
text="No Plugins Installed">
</Label>
<GridLayout class="icon"
*ngFor="let app of appDetails"
rows="*,auto" columns="*"
[nsRouterLink]="[app.resourcePath]">
<Image class="image"
row="0" col="0"
src="~{{app.pluginIconPath}}">
</Image>
<Label class="title"
row="1" col="0"
[text]="app.title">
</Label>
</GridLayout>
</WrapLayout>
</ScrollView>
Plugin Screen Examples¶
This section describes the styling of the public plugin displays.
Peek Plugin Inbox Style Example¶
Peek Plugin Inbox displays a list of unacknowledged items issued to the logged in user.
Inbox:

Peek Plugin Activity display a log of items issued to the logged in user.
Activity:

If a device user has a role of performing tasks, which are managed by Peek, Peek will issue items to the user via this plugin.
- The active task plugin receives items from other plugins
- The new items are persisted within the Peek Storage database
- Delivery to the users device is ensured
- Once the item is on the user device, it may be :
- Selected from the ‘Inbox’ tab, this will route to the plugin that issued the item.
- Actioned, actions will be delivered back to the initiating plugin back on the peek server.
- All items and the state of items are viewable from an administrators page.
- The Inbox Screen is accessed by the ‘Tasks’ button in the Title Bar.
- The ‘Tasks’ button also shows the number of tasks.
Examples:
- The following are use case examples of what can be done with the Active Task plugin.
- Notifications that arrive as read, and require no action. This can create an audit trail for the user.
- Notification that are unread until the user selects them. Selecting them will navigate to another plugin, the initiating plugin will be notified and it can then mark the task as read or delete it.
- Actions that are required. Actions can be created by initiating plugins, and stay “unread / unactioned” until the user completes what ever action is required within another plugin. The initiating plugin then removes or marks the action as completed.
- Question. A task can be created with multiple actions, upon selecting an action, the initiating plugin will be notified, it can then remove the task.
Components¶
The plugin-active-task-client component builds the navigation tabs. The tabs route to the components plugin-active-task-task-list and plugin-active-task-activity-list.
The plugin-active-task-task-list component builds rows of outstanding tasks from plugins configured to issue tasks.
The plugin-active-task-activity-list component builds rows of the activity from the plugins configured to show activity.
Classes¶
The .plugin-inbox
class contains the classes specific to the
Peek Plugin Active Task.
.pl-inbox,
.pl-inboxActivity,
.pl-inboxTasks {
.pl-inbox {
/*
Contains the style and classes for the inbox container
*/
...
.pl-inbox-item {
/*
Contains the style and classes for the
*/
...
.pl-inbox-icon {
/*
Contains the icon attributes unique to the .pl-inbox-item class
*/
...
}
.pl-inbox-info {
/*
Contains the info attributes unique to the .pl-inbox-item class
*/
...
.pl-inbox-title {
/*
Contains the title text attributes unique to the .pl-inbox-info class
*/
...
}
.pl-inbox-description {
/*
Contains the description text attributes unique to the .pl-inbox-info class
*/
...
}
.pl-inbox-date-time {
/*
Contains the date and time attributes unique to the .pl-inbox-info class
*/
...
}
}
}
.pl-inbox-read-more {
/*
Contains the read more link attributes unique to the .plugin-inbox class
*/
...
}
}
}
}
SCSS Files¶
The Inbox style classes are found in the
_plugin_inbox.scss
.
The Inbox HTML layout classes are found in the
_plugin_inbox.web.scss
.
The Inbox NativeScript layout classes are found in the
_plugin_inbox.ns.scss
.
HTML¶
plugin-active-task-client¶
<div class="pl-inbox">
<ul class="nav nav-tabs"
role="tablist">
<li class="active"
role="presentation">
<a aria-controls="home"
data-toggle="tab"
href="http://localhost:4200/#inboxTasks"
role="tab">
Inbox
</a>
</li>
<li role="presentation">
<a aria-controls="profile"
data-toggle="tab"
href="http://localhost:4200/#inboxActivity"
role="tab">
Activity
</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active"
role="tabpanel"
id="inboxTasks">
<plugin-active-task-task-list></plugin-active-task-task-list>
</div>
<div class="tab-pane"
role="tabpanel"
id="inboxActivity">
<plugin-active-task-activity-list></plugin-active-task-activity-list>
</div>
</div>
</div>
plugin-active-task-task-list¶
<div class="pl-inbox-tasks">
<div class="h3"
*ngIf="tasks.length === 0">
The inbox is empty.
</div>
<div class="pl-inbox-item bg-success"
*ngFor="let task of tasks"
(click)="taskClicked(task)">
<div class="pl-inbox-icon">
<i class="fa fa-comment"
aria-hidden="true"></i>
</div>
<div class="pl-inbox-info">
<div class="pl-inbox-title">
{{task.title}}
</div>
<div class="pl-inbox-description">
{{task.description}}
</div>
<div class="pl-inbox-date-time">
{{timePast(task)}} ago, {{dateTime(task)}}
</div>
</div>
<div class="pl-inbox-read-more">
<i class="fa fa-chevron-right"
aria-hidden="true"></i>
</div>
</div>
</div>
plugin-active-task-activity-list¶
<div class="pl-inbox-activity">
<div class="message"
*ngIf="activities.length === 0">
There is no recent activity.
</div>
<div class="pl-inbox-item"
*ngFor="let activity of activities"
(click)="activityClicked(activity)">
<div class="pl-inbox-info">
<div class="pl-inbox-title">
{{activity.title}}
</div>
<div class="pl-inbox-description">
{{activity.description}}
</div>
<div class="pl-inbox-date-time">
{{timePast(activity)}} ago, {{dateTime(activity)}}
</div>
</div>
<div class="pl-inbox-read-more">
<i class="fa fa-chevron-right"
aria-hidden="true"></i>
</div>
</div>
</div>
Peek Plugin Chat Style Example¶
Peek Plugin Chat displays active chat sessions and their messages.
- The active chat sessions should indicate if there are unread messages.
- The message lists will display sent messages on the right and received messages on the left.
- Background contextual colours will distinguish a successfully sent message or an emergency “SOS” message received.
Chats:

Messages:

Originally this plugin was designed to send messages between the power grid control room and field engineers.
Simple communications with external systems.
Components¶
The chat-list component displays a list of active chat sessions that route to the msg-list component. The “New Chat” button in the Navigation Bar routes to the new-chat component.
The new-chat component creates new chat sessions. The user builds a list of one or more users for a new chat session.
The msg-list component shows the list of sent and received messages for the selected chat session. The “angle-left” button in the Navigation Bar routes to the chat-list component. The user has the option to compose a new message to send of send an “SOS” message.
Classes¶
The .plugin-chat-list
class contain the classes specific to the
chat-list component.
The .plugin-chat-messages
class contains the classes specific to the msg-list
component.
The new-chat component uses generic classes, see Other Useful Styles.
.plugin-chat-list {
/*
Contains the chat-list component classes
*/
...
.chat-list-messages {
/*
Contains the Messages attributes unique to the Chat List
*/
...
.chat-list-icon {
/*
Contains the icon attributes unique to the message class
The icon is used to indicate unread messages
*/
...
}
.chat-list-title {
/*
Contains the topic text attributes unique to the message class
*/
...
}
}
}
.plugin-chat-messages {
/*
Contains the msg-list component classes
*/
...
.chat-messages-list {
/*
Attributes for the container of messages, unique to the Chat
Messages.
Scrolls through the messages with most recent at the bottom.
*/
...
.chat-messages-sent {
/*
Contains the sent message attributes unique to the message-list
class.
Container is right aligned with background colour different to the
received class.
bg-success class applied for a successfully sent message.
*/
...
}
.chat-messages-received {
/*
Contains the received text attributes unique to the message-list
class.
Container is right aligned with background colour different to the
sent class.
bg-warning class applied for an emergency priority message.
*/
...
}
.chat-messages-details {
/*
Contains the message details text attributes unique to the
message-list class.
The message details should not be the focus of attention (text-muted)
*/
...
}
.chat-messages-emergency {
/*
Contains the emergency priority message text attributes unique to the
message-list class
*/
...
}
.chat-messages-normal {
/*
Contains the normal priority message text attributes unique to the
message-list class
*/
...
}
}
.chat-messages-compose {
/*
Contains the compose message area attributes unique to the
chat messages.
Fixed to the bottom of the screen.
*/
...
.chat-messages-new-text {
/*
Contains the new message text attributes unique to the
chat-messages-compose class.
*/
...
}
}
}
.chat-messages-btn-group {
...
.chat-messages-btn {
/*
Contains the button attributes unique to the
chat-messages-compose class.
*/
...
}
}
SCSS Files¶
The Inbox style classes are found in the _plugin_chat.scss
.
The Inbox HTML layout classes are found in the
_plugin_chat.web.scss
.
The Inbox NativeScript layout classes are found in the
_plugin_chat.ns.scss
.
HTML¶
chat-list component¶
<!--TRANSITION WITH REASON DIALOG -->
<pl-chat-new-chat
*ngIf="isNewChatDialogShown()"
(create)="dialogConfirmed($event)"
(cancel)="dialogCanceled()"
[data]="newChatDialogData">
</pl-chat-new-chat>
<div class="peek-nav-section">
<!--
The following 'div' groups button to the left of the Nav Bar.
Can contain one to many buttons
-->
<div class="btn-group pull-left"
*ngIf="!isNewChatDialogShown()"
role="group">
<button class="btn"
role="group"
(click)="newChatClicked()">
New Chat
</button>
</div>
</div>
<div class="plugin-chat-list">
<!-- Use the template tag syntax, as this works with nativescript too -->
<ng-template ngFor let-chat [ngForOf]="chats" let-i="index">
<div class="chat-list-messages" (click)="chatClicked(chat)">
<!-- Unread indicator -->
<fa class="chat-list-icon" name="fw" *ngIf="isChatRead(chat)"></fa>
<fa class="chat-list-icon" name="comment-o" *ngIf="!isChatRead(chat)"></fa>
<!-- Other Users -->
<div class="chat-list-title" *ngFor="let user of otherChatUsers(chat)">
{{userDisplayName(user)}} ({{user.userId}})
</div>
</div>
</ng-template>
</div>
new-chat component¶
<div [@dialogAnimation]="dialogAnimationState"
(@dialogAnimation.done)="animationDone($event)">
<div class="h2">
Start a chat wth :
</div>
<div class="p"
*ngIf="!createButtonEnabled()">
No users selected
</div>
<ul>
<li *ngFor="let u of data.users">
{{u.displayName}}
</li>
</ul>
<div class="form-group">
<label class="h4"
for="userIdField">
Add User:
</label>
<select class="form-control"
id="userIdField"
name="userId"
[(ngModel)]="selectedUserIndex">
<option [value]="i" *ngFor="let i = index; let item of usersStrList">
{{item}}
</option>
</select>
</div>
<!-- BEGIN HANDBACK DIALOG -->
<div>
<Button class="btn" (click)="addUserClicked()"
[disabled]="!newButtonEnabled()">
Add User
</Button>
<Button class="btn" (click)="confirmClicked(false)"
[disabled]="!createButtonEnabled()">
Create Chat
</Button>
<Button class="btn" (click)="cancelClicked(false)">
Cancel
</Button>
</div>
</div>
msg-list component¶
<div class="peek-nav-section">
<div class="btn-group pull-left"
role="group">
<button class="btn"
role="group"
(click)="navToChatsClicked()">
<fa name="angle-left"></fa>
</button>
</div>
</div>
<div class="plugin-chat-messages"
#messageListRef>
<!-- No Messages -->
<div class="h3"
*ngIf="!haveMessages()">
No messages
</div>
<div class="chat-messages-list">
<div *ngFor="let i=index; let msg of messages()">
<!-- Unread marker -->
<hr *ngIf="isFirstUnreadMesage(i)"/>
<!-- From and Date -->
<div [class.sent]="isMessageFromThisUser(msg)"
[class.received]="!isMessageFromThisUser(msg)">
<div class="chat-messages-details"
*ngIf="!isMessageFromThisUser(msg)">
From {{userDisplayName(msg)}} ({{msg.fromUserId}}), {{timePast(msg)}}
ago
</div>
<div class="chat-messages-details"
*ngIf="isMessageFromThisUser(msg)">
{{timePast(msg)}} ago
</div>
<div [class.chat-messages-sent]="isMessageFromThisUser(msg)"
[class.chat-messages-received]="!isMessageFromThisUser(msg)"
[class.bg-success]="isNormalPriority(msg)"
[class.bg-danger]="isEmergencyPriority(msg)">
<div class="chat-messages-normal"
*ngIf="isNormalPriority(msg)">
{{msg.message}}
</div>
<div class="chat-messages-emergency"
*ngIf="isEmergencyPriority(msg)">
{{msg.message}}
</div>
</div>
</div>
</div>
</div>
<div class="chat-messages-compose">
<textarea class="form-control"
[(ngModel)]="newMessageText">
</textarea>
<button class="btn" type="button"
[disabled]="!sendEnabled()"
(click)="sendMsgClicked()">
Send
</button>
<button class="btn" type="button"
(click)="sendSosClicked()">
SOS
</button>
</div>
</div>