diff --git a/package-lock.json b/package-lock.json index 65d6fdc..724119e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "cg-select", - "version": "0.1.171", + "version": "0.2.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cg-select", - "version": "0.1.171", + "version": "0.2.1", "license": "ISC", "dependencies": { "@parcel/optimizer-css": "^2.8.0", + "@types/prettier": "^2.7.2", "gh-pages": "^4.0.0", "typescript": "^4.9.4" }, @@ -2081,6 +2082,11 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "node_modules/@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==" + }, "node_modules/abortcontroller-polyfill": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz", @@ -5404,6 +5410,11 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==" + }, "abortcontroller-polyfill": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz", diff --git a/package.json b/package.json index 5df75e9..cec7f93 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ }, "dependencies": { "@parcel/optimizer-css": "^2.8.0", + "@types/prettier": "^2.7.2", "gh-pages": "^4.0.0", "typescript": "^4.9.4" }, diff --git a/src/cg-selectTS.ts b/src/cg-selectTS.ts index 8379ab2..175064e 100644 --- a/src/cg-selectTS.ts +++ b/src/cg-selectTS.ts @@ -1,3 +1,7 @@ +import { + createNativeSelect, + createNativeSelectOption, +} from './components/create-element/create-elementTs'; import { IDataItem } from './components/utils/urils.interface'; import { createSelected, getFormatItem } from './components/utils/utilsTs'; import { ISgSelect } from './interfaces/cg-select.interface'; @@ -23,9 +27,10 @@ export class SGSelect implements ISgSelect { multiselectTag?: boolean; private element: Element | null; - private list: HTMLElement; + private list: Element | null | undefined; private options: ISgSelect; - private caret: HTMLElement; + private randomId: string; + private caret: Element | null | undefined; private category: string; private selectedItems: object[] | object; private itemsSelect: IItems[] | string[] | any; @@ -36,39 +41,74 @@ export class SGSelect implements ISgSelect { this.render(); } + /** + * Приватный метод инициализации экземпляра класса DropDown + * @method #init + * @member + * @protected + * @param {ISgSelect} setting передаваемые настройки селекта + * @description Приватный метод. Общая инициализация селекта. Получение настоек и преобразвание элементов селекта. + * @example + * { + selector: '.cg-dropdown_one', + placeholder: 'Выберите авто', + items: [ + 'BMW', + { + id: '213sade', + title: 'Opel', + value: 1, + }, + 'Mersedes', + 'MAN', + 'max', + ], + darkTheme: true, + multiselect: true, + multiselectTag: true, + } + */ private init(setting: ISgSelect): void { - const { items, multiselect, url, selector} = setting; + const { items, multiselect, url, selector } = setting; this.options = setting; - - const elem = document.querySelector(selector); this.element = elem; this.element?.addEventListener('click', (e) => { e.preventDefault(); - console.log('click'); - + this.open(); }); this.itemsSelect = []; - - if(multiselect === true){ - this.selectedItems = []; + + if (multiselect === true) { + this.selectedItems = []; } if (!items && url) { - this.renderUrl(); - return; + this.renderUrl(); + return; } - items.forEach((dataItem:IDataItem, index:number) => { - this.itemsSelect.push(getFormatItem(dataItem, index)) - }) + items.forEach((dataItem: any, index: number) => { + let itemInputs: IDataItem = { + ItemValue: dataItem, + }; + + this.itemsSelect.push(getFormatItem(itemInputs.ItemValue, index)); + }); } - private render() { + /** + * Приватный метод рендера экземпляра класса DropDown + *@protected + * @method #render + * @param {string} select необязательный елемент. Передаеться в метод initSelected + * @description Рендер елементов в селекте. + */ + private render(select?: string): void { const { styles, multiselect, @@ -82,14 +122,76 @@ export class SGSelect implements ISgSelect { const random = Math.random().toString(36).substring(2, 10); - this.initSelected() + this.initSelected(); + const ulList = document.createElement('ul'); + const nativeSelect = createNativeSelect(); + + let inputSearch: string = ''; + let textNode: Text; + + this.randomId = random; + + ulList.classList.add('list'); + + this.element?.appendChild(ulList); + + this.itemsSelect.forEach((dataItem: IItems | any) => { + this.element?.appendChild(nativeSelect); + + const liItem = document.createElement('li'); + const nativeOption = createNativeSelectOption(); + const strongItem = document.createElement('strong'); + + liItem.classList.add('list__item'); + strongItem.classList.add('category'); + + if (multiselect && multiselect === true) { + const checkBox = document.createElement('input'); + checkBox.type = 'checkbox'; + checkBox.setAttribute('id', `chbox-${dataItem.id}`); + liItem.appendChild(checkBox); + + if (multiselectTag && multiselectTag == true) { + checkBox.classList.add('displayHide'); + } + + nativeSelect.setAttribute('multiple', 'multiple'); + } + + if (dataItem.title) { + nativeOption.text = dataItem.title; + nativeOption.value = dataItem.title; + textNode = document.createTextNode(dataItem.title); + + nativeSelect.appendChild(nativeOption); + liItem.appendChild(textNode); + ulList.appendChild(liItem); + } else { + // Для отрисовки категорий + textNode = document.createTextNode(dataItem); + strongItem.appendChild(textNode); + ulList.appendChild(strongItem); + } + }); + + this.list = this.element?.querySelector('.list'); + this.caret = this.element?.querySelector('.caret'); + + // this.#addOptionsBehaviour(); } private renderUrl() {} - - private initSelected(){ + /** + * Привaтный метод экземпляра класса DropDown + * + * @method #initSelected + * @param {string} select необязательный елемент. Используется в методе selectIndex + * @description Отрисовывает и стилизует селект + * @protected + */ + private initSelected(select?: string): void { const { styles, selected, placeholder, lable, language } = this.options; if (selected) { @@ -104,4 +206,23 @@ export class SGSelect implements ISgSelect { // } } } + + /** + * Приватный метод экземпляра класса DropDown + * @protected + * @param {boolean} oneClick необязательный параметр передаваемый из функции buttonControl + * @description Открывает список для выбора элемента + * @method #open + */ + private open(oneClick?: boolean): void { + if (oneClick === true) { + this.list?.classList.add('open'); + this.caret?.classList.add('caret_rotate'); + } else { + this.list?.classList.toggle('open'); + this.caret?.classList.toggle('caret_rotate'); + } + } + + private addOptionsBehaviour() {} } diff --git a/src/components/create-element/create-elementTs.ts b/src/components/create-element/create-elementTs.ts new file mode 100644 index 0000000..c5d4f7c --- /dev/null +++ b/src/components/create-element/create-elementTs.ts @@ -0,0 +1,25 @@ + +/** + * Метод который создает нативный селект + * @returns {HTMLSelectElement} Возвращает созданный нативный селект + */ + +export function createNativeSelect(): HTMLSelectElement { + const nativeSelect = document.createElement('select'); + + nativeSelect.setAttribute('name', 'dataSelect'); + nativeSelect.classList.add('nativeSelect'); + return nativeSelect; +} + +/** + * Метод который создает Options для нативного селекта + * @returns {HTMLOptionElement} Возвращает созданные Options нативного селекта + */ +export function createNativeSelectOption(): HTMLOptionElement { + const nativeOption = document.createElement('option'); + + nativeOption.classList.add('nativeSelect__nativeOption'); + return nativeOption; +} + \ No newline at end of file diff --git a/src/components/utils/urils.interface.ts b/src/components/utils/urils.interface.ts index c681930..b21d691 100644 --- a/src/components/utils/urils.interface.ts +++ b/src/components/utils/urils.interface.ts @@ -1,5 +1,7 @@ +import { IItems } from "../../interfaces/items.interface"; + export interface IDataItem{ category?: string; categoryItems?: string; - ItemValue: object | string | number; + ItemValue: string | IItems | number; } \ No newline at end of file diff --git a/src/components/utils/utilsTs.ts b/src/components/utils/utilsTs.ts index 3c32005..e63d5eb 100644 --- a/src/components/utils/utilsTs.ts +++ b/src/components/utils/utilsTs.ts @@ -8,7 +8,7 @@ import { IDataItem } from './urils.interface'; * @returns {IDataItem | IItems} возвращает сформированный объект */ -export function getFormatItem(dataItem:IDataItem , index: number):IDataItem | IItems { +export function getFormatItem(dataItem:any , index: number) : IItems { const random = Math.random().toString(36).substring(2, 10); let item: IItems; @@ -20,6 +20,7 @@ export function getFormatItem(dataItem:IDataItem , index: number):IDataItem | II title: dataItem, value: index } + return item; } } diff --git a/src/interfaces/items.interface.ts b/src/interfaces/items.interface.ts index 1e55bfd..c7bfa0d 100644 --- a/src/interfaces/items.interface.ts +++ b/src/interfaces/items.interface.ts @@ -1,5 +1,5 @@ export interface IItems{ id: string; - title: string | number | object; + title: string; value: number | string } \ No newline at end of file