diff --git a/CHANGELOG.md b/CHANGELOG.md index 6675a8f..1c968bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,3 +46,16 @@ 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. + +### 27.02.2023 - update 0.2.5 + +- Moving an example using a select to a separate repository. +- Fixed bugs. +- Changed structure. diff --git a/README.md b/README.md index c59cfdf..5139058 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # CG-SELECT -## version ~ 0.2.32 +## version ~ 0.2.5 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. @@ -13,6 +13,7 @@ Customization, multi-selection and live search by elements are available. - In the multiselect mode, customization of chips (selected elements) is available. - Label of the element (if it was specified). - Switch themes from dark to light. +- The documentation also lists all the elements for catatomization using CSS. ## Installation @@ -79,6 +80,8 @@ All documentation on CG-SELECT is located in the folder of the same name. The do **To view it, follow the link -** https://cg-select.itguild.info/up_/documentation/index.html +**Russian version README -** https://github.com/apuc/cg-select/blob/main/READMERU.md + ## Contributing 1. Fork it! diff --git a/READMERU.md b/READMERU.md new file mode 100644 index 0000000..8478ccb --- /dev/null +++ b/READMERU.md @@ -0,0 +1,101 @@ +# CG-SELECT + +## version ~ 0.2.5 + +Этот компонент позволяет вам создать пользовательский Select. Он предлагает более гибкую настройку и использование select. +Доступна кастомизация, multi-selection, живой поиск по элементам и многое другое. + +### Возможность настройки основных элементов, таких как: + +- Кнопка самого селекта Select. +- Список с выбранными элементами. +- Placeholder. +- В режиме мультиселекта доступна кастомизация chips (выбранных элементов). +- Label элемента (если она была указана). +- Переключить тему с темной на светлую. +- Так же в документации указанны все элементы для катомизации с помощью CSS. + +## Installation + +``` +npm i cg-select +``` + +## Usage + +### Для создания компонента необходимо: + +1. Создайте обычную кнопку. +2. Добавьте ей класс cg-dropdown. + +``` + +``` + +3. Добавьте ему **уникальный класс**, + например: (cg-dropdown_categories) + +``` + +``` + +4. Создайте новый экземпляр класса (new CGSelect) +5. Передайте все нужные настройки как объект. + +#### Все варианты создания и управления селектом есть в документации, раздел "Конструктор класса CGSelect". + +### Пример создания обычного CGSelect. + +```javascript +import CGSelect from 'cg-select'; + +const dropdown = new CGSelect({ + selector: '.cg-dropdown_selector', + placeholder: 'Выберите авто', + items: [ + 'BMW', + { + id: '213sade', + title: 'Opel', + value: 1, + }, + 'Mersedes', + 'MAN', + 'Ferari', + ], +}); +``` + +## Примеры различных вариантов выбора. + +Рабочий пример -- https://cg-select.itguild.info/ + +![image](https://github.com/apuc/cg-select/blob/main/src/images/DefaultSelect.png) +![image](https://github.com/apuc/cg-select/blob/main/src/images/MultiSelect.png) +![image](https://github.com/apuc/cg-select/blob/main/src/images/WhiteTheme.png) +![image](https://github.com/apuc/cg-select/blob/main/src/images/Categories.png) + +Вся документация по CG-SELECT находится в одноименной папке. В документации описаны все методы и переменные, также есть примеры передачи настроек в CGSelect. Вы также можете открыть его на странице с примером, или перейти по ссылке ниже. + +**Для просмотра перейдите по ссылке -** https://cg-select.itguild.info/up_/documentation/index.html + +## Contributing + +1. Fork it! +2. Create your feature branch: `git checkout -b my-new-feature` +3. Commit your changes: `git commit -am 'Add some feature'` +4. Push to the branch: `git push origin my-new-feature` +5. Submit a pull request :D + +## Compatibility + +| Application Compatibility | JS | React | Angular | Vue | +| ------------------------- | :----------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------: | :---------------------------------------------------------------------: | +| CG-SELECT | ![image](https://github.com/apuc/cg-select/blob/main/src/images/yes.png) | ![image](https://github.com/apuc/cg-select/blob/main/src/images/yes.png) ![image](https://github.com/apuc/cg-select/blob/main/src/images/no.png) | ![image](https://github.com/apuc/cg-select/blob/main/src/images/no.png) | ![image](https://github.com/apuc/cg-select/blob/main/src/images/no.png) | +| Comment | Tested in Js applications and it worksуспешно. | Works only with a crutch in the form `setTimeout()` | not yet available | not yet available | + +## History + +16.12.2022 - release version 0.1.0! + +20.01.2023 - upgrade to version 0.2.1 diff --git a/docs/index.html b/docs/index.html index 510c223..949c04a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -62,7 +62,7 @@ -

version ~ 0.2.32

+

version ~ 0.2.5

This component allows you to create a custom select. It offers more flexible diff --git a/example/example.js b/example/example.js deleted file mode 100644 index f807677..0000000 --- a/example/example.js +++ /dev/null @@ -1,50 +0,0 @@ -const firstBtn = document.getElementById('first'); -const codeFirst = document.getElementById('codeFirst'); - -const secondBtn = document.getElementById('second'); -const codeSecond = document.getElementById('codeSecond'); - -const thirdBtn = document.getElementById('third'); -const codeThird = document.getElementById('codeThird'); - -const fourthBtn = document.getElementById('fourth'); -const codeFourth = document.getElementById('codeFourth'); - -const fifthBtn = document.getElementById('fifth'); -const codeFifth = document.getElementById('codeFifth'); - -const six = document.getElementById('six') -const codeSix = document.getElementById('codeSix'); - - -const Native = document.getElementById('Native') -const codeNative = document.getElementById('codeNative') - - -firstBtn.addEventListener('click', () => { - codeFirst.classList.toggle("active") -}) - -secondBtn.addEventListener('click', () => { - codeSecond.classList.toggle("active") -}) - -thirdBtn.addEventListener('click', () => { - codeThird.classList.toggle("active") -}) - -fourthBtn.addEventListener('click', () => { - codeFourth.classList.toggle("active") -}) - -fifthBtn.addEventListener('click', () => { - codeFifth.classList.toggle("active") -}) - -six.addEventListener('click', () => { - codeSix.classList.toggle("active") -}) - -Native.addEventListener('click', () => { - codeNative.classList.toggle("active") -}) \ No newline at end of file diff --git a/example/index.html b/example/index.html deleted file mode 100644 index b316ee7..0000000 --- a/example/index.html +++ /dev/null @@ -1,363 +0,0 @@ - - - - - - - - - - - - - Cg-Select - - - - -

-
-
-

CG-SELECT

- -
-
- -
-
- -
-
-

Default select

-
-
- -
- - - - - -
-              const dropdown = new CGSelect({
-                selector: '.cg-dropdown_one', 
-                placeholder: 'Choose a car', 
-                lable: 'EXAMPLE', 
-                items: [
-                  'BMW',
-                  {
-                    id: '213sade',
-                    title: 'Opel',
-                    value: 1,
-                  },
-                  'Mersedes', 
-                  'MAN',  
-                  'Ferari', 
-                ],
-                styles: {
-                  head: {
-                    width: '830px', 
-                  },
-                  list: {
-                    width: '824px', 
-                  },
-                },
-              });
-            
-
-
-
- -
-

Default select with function nativeSelectMode

- -
-

- *Native select appears on mobile resolution. -

-
- -
- - - -
-              const dropdown = new CGSelect({
-                selector: '.cg-dropdown_one', 
-                placeholder: 'Choose a car', 
-                nativeSelectMode: true,
-                items: [
-                  'BMW',
-                  {
-                    id: '213sade',
-                    title: 'Opel',
-                    value: 1,
-                  },
-                  'Mersedes', 
-                  'MAN',  
-                  'Ferari', 
-                ],
-                styles: {
-                  head: {
-                    width: '830px', 
-                  },
-                  list: {
-                    width: '824px', 
-                  },
-                },
-              });
-            
-
-
-
- -
-

Default select with function listDisplayMode

- -
-

- *When using this method, the selection sheet appears as a modal window. -

-
- -
- - - - -
-              const dropdown = new CGSelect({
-                selector: '.cg-dropdown_listDisplayMode', 
-                placeholder: 'Choose a car', 
-                listDisplayMode: true,
-                items: [
-                  'BMW',
-                  {
-                    id: '213sade',
-                    title: 'Opel',
-                    value: 1,
-                  },
-                  'Mersedes', 
-                  'MAN',  
-                  'Ferari', 
-                ],
-                styles: {
-                  head: {
-                    width: '830px', 
-                  },
-                  list: {
-                    width: '824px', 
-                  },
-                },
-              });
-            
-
-
-
- -
-

Select with data from URL

-
- -
- - - -
-            const dropdown = new CGSelect({
-              selector: '.cg-dropdown_three', 
-              placeholder: 'URL', 
-              url: 'https://jsonplaceholder.typicode.com/users',            
-              searchMode: true,
-              darkTheme: false,
-              language: 'ru',
-              styles: {
-                head: {
-                  width: '830px', 
-                },
-                list: {
-                  width: '824px', 
-                },
-              },
-            });
-          
-
-
- -
-

Categories

- -
- -
- - - -
-            const dropdown = new CGSelect({
-              selector: '.cg-dropdown_categories', 
-              placeholder: 'Выберите регион', 
-              searchMode: true,
-              items: [
-                {
-                  category: 'Russia',
-                  categoryItems: [
-                    {
-                      id: '28qwds',
-                      title: 'Москва',
-                      value: 0,
-                    },
-                    'Ростов-на-дону',
-                    'Саратов',
-                    'Волгоград',
-                    'Донецк',
-                  ],
-                },
-                {
-                  category: 'USA',
-                  categoryItems: [
-                    'Alabama', 
-                    'Texas', 
-                    'Colorado', 
-                    'Klirens', 
-                    'Los-Angeles'],
-                },
-                {
-                  category: 'France',
-                  categoryItems: ['Paris'],
-                },
-              ],
-              styles: {
-                head: {
-                  width: '830px', 
-                },
-                list: {
-                  width: '824px', 
-                },
-                placeholder: {
-                  maxWidth: '500px ',
-                },
-              },
-              multiselect: true,
-              multiselectTag: true,
-            });
-          
-
-
- -
-

Button control

-
- - -
- -
- -
- - - - -
-            const dropdown = new CGSelect({
-              selector: '.cg-dropdown_usedBtn', 
-              placeholder: 'Choose a car', 
-              searchMode: true,
-              items: [
-                  'BMW',
-                  {
-                    id: '213sade',
-                    title: 'Opel',
-                    value: 1,
-                  },
-                  'Mersedes', 
-                  'MAN',  
-                  'max', 
-              ],
-              styles: {
-                head: {
-                  width:  '830px',
-                  color:  'black',
-                  backgroundColor:  'rgb(176 223 167)',
-                },
-                list: {
-                  width:  '824px',
-                  color:  'black',
-                  backgroundColor:  'rgb(176 223 167)',
-                },
-                caret: {
-                  borderTop:  '6px solid black',
-                },
-                search: {
-                  backgroundColor:  '#d7ffff',
-                  borderRadius:  '5px',
-                  borderBottom:  'none',
-                  width:  '95%',
-                  color:  'black',
-                },
-              },
-              multiselect: true,
-            });
-          
-
-
- -
-

Function disabled

- - - - -
- -
- - - -
-            const dropdown = new CGSelect({
-              selector: '.cg-dropdown_checkboxDisable', 
-              placeholder: 'Choose a car', 
-              searchMode: true,
-              items: [
-                'BMW',
-                {
-                  id: '213sade',
-                  title: 'Opel',
-                  value: 1,
-                },
-                'Mersedes', 
-                'MAN',  
-                'Ferari', 
-              ],
-              styles: {
-                head: {
-                  width: '830px', 
-                },
-                list: {
-                  width: '824px', 
-                },
-                placeholder: {
-                  maxWidth: '500px ',
-                },
-              },
-              multiselect: true,
-            });
-          
-
-
-
- - - diff --git a/example/index.js b/example/index.js deleted file mode 100644 index c4a86d0..0000000 --- a/example/index.js +++ /dev/null @@ -1,238 +0,0 @@ -import { CGSelect } from '../src/cg-select'; -import './example'; - -// ------------------------------Обычный селект-------------------- -const dropdown = new CGSelect({ - selector: '.cg-dropdown_one', - placeholder: 'Choose a car', - label: 'EXAMPLE', - items: [ - 'BMW', - { - id: '213sade', - title: 'Opel', - value: 1, - }, - 'Mersedes', - 'MAN', - 'Ferari', - ], - styles: { - head: { - width: '830px', - }, - list: { - width: '824px', - }, - }, -}); - -dropdown.on('clear', function (e) { - console.log(`this state: ${e}`); -}); - -// ------------------------------NativeSelect----------------------- -const dropdownNativeSelect = new CGSelect({ - selector: '.cg-dropdown_selectNative', - placeholder: 'Choose a car', - nativeSelectMode: true, - items: [ - 'BMW', - { - id: '213sade', - title: 'Opel', - value: 1, - }, - 'Mersedes', - 'MAN', - 'Ferari', - 'Kamaz', - 'Ural', - ], - styles: { - head: { - width: '830px', - }, - list: { - width: '824px', - }, - }, - theme: 'dark', -}); - -// ------------------------------listDisplayMode-------------------- -const dropdownlistDisplayMode = new CGSelect({ - selector: '.cg-dropdown_listDisplayMode', - placeholder: 'Choose a car', - listDisplayMode: true, - items: [ - 'BMW', - { - id: '213sade', - title: 'Opel', - value: 1, - }, - 'Mersedes', - 'MAN', - 'Ferari', - ], - styles: { - head: { - width: '830px', - }, - list: { - width: '824px', - }, - }, -}); - -// --------------------------------Категории-------------------------- -const dropdown4 = new CGSelect({ - selector: '.cg-dropdown_categories', - placeholder: 'Choose region', - searchMode: true, - items: [ - { - category: 'Russia', - categoryItems: [ - { - id: '28qwds', - title: 'Москва', - value: 0, - }, - , - 'Ростов-на-дону', - 'Саратов', - 'Волгоград', - 'Донецк', - ], - }, - { - category: 'USA', - categoryItems: ['Alabama', 'Texas', 'Colorado', 'Klirens', 'Los-Angeles'], - }, - { - category: 'France', - categoryItems: ['Paris'], - }, - ], - styles: { - head: { - width: '830px', - }, - list: { - width: '824px', - }, - placeholder: { - maxWidth: '500px ', - }, - }, - multiselect: true, - multiselectTag: true, -}); - -//----------------управление с помощью кнопок---------------------------------- -const dropdownBtn = new CGSelect({ - selector: '.cg-dropdown_usedBtn', - placeholder: 'Choose a car', - searchMode: true, - items: [ - 'BMW', - { - id: '213sade', - title: 'Opel', - value: 1, - }, - 'Mersedes', - 'MAN', - 'max', - ], - styles: { - head: { - width: '830px', - color: 'black', - backgroundColor: 'rgb(176 223 167)', - }, - list: { - width: '824px', - color: 'black', - backgroundColor: 'rgb(176 223 167)', - }, - caret: { - borderTop: '6px solid black', - }, - search: { - backgroundColor: '#d7ffff', - borderRadius: '5px', - borderBottom: 'none', - width: '95%', - color: 'black', - }, - }, - multiselect: true, -}); - -const buttonOpen = document.querySelector('.button__open'); -const buttonClose = document.querySelector('.button__close'); - -dropdownBtn.buttonControl(buttonOpen, 'open'); -dropdownBtn.buttonControl(buttonClose, 'close'); - -//-------------------------Функция Disabled---------------------------------- -const dropdownDisabled = new CGSelect({ - selector: '.cg-dropdown_checkboxDisable', - placeholder: 'Choose a car', - searchMode: true, - items: [ - 'BMW', - { - id: '213sade', - title: 'Opel', - value: 1, - }, - 'Mersedes', - 'MAN', - 'max', - ], - styles: { - head: { - width: '830px', - }, - list: { - width: '824px', - }, - placeholder: { - maxWidth: '500px ', - }, - }, - multiselect: true, -}); -dropdownDisabled.disabled(true); -let chbox = document.getElementById('checkboxDisable'); - -chbox.addEventListener('click', () => { - if (chbox.checked == true) { - dropdownDisabled.disabled(false); - } else { - dropdownDisabled.disabled(true); - } -}); - -// ------------------------------URL-------------------- -const dropdown3 = new CGSelect({ - selector: '.cg-dropdown_three', - placeholder: 'URL', - url: 'https://jsonplaceholder.typicode.com/todos', - searchMode: true, - darkTheme: false, - language: 'ru', - styles: { - head: { - width: '830px', - }, - list: { - width: '824px', - }, - }, - multiselect: true, -}); diff --git a/index.js b/index.js index cae98de..d3c8b2f 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,3 @@ -import { CGSelect } from './src/cg-select.ts'; +import { CGSelect } from './src/cg-select'; export default CGSelect; diff --git a/package-lock.json b/package-lock.json index 1665717..b301e96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cg-select", - "version": "0.2.32", + "version": "0.2.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cg-select", - "version": "0.2.32", + "version": "0.2.5", "license": "ISC", "dependencies": { "@parcel/optimizer-css": "^2.8.0", diff --git a/package.json b/package.json index 648f3b4..ff44b8f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,8 @@ { "name": "cg-select", - "version": "0.2.32", + "version": "0.2.5", + "source": "index.js", + "main": "dist/index.js", "description": "Feature rich Select control for React/JS with multiselect, autocomplete and styling", "author": { "name": "CraftGroup", @@ -8,8 +10,8 @@ }, "homepage": "https://cg-select.itguild.info", "scripts": { - "start": "parcel example/index.html -p 4500 --open ", - "build": "parcel build example/index.js --no-cache", + "watch": "parcel watch", + "build": "parcel build", "deploy": "gh-pages -d dist", "predeploy": "npm run build" }, 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}