diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6675a8f..b7cb891 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -46,3 +46,10 @@ Tested in JS and React. Errors in work in React applications are revealed.
- Fixing bugs related to the cleanup of the select.
- Documentation navigation update.
- Added icon for example page and documentation.
+
+### 20.02.2023 - update 0.2.4
+
+- Added ability to create custom themes.
+- Added style builder on homepage.
+- Fixed documentation.
+- Added a block describing how to create your own themes.
diff --git a/README.md b/README.md
index 0886619..7b9e6c0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# CG-SELECT
-## version ~ 0.2.33
+## version ~ 0.2.4
This component allows you to create a custom select. It offers more flexible customization and use of select.
Customization, multi-selection and live search by elements are available.
diff --git a/READMERU.md b/READMERU.md
index a361de9..96a7874 100644
--- a/READMERU.md
+++ b/READMERU.md
@@ -1,6 +1,6 @@
# CG-SELECT
-## version ~ 0.2.33
+## version ~ 0.2.4
Этот компонент позволяет вам создать пользовательский Select. Он предлагает более гибкую настройку и использование select.
Доступна кастомизация, multi-selection, живой поиск по элементам и многое другое.
diff --git a/docs/index.html b/docs/index.html
index 99b1f79..5a8e523 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -62,7 +62,7 @@
- version ~ 0.2.33
+ version ~ 0.2.4
This component allows you to create a custom select. It offers more flexible
diff --git a/example/example.scss b/example/example.scss
index b1bd873..a4e07c5 100644
--- a/example/example.scss
+++ b/example/example.scss
@@ -1,8 +1,21 @@
@import '/src/main.scss';
+@import './src/constructor/constructor.scss';
* {
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
+ text-align: justify;
+}
+
+.testClass {
+ background-color: #8297ff;
+ color: white;
+}
+
+.listTest {
+ background-color: #8297ff;
+ border: 1px solid black;
+ color: white;
}
.body-example {
@@ -30,6 +43,7 @@
}
.header {
+ position: relative;
width: 100%;
border-radius: 5px;
display: flex;
@@ -112,6 +126,7 @@
}
&_submit {
+ text-align: center;
width: 200px;
height: 35px;
border-radius: 10px;
@@ -140,6 +155,40 @@
}
}
+.row {
+ display: flex;
+ justify-content: space-around;
+}
+
+.description-theme {
+ color: white;
+
+ .col {
+ width: 54%;
+ }
+
+ img {
+ border-radius: 15px;
+ }
+
+ .createTheme {
+ display: flex;
+ flex-direction: column;
+ }
+
+ h5 {
+ font-size: 18px;
+ margin: 0;
+ }
+ h6 {
+ font-size: 17px;
+ margin: 0;
+ }
+ p {
+ font-size: 16px;
+ }
+}
+
code {
display: none;
}
@@ -180,6 +229,7 @@ pre {
}
.check-code {
+ text-align: center;
width: 200px;
height: 35px;
cursor: pointer;
@@ -210,3 +260,11 @@ pre {
height: 40px;
}
}
+
+.version {
+ position: absolute;
+ color: white;
+ font-size: 10px;
+ right: 20px;
+ bottom: 0px;
+}
diff --git a/example/index.html b/example/index.html
index b316ee7..8863a25 100644
--- a/example/index.html
+++ b/example/index.html
@@ -31,6 +31,7 @@
Documentation
+ v. 0.2.4
@@ -192,6 +193,172 @@
+
+
Setting up and adding a theme
+
+
+
+
+
Default theme:
+
+ To change the theme of the select, you need to specify this parameter in the select
+ settings. The default theme is the classic theme, you can choose a white or dark
+ theme.
+
+
+
+ const dropdown = new CGSelect ({
+ selector: '.cg-dropdown_one',
+ placeholder: 'Choose a car',
+ lable: 'EXAMPLE',
+ items: [
+ ...
+ ],
+ theme : 'dark / white'
+ });
+
+
+
+
+
+
Create custom theme:
+
+
+ To create your own theme, you need to create an object with the following fields.
+ In these fields you need to insert the previously created css class. After
+ creating the object, just pass it to the select settings.
+
+
+
+ interface CustomTheme {
+ name: 'string',
+ styles: {
+ head?: 'string',
+ list?: 'testClass', ,
+ placeholder?: 'string', ,
+ caret?: 'string', ,
+ search?: 'string', ,
+ chips?: 'string', ,
+ lable?: 'string', ,
+ },
+ });
+
+
+
+
+
+
+
Example:
+
+
+
For JS
+ For TS
+
+
+
+
+
+ const newTheme = {
+ name: 'test',
+ styles: {
+ head: 'headTestClass',
+ list: 'listTestClass', ,
+ placeholder: 'placeholderTestClass', ,
+ caret: 'caretTestClass', ,
+ search: 'searchTestClass', ,
+ chips: 'chipsTestClass', ,
+ lable: 'lableTestClass', ,
+ },
+ });
+
+
+
+
+
+ const newCustomTheme : CustomTheme = {
+ name: 'test',
+ styles: {
+ head: 'headTestClass',
+ list: 'listTestClass', ,
+ placeholder: 'placeholderTestClass', ,
+ caret: 'caretTestClass', ,
+ search: 'searchTestClass', ,
+ chips: 'chipsTestClass', ,
+ lable: 'lableTestClass', ,
+ },
+ });
+
+
+
+
CSS
+
+
+ .headTestClass {
+ background-color: #8297ff;
+ color: white;
+ }
+
+ .listTestClass {
+ background-color: #8297ff;
+ border: 1px solid black;
+ color: white;
+ }
+
+
+
+
Example custom theme in CG-Select
+
+ See an example of a select on
+ codesandbox.io
+
+
+
+
+
+
+
+
+
Select constructor
+
+
+
Select Style Builder:
+
+ This is a constructor for styling a select online without downloading. For it to work,
+ you need to:
+
+ Select a part of the select for customization.
+ Enter styles in the text field in the form "color: red;".
+ Click on the render button.
+
+
+
+
+
+
+
+
+
+
+
Categories
diff --git a/example/index.js b/example/index.js
index c4a86d0..7ace743 100644
--- a/example/index.js
+++ b/example/index.js
@@ -1,5 +1,8 @@
import { CGSelect } from '../src/cg-select';
-import './example';
+import { newCustomTheme } from './src/themeTest';
+
+import './src/example';
+import './src/constructor/constructor';
// ------------------------------Обычный селект--------------------
const dropdown = new CGSelect({
@@ -27,10 +30,34 @@ const dropdown = new CGSelect({
},
});
-dropdown.on('clear', function (e) {
- console.log(`this state: ${e}`);
-});
+// dropdown.on('clear', function (e) {
+// console.log(`this state: ${e}`);
+// });
+const droptheme = new CGSelect({
+ selector: '.cg-dropdown_theme',
+ placeholder: 'Choose a car',
+ items: [
+ 'BMW',
+ {
+ id: '213sade',
+ title: 'Opel',
+ value: 1,
+ },
+ 'Mersedes',
+ 'MAN',
+ 'Ferari',
+ ],
+ styles: {
+ head: {
+ width: '830px',
+ },
+ list: {
+ width: '824px',
+ },
+ },
+ theme: newCustomTheme,
+});
// ------------------------------NativeSelect-----------------------
const dropdownNativeSelect = new CGSelect({
selector: '.cg-dropdown_selectNative',
diff --git a/example/src/constructor/constructor.js b/example/src/constructor/constructor.js
new file mode 100644
index 0000000..4df819e
--- /dev/null
+++ b/example/src/constructor/constructor.js
@@ -0,0 +1,83 @@
+import { CGSelect } from '../../../src/cg-select';
+
+const body = new CGSelect({
+ selector: '.body',
+ placeholder: 'Select element to style',
+ items: ['head', 'list', 'placeholder', 'caret', 'search'],
+});
+
+let head = '';
+let list = '';
+let placeholder = '';
+let caret = '';
+let valueSelect = '';
+
+const textarea = document.querySelector('#styles');
+const renderBtn = document.querySelector('.render');
+
+body.on('select', (e, value) => {
+ valueSelect = value;
+ textarea.value = '';
+ textarea.removeAttribute('disabled');
+ getValueSelect(valueSelect);
+});
+
+function getValueSelect(value) {
+ textarea.onkeyup = function () {
+ switch (value) {
+ case 'head':
+ // ввод стилей
+ head = textarea.value;
+ break;
+ case 'list':
+ list = textarea.value;
+ break;
+ case 'placeholder':
+ placeholder = textarea.value;
+ break;
+ case 'caret':
+ caret = textarea.value;
+ break;
+ case 'search':
+ search = textarea.value;
+ break;
+
+ default:
+ break;
+ }
+ };
+}
+
+renderBtn.addEventListener('click', () => {
+ const select = new CGSelect({
+ selector: '.select',
+ placeholder: 'Choose a car',
+ label: 'Exemple select',
+ items: [
+ 'BMW',
+ {
+ id: '213sade',
+ title: 'Opel',
+ value: 1,
+ },
+ 'Mersedes',
+ 'MAN',
+ 'Ferari',
+ ],
+ searchMode: true,
+ multiselect: true,
+ multiselectTag: true,
+ });
+
+ const drop = document.querySelector('.select');
+ let headSelect = drop.querySelector('.cg-select');
+ let listSelect = drop.querySelector('.list');
+ let placeholderSelect = drop.querySelector('.selected');
+ let caretSelect = drop.querySelector('.caret');
+ let searchSelect = drop.querySelector('.inputSearch');
+ headSelect.setAttribute('style', head);
+ listSelect.setAttribute('style', list);
+ placeholderSelect.setAttribute('style', placeholder);
+ caretSelect.setAttribute('style', caret);
+ searchSelect.setAttribute('style', search);
+});
diff --git a/example/src/constructor/constructor.scss b/example/src/constructor/constructor.scss
new file mode 100644
index 0000000..0739c16
--- /dev/null
+++ b/example/src/constructor/constructor.scss
@@ -0,0 +1,16 @@
+.textareaStyle {
+ resize: none;
+ border-radius: 5px;
+ margin: 15px;
+}
+
+.constructor {
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+}
+
+.liList {
+ margin-bottom: 5px;
+ font-size: 17px;
+}
diff --git a/example/example.js b/example/src/example.js
similarity index 66%
rename from example/example.js
rename to example/src/example.js
index f807677..2238b38 100644
--- a/example/example.js
+++ b/example/src/example.js
@@ -13,38 +13,36 @@ const codeFourth = document.getElementById('codeFourth');
const fifthBtn = document.getElementById('fifth');
const codeFifth = document.getElementById('codeFifth');
-const six = document.getElementById('six')
+const six = document.getElementById('six');
const codeSix = document.getElementById('codeSix');
-
-const Native = document.getElementById('Native')
-const codeNative = document.getElementById('codeNative')
-
+const Native = document.getElementById('Native');
+const codeNative = document.getElementById('codeNative');
firstBtn.addEventListener('click', () => {
- codeFirst.classList.toggle("active")
-})
+ codeFirst.classList.toggle('active');
+});
secondBtn.addEventListener('click', () => {
- codeSecond.classList.toggle("active")
-})
+ codeSecond.classList.toggle('active');
+});
thirdBtn.addEventListener('click', () => {
- codeThird.classList.toggle("active")
-})
+ codeThird.classList.toggle('active');
+});
fourthBtn.addEventListener('click', () => {
- codeFourth.classList.toggle("active")
-})
+ codeFourth.classList.toggle('active');
+});
fifthBtn.addEventListener('click', () => {
- codeFifth.classList.toggle("active")
-})
+ codeFifth.classList.toggle('active');
+});
six.addEventListener('click', () => {
- codeSix.classList.toggle("active")
-})
+ codeSix.classList.toggle('active');
+});
Native.addEventListener('click', () => {
- codeNative.classList.toggle("active")
-})
\ No newline at end of file
+ codeNative.classList.toggle('active');
+});
diff --git a/example/src/themeTest.ts b/example/src/themeTest.ts
new file mode 100644
index 0000000..ae66df1
--- /dev/null
+++ b/example/src/themeTest.ts
@@ -0,0 +1,9 @@
+import { CustomTheme } from 'components/theme/theme.interface';
+
+export const newCustomTheme: CustomTheme = {
+ name: 'test',
+ styles: {
+ head: 'testClass',
+ list: 'listTest',
+ },
+};
diff --git a/package-lock.json b/package-lock.json
index 0399bd1..0807227 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "cg-select",
- "version": "0.2.33",
+ "version": "0.2.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cg-select",
- "version": "0.2.33",
+ "version": "0.2.4",
"license": "ISC",
"dependencies": {
"@parcel/optimizer-css": "^2.8.0",
diff --git a/package.json b/package.json
index 09cdfdd..d7e3434 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cg-select",
- "version": "0.2.33",
+ "version": "0.2.4",
"description": "Feature rich Select control for React/JS with multiselect, autocomplete and styling",
"author": {
"name": "CraftGroup",
diff --git a/src/cg-select.ts b/src/cg-select.ts
index d760654..40a94e0 100644
--- a/src/cg-select.ts
+++ b/src/cg-select.ts
@@ -25,6 +25,7 @@ import { ILanguage } from './interfaces/language.interface';
import './main.scss';
import { changeTheme } from './components/theme/theme';
+import { CustomTheme } from 'components/theme/theme.interface';
/**
* @class Class Description ICgSelect
@@ -36,7 +37,7 @@ export class CGSelect implements ICgSelect {
selected?: string;
placeholder?: string;
items?: IItems[] | string[] | any;
- theme?: string;
+ theme?: string | CustomTheme;
searchMode?: boolean;
closeOnSelect?: boolean;
nativeSelectMode?: boolean;
@@ -916,17 +917,19 @@ export class CGSelect implements ICgSelect {
* @param callback
* @method on
*/
- public on(state: string, callback: (state: any) => any) {
+ public on(state: string, callback: (state: any, value?: string) => any) {
const options = this.element?.querySelectorAll('.list__item');
+ let value = '';
switch (state) {
case 'select':
options?.forEach((option: Element) => {
option.addEventListener('click', () => {
console.log('option:select', option.textContent);
+ value = option.textContent!;
+ callback(state, value);
});
});
- callback(state);
break;
case 'close':
this.element!.addEventListener('click', () => {
diff --git a/src/components/theme/theme.interface.ts b/src/components/theme/theme.interface.ts
new file mode 100644
index 0000000..af4420d
--- /dev/null
+++ b/src/components/theme/theme.interface.ts
@@ -0,0 +1,12 @@
+export interface CustomTheme {
+ name: string;
+ styles: {
+ head?: string;
+ list?: string;
+ placeholder?: string;
+ caret?: string;
+ search?: string;
+ chips?: string;
+ lable?: string;
+ };
+}
diff --git a/src/components/theme/theme.ts b/src/components/theme/theme.ts
index cf2e58b..571c70d 100644
--- a/src/components/theme/theme.ts
+++ b/src/components/theme/theme.ts
@@ -1,4 +1,6 @@
-export function changeTheme(element: Element, theme: string) {
+import { CustomTheme } from './theme.interface';
+
+export function changeTheme(element: Element, theme: string | CustomTheme) {
const select = element!.querySelector('.cg-select');
const caret = element!.querySelector('.caret');
const list = element!.querySelector('ul.list');
@@ -13,32 +15,37 @@ export function changeTheme(element: Element, theme: string) {
elem.classList.remove('pathWhite');
});
- switch (theme.toLowerCase()) {
- case 'dark':
- select!.classList.add('selectDark');
- list!.classList.add('listDark');
- nativeSelect?.classList.add('listDark');
- path.forEach((elem) => {
- elem.classList.add('pathWhite');
- });
- break;
- case 'white':
- select!.classList.add('selectWhite');
- caret!.classList.add('caretWhite');
- list!.classList.add('listWhite');
- nativeSelect?.classList.add('listWhite');
- path.forEach((elem) => {
- elem.classList.add('pathBlack');
- });
+ if (typeof theme === 'string') {
+ switch (theme) {
+ case 'dark':
+ select!.classList.add('selectDark');
+ list!.classList.add('listDark');
+ nativeSelect?.classList.add('listDark');
+ path.forEach((elem) => {
+ elem.classList.add('pathWhite');
+ });
+ break;
+ case 'white':
+ select!.classList.add('selectWhite');
+ caret!.classList.add('caretWhite');
+ list!.classList.add('listWhite');
+ nativeSelect?.classList.add('listWhite');
+ path.forEach((elem) => {
+ elem.classList.add('pathBlack');
+ });
- if (search!) {
- search!.classList.add('inputWhite');
- }
- break;
+ if (search!) {
+ search!.classList.add('inputWhite');
+ }
+ break;
- default:
- select!.classList.add('classicSelect');
- list!.classList.add('classicList');
- break;
+ default:
+ select!.classList.add('classicSelect');
+ list!.classList.add('classicList');
+ break;
+ }
+ } else {
+ select!.classList.add(`${theme.styles.head}`);
+ list!.classList.add(`${theme.styles.list}`);
}
}
diff --git a/src/components/utils/utils.interface.ts b/src/components/utils/utils.interface.ts
index 31ca536..d139979 100644
--- a/src/components/utils/utils.interface.ts
+++ b/src/components/utils/utils.interface.ts
@@ -1,3 +1,4 @@
+import { CustomTheme } from 'components/theme/theme.interface';
import { IItems } from 'interfaces/items.interface';
/**
@@ -55,5 +56,5 @@ export interface ISelectedItems {
* An optional parameter that is responsible for enabling a light/dark theme by default, the dark theme is set.
* @type {boolean}
*/
- theme?: string;
+ theme?: string | CustomTheme;
}
diff --git a/src/interfaces/cg-select.interface.ts b/src/interfaces/cg-select.interface.ts
index 403b1a6..39a0f07 100644
--- a/src/interfaces/cg-select.interface.ts
+++ b/src/interfaces/cg-select.interface.ts
@@ -1,3 +1,4 @@
+import { CustomTheme } from 'components/theme/theme.interface';
import { IItems } from './items.interface';
/**
@@ -29,7 +30,7 @@ export interface ICgSelect {
* An optional parameter responsible for switching between different themes, the classic theme is set by default.
* @type {string} values: dark, white
*/
- theme?: string;
+ theme?: string | CustomTheme;
/**
* An optional parameter that adds a live search on the select elements.
* @type {boolean}