Repository: exadel-inc/esl
Pull request #54 (2021-02-11 12:37:25)

dev -> main-beta


Patch:
diff --git a/.eslintrc.json b/.eslintrc.json
index a06e8498e..3bd449467 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -14,6 +14,7 @@
     "sourceType": "module"
   },
   "plugins": [
+    "import",
     "@typescript-eslint"
   ],
   "rules": {
@@ -101,6 +102,10 @@
     ],
     "spaced-comment": "warn",
     "use-isnan": "warn",
-    "valid-typeof": "off"
+    "valid-typeof": "off",
+
+    "import/export": "warn",
+    "import/named": "error",
+    "import/no-default-export": "warn"
   }
 }
diff --git a/.stylelintrc.json b/.stylelintrc.json
index b8e5a0545..6ae3811f8 100644
--- a/.stylelintrc.json
+++ b/.stylelintrc.json
@@ -2,9 +2,11 @@
   "plugins": ["./build/lint/import.stylelint.js"],
   "rules": {
     "at-rule-no-unknown": true,
-    "block-no-empty": true,
+    "block-no-empty": [true, { "severity": "warning" }],
+    "block-opening-brace-space-before": ["always", { "severity": "warning" }],
     "color-no-invalid-hex": true,
     "comment-no-empty": true,
+    "declaration-colon-space-after": ["always", { "severity": "warning" }],
     "declaration-block-no-duplicate-properties": true,
     "font-family-no-duplicate-names": true,
     "font-family-no-missing-generic-family-keyword": true,
@@ -18,12 +20,17 @@
     "no-extra-semicolons": true,
     "no-invalid-double-slash-comments": true,
     "property-no-unknown": true,
+    "selector-list-comma-space-before": "never",
+    "selector-pseudo-class-case": "lower",
+    "selector-pseudo-class-parentheses-space-inside": "never",
+    "selector-pseudo-element-case": "lower",
+    "selector-pseudo-element-colon-notation": "double",
     "selector-pseudo-class-no-unknown": true,
     "selector-pseudo-element-no-unknown": true,
     "selector-type-no-unknown": [true, {
       "ignore": ["custom-elements"]
     }],
-    "string-no-newline": true,
+    "string-no-newline": [true, { "severity": "warning" }],
     "unit-no-unknown": true,
     "esl-less/import-root": "never"
   }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3de914bb7..0ed42203b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,179 +1,3 @@
-# [2.0.0-beta.16](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.15...v2.0.0-beta.16) (2021-02-08)
-
-
-### Bug Fixes
-
-* allow super.register call for esl-base-element instances ([19e8e05](https://github.com/exadel-inc/esl/commit/19e8e051d413c28e1ecd74b2b636e1a3281d2d08))
-
-# [2.0.0-beta.15](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.14...v2.0.0-beta.15) (2021-02-04)
-
-
-### Features
-
-* add more label format for esl-select; fix select dropdown focus ([8682ec0](https://github.com/exadel-inc/esl/commit/8682ec054fcc31685221be050750ce77e669b425))
-
-# [2.0.0-beta.14](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.13...v2.0.0-beta.14) (2021-02-04)
-
-
-### Bug Fixes
-
-* fix focus and position calculation ([815b8ad](https://github.com/exadel-inc/esl/commit/815b8ad5bd58e0814a569dd3337884417f55f790))
-
-# [2.0.0-beta.13](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.12...v2.0.0-beta.13) (2021-02-04)
-
-
-### Bug Fixes
-
-* a11y ([8d1085b](https://github.com/exadel-inc/esl/commit/8d1085ba0d9e8e05e2633e8e943a50539972e279))
-
-
-### Features
-
-* add empty text for select. update select events and flow ([3435ae9](https://github.com/exadel-inc/esl/commit/3435ae9460853ceb64f9c51b44bb5a4e913c0afc))
-
-# [2.0.0-beta.12](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.11...v2.0.0-beta.12) (2021-02-04)
-
-
-### Bug Fixes
-
-* add full ts export for scroll ([1e40678](https://github.com/exadel-inc/esl/commit/1e406783222a74d7d22a7a9ea5b26566377c4d83))
-* optimize select performance. update demo content ([9c916d6](https://github.com/exadel-inc/esl/commit/9c916d684df4a75fe5a6bcc0d75fed7ea25781f5))
-
-
-### Features
-
-* esl-select component POC ([dd2644e](https://github.com/exadel-inc/esl/commit/dd2644eb0bd4840ad1285298f51f238e11aaa414))
-
-# [2.0.0-beta.11](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.10...v2.0.0-beta.11) (2021-02-03)
-
-
-### Bug Fixes
-
-* bouncing up when crossing between tabs ([ea7053b](https://github.com/exadel-inc/esl/commit/ea7053b64b97865f3768ba298d906a82da0a0e5e))
-
-# [2.0.0-beta.10](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.9...v2.0.0-beta.10) (2021-02-03)
-
-# [2.0.0-beta.9](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.8...v2.0.0-beta.9) (2021-02-03)
-
-# [2.0.0-beta.8](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.7...v2.0.0-beta.8) (2021-02-02)
-
-# [2.0.0-beta.7](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.6...v2.0.0-beta.7) (2021-02-02)
-
-
-* feat!: refactor of Panel & PanelStack ([d819259](https://github.com/exadel-inc/esl/commit/d8192599333101b46bab930326b2b2ef8eef6292))
-
-
-### Features
-
-* upgrade BasePopupGroupManager ([07aa02a](https://github.com/exadel-inc/esl/commit/07aa02a65173b85bbcf6076d7861a5950fc26e63))
-
-
-### BREAKING CHANGES
-
-* Panel Stack uses self group management.
-Group attribute should be removed to reach collapsible behavior.
-Panel Stack & Panel inner API changes.
-
-# [2.0.0-beta.6](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.5...v2.0.0-beta.6) (2021-02-01)
-
-
-### Bug Fixes
-
-* rename loaded event of ESLImage to the load event (from spec) ([23ecb84](https://github.com/exadel-inc/esl/commit/23ecb844fe41e54c1dd9ac58ac3f9fe23917ae97))
-
-
-### Code Refactoring
-
-* cleanup for ESLBasePopupGroupManager ([5f68efd](https://github.com/exadel-inc/esl/commit/5f68efdff5848e4a98f0293328545d00371c244d))
-
-
-### BREAKING CHANGES
-
-*  rename ESLBasePopupGroupManager to ESLPopupGroupDispatcher
-
-# [2.0.0-beta.5](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.4...v2.0.0-beta.5) (2021-02-01)
-
-
-### Bug Fixes
-
-* bind method hotfix ([b7d3b1c](https://github.com/exadel-inc/esl/commit/b7d3b1ca711044c3de29c872173e98bc9bb2a3bc))
-
-# [2.0.0-beta.4](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.3...v2.0.0-beta.4) (2021-01-31)
-
-
-### Features
-
-* add separate simplified ESLBaseTrigger ([3f5500a](https://github.com/exadel-inc/esl/commit/3f5500af7a7a5b2cd9020db9a80b3b8245ac64fe))
-* introduce EventUtils with a set of event related utilities ([04c5368](https://github.com/exadel-inc/esl/commit/04c536884d63dce864b2427cc2f98175b5e35e39))
-* introduce new BasePopupGroupManager based on events ([8f9a426](https://github.com/exadel-inc/esl/commit/8f9a4260dac3d9d4c604e7cbcf75b9628c426f87))
-
-
-* feat!: add last activator feature, fix outside action ([76bd08b](https://github.com/exadel-inc/esl/commit/76bd08ba4262e68a52de2ff21bc72ca8016c17ae))
-
-
-### Bug Fixes
-
-* fix package.json and IE compatibility problems ([68f1bb6](https://github.com/exadel-inc/esl/commit/68f1bb669d7b50acf68253cfeb795dac5b486ae1))
-
-
-### BREAKING CHANGES
-
-*  'outsideclick' initiator type replaced with 'outsideaction'
-
-# [2.0.0-beta.3](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.2...v2.0.0-beta.3) (2021-01-28)
-
-
-### Bug Fixes
-
-* fix ESLMedia events prefix ([76035fe](https://github.com/exadel-inc/esl/commit/76035fea0216157ee4f68ec9a7e14d20f3a4dc1a))
-
-# [2.0.0-beta.2](https://github.com/exadel-inc/esl/compare/v2.0.0-beta.1...v2.0.0-beta.2) (2021-01-28)
-
-
-### Features
-
-* !revert back esl prefix for events ([adef294](https://github.com/exadel-inc/esl/commit/adef294f76ef6b9c9a46cd743fd26d65b45cbfdf))
-* add originalWidth / originalHeight accessors to ESLImage ([365e31b](https://github.com/exadel-inc/esl/commit/365e31b78db67b4bbc335c17078b117459753aa4))
-
-
-### BREAKING CHANGES
-
-*  events of BasePopup now have esl prefix
-('esl:hide' / 'esl:show' / 'esl:before:hide' / 'esl:before:show')
-
- events of Trigger now have esl prefix:  'esl:change:active'
-
- events of Panel now have esl prefix: 'esl:after:hide' / 'esl:after:show'
-
-# [2.0.0-beta.1](https://github.com/exadel-inc/esl/compare/v1.0.1...v2.0.0-beta.1) (2021-01-26)
-
-
-* feat!: update for tab and trigger events; fix double a11y control for tabs ([dce85b6](https://github.com/exadel-inc/esl/commit/dce85b62a4b9e3fd270e1192a75f1796275f778f))
-* feat!: eventing cleanup ([22efb73](https://github.com/exadel-inc/esl/commit/22efb7308140f40c4493716c3de1e7705ef1c0ad))
-* feat!: popups massive cleanup 1 ([7441e41](https://github.com/exadel-inc/esl/commit/7441e411c0f586e366df3057c9c81b58fbdeab5f))
-
-
-### Bug Fixes
-
-* fix tracking click event for Popup ([2c3bff0](https://github.com/exadel-inc/esl/commit/2c3bff00a7f129e4382eca7fac37b7e6b28f2ead))
-* fix tracking click event for Popup (rename the method and arguments) ([8abd6e5](https://github.com/exadel-inc/esl/commit/8abd6e544ea49fc13379928d6b6f43f137e0bb76))
-* optimize UX for close outside feature ([c058400](https://github.com/exadel-inc/esl/commit/c0584007b0597b1b6c5d308592635267986f1efb))
-* remove eventNs for image & scroll fix image ready event ([2f3382f](https://github.com/exadel-inc/esl/commit/2f3382f206255b85be143fbb802d6c0fa12d4ac6))
-
-
-### Features
-
-* `[@ready](https://github.com/ready)` decorator and readyState listener ([6d1a32f](https://github.com/exadel-inc/esl/commit/6d1a32fd1d5b83dcb03902fb0cd874cc32b8f806))
-
-
-### BREAKING CHANGES
-
-* - `transitionend` event of ESLPanel replaced with `after:show`/`after:hide`
-- `statechange` event of ESLTrigger replaced with `change:active`
-* - `ESLBaseElement` no longer contains eventNs and $$fireNs methods
-- Whole popups based component system no longer use event namespaces
-* - `ESLBasePopup` statechange events replaced with a separate `(before:)show/hide`
-
 # [1.1.0](https://github.com/exadel-inc/esl/compare/v1.0.1...v1.1.0) (2021-01-27)
 
 
diff --git a/README.md b/README.md
index 5be1806a7..285397962 100644
--- a/README.md
+++ b/README.md
@@ -10,24 +10,28 @@ Exadel Smart Library (**ESL**) is a web components based library that gives you
 
 ## Library Structure
 ### Components
-- ##### [ESL Image](./src/modules/esl-image/README.md)
-- ##### [ESL Media](./src/modules/esl-media/README.md)
-- ##### [ESL Scrollbar](./src/modules/esl-scrollbar/README.md)
-
-- ##### [ESL Base Popup](./src/modules/esl-base-popup/README.md)
-- ##### [ESL Base Trigger](./src/modules/esl-base-trigger/README.md)
-- ##### [ESL Popup](./src/modules/esl-popup/README.md)
-- ##### [ESL Trigger](./src/modules/esl-trigger/README.md)
-- ##### [ESL Panel and Panel Stack](./src/modules/esl-panel/README.md)
-- ##### [ESL Tab and Tab Container](./src/modules/esl-tab/README.md)
+- ##### [ESL Image](src/modules/esl-image/README.md)
+- ##### [ESL Media](src/modules/esl-media/README.md)
+- ##### [ESL Scrollbar](src/modules/esl-scrollbar/README.md)
+
+- ##### [ESL Toggleable](src/modules/esl-toggleable/README.md)
+- ##### [ESL Base Trigger](src/modules/esl-base-trigger/README.md)
+- ##### [ESL Popup](src/modules/esl-popup/README.md)
+- ##### [ESL Trigger](src/modules/esl-trigger/README.md)
+- ##### [ESL Panel and Panel Stack](src/modules/esl-panel/README.md)
+- ##### [ESL Tab and Tab Container](src/modules/esl-tab/README.md)
 - ##### [ESL Scrollable Tabs](src/modules/esl-scrollable-tabs/README.md)
 - ##### [ESL Alert](src/modules/esl-alert/README.md)
 
+### Form Components
+- ##### [ESL Select](src/modules/esl-forms/esl-select/README.md)
+- ##### [ESL Select List](src/modules/esl-forms/esl-select-list/README.md)
+
 ### Utilities
-- ##### [ESL Base Element](./src/modules/esl-base-element/README.md)
-- ##### [ESL Media Query](./src/modules/esl-media-query/README.md)
-- ##### [ESL Traversing Query](./src/modules/esl-traversing-query/README.md)
-- ##### [ESL Utils](./src/modules/esl-utils/README.md)
+- ##### [ESL Base Element](src/modules/esl-base-element/README.md)
+- ##### [ESL Media Query](src/modules/esl-media-query/README.md)
+- ##### [ESL Traversing Query](src/modules/esl-traversing-query/README.md)
+- ##### [ESL Utils](src/modules/esl-utils/README.md)
 
 ---
 ## Installation Guide
@@ -127,7 +131,7 @@ In case you are using JetBrains IDE (IDEA or WebStorm) you can use this
 
 ## Roadmap
 
-- Releasable state for beta components (ESL Base Popup group)
+- Releasable state for beta components (ESL Toggleable group)
 - "Playground" demo server
 - npm release
 - ESLCarousel component release
diff --git a/docs/commit.md b/docs/commit.md
index 28ee5f2d3..09b6b2380 100644
--- a/docs/commit.md
+++ b/docs/commit.md
@@ -39,14 +39,24 @@ Type is a required part of the message, and it is limited by the following value
 | ci       | Continuous integration and deployment related changes |
 | perf     | Backward-compatible performance improvements |
 
-**To identify breaking changes add `!` in the end of type**
-
 Type should be in a lowercase.
 
+### BREAKING CHANGES
+
+**To identify breaking changes use `!` postfix for the <type>**
 ```text
 feat!: Hey I'm breaking something that already exist
 ```
 
+**Identify everything that break or change existing API or behaviour with the `BREACKING CHAGES:` list
+```text
+feat!: Hey I'm breaking something that already exist
+
+BREAKING CHANGES:
+  something was broken
+  some api was changed
+```
+
 ---
 
 ### \<scope\>
diff --git a/docs/styleguide.md b/docs/styleguide.md
new file mode 100644
index 000000000..0dd1c109d
--- /dev/null
+++ b/docs/styleguide.md
@@ -0,0 +1,40 @@
+# ESL Code Styleguide
+
+## Naming convention agreements
+
+### General
+- **PascalCase should be used for class names, constructors or, exceptionally, 
+  for variables that reference a constructor**
+- **Use camelCase for variable and method names**
+- **For constants (in case it is a final value) prefer an uppercase SNAKE_CASE convention**
+
+### Special conventions
+- `_private` (private notation) - **must use**
+  Typical cases: 
+  - For inner details that should be hidden from outside world
+  - Everything that can corrupt component from outside
+  - Listeners (e.g. `_onSomeEvent`), due to potential conflicts with consumer's code
+  
+- `__private__`(behavioral private notation) - **conditionally** for utilities and core inner details
+  Typical cases:
+   - For utils private state (can not get or set from outside)
+   - For core functionality private state (can not get or set from outside)
+
+- `$domElement`(JQuery notation / HTMLElement notation) - **must use**
+  Typical cases:
+  - For class variable that stores DOM element
+  - For accessor that returns DOM element
+
+- `_$element` (HTMLElement notation + private notation) - **use both**
+  Typical cases:
+  - For private variable that stores DOM element
+  - For private accessor that returns DOM element
+  
+#### *Notes:*
+- **Special conventions are applicable for public or internal API, function arguments and global variables**
+- **Special conventions are not applicable for local variables**
+- `observable$` (observable notation) - **declined for now** (due to the absence of real cases)
+
+## ES6 Imports/Exports
+ - Keep in mind that ESL supports ES6 tree shakable usage
+ - Prefer named imports over default definition
diff --git a/package-lock.json b/package-lock.json
index 04fa800bb..0a7debcf1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "@exadel/esl",
-  "version": "2.0.0-beta.16",
+  "version": "1.1.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -2092,6 +2092,12 @@
       "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==",
       "dev": true
     },
+    "@types/json5": {
+      "version": "0.0.29",
+      "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+      "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
+      "dev": true
+    },
     "@types/mdast": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz",
@@ -2836,6 +2842,19 @@
       "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=",
       "dev": true
     },
+    "array-includes": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz",
+      "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1",
+        "get-intrinsic": "^1.0.1",
+        "is-string": "^1.0.5"
+      }
+    },
     "array-initial": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
@@ -2908,6 +2927,17 @@
       "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
       "dev": true
     },
+    "array.prototype.flat": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz",
+      "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
+      }
+    },
     "arraybuffer.slice": {
       "version": "0.0.7",
       "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
@@ -4431,6 +4461,12 @@
       "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
       "dev": true
     },
+    "contains-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+      "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+      "dev": true
+    },
     "content-disposition": {
       "version": "0.5.3",
       "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
@@ -6050,6 +6086,260 @@
         }
       }
     },
+    "eslint-import-resolver-node": {
+      "version": "0.3.4",
+      "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz",
+      "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==",
+      "dev": true,
+      "requires": {
+        "debug": "^2.6.9",
+        "resolve": "^1.13.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "eslint-module-utils": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz",
+      "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==",
+      "dev": true,
+      "requires": {
+        "debug": "^2.6.9",
+        "pkg-dir": "^2.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "find-up": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+          "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^2.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+          "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^2.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+          "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+          "dev": true,
+          "requires": {
+            "p-try": "^1.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+          "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^1.1.0"
+          }
+        },
+        "p-try": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+          "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+          "dev": true
+        },
+        "path-exists": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+          "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+          "dev": true,
+          "requires": {
+            "find-up": "^2.1.0"
+          }
+        }
+      }
+    },
+    "eslint-plugin-import": {
+      "version": "2.22.1",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz",
+      "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==",
+      "dev": true,
+      "requires": {
+        "array-includes": "^3.1.1",
+        "array.prototype.flat": "^1.2.3",
+        "contains-path": "^0.1.0",
+        "debug": "^2.6.9",
+        "doctrine": "1.5.0",
+        "eslint-import-resolver-node": "^0.3.4",
+        "eslint-module-utils": "^2.6.0",
+        "has": "^1.0.3",
+        "minimatch": "^3.0.4",
+        "object.values": "^1.1.1",
+        "read-pkg-up": "^2.0.0",
+        "resolve": "^1.17.0",
+        "tsconfig-paths": "^3.9.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "doctrine": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+          "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "isarray": "^1.0.0"
+          }
+        },
+        "find-up": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+          "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^2.0.0"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "load-json-file": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+          "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.2",
+            "parse-json": "^2.2.0",
+            "pify": "^2.0.0",
+            "strip-bom": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+          "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^2.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+          "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+          "dev": true,
+          "requires": {
+            "p-try": "^1.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+          "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^1.1.0"
+          }
+        },
+        "p-try": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+          "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+          "dev": true
+        },
+        "parse-json": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+          "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.2.0"
+          }
+        },
+        "path-exists": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "dev": true
+        },
+        "path-type": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+          "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+          "dev": true,
+          "requires": {
+            "pify": "^2.0.0"
+          }
+        },
+        "read-pkg": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+          "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+          "dev": true,
+          "requires": {
+            "load-json-file": "^2.0.0",
+            "normalize-package-data": "^2.3.2",
+            "path-type": "^2.0.0"
+          }
+        },
+        "read-pkg-up": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+          "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+          "dev": true,
+          "requires": {
+            "find-up": "^2.0.0",
+            "read-pkg": "^2.0.0"
+          }
+        },
+        "strip-bom": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "dev": true
+        }
+      }
+    },
     "eslint-scope": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@@ -9340,6 +9630,12 @@
       "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
       "dev": true
     },
+    "is-string": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
+      "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
+      "dev": true
+    },
     "is-svg": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz",
@@ -21709,6 +22005,35 @@
         "semver": "^7.3.4"
       }
     },
+    "tsconfig-paths": {
+      "version": "3.9.0",
+      "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
+      "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==",
+      "dev": true,
+      "requires": {
+        "@types/json5": "^0.0.29",
+        "json5": "^1.0.1",
+        "minimist": "^1.2.0",
+        "strip-bom": "^3.0.0"
+      },
+      "dependencies": {
+        "json5": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+          "dev": true,
+          "requires": {
+            "minimist": "^1.2.0"
+          }
+        },
+        "strip-bom": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "dev": true
+        }
+      }
+    },
     "tslib": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
diff --git a/package.json b/package.json
index df1fd1a56..9c6b522c9 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,7 @@
     "lightweight",
     "flexible"
   ],
-  "version": "2.0.0-beta.16",
+  "version": "1.1.0",
   "private": true,
   "license": "MIT",
   "repository": {
@@ -41,7 +41,9 @@
     "start": "cd test-server && npm run dev",
     "clean": "gulp clean",
     "build": "gulp build",
-    "test": "concurrently \"gulp lint --silent\" \"jest --silent --noStackTrace\"",
+    "test": "concurrently \"npm run test:lint\" \"npm run test:unit\"",
+    "test:lint": "gulp lint --silent",
+    "test:unit": "jest --silent --noStackTrace",
     "test:report": "jest --coverage",
     "prepare": "npm run build",
     "preversion": "npm test"
@@ -73,6 +75,7 @@
     "concurrently": "^5.3.0",
     "cssnano": "^4.1.10",
     "eslint": "^7.19.0",
+    "eslint-plugin-import": "^2.22.1",
     "gulp": "^4.0.2",
     "gulp-clean": "^0.4.0",
     "gulp-eslint": "^6.0.0",
diff --git a/paths.json b/paths.json
index ef2dc7af4..d092fbe09 100644
--- a/paths.json
+++ b/paths.json
@@ -3,7 +3,14 @@
     "base": "./src/modules/",
     "ts": ["src/modules/**/*.ts", "!**/test/*.ts"],
     "less": ["src/modules/**/*.less"],
-    "css": ["src/modules/*.less", "src/modules/*/*.less", "src/modules/utils/*/*.less", "src/modules/beta/*/*.less", "!**/*.mixin.less"],
+    "css": [
+      "src/modules/*.less",
+      "src/modules/*/*.less",
+      "src/modules/esl-forms/*/*.less",
+      "src/modules/utils/*/*.less",
+      "src/modules/beta/*/*.less",
+      "!**/*.mixin.less"
+    ],
     "dest": "modules",
     "destPaths": ["modules/*"]
   },
diff --git a/src/modules/all.less b/src/modules/all.less
index 5c0983552..08786910b 100644
--- a/src/modules/all.less
+++ b/src/modules/all.less
@@ -5,7 +5,7 @@
 
 @import "./esl-scrollbar/core.less";
 
-@import "./esl-base-popup/core.less";
+@import "./esl-toggleable/core.less";
 @import "./esl-popup/core.less";
 @import "./esl-trigger/core.less";
 
@@ -15,3 +15,5 @@
 @import "./esl-scrollable-tabs/core.less";
 
 @import "./esl-alert/core.less";
+
+@import "./esl-forms/all.less";
diff --git a/src/modules/all.ts b/src/modules/all.ts
index 62a098e06..22553ec6c 100644
--- a/src/modules/all.ts
+++ b/src/modules/all.ts
@@ -7,7 +7,7 @@ export * from './esl-image/core';
 
 export * from './esl-media/core';
 
-export * from './esl-base-popup/core';
+export * from './esl-toggleable/core';
 export * from './esl-popup/core';
 export * from './esl-trigger/core';
 
@@ -20,3 +20,4 @@ export * from './esl-scrollbar/core';
 
 export * from './esl-alert/core';
 
+export * from './esl-forms/all';
diff --git a/src/modules/draft/all.less b/src/modules/draft/all.less
index 4a7318ede..70810585a 100644
--- a/src/modules/draft/all.less
+++ b/src/modules/draft/all.less
@@ -1,4 +1,1 @@
-@import "./esl-select/core.less";
-@import "./esl-select-list/core.less";
-
 @import "./esl-carousel/all.less";
diff --git a/src/modules/draft/all.ts b/src/modules/draft/all.ts
index f0a37d612..b15e00da5 100644
--- a/src/modules/draft/all.ts
+++ b/src/modules/draft/all.ts
@@ -1,3 +1,1 @@
-export * from './esl-select/core';
-export * from './esl-select-list/core';
 export * from './esl-carousel/all';
diff --git a/src/modules/draft/esl-carousel/core/esl-carousel-slide.ts b/src/modules/draft/esl-carousel/core/esl-carousel-slide.ts
index 24f3aab51..9f24ba3c5 100644
--- a/src/modules/draft/esl-carousel/core/esl-carousel-slide.ts
+++ b/src/modules/draft/esl-carousel/core/esl-carousel-slide.ts
@@ -25,5 +25,3 @@ export class ESLCarouselSlide extends ESLBaseElement {
     this.toggleAttribute('first', first);
   }
 }
-
-export default ESLCarouselSlide;
diff --git a/src/modules/draft/esl-carousel/core/esl-carousel.ts b/src/modules/draft/esl-carousel/core/esl-carousel.ts
index a5548de93..ce500644e 100644
--- a/src/modules/draft/esl-carousel/core/esl-carousel.ts
+++ b/src/modules/draft/esl-carousel/core/esl-carousel.ts
@@ -2,9 +2,9 @@ import {ExportNs} from '../../../esl-utils/environment/export-ns';
 import {ESLBaseElement, attr} from '../../../esl-base-element/core';
 import {deepCompare} from '../../../esl-utils/misc/object';
 import {ESLMediaRuleList} from '../../../esl-media-query/core';
-import ESLCarouselSlide from './esl-carousel-slide';
+import {ESLCarouselSlide} from './esl-carousel-slide';
 import {ESLCarouselView, ESLCarouselViewRegistry} from './view/esl-carousel-view';
-import ESLCarouselPlugin from '../plugin/esl-carousel-plugin';
+import {ESLCarouselPlugin} from '../plugin/esl-carousel-plugin';
 
 interface CarouselConfig { // Registry
   view?: string;
@@ -286,5 +286,3 @@ export class ESLCarousel extends ESLBaseElement {
     customElements.whenDefined(ESLCarouselSlide.is).then(() => super.register.call(this, tagName));
   }
 }
-
-export default ESLCarousel;
diff --git a/src/modules/draft/esl-carousel/core/view/esl-carousel-view.ts b/src/modules/draft/esl-carousel/core/view/esl-carousel-view.ts
index 4fabc0ae2..af1eb4754 100644
--- a/src/modules/draft/esl-carousel/core/view/esl-carousel-view.ts
+++ b/src/modules/draft/esl-carousel/core/view/esl-carousel-view.ts
@@ -1,4 +1,4 @@
-import ESLCarousel from '../esl-carousel';
+import {ESLCarousel} from '../esl-carousel';
 import {Observable} from '../../../../esl-utils/abstract/observable';
 
 export abstract class ESLCarouselView {
@@ -43,5 +43,3 @@ export class ESLCarouselViewRegistry extends Observable {
     this.fire(name, view);
   }
 }
-
-export default ESLCarouselView;
diff --git a/src/modules/draft/esl-carousel/core/view/esl-multi-carousel-view.ts b/src/modules/draft/esl-carousel/core/view/esl-multi-carousel-view.ts
index eb42661ff..cb6ea5296 100644
--- a/src/modules/draft/esl-carousel/core/view/esl-multi-carousel-view.ts
+++ b/src/modules/draft/esl-carousel/core/view/esl-multi-carousel-view.ts
@@ -1,5 +1,5 @@
+import {ESLCarousel} from '../esl-carousel';
 import {ESLCarouselView, ESLCarouselViewRegistry} from './esl-carousel-view';
-import ESLCarousel from '../esl-carousel';
 
 class ESLMultiCarouselView extends ESLCarouselView {
   constructor(carousel: ESLCarousel) {
@@ -133,5 +133,3 @@ class ESLMultiCarouselView extends ESLCarouselView {
 }
 
 ESLCarouselViewRegistry.instance.registerView('multiple', ESLMultiCarouselView);
-
-export default ESLMultiCarouselView;
diff --git a/src/modules/draft/esl-carousel/core/view/esl-single-carousel-view.ts b/src/modules/draft/esl-carousel/core/view/esl-single-carousel-view.ts
index 7c21b5bfb..92889f3a1 100644
--- a/src/modules/draft/esl-carousel/core/view/esl-single-carousel-view.ts
+++ b/src/modules/draft/esl-carousel/core/view/esl-single-carousel-view.ts
@@ -1,5 +1,5 @@
+import {ESLCarousel} from '../esl-carousel';
 import {ESLCarouselView, ESLCarouselViewRegistry} from './esl-carousel-view';
-import ESLCarousel from '../esl-carousel';
 
 class ESLSingleCarouselView extends ESLCarouselView {
 
@@ -62,5 +62,3 @@ class ESLSingleCarouselView extends ESLCarouselView {
 }
 
 ESLCarouselViewRegistry.instance.registerView('single', ESLSingleCarouselView);
-
-export default ESLSingleCarouselView;
diff --git a/src/modules/draft/esl-carousel/plugin/esl-carousel-autoplay.plugin.ts b/src/modules/draft/esl-carousel/plugin/esl-carousel-autoplay.plugin.ts
index 5a4fabb22..e434eb6e4 100644
--- a/src/modules/draft/esl-carousel/plugin/esl-carousel-autoplay.plugin.ts
+++ b/src/modules/draft/esl-carousel/plugin/esl-carousel-autoplay.plugin.ts
@@ -1,6 +1,6 @@
 import {ExportNs} from '../../../esl-utils/environment/export-ns';
 import {attr} from '../../../esl-base-element/core';
-import ESLCarouselPlugin from './esl-carousel-plugin';
+import {ESLCarouselPlugin} from './esl-carousel-plugin';
 
 /**
  * Slide Carousel Autoplay (Auto-Advance) plugin
@@ -90,5 +90,3 @@ export class ESLCarouselAutoplayPlugin extends ESLCarouselPlugin {
     }
   }
 }
-
-export default ESLCarouselAutoplayPlugin;
diff --git a/src/modules/draft/esl-carousel/plugin/esl-carousel-dots.plugin.ts b/src/modules/draft/esl-carousel/plugin/esl-carousel-dots.plugin.ts
index 53d7b1dcb..136468a5d 100644
--- a/src/modules/draft/esl-carousel/plugin/esl-carousel-dots.plugin.ts
+++ b/src/modules/draft/esl-carousel/plugin/esl-carousel-dots.plugin.ts
@@ -1,5 +1,5 @@
 import {ExportNs} from '../../../esl-utils/environment/export-ns';
-import ESLCarouselPlugin from './esl-carousel-plugin';
+import {ESLCarouselPlugin} from './esl-carousel-plugin';
 
 /**
  * Slide Carousel Dots plugin
@@ -37,6 +37,3 @@ export class ESLCarouselDotsPlugin extends ESLCarouselPlugin {
     return `<button role="button" class="carousel-dot ${isActive ? 'active-dot' : ''}" data-slide-target="g${index + 1}"></button>`;
   }
 }
-
-export default ESLCarouselDotsPlugin;
-
diff --git a/src/modules/draft/esl-carousel/plugin/esl-carousel-link.plugin.ts b/src/modules/draft/esl-carousel/plugin/esl-carousel-link.plugin.ts
index f989cb04b..9a5eb88f9 100644
--- a/src/modules/draft/esl-carousel/plugin/esl-carousel-link.plugin.ts
+++ b/src/modules/draft/esl-carousel/plugin/esl-carousel-link.plugin.ts
@@ -1,7 +1,7 @@
 import {ExportNs} from '../../../esl-utils/environment/export-ns';
 import {attr} from '../../../esl-base-element/core';
-import ESLCarousel from '../core/esl-carousel';
-import ESLCarouselPlugin from './esl-carousel-plugin';
+import {ESLCarousel} from '../core/esl-carousel';
+import {ESLCarouselPlugin} from './esl-carousel-plugin';
 
 /**
  * Slide Carousel Link plugin. Allows to bind carousel positions.
@@ -67,5 +67,3 @@ export class ESLCarouselLinkPlugin extends ESLCarouselPlugin {
     this._target = target;
   }
 }
-
-export default ESLCarouselLinkPlugin;
diff --git a/src/modules/draft/esl-carousel/plugin/esl-carousel-plugin.ts b/src/modules/draft/esl-carousel/plugin/esl-carousel-plugin.ts
index 6f20e8846..3a92b8a30 100644
--- a/src/modules/draft/esl-carousel/plugin/esl-carousel-plugin.ts
+++ b/src/modules/draft/esl-carousel/plugin/esl-carousel-plugin.ts
@@ -1,5 +1,5 @@
 import {ESLBaseElement} from '../../../esl-base-element/core';
-import ESLCarousel from '../core/esl-carousel';
+import {ESLCarousel} from '../core/esl-carousel';
 
 /**
  * {@link ESLCarousel} Plugin base class.
@@ -73,5 +73,3 @@ export abstract class ESLCarouselPlugin extends ESLBaseElement {
     customElements.whenDefined(ESLCarousel.is).then(() => super.register.call(this, tagName));
   }
 }
-
-export default ESLCarouselPlugin;
diff --git a/src/modules/draft/esl-carousel/plugin/esl-carousel-touch.plugin.ts b/src/modules/draft/esl-carousel/plugin/esl-carousel-touch.plugin.ts
index c6b8621e7..cf6c82d38 100644
--- a/src/modules/draft/esl-carousel/plugin/esl-carousel-touch.plugin.ts
+++ b/src/modules/draft/esl-carousel/plugin/esl-carousel-touch.plugin.ts
@@ -1,5 +1,5 @@
 import {ExportNs} from '../../../esl-utils/environment/export-ns';
-import ESLCarouselPlugin from './esl-carousel-plugin';
+import {ESLCarouselPlugin} from './esl-carousel-plugin';
 import {DeviceDetector} from '../../../esl-utils/environment/device-detector';
 import {EventUtils, Point} from '../../../esl-utils/dom/events';
 
@@ -72,5 +72,3 @@ export class ESLCarouselTouchPlugin extends ESLCarouselPlugin {
     event.stopPropagation();
   };
 }
-
-export default ESLCarouselTouchPlugin;
diff --git a/src/modules/esl-alert/core/esl-alert.ts b/src/modules/esl-alert/core/esl-alert.ts
index df3b4a4e0..9ee5d0015 100644
--- a/src/modules/esl-alert/core/esl-alert.ts
+++ b/src/modules/esl-alert/core/esl-alert.ts
@@ -1,20 +1,22 @@
 import {ExportNs} from '../../esl-utils/environment/export-ns';
 import {bind} from '../../esl-utils/decorators/bind';
 import {jsonAttr} from '../../esl-base-element/core';
-import {ESLBasePopup, PopupActionParams} from '../../esl-base-popup/core';
+import {ESLToggleable, ToggleableActionParams} from '../../esl-toggleable/core';
 import {DeviceDetector} from '../../esl-utils/environment/device-detector';
 import {CSSUtil} from '../../esl-utils/dom/styles';
 import {createZIndexIframe} from '../../esl-utils/fixes/ie-fixes';
 
-export interface AlertActionParams extends PopupActionParams {
+export interface AlertActionParams extends ToggleableActionParams {
   /** text to be shown; pass empty string or null to hide */
   text?: string;
+  /** html content */
+  html?: string;
   /** classes to add to alert element */
   cls?: string;
 }
 
 @ExportNs('Alert')
-export class ESLAlert extends ESLBasePopup {
+export class ESLAlert extends ESLToggleable {
   static is = 'esl-alert';
   static eventNs = 'esl:alert';
 
@@ -25,7 +27,7 @@ export class ESLAlert extends ESLBasePopup {
   @jsonAttr<AlertActionParams>({defaultValue: ESLAlert.defaultConfig})
   public defaultParams: AlertActionParams;
 
-  protected textEl: HTMLElement;
+  protected $text: HTMLElement;
 
   /** Register and create global alert instance */
   public static init() {
@@ -49,9 +51,13 @@ export class ESLAlert extends ESLBasePopup {
   }
 
   public onShow(params: AlertActionParams) {
-    if (params.text) {
+    if (params.text || params.html) {
       CSSUtil.addCls(this, params.cls);
-      this.textEl.textContent = params.text;
+      if (params.text) {
+        this.$text.textContent = params.text;
+      } else if (params.html) {
+        this.$text.innerHTML = params.html;
+      }
       super.onShow(params);
     }
     this.hide(params);
@@ -65,10 +71,10 @@ export class ESLAlert extends ESLBasePopup {
 
   protected connectedCallback() {
     super.connectedCallback();
-    this.textEl = document.createElement('span');
-    this.textEl.className = 'esl-alert-text';
+    this.$text = document.createElement('div');
+    this.$text.className = 'esl-alert-text';
     this.innerHTML = '';
-    this.appendChild(this.textEl);
+    this.appendChild(this.$text);
     if (DeviceDetector.isIE) {
       this.appendChild(createZIndexIframe());
     }
@@ -88,5 +94,3 @@ export class ESLAlert extends ESLBasePopup {
     window.removeEventListener(`${ESLAlert.eventNs}:hide`, this.onWindowEvent);
   }
 }
-
-export default ESLAlert;
diff --git a/src/modules/esl-base-popup/core.less b/src/modules/esl-base-popup/core.less
deleted file mode 100644
index de77578ed..000000000
--- a/src/modules/esl-base-popup/core.less
+++ /dev/null
@@ -1,1 +0,0 @@
-@import "./core/esl-popup-dispatcher.less";
diff --git a/src/modules/esl-base-popup/core.ts b/src/modules/esl-base-popup/core.ts
deleted file mode 100644
index c00bb1e56..000000000
--- a/src/modules/esl-base-popup/core.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './core/esl-base-popup';
-export * from './core/esl-popup-dispatcher';
diff --git a/src/modules/esl-base-popup/core/esl-popup-dispatcher.less b/src/modules/esl-base-popup/core/esl-popup-dispatcher.less
deleted file mode 100644
index 513220ea9..000000000
--- a/src/modules/esl-base-popup/core/esl-popup-dispatcher.less
+++ /dev/null
@@ -1,3 +0,0 @@
-esl-popup-dispatcher {
-  display: none;
-}
diff --git a/src/modules/esl-base-trigger/README.md b/src/modules/esl-base-trigger/README.md
index d4c5e1411..0bd1d3735 100644
--- a/src/modules/esl-base-trigger/README.md
+++ b/src/modules/esl-base-trigger/README.md
@@ -5,6 +5,6 @@ Version: *1.0.0-beta*.
 
 Authors: *Alexey Stsefanovich (ala'n)*, *Julia Murashko*.
 
-ESLBaseTrigger - base for a custom element, that allows to trigger ESLBasePopup instances state changes.
+ESLBaseTrigger - base for a custom element, that allows to trigger ESLToggleable instances state changes.
 
 Description TBD.
diff --git a/src/modules/esl-base-trigger/core/esl-base-trigger.ts b/src/modules/esl-base-trigger/core/esl-base-trigger.ts
index c002d69b4..5e47c7cf5 100644
--- a/src/modules/esl-base-trigger/core/esl-base-trigger.ts
+++ b/src/modules/esl-base-trigger/core/esl-base-trigger.ts
@@ -6,7 +6,7 @@ import {ENTER, SPACE} from '../../esl-utils/dom/keycodes';
 import {TraversingQuery} from '../../esl-traversing-query/core';
 
 import type {NoopFnSignature} from '../../esl-utils/misc/functions';
-import type {ESLBasePopup} from '../../esl-base-popup/core/esl-base-popup';
+import type {ESLToggleable} from '../../esl-toggleable/core/esl-toggleable';
 
 @ExportNs('BaseTrigger')
 export class ESLBaseTrigger extends ESLBaseElement {
@@ -19,16 +19,16 @@ export class ESLBaseTrigger extends ESLBaseElement {
   @attr({defaultValue: ''}) public activeClass: string;
   @attr({defaultValue: ''}) public activeClassTarget: string;
 
-  protected _popup: ESLBasePopup;
+  protected _$target: ESLToggleable;
   protected __unsubscribers: NoopFnSignature[];
 
-  public get popup() {
-    return this._popup;
+  public get $target() {
+    return this._$target;
   }
-  public set popup(newPopupInstance) {
+  public set $target(newPopupInstance) {
     this.unbindEvents();
-    this._popup = newPopupInstance;
-    if (this._popup) {
+    this._$target = newPopupInstance;
+    if (this._$target) {
       this.bindEvents();
       this._onPopupStateChange();
     }
@@ -49,7 +49,7 @@ export class ESLBaseTrigger extends ESLBaseElement {
   }
 
   protected bindEvents() {
-    if (!this.popup) return;
+    if (!this.$target) return;
     if (this.showEvent === this.hideEvent) {
       this.attachEventListener(this.showEvent, this._onToggleEvent);
     } else {
@@ -57,18 +57,18 @@ export class ESLBaseTrigger extends ESLBaseElement {
       this.attachEventListener(this.hideEvent, this._onHideEvent);
     }
 
-    this.popup.addEventListener('esl:show', this._onPopupStateChange);
-    this.popup.addEventListener('esl:hide', this._onPopupStateChange);
+    this.$target.addEventListener('esl:show', this._onPopupStateChange);
+    this.$target.addEventListener('esl:hide', this._onPopupStateChange);
 
     this.addEventListener('keydown', this._onKeydown);
   }
 
   protected unbindEvents() {
     (this.__unsubscribers || []).forEach((off) => off());
-    if (!this.popup) return;
+    if (!this.$target) return;
 
-    this.popup.removeEventListener('esl:show', this._onPopupStateChange);
-    this.popup.removeEventListener('esl:hide', this._onPopupStateChange);
+    this.$target.removeEventListener('esl:show', this._onPopupStateChange);
+    this.$target.removeEventListener('esl:hide', this._onPopupStateChange);
 
     this.removeEventListener('keydown', this._onKeydown);
   }
@@ -82,14 +82,14 @@ export class ESLBaseTrigger extends ESLBaseElement {
 
   @bind
   protected _onShowEvent(e: Event) {
-    this.popup.show({
+    this.$target.show({
       activator: this,
       delay: this.showDelayValue
     });
   }
   @bind
   protected _onHideEvent(e: Event) {
-    this.popup.hide({
+    this.$target.hide({
       activator: this,
       delay: this.hideDelayValue
     });
@@ -101,7 +101,7 @@ export class ESLBaseTrigger extends ESLBaseElement {
 
   @bind
   protected _onPopupStateChange() {
-    this.active = this.popup.open;
+    this.active = this.$target.open;
     const clsTarget = TraversingQuery.first(this.activeClassTarget, this) as HTMLElement;
     clsTarget && CSSUtil.toggleClsTo(clsTarget, this.activeClass, this.active);
     this.updateA11y();
@@ -125,8 +125,8 @@ export class ESLBaseTrigger extends ESLBaseElement {
     target.setAttribute('aria-expanded', String(this.active));
 
     // TODO: auto generate
-    if (this.popup.id) {
-      target.setAttribute('aria-controls', this.popup.id);
+    if (this.$target.id) {
+      target.setAttribute('aria-controls', this.$target.id);
     }
   }
 
diff --git a/src/modules/esl-forms/all.less b/src/modules/esl-forms/all.less
new file mode 100644
index 000000000..e72857e9b
--- /dev/null
+++ b/src/modules/esl-forms/all.less
@@ -0,0 +1,2 @@
+@import "./esl-select/core.less";
+@import "./esl-select-list/core.less";
diff --git a/src/modules/esl-forms/all.ts b/src/modules/esl-forms/all.ts
new file mode 100644
index 000000000..0ea82546b
--- /dev/null
+++ b/src/modules/esl-forms/all.ts
@@ -0,0 +1,2 @@
+export * from './esl-select/core';
+export * from './esl-select-list/core';
diff --git a/src/modules/esl-forms/esl-select-list/README.md b/src/modules/esl-forms/esl-select-list/README.md
new file mode 100644
index 000000000..ae4a63ce8
--- /dev/null
+++ b/src/modules/esl-forms/esl-select-list/README.md
@@ -0,0 +1,13 @@
+# [ESL](../../../../README.md) Select List
+
+Version: *1.0.0-beta*.  
+***Important Notice: the component is under beta version, it was tested and now ready to use but be aware of its potential critical API changes.***
+
+Authors: *Alexey Stsefanovich (ala'n)*.
+
+ESLSelectList - is a custom element, for customized selectable list representation.
+
+ESLSelectList is HTML5 form compatible.
+HTMLSelectElement is used as model for ESLSelectList in the current implementation.
+
+Description TBD.
diff --git a/src/modules/draft/esl-select-list/core.less b/src/modules/esl-forms/esl-select-list/core.less
similarity index 88%
rename from src/modules/draft/esl-select-list/core.less
rename to src/modules/esl-forms/esl-select-list/core.less
index be1495ce9..d1a55d601 100644
--- a/src/modules/draft/esl-select-list/core.less
+++ b/src/modules/esl-forms/esl-select-list/core.less
@@ -1,6 +1,6 @@
 // Variables defaults, can be overwritten on consumer side
 @esl-select-list-check: #fff;
-@esl-select-list-primary: #0a0;
+@esl-select-list-primary: #007bff;
 @esl-select-list-disabled: #aaa;
 @esl-select-list-secondary: #ccc;
 @esl-select-list-background: #fff;
diff --git a/src/modules/draft/esl-select-list/core.ts b/src/modules/esl-forms/esl-select-list/core.ts
similarity index 100%
rename from src/modules/draft/esl-select-list/core.ts
rename to src/modules/esl-forms/esl-select-list/core.ts
diff --git a/src/modules/draft/esl-select-list/core/esl-select-item.less b/src/modules/esl-forms/esl-select-list/core/esl-select-item.less
similarity index 98%
rename from src/modules/draft/esl-select-list/core/esl-select-item.less
rename to src/modules/esl-forms/esl-select-list/core/esl-select-item.less
index bbe570514..6c82cf1c9 100644
--- a/src/modules/draft/esl-select-list/core/esl-select-item.less
+++ b/src/modules/esl-forms/esl-select-list/core/esl-select-item.less
@@ -61,8 +61,11 @@ esl-select-item {
   pointer-events: none;
   color: @esl-select-list-disabled;
 
-  &[selected]::before {
+  &::before {
     border-color: @esl-select-list-disabled;
+  }
+
+  &[selected]::before {
     background-color: @esl-select-list-disabled;
   }
 }
diff --git a/src/modules/draft/esl-select-list/core/esl-select-item.ts b/src/modules/esl-forms/esl-select-list/core/esl-select-item.ts
similarity index 92%
rename from src/modules/draft/esl-select-list/core/esl-select-item.ts
rename to src/modules/esl-forms/esl-select-list/core/esl-select-item.ts
index 42dbd5092..f645d9b4e 100644
--- a/src/modules/draft/esl-select-list/core/esl-select-item.ts
+++ b/src/modules/esl-forms/esl-select-list/core/esl-select-item.ts
@@ -1,6 +1,9 @@
-import type {ESLSelectOption} from './esl-select-wrapper';
 import {attr, boolAttr, ESLBaseElement} from '../../../esl-base-element/core';
+import {ExportNs} from '../../../esl-utils/environment/export-ns';
+
+import type {ESLSelectOption} from './esl-select-wrapper';
 
+@ExportNs('SelectItem')
 export class ESLSelectItem extends ESLBaseElement {
   public static readonly is: string = 'esl-select-item';
 
diff --git a/src/modules/draft/esl-select-list/core/esl-select-list.less b/src/modules/esl-forms/esl-select-list/core/esl-select-list.less
similarity index 84%
rename from src/modules/draft/esl-select-list/core/esl-select-list.less
rename to src/modules/esl-forms/esl-select-list/core/esl-select-list.less
index d695e4f27..4a34f0503 100644
--- a/src/modules/draft/esl-select-list/core/esl-select-list.less
+++ b/src/modules/esl-forms/esl-select-list/core/esl-select-list.less
@@ -22,12 +22,16 @@
     clip: rect(0,0,0,0);
   }
 
-  esl-scrollbar.esl-scrollbar {
-    top: 60px;
+  esl-scrollbar {
+    top: 5px;
     bottom: 5px;
     right: 10px;
   }
 
+  &[multiple] esl-scrollbar {
+    top: 60px;
+  }
+
   .esl-select-list-container {
     flex: 1 1 auto;
     height: 100%;
@@ -38,4 +42,7 @@
     flex: 0 0 auto;
     border-bottom: 1px solid @esl-select-list-secondary;
   }
+  &:not([multiple]) .esl-select-all-item {
+    display: none;
+  }
 }
diff --git a/src/modules/draft/esl-select-list/core/esl-select-list.ts b/src/modules/esl-forms/esl-select-list/core/esl-select-list.ts
similarity index 92%
rename from src/modules/draft/esl-select-list/core/esl-select-list.ts
rename to src/modules/esl-forms/esl-select-list/core/esl-select-list.ts
index fcfc3b20d..d9bb9e1f3 100644
--- a/src/modules/draft/esl-select-list/core/esl-select-list.ts
+++ b/src/modules/esl-forms/esl-select-list/core/esl-select-list.ts
@@ -1,10 +1,11 @@
 import {attr, boolAttr} from '../../../esl-base-element/core';
 import {bind} from '../../../esl-utils/decorators/bind';
+import {ExportNs} from '../../../esl-utils/environment/export-ns';
 import {ESLScrollbar} from '../../../esl-scrollbar/core';
 import {ESLSelectItem} from './esl-select-item';
-
 import {ESLSelectWrapper} from './esl-select-wrapper';
 
+@ExportNs('SelectList')
 export class ESLSelectList extends ESLSelectWrapper {
   public static readonly is = 'esl-select-list';
   public static get observedAttributes() {
@@ -72,22 +73,22 @@ export class ESLSelectList extends ESLSelectWrapper {
   protected bindSelect() {
     const target = this.querySelector('[esl-select-target]') as HTMLSelectElement;
     if (!target || !(target instanceof HTMLSelectElement)) return;
-    this.select = target;
+    this.$select = target;
   }
 
   public bindEvents() {
-    if (!this.select) return;
+    if (!this.$select) return;
     this.addEventListener('click', this._onClick);
     this.addEventListener('keypress', this._onKeyboard);
   }
   public unbindEvents() {
-    if (!this.select) return;
+    if (!this.$select) return;
     this.removeEventListener('click', this._onClick);
     this.removeEventListener('keypress', this._onKeyboard);
   }
 
   protected _renderItems() {
-    if (!this.select) return;
+    if (!this.$select) return;
     this.$list.innerHTML = '';
     this.$items = this.options.map(ESLSelectItem.build);
     if (this.pinSelected) {
@@ -96,6 +97,7 @@ export class ESLSelectList extends ESLSelectWrapper {
     } else {
       this._renderGroup(this.$items);
     }
+    this.toggleAttribute('multiple', this.multiple);
   }
   protected _renderGroup(items: ESLSelectItem[]) {
     items.forEach((item) => this.$list.appendChild(item));
@@ -104,13 +106,14 @@ export class ESLSelectList extends ESLSelectWrapper {
   }
 
   protected _updateSelectAll() {
+    if (!this.multiple) return;
     this.$selectAll.selected = this.isAllSelected();
     this.$selectAll.textContent = this.selectAllLabel;
   }
   protected _updateDisabled() {
     this.setAttribute('aria-disabled', String(this.disabled));
-    if (!this.select) return;
-    this.select.disabled = this.disabled;
+    if (!this.$select) return;
+    this.$select.disabled = this.disabled;
   }
 
   @bind
diff --git a/src/modules/draft/esl-select-list/core/esl-select-wrapper.ts b/src/modules/esl-forms/esl-select-list/core/esl-select-wrapper.ts
similarity index 85%
rename from src/modules/draft/esl-select-list/core/esl-select-wrapper.ts
rename to src/modules/esl-forms/esl-select-list/core/esl-select-wrapper.ts
index 6e4d581bb..1d9da83be 100644
--- a/src/modules/draft/esl-select-list/core/esl-select-wrapper.ts
+++ b/src/modules/esl-forms/esl-select-list/core/esl-select-wrapper.ts
@@ -8,6 +8,8 @@ export interface ESLSelectOption {
 }
 
 export interface ESLSelectModel {
+  /** Allow multiple items */
+  multiple: boolean;
   /** Get list of options */
   options: ESLSelectOption[];
   /** Get list of selected options */
@@ -29,10 +31,10 @@ export interface ESLSelectModel {
 export abstract class ESLSelectWrapper extends ESLBaseElement implements ESLSelectModel {
   private _$select: HTMLSelectElement;
 
-  public get select() {
+  public get $select() {
     return this._$select;
   }
-  public set select(select: HTMLSelectElement) {
+  public set $select(select: HTMLSelectElement) {
     const prev = this._$select;
     this._$select = select;
     this._onTargetChange(select, prev);
@@ -50,8 +52,12 @@ export abstract class ESLSelectWrapper extends ESLBaseElement implements ESLSele
     if (newTarget) newTarget.addEventListener('change', this._onChange);
   }
 
+  public get multiple() {
+    return this.$select && this.$select.multiple;
+  }
+
   public get options(): ESLSelectOption[] {
-    return this._$select ? Array.from(this._$select.options) : [];
+    return this.$select ? Array.from(this.$select.options) : [];
   }
   public get selected(): ESLSelectOption[] {
     return this.options.filter((item) => item.selected);
@@ -64,7 +70,7 @@ export abstract class ESLSelectWrapper extends ESLBaseElement implements ESLSele
   public setSelected(value: string, state: boolean) {
     const option = this.getOption(value);
     option && (option.selected = state);
-    EventUtils.dispatch(this._$select, 'change');
+    EventUtils.dispatch(this.$select, 'change');
   }
   public isSelected(value: string): boolean {
     const opt = this.getOption(value);
@@ -79,7 +85,8 @@ export abstract class ESLSelectWrapper extends ESLBaseElement implements ESLSele
   }
 
   public setAllSelected(state: boolean) {
+    if (!this.multiple) return false;
     this.options.forEach((item) => item.selected = state);
-    EventUtils.dispatch(this._$select, 'change');
+    EventUtils.dispatch(this.$select, 'change');
   }
 }
diff --git a/src/modules/esl-forms/esl-select/README.md b/src/modules/esl-forms/esl-select/README.md
new file mode 100644
index 000000000..140d63adb
--- /dev/null
+++ b/src/modules/esl-forms/esl-select/README.md
@@ -0,0 +1,13 @@
+# [ESL](../../../../README.md) Select
+
+Version: *1.0.0-beta*.  
+***Important Notice: the component is under beta version, it was tested and now ready to use but be aware of its potential critical API changes.***
+
+Authors: *Alexey Stsefanovich (ala'n)*.
+
+ESLSelect - is a custom element, for customized select element.
+
+ESLSelect is HTML5 form compatible.
+HTMLSelectElement is used as model for ESLSelect in the current implementation.
+
+Description TBD.
diff --git a/src/modules/draft/esl-select/core.less b/src/modules/esl-forms/esl-select/core.less
similarity index 89%
rename from src/modules/draft/esl-select/core.less
rename to src/modules/esl-forms/esl-select/core.less
index 354347955..14978a6b4 100644
--- a/src/modules/draft/esl-select/core.less
+++ b/src/modules/esl-forms/esl-select/core.less
@@ -1,5 +1,5 @@
 // Variables defaults, can be overwritten on consumer side
-@esl-select-primary: #0a0;
+@esl-select-primary: #007bff;
 @esl-select-disabled: #aaa;
 @esl-select-empty-color: #aaa;
 
diff --git a/src/modules/draft/esl-select/core.ts b/src/modules/esl-forms/esl-select/core.ts
similarity index 100%
rename from src/modules/draft/esl-select/core.ts
rename to src/modules/esl-forms/esl-select/core.ts
diff --git a/src/modules/draft/esl-select/core/esl-select-dropdown.less b/src/modules/esl-forms/esl-select/core/esl-select-dropdown.less
similarity index 89%
rename from src/modules/draft/esl-select/core/esl-select-dropdown.less
rename to src/modules/esl-forms/esl-select/core/esl-select-dropdown.less
index ae8314db3..1d2000af5 100644
--- a/src/modules/draft/esl-select/core/esl-select-dropdown.less
+++ b/src/modules/esl-forms/esl-select/core/esl-select-dropdown.less
@@ -30,10 +30,14 @@
       margin-right: 20px;
     }
 
-    esl-scrollbar.esl-scrollbar {
-      top: 56px;
+    esl-scrollbar {
+      top: 6px;
       bottom: 6px;
       right: 2px;
     }
+
+    &[multiple] esl-scrollbar {
+      top: 56px;
+    }
   }
 }
diff --git a/src/modules/draft/esl-select/core/esl-select-dropdown.ts b/src/modules/esl-forms/esl-select/core/esl-select-dropdown.ts
similarity index 88%
rename from src/modules/draft/esl-select/core/esl-select-dropdown.ts
rename to src/modules/esl-forms/esl-select/core/esl-select-dropdown.ts
index 9bb48cae5..6c62e8e89 100644
--- a/src/modules/draft/esl-select/core/esl-select-dropdown.ts
+++ b/src/modules/esl-forms/esl-select/core/esl-select-dropdown.ts
@@ -1,11 +1,11 @@
-import {ESLBasePopup, PopupActionParams} from '../../../esl-base-popup/core/esl-base-popup';
+import {ESLToggleable, ToggleableActionParams} from '../../../esl-toggleable/core/esl-toggleable';
 import {bind} from '../../../esl-utils/decorators/bind';
 import {rafDecorator} from '../../../esl-utils/async/raf';
 import {ESLSelectList} from '../../esl-select-list/core';
 
 import type {ESLSelect} from './esl-select';
 
-export class ESLSelectDropdown extends ESLBasePopup {
+export class ESLSelectDropdown extends ESLToggleable {
   public static readonly is = 'esl-select-dropdown';
   public static register() {
     ESLSelectList.register();
@@ -28,7 +28,6 @@ export class ESLSelectDropdown extends ESLBasePopup {
   constructor() {
     super();
     this.$list = document.createElement(ESLSelectList.is) as ESLSelectList;
-    this.$list.pinSelected = true;
   }
 
   protected setInitialState() {}
@@ -51,19 +50,20 @@ export class ESLSelectDropdown extends ESLBasePopup {
     window.removeEventListener('resize', this._deferredUpdatePosition);
   }
 
-  protected onShow(params: PopupActionParams) {
+  protected onShow(params: ToggleableActionParams) {
     document.body.appendChild(this);
     this._disposeTimeout && window.clearTimeout(this._disposeTimeout);
 
-    this.$list.select = this.owner.select;
+    this.$list.pinSelected = this.owner.pinSelected;
     this.$list.selectAllLabel = this.owner.selectAllLabel;
+    this.$list.$select = this.owner.$select;
 
     super.onShow(params);
     const focusable = this.querySelector('[tabindex]') as HTMLElement;
     focusable && focusable.focus( { preventScroll: true } );
     this.updatePosition();
   }
-  protected onHide(params: PopupActionParams) {
+  protected onHide(params: ToggleableActionParams) {
     const select = this.activator;
     select && setTimeout(() => select.focus({ preventScroll: true }), 0);
     super.onHide(params);
diff --git a/src/modules/draft/esl-select/core/esl-select-renderer.less b/src/modules/esl-forms/esl-select/core/esl-select-renderer.less
similarity index 92%
rename from src/modules/draft/esl-select/core/esl-select-renderer.less
rename to src/modules/esl-forms/esl-select/core/esl-select-renderer.less
index bb5335323..e1f95237d 100644
--- a/src/modules/draft/esl-select/core/esl-select-renderer.less
+++ b/src/modules/esl-forms/esl-select/core/esl-select-renderer.less
@@ -47,4 +47,7 @@ esl-select-renderer {
       content: '\2715';
     }
   }
+  &:not([multiple]) .esl-select-clear-btn {
+    display: none;
+  }
 }
diff --git a/src/modules/draft/esl-select/core/esl-select-renderer.ts b/src/modules/esl-forms/esl-select/core/esl-select-renderer.ts
similarity index 98%
rename from src/modules/draft/esl-select/core/esl-select-renderer.ts
rename to src/modules/esl-forms/esl-select/core/esl-select-renderer.ts
index 6a0e3c257..517315dbf 100644
--- a/src/modules/draft/esl-select/core/esl-select-renderer.ts
+++ b/src/modules/esl-forms/esl-select/core/esl-select-renderer.ts
@@ -83,6 +83,7 @@ export class ESLSelectRenderer extends ESLBaseElement {
     if (!this.owner) return;
     const selected = this.owner.selected;
     this.hasValue = !!selected.length;
+    this.toggleAttribute('multiple', this.owner.multiple);
     this.applyItems(selected.map((item) => item.text));
   }
 
diff --git a/src/modules/draft/esl-select/core/esl-select.less b/src/modules/esl-forms/esl-select/core/esl-select.less
similarity index 84%
rename from src/modules/draft/esl-select/core/esl-select.less
rename to src/modules/esl-forms/esl-select/core/esl-select.less
index ace244a00..f2736102c 100644
--- a/src/modules/draft/esl-select/core/esl-select.less
+++ b/src/modules/esl-forms/esl-select/core/esl-select.less
@@ -1,11 +1,11 @@
-esl-select {
+.esl-select {
   display: inline-block;
   position: relative;
 
   min-width: 300px;
   max-width: 100%;
 
-  &.esl-select [esl-select-target] {
+  & [esl-select-target] {
     /* Visually hidden */
     position: absolute;
     width: 0;
@@ -21,7 +21,7 @@ esl-select {
     color: @esl-select-disabled;
 
     .esl-select-text,
-    .esl-select-renderer:after {
+    .esl-select-renderer::after {
       color: @esl-select-disabled;
     }
     .esl-select-clear-btn {
@@ -29,7 +29,7 @@ esl-select {
     }
   }
 
-  .esl-select-renderer:after {
+  .esl-select-renderer::after {
     content: '\2BC6';
     display: inline-block;
     flex: 0 0 auto;
@@ -48,7 +48,7 @@ esl-select {
     transition: transform .2s linear;
     transform-origin: center center;
   }
-  &[open] .esl-select-renderer:after {
+  &[open] .esl-select-renderer::after {
     transform: rotateX(180deg);
   }
 }
diff --git a/src/modules/draft/esl-select/core/esl-select.ts b/src/modules/esl-forms/esl-select/core/esl-select.ts
similarity index 90%
rename from src/modules/draft/esl-select/core/esl-select.ts
rename to src/modules/esl-forms/esl-select/core/esl-select.ts
index 1c4e5161a..07a4b70df 100644
--- a/src/modules/draft/esl-select/core/esl-select.ts
+++ b/src/modules/esl-forms/esl-select/core/esl-select.ts
@@ -1,11 +1,13 @@
 import {attr, boolAttr} from '../../../esl-base-element/core';
 import {bind} from '../../../esl-utils/decorators/bind';
 import {CSSUtil} from '../../../esl-utils/dom/styles';
+import {ExportNs} from '../../../esl-utils/environment/export-ns';
 
 import {ESLSelectRenderer} from './esl-select-renderer';
 import {ESLSelectDropdown} from './esl-select-dropdown';
 import {ESLSelectWrapper} from '../../esl-select-list/core/esl-select-wrapper';
 
+@ExportNs('Select')
 export class ESLSelect extends ESLSelectWrapper {
   public static readonly is = 'esl-select';
   public static get observedAttributes() {
@@ -32,6 +34,8 @@ export class ESLSelect extends ESLSelectWrapper {
   @boolAttr() public open: boolean;
   /** Disabled state marker */
   @boolAttr() public disabled: boolean;
+  /** Pin to top marker */
+  @boolAttr() public pinSelected: boolean;
 
   protected $text: ESLSelectRenderer;
   protected $dropdown: ESLSelectDropdown;
@@ -50,8 +54,8 @@ export class ESLSelect extends ESLSelectWrapper {
   protected connectedCallback() {
     super.connectedCallback();
 
-    this.select = this.querySelector('[esl-select-target]') as HTMLSelectElement;
-    if (!this.select) return;
+    this.$select = this.querySelector('[esl-select-target]') as HTMLSelectElement;
+    if (!this.$select) return;
 
     this._prepare();
     this._updateDisabled();
@@ -80,21 +84,21 @@ export class ESLSelect extends ESLSelectWrapper {
   }
 
   protected _prepare() {
-    this.$text.className = this.select.className;
+    this.$text.className = this.$select.className;
     this.$text.emptyText = this.emptyText;
     this.$text.moreLabelFormat = this.moreLabelFormat;
     this.$dropdown.owner = this;
     this.appendChild(this.$text);
   }
   protected _dispose() {
-    this.select.className = this.$text.className;
+    this.$select.className = this.$text.className;
     this.removeChild(this.$text);
   }
 
   protected _updateDisabled() {
     this.setAttribute('aria-disabled', String(this.disabled));
-    if (!this.select) return;
-    this.select.disabled = this.disabled;
+    if (!this.$select) return;
+    this.$select.disabled = this.disabled;
     if (this.disabled && this.open) this.$dropdown.hide();
   }
 
diff --git a/src/modules/esl-image/core/esl-image-iobserver.ts b/src/modules/esl-image/core/esl-image-iobserver.ts
index 24104327d..2a3955050 100644
--- a/src/modules/esl-image/core/esl-image-iobserver.ts
+++ b/src/modules/esl-image/core/esl-image-iobserver.ts
@@ -3,7 +3,7 @@
  * @version 1.0.0-alpha
  * @author Alexey Stsefanovich (ala'n), Yuliya Adamskaya
  */
-import ESLImage from './esl-image';
+import {ESLImage} from './esl-image';
 import {DeviceDetector} from '../../esl-utils/environment/device-detector';
 
 let iObserver: IntersectionObserver;
diff --git a/src/modules/esl-image/core/esl-image-strategies.ts b/src/modules/esl-image/core/esl-image-strategies.ts
index c852d4873..1d486fc8e 100644
--- a/src/modules/esl-image/core/esl-image-strategies.ts
+++ b/src/modules/esl-image/core/esl-image-strategies.ts
@@ -1,4 +1,4 @@
-import ESLImage from './esl-image';
+import {ESLImage} from './esl-image';
 
 /**
  * Describe mods configurations
diff --git a/src/modules/esl-image/core/esl-image.less b/src/modules/esl-image/core/esl-image.less
index a172e0842..a9a6ab28e 100644
--- a/src/modules/esl-image/core/esl-image.less
+++ b/src/modules/esl-image/core/esl-image.less
@@ -34,14 +34,14 @@
       max-width: 100%;
     }
 
-    &:after {
+    &::after {
       display: none;
       content: attr(alt);
     }
-    &[error]:after {
+    &[error]::after {
       display: inline-block;
     }
-    &[loaded]:after {
+    &[loaded]::after {
       display: none;
     }
 
diff --git a/src/modules/esl-image/core/esl-image.ts b/src/modules/esl-image/core/esl-image.ts
index cec9ac2de..f2f4403e1 100644
--- a/src/modules/esl-image/core/esl-image.ts
+++ b/src/modules/esl-image/core/esl-image.ts
@@ -308,5 +308,3 @@ export class ESLImage extends ESLBaseElement {
     return src === ESLImage.EMPTY_IMAGE;
   }
 }
-
-export default ESLImage;
diff --git a/src/modules/esl-media-query/core/esl-media-breakpoints.ts b/src/modules/esl-media-query/core/esl-media-breakpoints.ts
index 028624d7b..16d0738cb 100644
--- a/src/modules/esl-media-query/core/esl-media-breakpoints.ts
+++ b/src/modules/esl-media-query/core/esl-media-breakpoints.ts
@@ -97,5 +97,3 @@ export abstract class ESLMediaBreakpoints {
     });
   }
 }
-
-export default ESLMediaBreakpoints;
diff --git a/src/modules/esl-media-query/core/esl-media-query.ts b/src/modules/esl-media-query/core/esl-media-query.ts
index 36e559ed4..d3d70b186 100644
--- a/src/modules/esl-media-query/core/esl-media-query.ts
+++ b/src/modules/esl-media-query/core/esl-media-query.ts
@@ -121,5 +121,3 @@ export class ESLMediaQuery {
     return '[ESL MQ] (' + this.query.media + ')';
   }
 }
-
-export default ESLMediaQuery;
diff --git a/src/modules/esl-media-query/core/esl-media-rule-list.ts b/src/modules/esl-media-query/core/esl-media-rule-list.ts
index bb9a1afde..f4ac249c5 100644
--- a/src/modules/esl-media-query/core/esl-media-rule-list.ts
+++ b/src/modules/esl-media-query/core/esl-media-rule-list.ts
@@ -6,7 +6,7 @@
 
 import {Observable} from '../../esl-utils/abstract/observable';
 import {evaluate} from '../../esl-utils/misc/format';
-import ESLMediaRule from './esl-media-rule';
+import {ESLMediaRule} from './esl-media-rule';
 
 type PayloadParser<T> = (val: string) => T | undefined;
 
@@ -84,5 +84,3 @@ export class ESLMediaRuleList<T> extends Observable {
     }
   };
 }
-
-export default ESLMediaRuleList;
diff --git a/src/modules/esl-media-query/core/esl-media-rule.ts b/src/modules/esl-media-query/core/esl-media-rule.ts
index af0164464..fc55787e5 100644
--- a/src/modules/esl-media-query/core/esl-media-rule.ts
+++ b/src/modules/esl-media-query/core/esl-media-rule.ts
@@ -12,7 +12,7 @@
  * - Mobile / full browser detection (@MOBILE|@DESKTOP)
  */
 
-import ESLMediaQuery from './esl-media-query';
+import {ESLMediaQuery} from './esl-media-query';
 
 type PayloadParser<T> = (val: string) => T | undefined;
 
@@ -51,5 +51,3 @@ export class ESLMediaRule<T> extends ESLMediaQuery {
     return new ESLMediaRule(null, 'all');
   }
 }
-
-export default ESLMediaRule;
diff --git a/src/modules/esl-media/core/esl-media-iobserver.ts b/src/modules/esl-media/core/esl-media-iobserver.ts
index a05a98437..93f353133 100644
--- a/src/modules/esl-media/core/esl-media-iobserver.ts
+++ b/src/modules/esl-media/core/esl-media-iobserver.ts
@@ -3,7 +3,7 @@
  * @version 1.0.0-alpha
  * @author Alexey Stsefanovich (ala'n), Yuliya Adamskaya
  */
-import ESLMedia from './esl-media';
+import {ESLMedia} from './esl-media';
 
 const RATIO_TO_ACTIVATE = 0.75; // TODO: customizable, at least global
 const RATIO_TO_DEACTIVATE = 0.20; // TODO: customizable, at least global
diff --git a/src/modules/esl-media/core/esl-media-manager.ts b/src/modules/esl-media/core/esl-media-manager.ts
index 6b8fa1b2f..c8b5cf284 100644
--- a/src/modules/esl-media/core/esl-media-manager.ts
+++ b/src/modules/esl-media/core/esl-media-manager.ts
@@ -5,7 +5,7 @@
  * @version 1.0.0-alpha
  * @author Alexey Stsefanovich (ala'n), Yuliya Adamskaya
  */
-import ESLMedia from './esl-media';
+import {ESLMedia} from './esl-media';
 
 const managerMap = new Map<string, ESLMedia>();
 
@@ -41,5 +41,3 @@ export class MediaGroupRestrictionManager {
     }
   }
 }
-
-export default MediaGroupRestrictionManager;
diff --git a/src/modules/esl-media/core/esl-media-registry.ts b/src/modules/esl-media/core/esl-media-registry.ts
index 08264b8f0..cc9d50da0 100644
--- a/src/modules/esl-media/core/esl-media-registry.ts
+++ b/src/modules/esl-media/core/esl-media-registry.ts
@@ -3,7 +3,7 @@
  * @version 1.0.0-alpha
  * @author Yuliya Adamskaya, Natallia Harshunova
  */
-import ESLMedia from './esl-media';
+import {ESLMedia} from './esl-media';
 import {Observable} from '../../esl-utils/abstract/observable';
 import type {BaseProvider, ProviderType} from './esl-media-provider';
 
@@ -69,5 +69,3 @@ export class ESLMediaProviderRegistry extends Observable {
     return new provider(media, config);
   }
 }
-
-export default ESLMediaProviderRegistry.instance;
diff --git a/src/modules/esl-media/core/esl-media.less b/src/modules/esl-media/core/esl-media.less
index a52d4c295..1984ec7f0 100644
--- a/src/modules/esl-media/core/esl-media.less
+++ b/src/modules/esl-media/core/esl-media.less
@@ -22,7 +22,7 @@
         z-index: -1;
         pointer-events: none;
       }
-      &:after {
+      &::after {
         content: '';
         position: absolute;
         top: 0;
diff --git a/src/modules/esl-media/core/esl-media.ts b/src/modules/esl-media/core/esl-media.ts
index 1b185cd6a..d9c7bf75d 100644
--- a/src/modules/esl-media/core/esl-media.ts
+++ b/src/modules/esl-media/core/esl-media.ts
@@ -17,8 +17,8 @@ import {TraversingQuery} from '../../esl-traversing-query/core';
 
 import {getIObserver} from './esl-media-iobserver';
 import {BaseProvider, PlayerStates} from './esl-media-provider';
-import ESLMediaRegistry from './esl-media-registry';
-import MediaGroupRestrictionManager from './esl-media-manager';
+import {ESLMediaProviderRegistry} from './esl-media-registry';
+import {MediaGroupRestrictionManager} from './esl-media-manager';
 
 @ExportNs('Media')
 export class ESLMedia extends ESLBaseElement {
@@ -83,7 +83,7 @@ export class ESLMedia extends ESLBaseElement {
   }
 
   static supports(name: string): boolean {
-    return ESLMediaRegistry.has(name);
+    return ESLMediaProviderRegistry.instance.has(name);
   }
 
   protected connectedCallback() {
@@ -92,7 +92,7 @@ export class ESLMedia extends ESLBaseElement {
       this.setAttribute('role', 'application');
     }
     this.innerHTML += '<!-- Inner Content, do not modify it manually -->';
-    ESLMediaRegistry.addListener(this._onRegistryStateChange);
+    ESLMediaProviderRegistry.instance.addListener(this._onRegistryStateChange);
     if (this.conditionQuery) {
       this.conditionQuery.addListener(this.deferredReinitialize);
     }
@@ -105,7 +105,7 @@ export class ESLMedia extends ESLBaseElement {
 
   protected disconnectedCallback() {
     super.disconnectedCallback();
-    ESLMediaRegistry.removeListener(this._onRegistryStateChange);
+    ESLMediaProviderRegistry.instance.removeListener(this._onRegistryStateChange);
     if (this.conditionQuery) {
       this.conditionQuery.removeListener(this.deferredReinitialize);
     }
@@ -154,7 +154,7 @@ export class ESLMedia extends ESLBaseElement {
     this._provider = null;
 
     if (this.canActivate()) {
-      this._provider = ESLMediaRegistry.createFor(this);
+      this._provider = ESLMediaProviderRegistry.instance.createFor(this);
       if (this._provider) {
         this._provider.bind();
         console.debug('[ESL] Media provider bound', this._provider);
@@ -349,5 +349,3 @@ export class ESLMedia extends ESLBaseElement {
     return EventUtils.dispatch(this, ns + eventName, eventInit);
   }
 }
-
-export default ESLMedia;
diff --git a/src/modules/esl-panel/core/esl-panel-stack.ts b/src/modules/esl-panel/core/esl-panel-stack.ts
index 71cd94b79..e8c0d841d 100644
--- a/src/modules/esl-panel/core/esl-panel-stack.ts
+++ b/src/modules/esl-panel/core/esl-panel-stack.ts
@@ -5,7 +5,7 @@ import {bind} from '../../esl-utils/decorators/bind';
 import {CSSUtil} from '../../esl-utils/dom/styles';
 import {ESLMediaQuery} from '../../esl-media-query/core';
 
-import ESLPanel from './esl-panel';
+import {ESLPanel} from './esl-panel';
 
 @ExportNs('PanelStack')
 export class ESLPanelStack extends ESLBaseElement {
@@ -150,5 +150,3 @@ export class ESLPanelStack extends ESLBaseElement {
     CSSUtil.toggleClsTo(this, this.accordionClass, this.isAccordion);
   };
 }
-
-export default ESLPanelStack;
diff --git a/src/modules/esl-panel/core/esl-panel.ts b/src/modules/esl-panel/core/esl-panel.ts
index c1d0ca009..d13d802c9 100644
--- a/src/modules/esl-panel/core/esl-panel.ts
+++ b/src/modules/esl-panel/core/esl-panel.ts
@@ -3,17 +3,17 @@ import {CSSUtil} from '../../esl-utils/dom/styles';
 import {bind} from '../../esl-utils/decorators/bind';
 import {afterNextRender} from '../../esl-utils/async/raf';
 import {attr, boolAttr, jsonAttr} from '../../esl-base-element/core';
-import {ESLBasePopup, PopupActionParams} from '../../esl-base-popup/core';
+import {ESLToggleable, ToggleableActionParams} from '../../esl-toggleable/core';
 
-import ESLPanelStack from './esl-panel-stack';
+import {ESLPanelStack} from './esl-panel-stack';
 
-export interface PanelActionParams extends PopupActionParams {
+export interface PanelActionParams extends ToggleableActionParams {
   noCollapse?: boolean;
   noAnimation?: boolean;
 }
 
 @ExportNs('Panel')
-export class ESLPanel extends ESLBasePopup {
+export class ESLPanel extends ESLToggleable {
   public static is = 'esl-panel';
 
   @attr({defaultValue: 'open'}) public activeClass: string;
@@ -25,7 +25,7 @@ export class ESLPanel extends ESLBasePopup {
   @boolAttr() public startAnimation: boolean;
 
   @jsonAttr<PanelActionParams>({defaultValue: {force: true, initiator: 'init', noAnimation: true}})
-  public initialParams: PopupActionParams;
+  public initialParams: ToggleableActionParams;
 
   protected _initialHeight: number = 0;
 
@@ -107,10 +107,8 @@ export class ESLPanel extends ESLBasePopup {
   }
 
   /** The panels use panel stack config for actions */
-  protected mergeDefaultParams(params?: PopupActionParams): PopupActionParams {
+  protected mergeDefaultParams(params?: ToggleableActionParams): ToggleableActionParams {
     const stackConfig = this.stack?.panelConfig || {};
     return Object.assign({}, stackConfig, this.defaultParams, params || {});
   }
 }
-
-export default ESLPanel;
diff --git a/src/modules/esl-popup/core/esl-popup.ts b/src/modules/esl-popup/core/esl-popup.ts
index b07963dc7..11955b138 100644
--- a/src/modules/esl-popup/core/esl-popup.ts
+++ b/src/modules/esl-popup/core/esl-popup.ts
@@ -1,25 +1,23 @@
 import {ExportNs} from '../../esl-utils/environment/export-ns';
 import {attr} from '../../esl-base-element/core';
-import {ESLBasePopup, PopupActionParams} from '../../esl-base-popup/core';
+import {ESLToggleable, ToggleableActionParams} from '../../esl-toggleable/core';
 import {ScrollStrategy, ScrollUtility} from '../../esl-utils/dom/scroll';
 
 @ExportNs('Popup')
-export class ESLPopup extends ESLBasePopup {
+export class ESLPopup extends ESLToggleable {
   public static is = 'esl-popup';
 
   @attr({defaultValue: null}) public disableScroll: ScrollStrategy;
 
-  protected onShow(params: PopupActionParams) {
+  protected onShow(params: ToggleableActionParams) {
     super.onShow(params);
 
     this.disableScroll !== null && ScrollUtility.requestLock(this, this.disableScroll);
   }
 
-  protected onHide(params: PopupActionParams) {
+  protected onHide(params: ToggleableActionParams) {
     super.onHide(params);
 
     this.disableScroll !== null && ScrollUtility.requestUnlock(this, this.disableScroll);
   }
 }
-
-export default ESLPopup;
diff --git a/src/modules/esl-scrollable-tabs/core/esl-scrollable-tabs.ts b/src/modules/esl-scrollable-tabs/core/esl-scrollable-tabs.ts
index 2604f47f3..1190d67cd 100644
--- a/src/modules/esl-scrollable-tabs/core/esl-scrollable-tabs.ts
+++ b/src/modules/esl-scrollable-tabs/core/esl-scrollable-tabs.ts
@@ -134,5 +134,3 @@ export class ESLScrollableTabs extends ESLTabsContainer {
     this.deferredFitToViewport(this.current() as ESLTab, 'auto');
   });
 }
-
-export default ESLScrollableTabs;
diff --git a/src/modules/esl-scrollbar/core/esl-scrollbar-arrows.less b/src/modules/esl-scrollbar/core/esl-scrollbar-arrows.less
index 0c7d9c313..3c6dfe200 100644
--- a/src/modules/esl-scrollbar/core/esl-scrollbar-arrows.less
+++ b/src/modules/esl-scrollbar/core/esl-scrollbar-arrows.less
@@ -4,8 +4,8 @@
       padding-top: 15px;
       padding-bottom: 15px;
       .scrollbar-track {
-        &:before,
-        &:after {
+        &::before,
+        &::after {
           content: '';
           position: absolute;
           display: block;
@@ -15,11 +15,11 @@
           background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 10' xml:space='preserve'%3E%3Cpolyline points='0,0 8,8 16,0' fill='none' stroke='%23BBBBBB' stroke-width='5'/%3E%3C/svg%3E");
           background-repeat: no-repeat;
         }
-        &:before {
+        &::before {
           top: -15px;
           transform: scaleY(-1);
         }
-        &:after {
+        &::after {
           bottom: -15px;
         }
       }
@@ -29,8 +29,8 @@
       padding-left: 15px;
       padding-right: 15px;
       .scrollbar-track {
-        &:before,
-        &:after {
+        &::before,
+        &::after {
           content: '';
           position: absolute;
           display: block;
@@ -40,11 +40,11 @@
           background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 16' xml:space='preserve'%3E%3Cpolyline points='0,16 8,8 0,0' fill='none' stroke='%23BBBBBB' stroke-width='5'/%3E%3C/svg%3E");
           background-repeat: no-repeat;
         }
-        &:before {
+        &::before {
           left: -15px;
           transform: scaleX(-1);
         }
-        &:after {
+        &::after {
           right: -15px;
         }
       }
diff --git a/src/modules/esl-scrollbar/core/esl-scrollbar.ts b/src/modules/esl-scrollbar/core/esl-scrollbar.ts
index 578c57c39..59ce2c46c 100644
--- a/src/modules/esl-scrollbar/core/esl-scrollbar.ts
+++ b/src/modules/esl-scrollbar/core/esl-scrollbar.ts
@@ -27,10 +27,10 @@ export class ESLScrollbar extends ESLBaseElement {
 
   protected $scrollbarThumb: HTMLElement;
   protected $scrollbarTrack: HTMLElement;
-  protected $scrollableContent: HTMLElement | null;
 
-  protected _initialMousePosition: number;
+  protected _$target: HTMLElement | null;
   protected _initialPosition: number;
+  protected _initialMousePosition: number;
 
   protected deferredRefresh = rafDecorator(() => this.refresh());
   protected _resizeObserver = new ResizeObserver(this.deferredRefresh);
@@ -60,18 +60,18 @@ export class ESLScrollbar extends ESLBaseElement {
   }
 
   protected findTarget() {
-    this.targetElement = this.target ?
+    this.$target = this.target ?
       TraversingQuery.first(this.target, this) as HTMLElement :
       null;
   }
 
-  public get targetElement() {
-    return this.$scrollableContent || null;
+  public get $target() {
+    return this._$target || null;
   }
 
-  public set targetElement(content: HTMLElement | null) {
+  public set $target(content: HTMLElement | null) {
     this.unbindTargetEvents();
-    this.$scrollableContent = content;
+    this._$target = content;
     this.bindTargetEvents();
     this.deferredRefresh();
   }
@@ -94,20 +94,20 @@ export class ESLScrollbar extends ESLBaseElement {
   }
 
   protected bindTargetEvents() {
-    if (!this.$scrollableContent) return;
-    if (document.documentElement === this.$scrollableContent) {
+    if (!this.$target) return;
+    if (document.documentElement === this.$target) {
       window.addEventListener('resize', this._onRefresh, {passive: true});
       window.addEventListener('scroll', this._onRefresh, {passive: true});
     } else {
-      this._resizeObserver.observe(this.$scrollableContent);
-      this._mutationObserver.observe(this.$scrollableContent, {childList: true});
-      Array.from(this.$scrollableContent.children).forEach((el) => this._resizeObserver.observe(el));
-      this.$scrollableContent.addEventListener('scroll', this._onRefresh, {passive: true});
+      this._resizeObserver.observe(this.$target);
+      this._mutationObserver.observe(this.$target, {childList: true});
+      Array.from(this.$target.children).forEach((el) => this._resizeObserver.observe(el));
+      this.$target.addEventListener('scroll', this._onRefresh, {passive: true});
     }
   }
 
   protected updateContentObserve(recs: MutationRecord[] = []) {
-    if (!this.$scrollableContent) return;
+    if (!this.$target) return;
     const contentChanges = recs.filter((rec) => rec.type === 'childList');
     contentChanges.forEach((rec) => {
       Array.from(rec.addedNodes)
@@ -128,22 +128,22 @@ export class ESLScrollbar extends ESLBaseElement {
   }
 
   protected unbindTargetEvents() {
-    if (!this.$scrollableContent) return;
-    if (document.documentElement === this.$scrollableContent) {
+    if (!this.$target) return;
+    if (document.documentElement === this.$target) {
       window.removeEventListener('resize', this._onRefresh);
       window.removeEventListener('scroll', this._onRefresh);
     } else {
       this._resizeObserver.disconnect();
       this._mutationObserver.disconnect();
-      this.$scrollableContent.removeEventListener('scroll', this._onRefresh);
+      this.$target.removeEventListener('scroll', this._onRefresh);
     }
   }
 
   public get scrollableSize() {
-    if (!this.targetElement) return 0;
+    if (!this.$target) return 0;
     return this.horizontal ?
-      this.targetElement.scrollWidth - this.targetElement.clientWidth :
-      this.targetElement.scrollHeight - this.targetElement.clientHeight;
+      this.$target.scrollWidth - this.$target.clientWidth :
+      this.$target.scrollHeight - this.$target.clientHeight;
   }
 
   public get trackOffset() {
@@ -156,15 +156,15 @@ export class ESLScrollbar extends ESLBaseElement {
 
   public get thumbSize() {
     // behave as native scroll
-    if (!this.targetElement || !this.targetElement.scrollWidth || !this.targetElement.scrollHeight) return 1;
-    const areaSize = this.horizontal ? this.targetElement.clientWidth : this.targetElement.clientHeight;
-    const scrollSize = this.horizontal ? this.targetElement.scrollWidth : this.targetElement.scrollHeight;
+    if (!this.$target || !this.$target.scrollWidth || !this.$target.scrollHeight) return 1;
+    const areaSize = this.horizontal ? this.$target.clientWidth : this.$target.clientHeight;
+    const scrollSize = this.horizontal ? this.$target.scrollWidth : this.$target.scrollHeight;
     return Math.min((areaSize + 1) / scrollSize, 1);
   }
 
   public get position() {
-    if (!this.targetElement) return 0;
-    const scrollOffset = this.horizontal ? this.targetElement.scrollLeft : this.targetElement.scrollTop;
+    if (!this.$target) return 0;
+    const scrollOffset = this.horizontal ? this.$target.scrollLeft : this.$target.scrollTop;
     return this.scrollableSize ? (scrollOffset / this.scrollableSize) : 0;
   }
 
@@ -178,8 +178,8 @@ export class ESLScrollbar extends ESLBaseElement {
    * Scroll target element to passed position
    */
   protected scrollTargetTo(pos: number) {
-    if (!this.targetElement) return;
-    this.targetElement.scrollTo({
+    if (!this.$target) return;
+    this.$target.scrollTo({
       [this.horizontal ? 'left' : 'top']: pos,
       behavior: this.dragging ? 'auto' : 'smooth'
     });
@@ -306,9 +306,7 @@ export class ESLScrollbar extends ESLBaseElement {
   protected _onRefresh(event: Event) {
     const target = event.target as HTMLElement;
     if (event.type === 'scroll' && this.dragging) return;
-    if (event.type === 'esl:refresh' && !TraversingUtils.isRelative(target.parentNode, this.targetElement)) return;
+    if (event.type === 'esl:refresh' && !TraversingUtils.isRelative(target.parentNode, this.$target)) return;
     this.deferredRefresh();
   }
 }
-
-export default ESLScrollbar;
diff --git a/src/modules/esl-tab/core/esl-tab.ts b/src/modules/esl-tab/core/esl-tab.ts
index 08db9d984..edc8e54f4 100644
--- a/src/modules/esl-tab/core/esl-tab.ts
+++ b/src/modules/esl-tab/core/esl-tab.ts
@@ -1,5 +1,5 @@
 import {ExportNs} from '../../esl-utils/environment/export-ns';
-import ESLTrigger from '../../esl-trigger/core/esl-trigger';
+import {ESLTrigger} from '../../esl-trigger/core';
 
 @ExportNs('Tab')
 export class ESLTab extends ESLTrigger {
@@ -12,10 +12,8 @@ export class ESLTab extends ESLTrigger {
     target.setAttribute('tabindex', this.active ? '0' : '-1');
 
     // TODO: auto generate
-    if (this.popup.id) {
-      this.setAttribute('aria-controls', this.popup.id);
+    if (this.$target.id) {
+      this.setAttribute('aria-controls', this.$target.id);
     }
   }
 }
-
-export default ESLTab;
diff --git a/src/modules/esl-tab/core/esl-tabs-container.ts b/src/modules/esl-tab/core/esl-tabs-container.ts
index 17a9de23e..d5b3836ba 100644
--- a/src/modules/esl-tab/core/esl-tabs-container.ts
+++ b/src/modules/esl-tab/core/esl-tabs-container.ts
@@ -1,7 +1,6 @@
 import {ESLTriggersContainer, GroupTarget} from '../../esl-trigger/core/esl-triggers-container';
+import {ESLTab} from './esl-tab';
 import {ExportNs} from '../../esl-utils/environment/export-ns';
-import ESLTab from './esl-tab';
-import ESLTrigger from '../../esl-trigger/core/esl-trigger';
 import {attr} from '../../esl-base-element/decorators/attr';
 
 @ExportNs('TabsContainer')
@@ -15,7 +14,7 @@ export class ESLTabsContainer extends ESLTriggersContainer {
     return els ? Array.from(els) as ESLTab[] : [];
   }
 
-  public goTo(target: GroupTarget, from: ESLTrigger | null = this.current()) {
+  public goTo(target: GroupTarget, from: ESLTab | null = this.current()) {
     if (!from) return;
     super.goTo(target, from);
     const targetEl = this[target](from);
@@ -23,5 +22,3 @@ export class ESLTabsContainer extends ESLTriggersContainer {
     targetEl.click();
   }
 }
-
-export default ESLTabsContainer;
diff --git a/src/modules/esl-base-popup/README.md b/src/modules/esl-toggleable/README.md
similarity index 53%
rename from src/modules/esl-base-popup/README.md
rename to src/modules/esl-toggleable/README.md
index 5aac4d17b..b2b94ffac 100644
--- a/src/modules/esl-base-popup/README.md
+++ b/src/modules/esl-toggleable/README.md
@@ -1,4 +1,4 @@
-# [ESL](../../../README.md) Base Popup
+# [ESL](../../../README.md) Toggleable
 
 Version: *1.0.0-beta*.
 
@@ -6,12 +6,12 @@ Version: *1.0.0-beta*.
 
 Authors: *Julia Murashko*, *Alexey Stsefanovich (ala'n)*.
 
-ESLBasePopup - is a custom element, that is used as a base for "Popup like" components creation.
+ESLToggleable - is a custom element, that is used as a base for "Popup like" components creation.
 
-ESLPopupDispatcher - plugin component, that prevents activation of multiple ESLBasePopup instances in bounds of managed container.
+ESLToggleableDispatcher - plugin component, that prevents activation of multiple ESLToggleable instances in bounds of managed container.
 Usually (and by default) binds to document.body. Use native DOM events to manage controlled instances state.
 
-Use `ESLPopupDispatcher.init()` to initialize (and bind) ESLPopupDispatcher.
+Use `ESLToggleableDispatcher.init()` to initialize (and bind) ESLToggleableDispatcher.
 
 ---
 
@@ -20,8 +20,8 @@ Use `ESLPopupDispatcher.init()` to initialize (and bind) ESLPopupDispatcher.
  - onHide - 'hide' actions to execute when instance becomes inactive
  
 ### Public API:
- - show - trigger popup activation
- - hide - trigger popup deactivation
- - toggle - toggle popup state
+ - show - trigger element activation
+ - hide - trigger element deactivation
+ - toggle - toggle element state
 
 Description TBD.
diff --git a/src/modules/esl-toggleable/core.less b/src/modules/esl-toggleable/core.less
new file mode 100644
index 000000000..a46d477dc
--- /dev/null
+++ b/src/modules/esl-toggleable/core.less
@@ -0,0 +1,1 @@
+@import "./core/esl-toggleable-dispatcher.less";
diff --git a/src/modules/esl-toggleable/core.ts b/src/modules/esl-toggleable/core.ts
new file mode 100644
index 000000000..21676a4cb
--- /dev/null
+++ b/src/modules/esl-toggleable/core.ts
@@ -0,0 +1,2 @@
+export * from './core/esl-toggleable';
+export * from './core/esl-toggleable-dispatcher';
diff --git a/src/modules/esl-toggleable/core/esl-toggleable-dispatcher.less b/src/modules/esl-toggleable/core/esl-toggleable-dispatcher.less
new file mode 100644
index 000000000..cf764f26a
--- /dev/null
+++ b/src/modules/esl-toggleable/core/esl-toggleable-dispatcher.less
@@ -0,0 +1,3 @@
+esl-toggleable-dispatcher {
+  display: none;
+}
diff --git a/src/modules/esl-base-popup/core/esl-popup-dispatcher.ts b/src/modules/esl-toggleable/core/esl-toggleable-dispatcher.ts
similarity index 71%
rename from src/modules/esl-base-popup/core/esl-popup-dispatcher.ts
rename to src/modules/esl-toggleable/core/esl-toggleable-dispatcher.ts
index adcb96d9c..458db34e7 100644
--- a/src/modules/esl-base-popup/core/esl-popup-dispatcher.ts
+++ b/src/modules/esl-toggleable/core/esl-toggleable-dispatcher.ts
@@ -1,16 +1,16 @@
-import {ESLBasePopup} from './esl-base-popup';
+import {ESLToggleable} from './esl-toggleable';
 import {ESLBaseElement} from '../../esl-base-element/core';
 import {bind} from '../../esl-utils/decorators/bind';
 import {EventUtils} from '../../esl-utils/dom/events';
 import {ExportNs} from '../../esl-utils/environment/export-ns';
 
-@ExportNs('PopupGroupDispatcher')
-export class ESLPopupDispatcher extends ESLBaseElement {
-  public static readonly is = 'esl-popup-dispatcher';
+@ExportNs('ToggleableGroupDispatcher')
+export class ESLToggleableDispatcher extends ESLBaseElement {
+  public static readonly is = 'esl-toggleable-dispatcher';
 
   /**
-   * Initialize PopupGroupDispatcher
-   * Uses esl-popup-dispatcher tag and document body root by default
+   * Initialize ToggleableGroupDispatcher
+   * Uses esl-toggleable-dispatcher tag and document body root by default
    */
   public static init(root: HTMLElement = document.body, tagName: string = this.is) {
     if (!root) throw new Error('Root element should be specified');
@@ -21,7 +21,7 @@ export class ESLPopupDispatcher extends ESLBaseElement {
   }
 
   protected _root: HTMLElement | null;
-  protected _popups: Map<string, ESLBasePopup> = new Map<string, ESLBasePopup>();
+  protected _popups: Map<string, ESLToggleable> = new Map<string, ESLToggleable>();
 
   protected connectedCallback() {
     super.connectedCallback();
@@ -58,35 +58,35 @@ export class ESLPopupDispatcher extends ESLBaseElement {
   }
 
   /** Guard-condition for targets */
-  protected isAcceptable(target: any): target is ESLBasePopup {
-    if (!(target instanceof ESLBasePopup)) return false;
+  protected isAcceptable(target: any): target is ESLToggleable {
+    if (!(target instanceof ESLToggleable)) return false;
     return !!target.groupName;
   }
 
-  /** Hide active popup in group */
+  /** Hide active element in group */
   public hideActive(groupName: string) {
     this.getActive(groupName)?.hide();
   }
 
-  /** Set active popup in group */
-  public setActive(groupName: string, popup: ESLBasePopup) {
+  /** Set active element in group */
+  public setActive(groupName: string, popup: ESLToggleable) {
     if (!groupName) return;
     this.hideActive(groupName);
     this._popups.set(groupName, popup);
   }
 
-  /** Get active popup in group or undefined if group doesn't exist */
-  public getActive(groupName: string): ESLBasePopup | undefined {
+  /** Get active element in group or undefined if group doesn't exist */
+  public getActive(groupName: string): ESLToggleable | undefined {
     return this._popups.get(groupName);
   }
 
-  /** Delete popup from the group if passed popup is currently active */
-  public deleteActive(groupName: string, popup: ESLBasePopup) {
+  /** Delete element from the group if passed element is currently active */
+  public deleteActive(groupName: string, popup: ESLToggleable) {
     if (this.getActive(groupName) !== popup) return;
     this._popups.delete(groupName);
   }
 
-  /** Hide active popup before e.target (popup) will be shown */
+  /** Hide active element before e.target will be shown */
   @bind
   protected _onBeforeShow(e: CustomEvent) {
     const target = EventUtils.source(e);
@@ -94,7 +94,7 @@ export class ESLPopupDispatcher extends ESLBaseElement {
     this.hideActive(target.groupName);
   }
 
-  /** Update active popup after a new popup is shown */
+  /** Update active element after a new element is shown */
   @bind
   protected _onShow(e: CustomEvent) {
     const target = EventUtils.source(e);
@@ -103,7 +103,7 @@ export class ESLPopupDispatcher extends ESLBaseElement {
     this.setActive(target.groupName, target);
   }
 
-  /** Update group state after active popup is hidden */
+  /** Update group state after active element is hidden */
   @bind
   protected _onHide(e: CustomEvent) {
     const target = EventUtils.source(e);
@@ -112,7 +112,7 @@ export class ESLPopupDispatcher extends ESLBaseElement {
     this.deleteActive(target.groupName, target);
   }
 
-  /** Update active popups */
+  /** Update active elements */
   @bind
   protected _onChangeGroup(e: CustomEvent) {
     const target = EventUtils.source(e);
diff --git a/src/modules/esl-base-popup/core/esl-base-popup.ts b/src/modules/esl-toggleable/core/esl-toggleable.ts
similarity index 83%
rename from src/modules/esl-base-popup/core/esl-base-popup.ts
rename to src/modules/esl-toggleable/core/esl-toggleable.ts
index 4bb668c37..bbba91bab 100644
--- a/src/modules/esl-base-popup/core/esl-base-popup.ts
+++ b/src/modules/esl-toggleable/core/esl-toggleable.ts
@@ -7,7 +7,7 @@ import {DeviceDetector} from '../../esl-utils/environment/device-detector';
 import {DelayedTask} from '../../esl-utils/async/delayed-task';
 import {ESLBaseElement, attr, jsonAttr, boolAttr} from '../../esl-base-element/core';
 
-export interface PopupActionParams {
+export interface ToggleableActionParams {
   initiator?: string;
   delay?: number;
   showDelay?: number;
@@ -18,10 +18,10 @@ export interface PopupActionParams {
   activator?: HTMLElement;
 }
 
-const activators: WeakMap<ESLBasePopup, HTMLElement | undefined> = new WeakMap();
+const activators: WeakMap<ESLToggleable, HTMLElement | undefined> = new WeakMap();
 
-@ExportNs('BasePopup')
-export class ESLBasePopup extends ESLBaseElement {
+@ExportNs('Toggleable')
+export class ESLToggleable extends ESLBaseElement {
   static get observedAttributes() {
     return ['open', 'group'];
   }
@@ -41,10 +41,10 @@ export class ESLBasePopup extends ESLBaseElement {
   @boolAttr() public closeOnEsc: boolean;
   @boolAttr() public closeOnOutsideAction: boolean;
 
-  @jsonAttr<PopupActionParams>({defaultValue: {force: true, initiator: 'init'}})
-  public initialParams: PopupActionParams;
-  @jsonAttr<PopupActionParams>({defaultValue: {}})
-  public defaultParams: PopupActionParams;
+  @jsonAttr<ToggleableActionParams>({defaultValue: {force: true, initiator: 'init'}})
+  public initialParams: ToggleableActionParams;
+  @jsonAttr<ToggleableActionParams>({defaultValue: {}})
+  public defaultParams: ToggleableActionParams;
 
   protected attributeChangedCallback(attrName: string, oldVal: string, newVal: string) {
     if (!this.connected || newVal === oldVal) return;
@@ -110,28 +110,28 @@ export class ESLBasePopup extends ESLBaseElement {
     }
   }
 
-  protected mergeDefaultParams(params?: PopupActionParams): PopupActionParams {
+  protected mergeDefaultParams(params?: ToggleableActionParams): ToggleableActionParams {
     return Object.assign({}, this.defaultParams, params || {});
   }
 
   /**
-   * Toggle popup state
+   * Toggle element state
    */
-  public toggle(state: boolean = !this.open, params?: PopupActionParams) {
+  public toggle(state: boolean = !this.open, params?: ToggleableActionParams) {
     return state ? this.show(params) : this.hide(params);
   }
 
   /**
-   * Changes popup state to active
+   * Change element state to active
    */
-  public show(params?: PopupActionParams) {
+  public show(params?: ToggleableActionParams) {
     params = this.mergeDefaultParams(params);
     this.planShowTask(params);
     this.bindOutsideEventTracking(this.closeOnOutsideAction);
     this.bindHoverStateTracking(!!params.trackHover);
     return this;
   }
-  private planShowTask(params: PopupActionParams) {
+  private planShowTask(params: ToggleableActionParams) {
     this._task.put(() => {
       if (!params.force && this._open) return;
       if (!params.silent && !this.$$fire('before:show', {detail: {params}})) return;
@@ -141,16 +141,16 @@ export class ESLBasePopup extends ESLBaseElement {
   }
 
   /**
-   * Changes popup state to inactive
+   * Change element state to inactive
    */
-  public hide(params?: PopupActionParams) {
+  public hide(params?: ToggleableActionParams) {
     params = this.mergeDefaultParams(params);
     this.planHideTask(params);
     this.bindOutsideEventTracking(false);
     this.bindHoverStateTracking(!!params.trackHover);
     return this;
   }
-  private planHideTask(params: PopupActionParams) {
+  private planHideTask(params: ToggleableActionParams) {
     this._task.put(() => {
       if (!params.force && !this._open) return;
       if (!params.silent && !this.$$fire('before:hide',{detail: {params}})) return;
@@ -159,7 +159,7 @@ export class ESLBasePopup extends ESLBaseElement {
     }, defined(params.hideDelay, params.delay));
   }
 
-  /** Last element that activate popup. Uses {@link PopupActionParams.activator}*/
+  /** Last component that activate element. Uses {@link ToggleableActionParams.activator}*/
   public get activator() {
     return activators.get(this);
   }
@@ -167,7 +167,7 @@ export class ESLBasePopup extends ESLBaseElement {
   /**
    * Returns element to apply a11y attributes
    */
-  protected get a11yTarget() {
+  protected get $a11yTarget() {
     const target = this.getAttribute('a11y-target');
     if (target === 'none') return;
     return target ? this.querySelector(target) : this;
@@ -177,15 +177,15 @@ export class ESLBasePopup extends ESLBaseElement {
    * Called on show and on hide actions to update a11y state accordingly
    */
   protected updateA11y() {
-    const targetEl = this.a11yTarget;
+    const targetEl = this.$a11yTarget;
     if (!targetEl) return;
     targetEl.setAttribute('aria-hidden', String(!this._open));
   }
 
   /**
-   * Action to show popup
+   * Action to show element
    */
-  protected onShow(params: PopupActionParams) {
+  protected onShow(params: ToggleableActionParams) {
     activators.set(this, params.activator);
     this.open = this._open = true;
     CSSUtil.addCls(this, this.activeClass);
@@ -195,9 +195,9 @@ export class ESLBasePopup extends ESLBaseElement {
   }
 
   /**
-   * Action to hide popup
+   * Action to hide element
    */
-  protected onHide(params: PopupActionParams) {
+  protected onHide(params: ToggleableActionParams) {
     activators.delete(this);
     this.open = this._open = false;
     CSSUtil.removeCls(this, this.activeClass);
diff --git a/src/modules/esl-trigger/README.md b/src/modules/esl-trigger/README.md
index 3745d24e1..0af5240e4 100644
--- a/src/modules/esl-trigger/README.md
+++ b/src/modules/esl-trigger/README.md
@@ -5,6 +5,6 @@ Version: *1.0.0-beta*.
 
 Authors: *Alexey Stsefanovich (ala'n)*, *Julia Murashko*.
 
-ESLTrigger - custom element, that allows to trigger ESLBasePopup instances state changes.
+ESLTrigger - custom element, that allows to trigger ESLToggleable instances state changes.
 
 Description TBD.
diff --git a/src/modules/esl-trigger/core/esl-trigger.ts b/src/modules/esl-trigger/core/esl-trigger.ts
index 4ac1b15bc..513e79f97 100644
--- a/src/modules/esl-trigger/core/esl-trigger.ts
+++ b/src/modules/esl-trigger/core/esl-trigger.ts
@@ -6,7 +6,7 @@ import {bind} from '../../esl-utils/decorators/bind';
 import {ready} from '../../esl-utils/decorators/ready';
 import {TraversingQuery} from '../../esl-traversing-query/core';
 
-import type {ESLBasePopup} from '../../esl-base-popup/core/esl-base-popup';
+import type {ESLToggleable} from '../../esl-toggleable/core/esl-toggleable';
 
 @ExportNs('Trigger')
 export class ESLTrigger extends ESLBaseTrigger {
@@ -56,7 +56,7 @@ export class ESLTrigger extends ESLBaseTrigger {
 
   protected updatePopupFromTarget() {
     if (!this.target) return;
-    this.popup = TraversingQuery.first(this.target, this) as ESLBasePopup;
+    this.$target = TraversingQuery.first(this.target, this) as ESLToggleable;
   }
 
   public get showEvent() {
@@ -77,7 +77,7 @@ export class ESLTrigger extends ESLBaseTrigger {
 
   @bind
   protected _onHideEvent(e: Event) {
-    this.popup.hide({
+    this.$target.hide({
       activator: this,
       delay: this.hideDelayValue,
       trackHover: this.event === 'hover' && this.mode === 'toggle'
@@ -93,5 +93,3 @@ export class ESLTrigger extends ESLBaseTrigger {
     return !hideDelay || isNaN(+hideDelay) ? undefined : +hideDelay;
   }
 }
-
-export default ESLTrigger;
diff --git a/src/modules/esl-trigger/core/esl-triggers-container.ts b/src/modules/esl-trigger/core/esl-triggers-container.ts
index 6f0c48e6c..9b111693f 100644
--- a/src/modules/esl-trigger/core/esl-triggers-container.ts
+++ b/src/modules/esl-trigger/core/esl-triggers-container.ts
@@ -76,5 +76,3 @@ export class ESLTriggersContainer extends ESLBaseElement {
     targetEl.focus();
   }
 }
-
-export default ESLTriggersContainer;
diff --git a/src/modules/esl-utils/decorators/bind.ts b/src/modules/esl-utils/decorators/bind.ts
index 4fc0a4fd9..be603204f 100644
--- a/src/modules/esl-utils/decorators/bind.ts
+++ b/src/modules/esl-utils/decorators/bind.ts
@@ -1,4 +1,4 @@
-const BINDINGS_STORE_KEY = '__fnBindings';
+const BINDINGS_STORE_KEY = '__fnBindings__';
 /** Decorator "bind" allows to bind prototype method context to class instance */
 // eslint-disable-next-line @typescript-eslint/ban-types
 export function bind<T extends Function>(target: object,
diff --git a/src/modules/lib.ts b/src/modules/lib.ts
index 1af2e49c4..45073b445 100644
--- a/src/modules/lib.ts
+++ b/src/modules/lib.ts
@@ -7,8 +7,8 @@ import type {ESLMedia} from './esl-media/core/esl-media';
 
 import type {ESLScrollbar} from './esl-scrollbar/core/esl-scrollbar';
 
-import type {ESLPopupDispatcher} from './esl-base-popup/core/esl-popup-dispatcher';
-import type {ESLBasePopup} from './esl-base-popup/core/esl-base-popup';
+import type {ESLToggleableDispatcher} from './esl-toggleable/core/esl-toggleable-dispatcher';
+import type {ESLToggleable} from './esl-toggleable/core/esl-toggleable';
 import type {ESLPopup} from './esl-popup/core/esl-popup';
 import type {ESLTrigger} from './esl-trigger/core/esl-trigger';
 import type {ESLTab} from './esl-tab/core/esl-tab';
@@ -18,6 +18,8 @@ import type {ESLPanelStack} from './esl-panel/core/esl-panel-stack';
 import type {ESLTabsContainer} from './esl-tab/core/esl-tabs-container';
 import type {ESLScrollableTabs} from './esl-scrollable-tabs/core/esl-scrollable-tabs';
 
+import type {ESLSelect, ESLSelectList, ESLSelectItem} from './esl-forms/all';
+
 import type {ESLCarousel} from './draft/esl-carousel/core/esl-carousel';
 import type {ESLCarouselDotsPlugin} from './draft/esl-carousel/plugin/esl-carousel-dots.plugin';
 import type {ESLCarouselLinkPlugin} from './draft/esl-carousel/plugin/esl-carousel-link.plugin';
@@ -40,8 +42,8 @@ declare global {
     Media?: typeof ESLMedia;
     Scrollbar?: typeof ESLScrollbar;
 
-    PopupGroupDispatcher?: typeof ESLPopupDispatcher;
-    BasePopup?: typeof ESLBasePopup;
+    ToggleableGroupDispatcher?: typeof ESLToggleableDispatcher;
+    Toggleable?: typeof ESLToggleable;
     Popup?: typeof ESLPopup;
     Trigger?: typeof ESLTrigger;
     Tab?: typeof ESLTab;
@@ -51,6 +53,10 @@ declare global {
     TabsContainer?: typeof ESLTabsContainer;
     ScrollableTabs?: typeof ESLScrollableTabs;
 
+    Select?: typeof ESLSelect;
+    SelectList?: typeof ESLSelectList;
+    SelectItem?: typeof ESLSelectItem;
+
     Carousel?: typeof ESLCarousel;
     CarouselPlugins: {
       Dots?: typeof ESLCarouselDotsPlugin;


Test patch:
diff --git a/src/modules/esl-media-query/test/esl-media-breakpoints.test.ts b/src/modules/esl-media-query/test/esl-media-breakpoints.test.ts
index 793adf8cd..4cf2019a5 100644
--- a/src/modules/esl-media-query/test/esl-media-breakpoints.test.ts
+++ b/src/modules/esl-media-query/test/esl-media-breakpoints.test.ts
@@ -1,4 +1,4 @@
-import ESLMediaBreakpoints from '../core/esl-media-breakpoints';
+import {ESLMediaBreakpoints} from '../core/esl-media-breakpoints';
 
 describe('esl breakpoints test', () => {
   test('Get all breakpoints', () => {
diff --git a/src/modules/esl-media-query/test/esl-media-query.test.ts b/src/modules/esl-media-query/test/esl-media-query.test.ts
index 8524b44b5..a3aa14fff 100644
--- a/src/modules/esl-media-query/test/esl-media-query.test.ts
+++ b/src/modules/esl-media-query/test/esl-media-query.test.ts
@@ -18,8 +18,8 @@
 import {mmMock} from "../../esl-utils/test/matchMedia.mock";
 import {DDMock} from "../../esl-utils/test/deviceDetector.mock";
 
-import ESLMediaBreakpoints from '../core/esl-media-breakpoints';
-import ESLMediaQuery from '../core/esl-media-query';
+import {ESLMediaBreakpoints} from '../core/esl-media-breakpoints';
+import {ESLMediaQuery} from '../core/esl-media-query';
 
 describe('ESLMediaQuery tests', () => {
   beforeAll(() => {
diff --git a/src/modules/esl-media/test/media-manager.test.ts b/src/modules/esl-media/test/media-manager.test.ts
index 2038cc055..97414bd73 100644
--- a/src/modules/esl-media/test/media-manager.test.ts
+++ b/src/modules/esl-media/test/media-manager.test.ts
@@ -1,6 +1,6 @@
 import '../../../polyfills/es5-target-shim';
-import ESLMedia from '../core/esl-media';
-import MediaGroupRestrictionManager from '../core/esl-media-manager';
+import {ESLMedia} from '../core/esl-media';
+import {MediaGroupRestrictionManager} from '../core/esl-media-manager';
 
 describe('ESLMedia: MediaGroupRestrictionManager tests', () => {
   ESLMedia.register();
diff --git a/src/modules/esl-utils/async/test/throttle.test.ts b/src/modules/esl-utils/async/test/throttle.test.ts
index 5a2600c40..0ab8b0853 100644
--- a/src/modules/esl-utils/async/test/throttle.test.ts
+++ b/src/modules/esl-utils/async/test/throttle.test.ts
@@ -21,8 +21,8 @@ describe('async/throttle', () => {
       throttled();
       expect(fn).toBeCalledTimes(3);
       done();
-    }, 150);
-  }, 250);
+    }, 200);
+  }, 300);
 
   test('test context', () => {
     const fn = function () { return this; };
diff --git a/test-server/src/localdev.ts b/test-server/src/localdev.ts
index c5c506244..42eee6fbc 100644
--- a/test-server/src/localdev.ts
+++ b/test-server/src/localdev.ts
@@ -25,7 +25,9 @@ import {
   ESLScrollableTabs,
   ESLScrollbar,
   ESLAlert,
-  ESLPopupDispatcher
+  ESLToggleableDispatcher,
+  ESLSelect,
+  ESLSelectList
 } from '../../src/modules/all';
 
 import '../../src/modules/esl-media/providers/iframe-provider';
@@ -35,8 +37,6 @@ import '../../src/modules/esl-media/providers/youtube-provider';
 import '../../src/modules/esl-media/providers/brightcove-provider';
 
 import {
-  ESLSelect,
-  ESLSelectList,
   ESLCarousel,
   ESLCarouselPlugins
 } from '../../src/modules/draft/all';
@@ -44,7 +44,7 @@ import {
 ESLImage.register();
 ESLMedia.register();
 
-ESLPopupDispatcher.init();
+ESLToggleableDispatcher.init();
 ESLPopup.register();
 ESLPanel.register();
 ESLPanelStack.register();
diff --git a/test-server/views/layouts/footer.html b/test-server/views/layouts/footer.html
index 50bee2061..4b81ec30a 100644
--- a/test-server/views/layouts/footer.html
+++ b/test-server/views/layouts/footer.html
@@ -1,6 +1,6 @@
 <div class="container">
   <div class="text-center">
-    <div class="text-muted">© 2020 Exadel, Inc</div>
+    <div class="text-muted">© 2021 Exadel, Inc</div>
     <div class="text-muted">Core Team Contributors:
       <a href="mailto:astsefanovich@exadel.com">Alexey Stsefanovich</a>,
       <a href="mailto:ymurashka@exadel.com">Julia Murashko</a>,
diff --git a/test-server/views/pages/esl-forms/esl-select-list.html b/test-server/views/pages/esl-forms/esl-select-list.html
new file mode 100644
index 000000000..9074db614
--- /dev/null
+++ b/test-server/views/pages/esl-forms/esl-select-list.html
@@ -0,0 +1,333 @@
+---
+layout: ../../layouts/basic.html
+containerCls: container
+title: ESL Select List
+---
+
+{{##content:
+<section class="row">
+  <div class="col-12">
+    <style>
+      .form {
+        display: block;
+        width: 100%;
+      }
+    </style>
+    <div class="row demo">
+      <form class="form bg-white border border-primary p-4" action="javascript: void 0;">
+        <div class="">
+          <div class="form-group">
+            <label for="country_field" class="form-label">Please select your country: </label>
+            <esl-select-list style="display: block"
+                             select-all-label="Select All Countries">
+              <select esl-select-target
+                      id="country_field"
+                      name="country_field"
+                      class="form-control">
+                <option>Afghanistan</option>
+                <option>Albania</option>
+                <option>Algeria</option>
+                <option>Andorra</option>
+                <option>Angola</option>
+                <option>Antigua and Barbuda</option>
+                <option>Argentina</option>
+                <option>Armenia</option>
+                <option>Australia</option>
+                <option>Austria</option>
+                <option>Azerbaijan</option>
+                <option>Bahamas</option>
+                <option>Bahrain</option>
+                <option>Bangladesh</option>
+                <option>Barbados</option>
+                <option>Belarus</option>
+                <option>Belgium</option>
+                <option>Belize</option>
+                <option>Benin</option>
+                <option>Bhutan</option>
+                <option>Bolivia</option>
+                <option>Bosnia and Herzegovina</option>
+                <option>Botswana</option>
+                <option>Brazil</option>
+                <option>Brunei</option>
+                <option>Bulgaria</option>
+                <option>Burkina Faso</option>
+                <option>Burundi</option>
+                <option>Côte d'Ivoire</option>
+                <option>Cabo Verde</option>
+                <option>Cambodia</option>
+                <option>Cameroon</option>
+                <option>Canada</option>
+                <option>Central African Republic</option>
+                <option>Chad</option>
+                <option>Chile</option>
+                <option>China</option>
+                <option>Colombia</option>
+                <option>Comoros</option>
+                <option>Congo (Congo-Brazzaville)</option>
+                <option>Costa Rica</option>
+                <option>Croatia</option>
+                <option>Cuba</option>
+                <option>Cyprus</option>
+                <option>Czechia (Czech Republic)</option>
+                <option>Democratic Republic of the Congo</option>
+                <option>Denmark</option>
+                <option>Djibouti</option>
+                <option>Dominica</option>
+                <option>Dominican Republic</option>
+                <option>Ecuador</option>
+                <option>Egypt</option>
+                <option>El Salvador</option>
+                <option>Equatorial Guinea</option>
+                <option>Eritrea</option>
+                <option>Estonia</option>
+                <option>Eswatini (fmr. "Swaziland")</option>
+                <option>Ethiopia</option>
+                <option>Fiji</option>
+                <option>Finland</option>
+                <option>France</option>
+                <option>Gabon</option>
+                <option>Gambia</option>
+                <option>Georgia</option>
+                <option>Germany</option>
+                <option>Ghana</option>
+                <option>Greece</option>
+                <option>Grenada</option>
+                <option>Guatemala</option>
+                <option>Guinea</option>
+                <option>Guinea-Bissau</option>
+                <option>Guyana</option>
+                <option>Haiti</option>
+                <option>Holy See</option>
+                <option>Honduras</option>
+                <option>Hungary</option>
+                <option>Iceland</option>
+                <option>India</option>
+                <option>Indonesia</option>
+                <option>Iran</option>
+                <option>Iraq</option>
+                <option>Ireland</option>
+                <option>Israel</option>
+                <option>Italy</option>
+                <option>Jamaica</option>
+                <option>Japan</option>
+                <option>Jordan</option>
+                <option>Kazakhstan</option>
+                <option>Kenya</option>
+                <option>Kiribati</option>
+                <option>Kuwait</option>
+                <option>Kyrgyzstan</option>
+                <option>Laos</option>
+                <option>Latvia</option>
+                <option>Lebanon</option>
+                <option>Lesotho</option>
+                <option>Liberia</option>
+                <option>Libya</option>
+                <option>Liechtenstein</option>
+                <option>Lithuania</option>
+                <option>Luxembourg</option>
+                <option>Madagascar</option>
+                <option>Malawi</option>
+                <option>Malaysia</option>
+                <option>Maldives</option>
+                <option>Mali</option>
+                <option>Malta</option>
+                <option>Marshall Islands</option>
+                <option>Mauritania</option>
+                <option>Mauritius</option>
+                <option>Mexico</option>
+                <option>Micronesia</option>
+                <option>Moldova</option>
+                <option>Monaco</option>
+                <option>Mongolia</option>
+                <option>Montenegro</option>
+                <option>Morocco</option>
+                <option>Mozambique</option>
+                <option>Myanmar (formerly Burma)</option>
+                <option>Namibia</option>
+                <option>Nauru</option>
+                <option>Nepal</option>
+                <option>Netherlands</option>
+                <option>New Zealand</option>
+                <option>Nicaragua</option>
+                <option>Niger</option>
+                <option>Nigeria</option>
+                <option>North Korea</option>
+                <option>North Macedonia</option>
+                <option>Norway</option>
+                <option>Oman</option>
+                <option>Pakistan</option>
+                <option>Palau</option>
+                <option>Palestine State</option>
+                <option>Panama</option>
+                <option>Papua New Guinea</option>
+                <option>Paraguay</option>
+                <option>Peru</option>
+                <option>Philippines</option>
+                <option>Poland</option>
+                <option>Portugal</option>
+                <option>Qatar</option>
+                <option>Romania</option>
+                <option>Russia</option>
+                <option>Rwanda</option>
+                <option>Saint Kitts and Nevis</option>
+                <option>Saint Lucia</option>
+                <option>Saint Vincent and the Grenadines</option>
+                <option>Samoa</option>
+                <option>San Marino</option>
+                <option>Sao Tome and Principe</option>
+                <option>Saudi Arabia</option>
+                <option>Senegal</option>
+                <option>Serbia</option>
+                <option>Seychelles</option>
+                <option>Sierra Leone</option>
+                <option>Singapore</option>
+                <option>Slovakia</option>
+                <option>Slovenia</option>
+                <option>Solomon Islands</option>
+                <option>Somalia</option>
+                <option>South Africa</option>
+                <option>South Korea</option>
+                <option>South Sudan</option>
+                <option>Spain</option>
+                <option>Sri Lanka</option>
+                <option>Sudan</option>
+                <option>Suriname</option>
+                <option>Sweden</option>
+                <option>Switzerland</option>
+                <option>Syria</option>
+                <option>Tajikistan</option>
+                <option>Tanzania</option>
+                <option>Thailand</option>
+                <option>Timor-Leste</option>
+                <option>Togo</option>
+                <option>Tonga</option>
+                <option>Trinidad and Tobago</option>
+                <option>Tunisia</option>
+                <option>Turkey</option>
+                <option>Turkmenistan</option>
+                <option>Tuvalu</option>
+                <option>Uganda</option>
+                <option>Ukraine</option>
+                <option>United Arab Emirates</option>
+                <option>United Kingdom</option>
+                <option>United States of America</option>
+                <option>Uruguay</option>
+                <option>Uzbekistan</option>
+                <option>Vanuatu</option>
+                <option>Venezuela</option>
+                <option>Vietnam</option>
+                <option>Yemen</option>
+                <option>Zambia</option>
+                <option>Zimbabwe</option>
+              </select>
+            </esl-select-list>
+          </div>
+
+          <div class="form-group">
+            <label for="color_field_3" class="form-label">Color List</label>
+            <esl-select-list class="form-control" select-all-label="Select All Colors">
+              <select esl-select-target
+                      multiple
+                      id="color_field_3"
+                      name="color_field_3"
+                      class="form-control">
+                <option value="#0048BA">Absolute Zero</option>
+                <option value="#B0BF1A">Acid green</option>
+                <option value="#7CB9E8">Aero</option>
+                <option value="#C0E8D5">Aero blue</option>
+                <option value="#B284BE">African violet</option>
+                <option value="#72A0C1">Air superiority blue</option>
+                <option value="#EDEAE0">Alabaster</option>
+                <option value="#EFDECD">Almond</option>
+                <option value="#E52B50">Amaranth</option>
+                <option value="#3B7A57">Amazon</option>
+                <option value="#FFBF00">Amber</option>
+                <option value="#FF7E00">Amber (SAE/ECE)</option>
+                <option value="#9966CC">Amethyst</option>
+                <option value="#A4C639">Android green</option>
+                <option value="#CD9575">Antique brass</option>
+                <option value="#665D1E">Antique bronze</option>
+                <option value="#915C83">Antique fuchsia</option>
+                <option value="#841B2D">Antique ruby</option>
+                <option value="#BF4F51">Bittersweet shimmer</option>
+                <option value="#000000" selected>Black</option>
+                <option value="#1B1811">Black chocolate</option>
+                <option value="#3B2F2F">Black coffee</option>
+                <option value="#54626F">Black coral</option>
+                <option value="#3B3C36">Black olive</option>
+                <option value="#BFAFB2">Black Shadows</option>
+                <option value="#FFEBCD">Blanched almond</option>
+                <option value="#A57164">Blast-off bronze</option>
+                <option value="#DE5D83">Blush</option>
+                <option value="#79443B">Bole</option>
+                <option value="#E3DAC9">Bone</option>
+                <option value="#006A4E">Bottle green</option>
+                <option value="#87413F">Brandy</option>
+                <option value="#CB4154">Brick red</option>
+                <option value="#66FF00">Bright green</option>
+                <option value="#D891EF">Bright lilac</option>
+                <option value="#C32148">Bright maroon</option>
+                <option value="#1974D2">Bright navy blue</option>
+                <option value="#FFAA1D">Bright yellow (Crayola)</option>
+                <option value="#FF55A3">Brilliant rose</option>
+                <option value="#FB607F">Brink pink</option>
+                <option value="#004225">British racing green</option>
+                <option value="#CD7F32">Bronze</option>
+                <option value="#88540B">Brown</option>
+                <option value="#AF6E4D">Brown sugar</option>
+                <option value="#7BB661">Bud green</option>
+                <option value="#FFC680">Buff</option>
+                <option value="#800020">Burgundy</option>
+                <option value="#DEB887">Burlywood</option>
+                <option value="#A17A74">Burnished brown</option>
+                <option value="#CC5500">Burnt orange</option>
+                <option value="#E97451">Burnt sienna</option>
+                <option value="#8A3324">Burnt umber</option>
+                <option value="#BD33A4">Byzantine</option>
+                <option value="#702963">Byzantium</option>
+                <option value="#536872">Cadet</option>
+                <option value="#5F9EA0">Cadet blue</option>
+                <option value="#A9B2C3">Cadet blue (Crayola)</option>
+                <option value="#91A3B0">Cadet grey</option>
+                <option value="#006B3C">Cadmium green</option>
+                <option value="#ED872D">Cadmium orange</option>
+                <option value="#E30022">Cadmium red</option>
+              </select>
+            </esl-select-list>
+          </div>
+        </div>
+        <div class="form-group">
+          <button class="btn btn-primary">Submit</button>
+        </div>
+      </form>
+    </div>
+
+    <div class="demo-info panel panel-info">
+    </div>
+    <script>
+      (function () {
+        var form = document.querySelector('form');
+        var info = document.querySelector('.demo-info');
+        if (!info) return;
+
+        function upd() {
+          var data = {};
+          var formData = new FormData(form);
+          formData.forEach(((value, key) => {
+            if (key in data) {
+              data[key] = [].concat(data[key]).concat(value);
+            } else {
+              data[key] = value;
+            }
+          }));
+
+          info.textContent = JSON.stringify(data, null, 2);
+          info.removeAttribute('hidden');
+        }
+
+        form.addEventListener('submit', upd);
+      })();
+    </script>
+  </div>
+</section>
+#}}
diff --git a/test-server/views/pages/esl-select.html b/test-server/views/pages/esl-forms/esl-select.html
similarity index 74%
rename from test-server/views/pages/esl-select.html
rename to test-server/views/pages/esl-forms/esl-select.html
index f911367c9..43b118537 100644
--- a/test-server/views/pages/esl-select.html
+++ b/test-server/views/pages/esl-forms/esl-select.html
@@ -1,7 +1,7 @@
 ---
-layout: ../layouts/basic.html
+layout: ../../layouts/basic.html
 containerCls: container
-title: ESL Select component
+title: ESL Select
 ---
 
 {{##content:
@@ -16,8 +16,217 @@ title: ESL Select component
     <div class="row demo">
       <form class="form bg-white border border-primary p-4" action="javascript: void 0;">
         <div class="">
+          <div class="form-group">
+            <label for="country_field" class="form-label">Please select your country: </label>
+            <esl-select style="display: block"
+                        empty-text="Country"
+                        select-all-label="Select All Countries">
+              <select esl-select-target
+                      id="country_field"
+                      name="country_field"
+                      class="form-control">
+                <option>Afghanistan</option>
+                <option>Albania</option>
+                <option>Algeria</option>
+                <option>Andorra</option>
+                <option>Angola</option>
+                <option>Antigua and Barbuda</option>
+                <option>Argentina</option>
+                <option>Armenia</option>
+                <option>Australia</option>
+                <option>Austria</option>
+                <option>Azerbaijan</option>
+                <option>Bahamas</option>
+                <option>Bahrain</option>
+                <option>Bangladesh</option>
+                <option>Barbados</option>
+                <option>Belarus</option>
+                <option>Belgium</option>
+                <option>Belize</option>
+                <option>Benin</option>
+                <option>Bhutan</option>
+                <option>Bolivia</option>
+                <option>Bosnia and Herzegovina</option>
+                <option>Botswana</option>
+                <option>Brazil</option>
+                <option>Brunei</option>
+                <option>Bulgaria</option>
+                <option>Burkina Faso</option>
+                <option>Burundi</option>
+                <option>Côte d'Ivoire</option>
+                <option>Cabo Verde</option>
+                <option>Cambodia</option>
+                <option>Cameroon</option>
+                <option>Canada</option>
+                <option>Central African Republic</option>
+                <option>Chad</option>
+                <option>Chile</option>
+                <option>China</option>
+                <option>Colombia</option>
+                <option>Comoros</option>
+                <option>Congo (Congo-Brazzaville)</option>
+                <option>Costa Rica</option>
+                <option>Croatia</option>
+                <option>Cuba</option>
+                <option>Cyprus</option>
+                <option>Czechia (Czech Republic)</option>
+                <option>Democratic Republic of the Congo</option>
+                <option>Denmark</option>
+                <option>Djibouti</option>
+                <option>Dominica</option>
+                <option>Dominican Republic</option>
+                <option>Ecuador</option>
+                <option>Egypt</option>
+                <option>El Salvador</option>
+                <option>Equatorial Guinea</option>
+                <option>Eritrea</option>
+                <option>Estonia</option>
+                <option>Eswatini (fmr. "Swaziland")</option>
+                <option>Ethiopia</option>
+                <option>Fiji</option>
+                <option>Finland</option>
+                <option>France</option>
+                <option>Gabon</option>
+                <option>Gambia</option>
+                <option>Georgia</option>
+                <option>Germany</option>
+                <option>Ghana</option>
+                <option>Greece</option>
+                <option>Grenada</option>
+                <option>Guatemala</option>
+                <option>Guinea</option>
+                <option>Guinea-Bissau</option>
+                <option>Guyana</option>
+                <option>Haiti</option>
+                <option>Holy See</option>
+                <option>Honduras</option>
+                <option>Hungary</option>
+                <option>Iceland</option>
+                <option>India</option>
+                <option>Indonesia</option>
+                <option>Iran</option>
+                <option>Iraq</option>
+                <option>Ireland</option>
+                <option>Israel</option>
+                <option>Italy</option>
+                <option>Jamaica</option>
+                <option>Japan</option>
+                <option>Jordan</option>
+                <option>Kazakhstan</option>
+                <option>Kenya</option>
+                <option>Kiribati</option>
+                <option>Kuwait</option>
+                <option>Kyrgyzstan</option>
+                <option>Laos</option>
+                <option>Latvia</option>
+                <option>Lebanon</option>
+                <option>Lesotho</option>
+                <option>Liberia</option>
+                <option>Libya</option>
+                <option>Liechtenstein</option>
+                <option>Lithuania</option>
+                <option>Luxembourg</option>
+                <option>Madagascar</option>
+                <option>Malawi</option>
+                <option>Malaysia</option>
+                <option>Maldives</option>
+                <option>Mali</option>
+                <option>Malta</option>
+                <option>Marshall Islands</option>
+                <option>Mauritania</option>
+                <option>Mauritius</option>
+                <option>Mexico</option>
+                <option>Micronesia</option>
+                <option>Moldova</option>
+                <option>Monaco</option>
+                <option>Mongolia</option>
+                <option>Montenegro</option>
+                <option>Morocco</option>
+                <option>Mozambique</option>
+                <option>Myanmar (formerly Burma)</option>
+                <option>Namibia</option>
+                <option>Nauru</option>
+                <option>Nepal</option>
+                <option>Netherlands</option>
+                <option>New Zealand</option>
+                <option>Nicaragua</option>
+                <option>Niger</option>
+                <option>Nigeria</option>
+                <option>North Korea</option>
+                <option>North Macedonia</option>
+                <option>Norway</option>
+                <option>Oman</option>
+                <option>Pakistan</option>
+                <option>Palau</option>
+                <option>Palestine State</option>
+                <option>Panama</option>
+                <option>Papua New Guinea</option>
+                <option>Paraguay</option>
+                <option>Peru</option>
+                <option>Philippines</option>
+                <option>Poland</option>
+                <option>Portugal</option>
+                <option>Qatar</option>
+                <option>Romania</option>
+                <option>Russia</option>
+                <option>Rwanda</option>
+                <option>Saint Kitts and Nevis</option>
+                <option>Saint Lucia</option>
+                <option>Saint Vincent and the Grenadines</option>
+                <option>Samoa</option>
+                <option>San Marino</option>
+                <option>Sao Tome and Principe</option>
+                <option>Saudi Arabia</option>
+                <option>Senegal</option>
+                <option>Serbia</option>
+                <option>Seychelles</option>
+                <option>Sierra Leone</option>
+                <option>Singapore</option>
+                <option>Slovakia</option>
+                <option>Slovenia</option>
+                <option>Solomon Islands</option>
+                <option>Somalia</option>
+                <option>South Africa</option>
+                <option>South Korea</option>
+                <option>South Sudan</option>
+                <option>Spain</option>
+                <option>Sri Lanka</option>
+                <option>Sudan</option>
+                <option>Suriname</option>
+                <option>Sweden</option>
+                <option>Switzerland</option>
+                <option>Syria</option>
+                <option>Tajikistan</option>
+                <option>Tanzania</option>
+                <option>Thailand</option>
+                <option>Timor-Leste</option>
+                <option>Togo</option>
+                <option>Tonga</option>
+                <option>Trinidad and Tobago</option>
+                <option>Tunisia</option>
+                <option>Turkey</option>
+                <option>Turkmenistan</option>
+                <option>Tuvalu</option>
+                <option>Uganda</option>
+                <option>Ukraine</option>
+                <option>United Arab Emirates</option>
+                <option>United Kingdom</option>
+                <option>United States of America</option>
+                <option>Uruguay</option>
+                <option>Uzbekistan</option>
+                <option>Vanuatu</option>
+                <option>Venezuela</option>
+                <option>Vietnam</option>
+                <option>Yemen</option>
+                <option>Zambia</option>
+                <option>Zimbabwe</option>
+              </select>
+            </esl-select>
+          </div>
+
           <esl-select class="form-group"
                       style="display: block"
+                      pin-selected
                       empty-text="Color"
                       select-all-label="All Colors">
             <label for="color_field" class="form-label">Color</label>
@@ -355,6 +564,7 @@ title: ESL Select component
           </esl-select>
           <esl-select class="form-group"
                       style="display: block"
+                      pin-selected
                       empty-text="Color 2"
                       select-all-label="All Colors">
             <label for="color_field_2" class="form-label">Color 2</label>
@@ -426,79 +636,6 @@ title: ESL Select component
               <option value="#E30022">Cadmium red</option>
             </select>
           </esl-select>
-
-          <div class="form-group">
-            <label for="color_field_3" class="form-label">Color List</label>
-            <esl-select-list class="form-control" select-all-label="Select All Colors">
-              <select esl-select-target
-                      multiple
-                      id="color_field_3"
-                      name="color_field_3"
-                      class="form-control">
-                <option value="#0048BA">Absolute Zero</option>
-                <option value="#B0BF1A">Acid green</option>
-                <option value="#7CB9E8">Aero</option>
-                <option value="#C0E8D5">Aero blue</option>
-                <option value="#B284BE">African violet</option>
-                <option value="#72A0C1">Air superiority blue</option>
-                <option value="#EDEAE0">Alabaster</option>
-                <option value="#EFDECD">Almond</option>
-                <option value="#E52B50">Amaranth</option>
-                <option value="#3B7A57">Amazon</option>
-                <option value="#FFBF00">Amber</option>
-                <option value="#FF7E00">Amber (SAE/ECE)</option>
-                <option value="#9966CC">Amethyst</option>
-                <option value="#A4C639">Android green</option>
-                <option value="#CD9575">Antique brass</option>
-                <option value="#665D1E">Antique bronze</option>
-                <option value="#915C83">Antique fuchsia</option>
-                <option value="#841B2D">Antique ruby</option>
-                <option value="#BF4F51">Bittersweet shimmer</option>
-                <option value="#000000" selected>Black</option>
-                <option value="#1B1811">Black chocolate</option>
-                <option value="#3B2F2F">Black coffee</option>
-                <option value="#54626F">Black coral</option>
-                <option value="#3B3C36">Black olive</option>
-                <option value="#BFAFB2">Black Shadows</option>
-                <option value="#FFEBCD">Blanched almond</option>
-                <option value="#A57164">Blast-off bronze</option>
-                <option value="#DE5D83">Blush</option>
-                <option value="#79443B">Bole</option>
-                <option value="#E3DAC9">Bone</option>
-                <option value="#006A4E">Bottle green</option>
-                <option value="#87413F">Brandy</option>
-                <option value="#CB4154">Brick red</option>
-                <option value="#66FF00">Bright green</option>
-                <option value="#D891EF">Bright lilac</option>
-                <option value="#C32148">Bright maroon</option>
-                <option value="#1974D2">Bright navy blue</option>
-                <option value="#FFAA1D">Bright yellow (Crayola)</option>
-                <option value="#FF55A3">Brilliant rose</option>
-                <option value="#FB607F">Brink pink</option>
-                <option value="#004225">British racing green</option>
-                <option value="#CD7F32">Bronze</option>
-                <option value="#88540B">Brown</option>
-                <option value="#AF6E4D">Brown sugar</option>
-                <option value="#7BB661">Bud green</option>
-                <option value="#FFC680">Buff</option>
-                <option value="#800020">Burgundy</option>
-                <option value="#DEB887">Burlywood</option>
-                <option value="#A17A74">Burnished brown</option>
-                <option value="#CC5500">Burnt orange</option>
-                <option value="#E97451">Burnt sienna</option>
-                <option value="#8A3324">Burnt umber</option>
-                <option value="#BD33A4">Byzantine</option>
-                <option value="#702963">Byzantium</option>
-                <option value="#536872">Cadet</option>
-                <option value="#5F9EA0">Cadet blue</option>
-                <option value="#A9B2C3">Cadet blue (Crayola)</option>
-                <option value="#91A3B0">Cadet grey</option>
-                <option value="#006B3C">Cadmium green</option>
-                <option value="#ED872D">Cadmium orange</option>
-                <option value="#E30022">Cadmium red</option>
-              </select>
-            </esl-select-list>
-          </div>
         </div>
         <div class="form-group">
           <button class="btn btn-primary">Submit</button>