Theming the Modern
Toolkit
Phil Guerrant
Senior Software Engineer, Sencha
Getting Started
Choosing Between App and Theme
• Both can contain styling
• Theme contains shared styling
• Application contains its own styling
Generating an Application
sencha -sdk path/to/sdk generate app -modern ThemeDemo theme-demo
Application Structure
Set theme variables in sass/var/all.scss
$base-color: green;
$panel-body-font-size: 15px;
Theme Variables
http://docs.sencha.com
Application Structure
• Rule generating code goes in sass/src/
• Mixin calls
• CSS rules
• scss files are auto-included based on class-
path of classes in your application
• Ext class - ThemeDemo.view.Main
• Includes sass/src/view/Main.scss
Rapid Development Using Fashion
sencha app watch --fashion
[INF] Server started at port : 1841
[INF] Application available at http://localhost:1841
Generating a Theme Package
Allows styling to be shared between applications
# your application directory
cd theme-demo
sencha generate package --type theme --extend theme-triton --name my-theme
Generating a Theme Package
Theme Package Structure
• scss files are auto-included based on class-
path of framework classes
• e.g. Ext.field.Text
Theme Hierarchy
Classic Toolkit Modern Toolkit
base
neutral
classic
gray
neptune
crisp
crisp-touch
neptune-touch
triton
base
neptune
triton
ios
material
Variables
Variables
All theme variables must be dynamic
• dynamic() must be used for any newly declared variables.
• When overriding framework variables dynamic() is not required
• When in doubt it is safe to always use dynamic()
Dynamic Variables
Last assignment wins, and is valid throughout entire scope
$base-color: dynamic(blue); /* CSS Output */
.foo {
background: red;
}
$base-color: dynamic(red);
.foo {
background: $base-color;
}
Component Variables
Begin with xtype, end with CSS property name
$button-font-size
$tab-background-color
$listitem-border-width
Element Variables
Element name after xtype but before CSS property name
$button-badge-color
$textfield-input-padding
$listitem-disclosure-margin
State Variables
State name after the thing it describes (xtype or element)
$button-pressed-color
$listitem-selected-border-color
$listitem-disclosure-pressed-background-color
State Names
• pressed
• hovered
• selected
• focused
• disabled
Style Inheritance
Style Inheritance
Components should inherit styles defined by their
superclasses
Style Inheritance
classCls – the inheritable
baseCls
Ext.define('Child', {
extend: 'Parent',
classCls: 'x-child'
});
Style Inheritance
classCls allows styles to cascade through the Component
hierarchyExt.define('Parent', {
extend: 'Ext.Component',
classCls: 'x-parent'
});
<div class="x-component
x-parent
x-child">
</div>
Ext.create('Child');
Ext.define('Child', {
extend: 'Parent',
classCls: 'x-child',
classClsRoot: true
});
Style Inheritance – Opting Out
classClsRoot defines inheritance boundary
Ext.define('Parent', {
extend: 'Ext.Component',
classCls: 'x-parent'
});
<div class="x-child"></div>
Ext.create('Child');
Component UIs
Component UIs
One component, multiple presentations
Component UIs
One component, multiple presentations
Ext.create({
xtype: 'button',
ui: 'action'
});
<div class="x-button
x-button-action">
</div>
Ext.define('Child', {
extend: 'Parent',
classCls: 'x-child'
});
UI Inheritance
UI name is appended to each classCls in the hierarchy
Ext.define('Parent', {
extend: 'Ext.Component',
classCls: 'x-parent'
});
<div class="x-component
x-parent
x-child
x-component-foo
x-parent-foo
x-child-foo">
</div>
Ext.create('Child', {
ui: 'foo'
});
UIs are Composable
Use one or many, your choice
Ext.create({
xtype: 'button',
ui: 'action round'
});
<div class="x-button
x-button-action
x-button-round">
</div>
UI Mixins
The structure of a UI mixin
// theme-neptune/sass/var/Button.scss
@mixin button-ui(
$ui: null,
$color: null,
$border-color: null
) {
$ui-suffix: ui-suffix($ui); // -#{$ui} OR empty string
.x-button#{$ui-suffix} { // .x-button[-ui]
color: $color;
border-color: $border-color;
}
}
UI Mixins
The magic of null
$color1: null;
$color2: red;
/* CSS Output */
.button {
border-color: red;
}.button {
color: $color1;
border-color: $color2;
}
UI Mixins
The magic of null
@include button-ui(
$ui: foo
);
/* CSS Output */
Empty!
UI Mixins
The magic of null
@include button-ui(
$ui: foo,
$color: green
);
/* CSS Output */
.x-button {
color: green;
}
UIs Mixins
The default UI
// theme-neptune/sass/var/Button.scss
$button-color: #606060;
$button-border-color: #e4e4e4;
. . .
// theme-neptune/sass/src/Button.scss
@include button-ui(
$color: $button-color,
$border-color: $button-border-color
. . .
);
No $ui parameter
($ui == null)
UIs Mixins
The default UI
/* CSS Output */
.x-button {
. . .
}
.x-button.x-pressed {
. . .
}
.x-button .x-icon-el {
. . .
}
UIs Mixins
Additional UIs
/* CSS Output */
.x-button-alert {
. . .
}
.x-button-alert.x-pressed {
. . .
}
.x-button-alert .x-icon-el {
. . .
}
Theming Lists and Grids
Can Grids have UIs?
Column Header Check Column Header
Group
Header
Row
Check
Cell
Expander
Cell Paging
Toolbar
Text
Cell
Row Numberer
Cell
Number
Cell
Widget
Cell
Date
Cell
Grids are Lists
Use itemConfig to configure the UI of list items
Ext.create({
xtype: 'list',
itemConfig: {
ui: 'contact'
}
});
@include listitem-ui(
$ui: contact,
$color: #fff,
$background-color: #444,
$border-color: #777
);
Before After
Row
Grids are Lists
Use itemConfig to configure the UI of grid rows
Ext.create({
xtype: 'grid',
itemConfig: {
ui: 'contact'
}
});
@include gridrow-ui(
$ui: contact,
$background-color: #888
);
Group
Header
Grids Group Row UI
Use the “header” config of the grid row
Ext.create({
xtype: 'grid',
itemConfig: {
header: {
ui: 'contact'
}
}
});
@include rowheader-ui(
$ui: contact,
$background-color: #ccc
);
Column Header
Grid Column Header UI
Set the UI on the column config
Ext.create({
xtype: 'grid',
columns: [{
text: 'Name',
ui: 'contact'
}]
});
@include gridcolumn-ui(
$ui: contact,
$color: white,
$background-color: gray
);
Text
Cell
Grid Cell UI
Use the “cell” config of the column
Ext.create({
xtype: 'grid',
columns: [{
text: 'Name',
cell: {
ui: 'contact'
}
}]
});
@include gridcell-ui(
$ui: contact,
$font-weight: bold
);
Paging
Toolbar
Grid Paging Toolbar UI
Use the “toolbar” config of the Paging Toolbar plugin
Ext.create({
xtype: 'grid',
plugins: [{
type: 'pagingtoolbar',
toolbar: {
ui: 'contact'
}
}]
});
@include pagingtoolbar-ui(
$ui: contact,
$padding: 30px,
$background-color: #ddd
);
SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant
SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant
Compound Components are the Sum of Their Parts
This pattern is repeated throughout the framework
Other Examples:
• Slider/Thumb
• TextField/Trigger
Exceptions:
Panel/Panel Header/Tools (on roadmap for improvement)
Big Mode
Big Mode
Larger sizing and spacing for touch screens
• Classic toolkit used separate themes (neptune vs. neptune-touch)
• Modern toolkit – single theme
Big Mode
Larger sizing and spacing for touch screens
<html class="x-big">
Big Mode
Choosing between big and normal modes
// theme-neptune/overrides/init.js
Ext.theme.getDocCls = function() {
return Ext.platformTags.desktop ? '' : 'x-big';
};
Big Mode
Opting Out
$enable-big: false;
Big Mode
Implementing big mode rules
// UI mixin code
.x-button {
padding: $padding;
@if $enable-big {
.x-big & {
padding: $padding-big;
}
}
}
/* CSS Output */
.x-button {
padding: 5px;
}
.x-big .x-button {
padding: 10px;
}
Breaking the Rules
Before Breaking the Rules
What do I do when the theming API does not meet my needs?
1. Let us know on the forums – https://sencha.com/forum
2. Add your own styling using the same techniques that the framework uses.
classCls
Always matches the xtype and goes on the main element
Ext.define('Ext.grid.column.Column', {
xtype: 'gridcolumn',
classCls: 'x-gridcolumn'
});
<div class="x-gridcolumn
x-gridcolumn-contact">
</div>
// instance config
{
ui: 'contact'
}
State and Configuration CSS Classes
Always on the main element
Ext.define('Ext.grid.column.Column', {
xtype: 'gridcolumn',
classCls: 'x-gridcolumn',
config: {
align: 'left'
}
});
<div class="x-gridcolumn
x-sorted
x-align-left">
</div>
State and Configuration CSS Classes
Always chain to the classCls
.x-align-left .x-title-el
.x-gridcolumn.x-sorted .x-sorted
.x-gridcolumn-contact.x-align-left
Reference Elements
Should be named x-[name]-el
Ext.define('Ext.grid.column.Column', {
template: [{
reference: 'titleElement',
className: 'x-title-el'
}]
});
Reference Elements
Prefer descendant selectors over child selectors
.x-gridcolumn .x-title-el {
. . .
}
.x-gridcolumn > .x-title-el {
. . .
}
Reference Elements
Prefer descendant selectors over child selectors
• Except when container nesting is
possible
• Include xtype/ui info in class name
.x-panel-inner-foo {
. . .
}
When in Doubt
Copy the selectors used by the framework
Material and iOS
iOS Material
Material Dark
iOS Theme
• Based on Triton
• Follows the latest iOS look and feel
• Will evolve with iOS
• Customizable – all framework theme variables and mixins are available
Material Theme
• Based on Neptune
• Follows the material design guidelines https://material.google.com
• Material Color Palette
• Supports CSS Variables
Material Color Palette
Deep Purple
#673AB7
Red
#F44336
Material Color Palette
https://material.google.com/style/color.html
Light Blue
#03A9F4
Green
#4CAF50
Yellow
#FFEB3B
Deep Orange
#FF5722
Blue Grey
#607D8B
Pink
#E91E63
Purple
#9C27B0
Indigo
#3F51B5
Blue
#2196F3
Cyan
#00BCD4
Teal
#009688
Light Green
#8BC34A
Lime
#CDDC39
Amber
#FFC107
Orange
#FF9800
Brown
#795548
Grey
#9E9E9E
Black
#000000
White
#FFFFFF
$base-color-name: indigo;
$accent-color-name: yellow;
$dark-mode: true;
Configuring the Material Theme
• Configure base color, accent color,
and dark mode
• All derived colors, spacing and sizing
are handled automatically
• Can be further customized using
theme variables and mixins but this is
outside the scope of material design.
Selecting Themes by Platform
Step 1: Setup multiple build profiles in app.json
{
"builds": {
"material": {
"theme": "theme-material"
},
"ios": {
"theme": "theme-ios"
},
"triton": {
"theme": "theme-triton"
}
}
}
Selecting Themes by Platform
Step 2: Setup output directories in app.json (same as universal
app){
"output": {
"base": "${workspace.build.dir}/${build.environment}/${app.name}",
"page": "index.html",
"manifest": "${build.id}.json",
"js": "${build.id}/app.js",
"appCache": {
"enable": false
},
"resources": {
"path": "${build.id}/resources",
"shared": "resources"
}
}
}
Selecting Themes by Platform
Step 3: Use Ext.beforeLoad to select a profile
<script type="text/javascript">
var Ext = Ext || {}; // Ext namespace won't be defined yet...
Ext.beforeLoad = function (tags) {
var profile;
if (tags.ios) {
profile = 'ios';
} else if (tags.android) {
profile = 'material';
} else {
profile = 'triton';
}
Ext.manifest = profile;
};
</script>
Demo
Please Take the Survey in the Mobile App
• Navigate to this session in the mobile app
• Click on “Evaluate Session”
• Respondents will be entered into a drawing to win one of five $50 Amazon gift cards
SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant

More Related Content

PPT
SenchaCon 2016: Add Magic to Your Ext JS Apps with D3 Visualizations - Vitaly...
PPTX
SenchaCon 2016: Keynote Presentation - Art Landro, Gautam Agrawal, Mark Brocato
PPTX
Slick: Bringing Scala’s Powerful Features to Your Database Access
PPTX
Moving from JFreeChart to JavaFX with JavaFX Chart Extensions
PDF
Brief introduction of Slick
PDF
Lobos Introduction
PDF
Drupal 8: Fields reborn
PDF
Drupal & javascript
SenchaCon 2016: Add Magic to Your Ext JS Apps with D3 Visualizations - Vitaly...
SenchaCon 2016: Keynote Presentation - Art Landro, Gautam Agrawal, Mark Brocato
Slick: Bringing Scala’s Powerful Features to Your Database Access
Moving from JFreeChart to JavaFX with JavaFX Chart Extensions
Brief introduction of Slick
Lobos Introduction
Drupal 8: Fields reborn
Drupal & javascript

What's hot (20)

PDF
Drupal 8 Sample Module
PPTX
Django - sql alchemy - jquery
PDF
Doctrine 2
PPTX
Mule esb – connecting to ms sql db
PDF
Database madness with_mongoengine_and_sql_alchemy
PPT
Cleaner APIs, Cleaner UIs with Visage (33rd Degrees)
PDF
Practical Experience Building JavaFX Rich Clients
PDF
Hidden Gems in Swift
PDF
Drupal 8: Routing & More
ODP
An introduction to SQLAlchemy
PPT
J query
PDF
Upgrade your javascript to drupal 8
PDF
Introduction to SQLAlchemy ORM
PPTX
J query1
PDF
Introduction to SQLAlchemy and Alembic Migrations
PPTX
Omnisearch in AEM 6.2 - Search All the Things
PDF
Http4s, Doobie and Circe: The Functional Web Stack
PDF
Error based blind sqli
PDF
Drupal 8: Forms
PDF
Alfredo-PUMEX
Drupal 8 Sample Module
Django - sql alchemy - jquery
Doctrine 2
Mule esb – connecting to ms sql db
Database madness with_mongoengine_and_sql_alchemy
Cleaner APIs, Cleaner UIs with Visage (33rd Degrees)
Practical Experience Building JavaFX Rich Clients
Hidden Gems in Swift
Drupal 8: Routing & More
An introduction to SQLAlchemy
J query
Upgrade your javascript to drupal 8
Introduction to SQLAlchemy ORM
J query1
Introduction to SQLAlchemy and Alembic Migrations
Omnisearch in AEM 6.2 - Search All the Things
Http4s, Doobie and Circe: The Functional Web Stack
Error based blind sqli
Drupal 8: Forms
Alfredo-PUMEX
Ad

Viewers also liked (20)

PPTX
SenchaCon 2016: The Modern Toolchain - Ross Gerbasi
PPTX
SenchaCon 2016: Building Enterprise Ext JS Apps with Mavenized Sencha Cmd - F...
PPTX
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
PPTX
SenchaCon 2016: Being Productive with the New Sencha Fiddle - Mitchell Simoens
PPTX
SenchaCon 2016: A Data-Driven Application for the Embedded World - Jean-Phili...
PPTX
SenchaCon 2016: Advanced Techniques for Buidling Ext JS Apps with Electron - ...
PPTX
SenchaCon 2016: Upgrading an Ext JS 4.x Application to Ext JS 6.x - Mark Linc...
PPTX
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
PPTX
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
PPTX
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
PPTX
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
PPTX
SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov
PPTX
SenchaCon 2016: How Sencha Test Helps Automate Functional Testing of Ext JS M...
PPTX
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
PPTX
SenchaCon 2016: Handle Real-World Data with Confidence - Fredric Berling
PPTX
SenchaCon 2016: Using Ext JS to Turn Big Data into Intelligence - Olga Petrov...
PDF
Maths assignment
PPTX
SenchaCon 2016: Design Methods for Better Product Development - Andrew Hemans
PPTX
SenchaCon 2016: The Once and Future Grid - Nige White
PPTX
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
SenchaCon 2016: The Modern Toolchain - Ross Gerbasi
SenchaCon 2016: Building Enterprise Ext JS Apps with Mavenized Sencha Cmd - F...
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
SenchaCon 2016: Being Productive with the New Sencha Fiddle - Mitchell Simoens
SenchaCon 2016: A Data-Driven Application for the Embedded World - Jean-Phili...
SenchaCon 2016: Advanced Techniques for Buidling Ext JS Apps with Electron - ...
SenchaCon 2016: Upgrading an Ext JS 4.x Application to Ext JS 6.x - Mark Linc...
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov
SenchaCon 2016: How Sencha Test Helps Automate Functional Testing of Ext JS M...
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
SenchaCon 2016: Handle Real-World Data with Confidence - Fredric Berling
SenchaCon 2016: Using Ext JS to Turn Big Data into Intelligence - Olga Petrov...
Maths assignment
SenchaCon 2016: Design Methods for Better Product Development - Andrew Hemans
SenchaCon 2016: The Once and Future Grid - Nige White
SenchaCon 2016: Learn the Top 10 Best ES2015 Features - Lee Boonstra
Ad

Similar to SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant (20)

PPT
J query b_dotnet_ug_meet_12_may_2012
ZIP
Django at the Disco
ZIP
Django at the Disco
ZIP
Django at the Disco
ZIP
Django at the Disco
PDF
taking-flight-tailwind-css for beginners.pdf
PDF
Pfnp slides
PDF
Django at the Disco
PDF
Sencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
PDF
Django Rest Framework and React and Redux, Oh My!
PDF
Making the most of New CSS Layout
PPTX
Building Potent WordPress Websites
PDF
SMACSS Workshop
PPTX
Build a better UI component library with Styled System
PDF
Styling Components with JavaScript: MelbCSS Edition
PPTX
Android Custom views
PDF
The Creative New World of CSS
PDF
CSMess to OOCSS: Refactoring CSS with Object Oriented Design
PPT
An Introduction to CSS
PDF
Refresh Tallahassee: The RE/MAX Front End Story
J query b_dotnet_ug_meet_12_may_2012
Django at the Disco
Django at the Disco
Django at the Disco
Django at the Disco
taking-flight-tailwind-css for beginners.pdf
Pfnp slides
Django at the Disco
Sencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Django Rest Framework and React and Redux, Oh My!
Making the most of New CSS Layout
Building Potent WordPress Websites
SMACSS Workshop
Build a better UI component library with Styled System
Styling Components with JavaScript: MelbCSS Edition
Android Custom views
The Creative New World of CSS
CSMess to OOCSS: Refactoring CSS with Object Oriented Design
An Introduction to CSS
Refresh Tallahassee: The RE/MAX Front End Story

More from Sencha (20)

PDF
Breathe New Life into Your Existing JavaScript Applications with Web Components
PDF
Ext JS 6.6 Highlights
PDF
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
PDF
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
PDF
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
PDF
Sencha Roadshow 2017: What's New in Sencha Test
PDF
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
PDF
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
PDF
Sencha Roadshow 2017: Mobile First or Desktop First
PDF
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
PDF
Leveraging React and GraphQL to Create a Performant, Scalable Data Grid
PDF
Learn Key Insights from The State of Web Application Testing Research Report
PPTX
Introducing ExtReact: Adding Powerful Sencha Components to React Apps
PPT
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
PPT
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
PPTX
Ext JS Architecture Best Practices - Mitchell Simeons
PPTX
Building Ext JS Using HATEOAS - Jeff Stano
PPTX
SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package...
PPTX
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
PPTX
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
Breathe New Life into Your Existing JavaScript Applications with Web Components
Ext JS 6.6 Highlights
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
Sencha Roadshow 2017: What's New in Sencha Test
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
Sencha Roadshow 2017: Mobile First or Desktop First
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
Leveraging React and GraphQL to Create a Performant, Scalable Data Grid
Learn Key Insights from The State of Web Application Testing Research Report
Introducing ExtReact: Adding Powerful Sencha Components to React Apps
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
Ext JS Architecture Best Practices - Mitchell Simeons
Building Ext JS Using HATEOAS - Jeff Stano
SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package...
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...

Recently uploaded (20)

PDF
Transform-Your-Factory-with-AI-Driven-Quality-Engineering.pdf
PDF
Statistics on Ai - sourced from AIPRM.pdf
PDF
INTERSPEECH 2025 「Recent Advances and Future Directions in Voice Conversion」
PPTX
Microsoft User Copilot Training Slide Deck
PDF
Dell Pro Micro: Speed customer interactions, patient processing, and learning...
PPTX
Custom Battery Pack Design Considerations for Performance and Safety
PDF
Early detection and classification of bone marrow changes in lumbar vertebrae...
PPTX
AI-driven Assurance Across Your End-to-end Network With ThousandEyes
PPTX
Internet of Everything -Basic concepts details
PDF
sustainability-14-14877-v2.pddhzftheheeeee
PDF
4 layer Arch & Reference Arch of IoT.pdf
PDF
The-Future-of-Automotive-Quality-is-Here-AI-Driven-Engineering.pdf
PDF
NewMind AI Weekly Chronicles – August ’25 Week IV
PDF
Enhancing plagiarism detection using data pre-processing and machine learning...
PDF
Data Virtualization in Action: Scaling APIs and Apps with FME
PPTX
Build Your First AI Agent with UiPath.pptx
PDF
Rapid Prototyping: A lecture on prototyping techniques for interface design
PPTX
Module 1 Introduction to Web Programming .pptx
DOCX
Basics of Cloud Computing - Cloud Ecosystem
DOCX
search engine optimization ppt fir known well about this
Transform-Your-Factory-with-AI-Driven-Quality-Engineering.pdf
Statistics on Ai - sourced from AIPRM.pdf
INTERSPEECH 2025 「Recent Advances and Future Directions in Voice Conversion」
Microsoft User Copilot Training Slide Deck
Dell Pro Micro: Speed customer interactions, patient processing, and learning...
Custom Battery Pack Design Considerations for Performance and Safety
Early detection and classification of bone marrow changes in lumbar vertebrae...
AI-driven Assurance Across Your End-to-end Network With ThousandEyes
Internet of Everything -Basic concepts details
sustainability-14-14877-v2.pddhzftheheeeee
4 layer Arch & Reference Arch of IoT.pdf
The-Future-of-Automotive-Quality-is-Here-AI-Driven-Engineering.pdf
NewMind AI Weekly Chronicles – August ’25 Week IV
Enhancing plagiarism detection using data pre-processing and machine learning...
Data Virtualization in Action: Scaling APIs and Apps with FME
Build Your First AI Agent with UiPath.pptx
Rapid Prototyping: A lecture on prototyping techniques for interface design
Module 1 Introduction to Web Programming .pptx
Basics of Cloud Computing - Cloud Ecosystem
search engine optimization ppt fir known well about this

SenchaCon 2016: Theming the Modern Toolkit - Phil Guerrant

  • 1. Theming the Modern Toolkit Phil Guerrant Senior Software Engineer, Sencha
  • 3. Choosing Between App and Theme • Both can contain styling • Theme contains shared styling • Application contains its own styling
  • 4. Generating an Application sencha -sdk path/to/sdk generate app -modern ThemeDemo theme-demo
  • 5. Application Structure Set theme variables in sass/var/all.scss $base-color: green; $panel-body-font-size: 15px;
  • 7. Application Structure • Rule generating code goes in sass/src/ • Mixin calls • CSS rules • scss files are auto-included based on class- path of classes in your application • Ext class - ThemeDemo.view.Main • Includes sass/src/view/Main.scss
  • 8. Rapid Development Using Fashion sencha app watch --fashion [INF] Server started at port : 1841 [INF] Application available at http://localhost:1841
  • 9. Generating a Theme Package Allows styling to be shared between applications # your application directory cd theme-demo sencha generate package --type theme --extend theme-triton --name my-theme
  • 11. Theme Package Structure • scss files are auto-included based on class- path of framework classes • e.g. Ext.field.Text
  • 12. Theme Hierarchy Classic Toolkit Modern Toolkit base neutral classic gray neptune crisp crisp-touch neptune-touch triton base neptune triton ios material
  • 14. Variables All theme variables must be dynamic • dynamic() must be used for any newly declared variables. • When overriding framework variables dynamic() is not required • When in doubt it is safe to always use dynamic()
  • 15. Dynamic Variables Last assignment wins, and is valid throughout entire scope $base-color: dynamic(blue); /* CSS Output */ .foo { background: red; } $base-color: dynamic(red); .foo { background: $base-color; }
  • 16. Component Variables Begin with xtype, end with CSS property name $button-font-size $tab-background-color $listitem-border-width
  • 17. Element Variables Element name after xtype but before CSS property name $button-badge-color $textfield-input-padding $listitem-disclosure-margin
  • 18. State Variables State name after the thing it describes (xtype or element) $button-pressed-color $listitem-selected-border-color $listitem-disclosure-pressed-background-color
  • 19. State Names • pressed • hovered • selected • focused • disabled
  • 21. Style Inheritance Components should inherit styles defined by their superclasses
  • 22. Style Inheritance classCls – the inheritable baseCls
  • 23. Ext.define('Child', { extend: 'Parent', classCls: 'x-child' }); Style Inheritance classCls allows styles to cascade through the Component hierarchyExt.define('Parent', { extend: 'Ext.Component', classCls: 'x-parent' }); <div class="x-component x-parent x-child"> </div> Ext.create('Child');
  • 24. Ext.define('Child', { extend: 'Parent', classCls: 'x-child', classClsRoot: true }); Style Inheritance – Opting Out classClsRoot defines inheritance boundary Ext.define('Parent', { extend: 'Ext.Component', classCls: 'x-parent' }); <div class="x-child"></div> Ext.create('Child');
  • 26. Component UIs One component, multiple presentations
  • 27. Component UIs One component, multiple presentations Ext.create({ xtype: 'button', ui: 'action' }); <div class="x-button x-button-action"> </div>
  • 28. Ext.define('Child', { extend: 'Parent', classCls: 'x-child' }); UI Inheritance UI name is appended to each classCls in the hierarchy Ext.define('Parent', { extend: 'Ext.Component', classCls: 'x-parent' }); <div class="x-component x-parent x-child x-component-foo x-parent-foo x-child-foo"> </div> Ext.create('Child', { ui: 'foo' });
  • 29. UIs are Composable Use one or many, your choice Ext.create({ xtype: 'button', ui: 'action round' }); <div class="x-button x-button-action x-button-round"> </div>
  • 30. UI Mixins The structure of a UI mixin // theme-neptune/sass/var/Button.scss @mixin button-ui( $ui: null, $color: null, $border-color: null ) { $ui-suffix: ui-suffix($ui); // -#{$ui} OR empty string .x-button#{$ui-suffix} { // .x-button[-ui] color: $color; border-color: $border-color; } }
  • 31. UI Mixins The magic of null $color1: null; $color2: red; /* CSS Output */ .button { border-color: red; }.button { color: $color1; border-color: $color2; }
  • 32. UI Mixins The magic of null @include button-ui( $ui: foo ); /* CSS Output */ Empty!
  • 33. UI Mixins The magic of null @include button-ui( $ui: foo, $color: green ); /* CSS Output */ .x-button { color: green; }
  • 34. UIs Mixins The default UI // theme-neptune/sass/var/Button.scss $button-color: #606060; $button-border-color: #e4e4e4; . . . // theme-neptune/sass/src/Button.scss @include button-ui( $color: $button-color, $border-color: $button-border-color . . . ); No $ui parameter ($ui == null)
  • 35. UIs Mixins The default UI /* CSS Output */ .x-button { . . . } .x-button.x-pressed { . . . } .x-button .x-icon-el { . . . }
  • 36. UIs Mixins Additional UIs /* CSS Output */ .x-button-alert { . . . } .x-button-alert.x-pressed { . . . } .x-button-alert .x-icon-el { . . . }
  • 39. Column Header Check Column Header Group Header Row Check Cell Expander Cell Paging Toolbar Text Cell Row Numberer Cell Number Cell Widget Cell Date Cell
  • 40. Grids are Lists Use itemConfig to configure the UI of list items Ext.create({ xtype: 'list', itemConfig: { ui: 'contact' } }); @include listitem-ui( $ui: contact, $color: #fff, $background-color: #444, $border-color: #777 );
  • 42. Row
  • 43. Grids are Lists Use itemConfig to configure the UI of grid rows Ext.create({ xtype: 'grid', itemConfig: { ui: 'contact' } }); @include gridrow-ui( $ui: contact, $background-color: #888 );
  • 45. Grids Group Row UI Use the “header” config of the grid row Ext.create({ xtype: 'grid', itemConfig: { header: { ui: 'contact' } } }); @include rowheader-ui( $ui: contact, $background-color: #ccc );
  • 47. Grid Column Header UI Set the UI on the column config Ext.create({ xtype: 'grid', columns: [{ text: 'Name', ui: 'contact' }] }); @include gridcolumn-ui( $ui: contact, $color: white, $background-color: gray );
  • 49. Grid Cell UI Use the “cell” config of the column Ext.create({ xtype: 'grid', columns: [{ text: 'Name', cell: { ui: 'contact' } }] }); @include gridcell-ui( $ui: contact, $font-weight: bold );
  • 51. Grid Paging Toolbar UI Use the “toolbar” config of the Paging Toolbar plugin Ext.create({ xtype: 'grid', plugins: [{ type: 'pagingtoolbar', toolbar: { ui: 'contact' } }] }); @include pagingtoolbar-ui( $ui: contact, $padding: 30px, $background-color: #ddd );
  • 54. Compound Components are the Sum of Their Parts This pattern is repeated throughout the framework Other Examples: • Slider/Thumb • TextField/Trigger Exceptions: Panel/Panel Header/Tools (on roadmap for improvement)
  • 56. Big Mode Larger sizing and spacing for touch screens • Classic toolkit used separate themes (neptune vs. neptune-touch) • Modern toolkit – single theme
  • 57. Big Mode Larger sizing and spacing for touch screens <html class="x-big">
  • 58. Big Mode Choosing between big and normal modes // theme-neptune/overrides/init.js Ext.theme.getDocCls = function() { return Ext.platformTags.desktop ? '' : 'x-big'; };
  • 60. Big Mode Implementing big mode rules // UI mixin code .x-button { padding: $padding; @if $enable-big { .x-big & { padding: $padding-big; } } } /* CSS Output */ .x-button { padding: 5px; } .x-big .x-button { padding: 10px; }
  • 62. Before Breaking the Rules What do I do when the theming API does not meet my needs? 1. Let us know on the forums – https://sencha.com/forum 2. Add your own styling using the same techniques that the framework uses.
  • 63. classCls Always matches the xtype and goes on the main element Ext.define('Ext.grid.column.Column', { xtype: 'gridcolumn', classCls: 'x-gridcolumn' }); <div class="x-gridcolumn x-gridcolumn-contact"> </div> // instance config { ui: 'contact' }
  • 64. State and Configuration CSS Classes Always on the main element Ext.define('Ext.grid.column.Column', { xtype: 'gridcolumn', classCls: 'x-gridcolumn', config: { align: 'left' } }); <div class="x-gridcolumn x-sorted x-align-left"> </div>
  • 65. State and Configuration CSS Classes Always chain to the classCls .x-align-left .x-title-el .x-gridcolumn.x-sorted .x-sorted .x-gridcolumn-contact.x-align-left
  • 66. Reference Elements Should be named x-[name]-el Ext.define('Ext.grid.column.Column', { template: [{ reference: 'titleElement', className: 'x-title-el' }] });
  • 67. Reference Elements Prefer descendant selectors over child selectors .x-gridcolumn .x-title-el { . . . } .x-gridcolumn > .x-title-el { . . . }
  • 68. Reference Elements Prefer descendant selectors over child selectors • Except when container nesting is possible • Include xtype/ui info in class name .x-panel-inner-foo { . . . }
  • 69. When in Doubt Copy the selectors used by the framework
  • 72. iOS Theme • Based on Triton • Follows the latest iOS look and feel • Will evolve with iOS • Customizable – all framework theme variables and mixins are available
  • 73. Material Theme • Based on Neptune • Follows the material design guidelines https://material.google.com • Material Color Palette • Supports CSS Variables
  • 75. Deep Purple #673AB7 Red #F44336 Material Color Palette https://material.google.com/style/color.html Light Blue #03A9F4 Green #4CAF50 Yellow #FFEB3B Deep Orange #FF5722 Blue Grey #607D8B Pink #E91E63 Purple #9C27B0 Indigo #3F51B5 Blue #2196F3 Cyan #00BCD4 Teal #009688 Light Green #8BC34A Lime #CDDC39 Amber #FFC107 Orange #FF9800 Brown #795548 Grey #9E9E9E Black #000000 White #FFFFFF
  • 76. $base-color-name: indigo; $accent-color-name: yellow; $dark-mode: true; Configuring the Material Theme • Configure base color, accent color, and dark mode • All derived colors, spacing and sizing are handled automatically • Can be further customized using theme variables and mixins but this is outside the scope of material design.
  • 77. Selecting Themes by Platform Step 1: Setup multiple build profiles in app.json { "builds": { "material": { "theme": "theme-material" }, "ios": { "theme": "theme-ios" }, "triton": { "theme": "theme-triton" } } }
  • 78. Selecting Themes by Platform Step 2: Setup output directories in app.json (same as universal app){ "output": { "base": "${workspace.build.dir}/${build.environment}/${app.name}", "page": "index.html", "manifest": "${build.id}.json", "js": "${build.id}/app.js", "appCache": { "enable": false }, "resources": { "path": "${build.id}/resources", "shared": "resources" } } }
  • 79. Selecting Themes by Platform Step 3: Use Ext.beforeLoad to select a profile <script type="text/javascript"> var Ext = Ext || {}; // Ext namespace won't be defined yet... Ext.beforeLoad = function (tags) { var profile; if (tags.ios) { profile = 'ios'; } else if (tags.android) { profile = 'material'; } else { profile = 'triton'; } Ext.manifest = profile; }; </script>
  • 80. Demo
  • 81. Please Take the Survey in the Mobile App • Navigate to this session in the mobile app • Click on “Evaluate Session” • Respondents will be entered into a drawing to win one of five $50 Amazon gift cards