diff --git a/README.md b/README.md index 7394df0..20cc7ef 100644 --- a/README.md +++ b/README.md @@ -316,6 +316,36 @@ When set to false, when clicking on a rail, the click event will be allowed to p When set to true, you can scroll the container by selecting text and move the cursor. **Default: false** +### theme +A string. It's a class name added to the container element. The class name is prepended with `ps-theme-`. So default theme class name is `ps-theme-default`. In order to create custom themes with scss use `ps-container($theme)` mixin, where `$theme` is a scss map. +**Default: 'default'** + +**Example 1:** + +Add `theme` parameter: +```javascript +Ps.initialize(container, { + theme: 'my-theme-name' +}); +``` +Create a class name prefixed with `.ps-theme-`. Include `ps-container()` mixin. It's recommended to use `map-merge()` to extend `$ps-theme-default` map with your custom styles. +```css# +.ps-theme-my-theme-name { + @include ps-container(map-merge($ps-theme-default, ( + border-radius: 0, + scrollbar-x-rail-height: 20px, + scrollbar-x-height: 20px, + scrollbar-y-rail-width: 20px, + scrollbar-y-width: 20px,) + )); +} +``` + +**Example 2:** + +Alternatively, if you don't want to create your own themes, but only modify the default one, you could simply overwrite `$ps-*` variables with your own values. In this case `theme` parameter is not required when calling `.initialize()` method. Remember do define your own variables before the `theme.scss` file is imported. + + ## Events perfect-scrollbar dispatches custom events. diff --git a/examples/custom-theme.html b/examples/custom-theme.html new file mode 100644 index 0000000..c9d4965 --- /dev/null +++ b/examples/custom-theme.html @@ -0,0 +1,27 @@ + + + + + perfect-scrollbar example + + + + + +
+
+
+
+ + + diff --git a/src/css/main.scss b/src/css/main.scss index e370139..ae1f655 100644 --- a/src/css/main.scss +++ b/src/css/main.scss @@ -1,134 +1,3 @@ -// Colors -$ps-rail-hover: #eee; -$ps-bar-default: #aaa; -$ps-bar-hover: #999; - -// Helper mixins -@mixin border-radius($r) { - -webkit-border-radius: $r; - -moz-border-radius: $r; - -ms-border-radius: $r; - border-radius: $r; -} - -@mixin transition($t...) { - -webkit-transition: $t; - -moz-transition: $t; - -o-transition: $t; - transition: $t; -} - -// Scrollbar mixins -@mixin scrollbar-rail-default { - display: none; - position: absolute; /* please don't change 'position' */ - @include border-radius(4px); - opacity: 0; - @include transition(background-color .2s linear, opacity .2s linear); -} - -@mixin scrollbar-rail-hover { - background-color: $ps-rail-hover; - opacity: 0.9; -} - -@mixin scrollbar-default { - position: absolute; /* please don't change 'position' */ - background-color: $ps-bar-default; - @include border-radius(4px); - @include transition(background-color .2s linear); -} - -@mixin scrollbar-hover { - background-color: $ps-bar-hover; -} - -@mixin in-scrolling { - &.ps-in-scrolling { - pointer-events: none; - &.ps-x>.ps-scrollbar-x-rail{ - @include scrollbar-rail-hover; - >.ps-scrollbar-x { - @include scrollbar-hover; - } - } - &.ps-y>.ps-scrollbar-y-rail { - @include scrollbar-rail-hover; - >.ps-scrollbar-y { - @include scrollbar-hover; - } - } - } -} - -.ps-container { - -ms-touch-action: none; - touch-action: none; - overflow: hidden !important; - -ms-overflow-style: none; - - // Edge - @supports (-ms-overflow-style: none) { - overflow: auto !important; - } - // IE10+ - @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { - overflow: auto !important; - } - - &.ps-active-x > .ps-scrollbar-x-rail, - &.ps-active-y > .ps-scrollbar-y-rail { - display: block; - } - - @include in-scrolling; - - >.ps-scrollbar-x-rail { - @include scrollbar-rail-default; - bottom: 3px; /* there must be 'bottom' for ps-scrollbar-x-rail */ - height: 8px; - - >.ps-scrollbar-x { - @include scrollbar-default; - bottom: 0; /* there must be 'bottom' for ps-scrollbar-x */ - height: 8px; - } - } - - >.ps-scrollbar-y-rail { - @include scrollbar-rail-default; - right: 3px; /* there must be 'right' for ps-scrollbar-y-rail */ - width: 8px; - - >.ps-scrollbar-y { - @include scrollbar-default; - right: 0; /* there must be 'right' for ps-scrollbar-y */ - width: 8px; - } - } - - &:hover, &.ps-focus { - @include in-scrolling; - - >.ps-scrollbar-x-rail, - >.ps-scrollbar-y-rail { - opacity: 0.6; - } - - >.ps-scrollbar-x-rail:hover { - @include scrollbar-rail-hover; - - >.ps-scrollbar-x { - @include scrollbar-hover; - } - } - - >.ps-scrollbar-y-rail:hover { - @include scrollbar-rail-hover; - - >.ps-scrollbar-y { - @include scrollbar-hover; - } - } - } -} +@import 'variables'; +@import 'mixins'; +@import 'themes'; diff --git a/src/css/mixins.scss b/src/css/mixins.scss new file mode 100644 index 0000000..f2abecf --- /dev/null +++ b/src/css/mixins.scss @@ -0,0 +1,120 @@ +// Helper mixins +@mixin border-radius($r) { + -webkit-border-radius: $r; + -moz-border-radius: $r; + -ms-border-radius: $r; + border-radius: $r; +} + +@mixin transition($t...) { + -webkit-transition: $t; + -moz-transition: $t; + -o-transition: $t; + transition: $t; +} + +// Scrollbar mixins +@mixin scrollbar-rail-default($theme) { + display: none; + position: absolute; /* please don't change 'position' */ + @include border-radius(map_get($theme, border-radius)); + opacity: map_get($theme, rail-default-opacity); + @include transition(background-color .2s linear, opacity .2s linear); +} + +@mixin scrollbar-rail-hover($theme) { + background-color: map_get($theme, rail-hover-bg); + opacity: map_get($theme, rail-hover-opacity); +} + +@mixin scrollbar-default($theme) { + position: absolute; /* please don't change 'position' */ + background-color: map_get($theme, bar-container-hover-bg); + @include border-radius(map_get($theme, border-radius)); + @include transition(background-color .2s linear); +} + +@mixin scrollbar-hover($theme) { + background-color: map_get($theme, bar-hover-bg); +} + +@mixin in-scrolling($theme) { + &.ps-in-scrolling { + pointer-events: none; + &.ps-x > .ps-scrollbar-x-rail { + @include scrollbar-rail-hover($theme); + > .ps-scrollbar-x { + @include scrollbar-hover($theme); + } + } + &.ps-y > .ps-scrollbar-y-rail { + @include scrollbar-rail-hover($theme); + > .ps-scrollbar-y { + @include scrollbar-hover($theme); + } + } + } +} + +// Layout and theme mixin +@mixin ps-container($theme) { + -ms-touch-action: none; + overflow: hidden !important; + + &.ps-active-x > .ps-scrollbar-x-rail, + &.ps-active-y > .ps-scrollbar-y-rail { + display: block; + background-color: map_get($theme, bar-bg); + } + + @include in-scrolling($theme); + + > .ps-scrollbar-x-rail { + @include scrollbar-rail-default($theme); + bottom: map_get($theme, scrollbar-x-rail-bottom); /* there must be 'bottom' for ps-scrollbar-x-rail */ + height: map_get($theme, scrollbar-x-rail-height); + + > .ps-scrollbar-x { + @include scrollbar-default($theme); + bottom: map_get($theme, scrollbar-x-bottom); /* there must be 'bottom' for ps-scrollbar-x */ + height: map_get($theme, scrollbar-x-height); + } + } + + > .ps-scrollbar-y-rail { + @include scrollbar-rail-default($theme); + right: map_get($theme, scrollbar-y-rail-right); /* there must be 'right' for ps-scrollbar-y-rail */ + width: map_get($theme, scrollbar-y-rail-width); + + > .ps-scrollbar-y { + @include scrollbar-default($theme); + right: map_get($theme, scrollbar-y-right); /* there must be 'right' for ps-scrollbar-y */ + width: map_get($theme, scrollbar-y-width); + } + } + + &:hover { + @include in-scrolling($theme); + + > .ps-scrollbar-x-rail, + > .ps-scrollbar-y-rail { + opacity: map_get($theme, rail-container-hover-opacity); + } + + > .ps-scrollbar-x-rail:hover { + @include scrollbar-rail-hover($theme); + + > .ps-scrollbar-x { + @include scrollbar-hover($theme); + } + } + + > .ps-scrollbar-y-rail:hover { + @include scrollbar-rail-hover($theme); + + > .ps-scrollbar-y { + @include scrollbar-hover($theme); + } + } + } +} diff --git a/src/css/themes.scss b/src/css/themes.scss new file mode 100644 index 0000000..af6defe --- /dev/null +++ b/src/css/themes.scss @@ -0,0 +1,23 @@ +$ps-theme-default: ( + border-radius: $ps-border-radius, + rail-default-opacity: $ps-rail-default-opacity, + rail-container-hover-opacity: $ps-rail-container-hover-opacity, + rail-hover-opacity: $ps-rail-hover-opacity, + bar-bg: $ps-bar-bg, + bar-container-hover-bg: $ps-bar-container-hover-bg, + bar-hover-bg: $ps-bar-hover-bg, + rail-hover-bg: $ps-rail-hover-bg, + scrollbar-x-rail-bottom: $ps-scrollbar-x-rail-bottom, + scrollbar-x-rail-height: $ps-scrollbar-x-rail-height, + scrollbar-x-bottom: $ps-scrollbar-x-bottom, + scrollbar-x-height: $ps-scrollbar-x-height, + scrollbar-y-rail-right: $ps-scrollbar-y-rail-right, + scrollbar-y-rail-width: $ps-scrollbar-y-rail-width, + scrollbar-y-right: $ps-scrollbar-y-right, + scrollbar-y-width: $ps-scrollbar-y-width, +); + +// Default theme +.ps-container { + @include ps-container($ps-theme-default); +} diff --git a/src/css/variables.scss b/src/css/variables.scss new file mode 100644 index 0000000..d67c156 --- /dev/null +++ b/src/css/variables.scss @@ -0,0 +1,22 @@ +// Colors +$ps-border-radius: 4px !default; + +$ps-rail-default-opacity: 0 !default; +$ps-rail-container-hover-opacity: 0.6 !default; +$ps-rail-hover-opacity: 0.9 !default; + +$ps-bar-bg: transparent !default; +$ps-bar-container-hover-bg: #aaa !default; +$ps-bar-hover-bg: #999 !default; +$ps-rail-hover-bg: #eee !default; + +// Sizes +$ps-scrollbar-x-rail-bottom: 3px !default; +$ps-scrollbar-x-rail-height: 8px !default; +$ps-scrollbar-x-bottom: 0 !default; +$ps-scrollbar-x-height: 8px !default; + +$ps-scrollbar-y-rail-right: 3px !default; +$ps-scrollbar-y-rail-width: 8px !default; +$ps-scrollbar-y-right: 0 !default; +$ps-scrollbar-y-width: 8px !default; diff --git a/src/js/plugin/default-setting.js b/src/js/plugin/default-setting.js index 9497447..521c73e 100644 --- a/src/js/plugin/default-setting.js +++ b/src/js/plugin/default-setting.js @@ -13,5 +13,6 @@ module.exports = { useKeyboard: true, useSelectionScroll: false, wheelPropagation: false, - wheelSpeed: 1 + wheelSpeed: 1, + theme: 'default' }; diff --git a/src/js/plugin/initialize.js b/src/js/plugin/initialize.js index 156ef1a..a983434 100644 --- a/src/js/plugin/initialize.js +++ b/src/js/plugin/initialize.js @@ -23,6 +23,7 @@ module.exports = function (element, userSettings) { var i = instances.add(element); i.settings = h.extend(i.settings, userSettings); + cls.add(element, 'ps-theme-' + i.settings.theme); clickRailHandler(element); dragScrollbarHandler(element);