Skip to content

Commit

Permalink
fix: when data array is null it shouldn't throw
Browse files Browse the repository at this point in the history
- fix null data error thrown & couple of other fixes
  • Loading branch information
ghiscoding committed Mar 4, 2023
1 parent d3147eb commit 184dffa
Show file tree
Hide file tree
Showing 10 changed files with 469 additions and 39 deletions.
2 changes: 2 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tsconfig.json
tsconfig.tsbuildinfo
8 changes: 4 additions & 4 deletions demo/src/options/options26.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ export default class Example {
mount() {
this.ms1 = multipleSelect('#basic', {
styler: (row: OptionRowData | OptGroupRowData) => {
if (+row.value === 1) {
if (+(row?.value ?? 0) === 1) {
return 'background-color: #ffee00; color: #ff0000;';
}
if (+row.value === 6) {
if (+(row?.value ?? 0) === 6) {
return 'background-color: #000; color: #fff;';
}
return null;
Expand All @@ -19,10 +19,10 @@ export default class Example {

this.ms2 = multipleSelect('#group', {
styler: (row: OptionRowData | OptGroupRowData) => {
if (row.type === 'optgroup') {
if (row?.type === 'optgroup') {
return 'color: #777; font-weight: normal;';
}
if (+row.value === 1) {
if (+(row?.value ?? 0) === 1) {
return 'color: blue;';
}
return null;
Expand Down
2 changes: 1 addition & 1 deletion demo/src/options/options27.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ <h2 class="bd-title">
</span>
</span>
</h2>
<div class="demo-subtitle">Use <code>textTemplate</code> to custom the text template.</div>
<div class="demo-subtitle">Use <code>textTemplate</code> to customize the text template.</div>
</div>
</div>

Expand Down
7 changes: 6 additions & 1 deletion lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
"scripts": {
"clean": "rimraf dist",
"build": "pnpm build:all && pnpm build:types:prod",
"builder": "vite build && vite build --config vite-locales.config.ts",
"build:vite": "vite build",
"build:vite2": "vite build --config vite-locales.config.ts",
"postbuild": "run-s sass:build sass:copy --npm-path pnpm",
"dev:init": "pnpm sass:build && pnpm build:locales && pnpm sass:copy && pnpm build:types && pnpm build:esm",
"build:all": "node build-prod.mjs && pnpm build:types:prod",
Expand Down Expand Up @@ -67,6 +70,8 @@
"postcss": "^8.4.21",
"postcss-cli": "^10.1.0",
"sass": "^1.58.3",
"typescript": "^5.0.0-beta"
"typescript": "^5.0.0-rc",
"vite": "^4.1.2",
"vite-plugin-dts": "^2.0.2"
}
}
52 changes: 26 additions & 26 deletions lib/src/MultipleSelectInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from './utils/domUtils';
import { BindingEventService, VirtualScroll } from './services';
import { MultipleSelectOption } from './interfaces/multipleSelectOption.interface';
import { MultipleSelectLocales, OptGroupRowData, OptionRowData } from './interfaces';
import { MultipleSelectLocales, OptGroupRowData, OptionDataObject, OptionRowData } from './interfaces';

export class MultipleSelectInstance {
protected _bindEventService: BindingEventService;
Expand All @@ -25,7 +25,7 @@ export class MultipleSelectInstance {
protected closeElm?: HTMLElement | null;
protected filterText = '';
protected updateData: any[] = [];
protected data: OptionRowData[] = [];
protected data?: Array<OptionRowData | OptGroupRowData> = [];
protected dataTotal?: any;
protected dropElm!: HTMLDivElement;
protected okButtonElm?: HTMLButtonElement;
Expand Down Expand Up @@ -253,7 +253,7 @@ export class MultipleSelectInstance {
}

protected initData() {
const data: any[] = [];
const data: Array<OptionRowData> = [];

if (this.options.data) {
if (Array.isArray(this.options.data)) {
Expand All @@ -267,10 +267,10 @@ export class MultipleSelectInstance {
return it;
});
} else if (typeof this.options.data === 'object') {
for (const [value, text] of Object.entries(this.options.data)) {
for (const [value, text] of Object.entries(this.options.data as OptionDataObject)) {
data.push({
value,
text,
text: `${text}`,
});
}
this.data = data;
Expand All @@ -288,7 +288,7 @@ export class MultipleSelectInstance {
this.fromHtml = true;
}

this.dataTotal = setDataKeys(this.data);
this.dataTotal = setDataKeys(this.data || []);
}

protected initRow(elm: HTMLOptionElement, groupDisabled?: boolean) {
Expand Down Expand Up @@ -361,7 +361,7 @@ export class MultipleSelectInstance {

let length = 0;
for (const option of this.data || []) {
if (option.type === 'optgroup') {
if ((option as OptGroupRowData).type === 'optgroup') {
length += (option as OptGroupRowData).children.length;
} else {
length += 1;
Expand Down Expand Up @@ -436,8 +436,8 @@ export class MultipleSelectInstance {
if (this.updateDataStart < 0) {
this.updateDataStart = 0;
}
if (this.updateDataEnd > this.data.length) {
this.updateDataEnd = this.data.length;
if (this.updateDataEnd > (this.data?.length ?? 0)) {
this.updateDataEnd = this.data?.length ?? 0;
}
}
};
Expand Down Expand Up @@ -476,7 +476,7 @@ export class MultipleSelectInstance {
const rows = [];

this.updateData = [];
this.data.forEach((row) => {
this.data?.forEach((row) => {
rows.push(...this.initListItem(row));
});

Expand Down Expand Up @@ -572,7 +572,7 @@ export class MultipleSelectInstance {
let selectedTotal = 0;

for (const row of this.data || []) {
if (row.type === 'optgroup') {
if ((row as OptGroupRowData).type === 'optgroup') {
const selectedCount = (row as OptGroupRowData).children.filter((child) => {
return child && child.selected && !child.disabled && child.visible;
}).length;
Expand All @@ -593,9 +593,9 @@ export class MultipleSelectInstance {
}

this.allSelected =
this.data.filter((row: OptionRowData) => {
this.data?.filter((row: OptionRowData | OptGroupRowData) => {
return row.selected && !row.disabled && row.visible;
}).length === this.data.filter((row) => !row.disabled && row.visible && !row.divider).length;
}).length === this.data?.filter((row) => !row.disabled && row.visible && !row.divider).length;

if (!ignoreTrigger) {
if (this.allSelected) {
Expand Down Expand Up @@ -806,7 +806,7 @@ export class MultipleSelectInstance {
this.noResultsElm.style.display = 'none';
}

if (!this.data.length) {
if (!this.data?.length) {
if (this.selectAllElm?.parentElement) {
this.selectAllElm.parentElement.style.display = 'none';
}
Expand Down Expand Up @@ -849,7 +849,7 @@ export class MultipleSelectInstance {
const multElms = this.dropElm.querySelectorAll<HTMLDivElement>('.multiple');
multElms.forEach((multElm) => (multElm.style.width = `${this.options.multipleWidth}px`));

if (this.data.length && this.options.filter) {
if (this.data?.length && this.options.filter) {
if (this.searchInputElm) {
this.searchInputElm.value = '';
this.searchInputElm.focus();
Expand Down Expand Up @@ -988,7 +988,7 @@ export class MultipleSelectInstance {
}
}

const noResult = this.data.filter((row) => row.visible).length === 0;
const noResult = this.data?.filter((row) => row.visible).length === 0;

if (this.selectAllElm) {
this.selectAllElm.checked = this.allSelected;
Expand Down Expand Up @@ -1037,7 +1037,7 @@ export class MultipleSelectInstance {
getSelects(type = 'value') {
const values = [];
for (const row of this.data || []) {
if (row.type === 'optgroup') {
if ((row as OptGroupRowData).type === 'optgroup') {
const selectedChildren = (row as OptGroupRowData).children.filter((child) => child?.selected);
if (!selectedChildren.length) {
continue;
Expand All @@ -1052,13 +1052,13 @@ export class MultipleSelectInstance {
} else {
const value = [];
value.push('[');
value.push(row.label);
value.push((row as OptGroupRowData).label);
value.push(`: ${selectedChildren.map((child: any) => child[type]).join(', ')}`);
value.push(']');
values.push(value.join(''));
}
} else if (row.selected) {
values.push(type === 'value' ? row._value || row[type] : (row as any)[type]);
values.push(type === 'value' ? row._value || (row as OptionRowData)[type] : (row as any)[type]);
}
}
return values;
Expand All @@ -1085,7 +1085,7 @@ export class MultipleSelectInstance {
};

for (const row of this.data || []) {
if (row.type === 'optgroup') {
if ((row as OptGroupRowData).type === 'optgroup') {
_setSelects((row as OptGroupRowData).children);
} else {
_setSelects([row]);
Expand Down Expand Up @@ -1143,7 +1143,7 @@ export class MultipleSelectInstance {

protected _checkAll(checked: boolean, ignoreUpdate?: boolean) {
for (const row of this.data || []) {
if (row.type === 'optgroup') {
if ((row as OptGroupRowData).type === 'optgroup') {
this._checkGroup(row, checked, true);
} else if (!row.disabled && !row.divider && (ignoreUpdate || row.visible)) {
row.selected = checked;
Expand Down Expand Up @@ -1177,7 +1177,7 @@ export class MultipleSelectInstance {
return;
}
for (const row of this.data || []) {
if (row.type === 'optgroup') {
if ((row as OptGroupRowData).type === 'optgroup') {
for (const child of (row as OptGroupRowData).children) {
if (child) {
if (!child.divider) {
Expand Down Expand Up @@ -1221,9 +1221,9 @@ export class MultipleSelectInstance {
this.filterText = text;

for (const row of this.data || []) {
if (row.type === 'optgroup') {
if ((row as OptGroupRowData).type === 'optgroup') {
if (this.options.filterGroup) {
const rowLabel = `${row?.label ?? ''}`;
const rowLabel = `${(row as OptGroupRowData)?.label ?? ''}`;
if (row !== undefined && row !== null) {
const visible = this.options.customFilter(
removeDiacritics(rowLabel.toLowerCase()),
Expand All @@ -1242,7 +1242,7 @@ export class MultipleSelectInstance {
} else {
for (const child of (row as OptGroupRowData).children) {
if (child !== undefined && child !== null) {
const childText = `${child?.text ?? ''}`;
const childText = `${(child as OptionRowData)?.text ?? ''}`;
child.visible = this.options.customFilter(
removeDiacritics(childText.toLowerCase()),
removeDiacritics(text),
Expand All @@ -1254,7 +1254,7 @@ export class MultipleSelectInstance {
row.visible = (row as OptGroupRowData).children.filter((child: any) => child?.visible).length > 0;
}
} else {
const rowText = `${row?.text ?? ''}`;
const rowText = `${(row as OptionRowData)?.text ?? ''}`;
row.visible = this.options.customFilter(
removeDiacritics(rowText.toLowerCase()),
removeDiacritics(text),
Expand Down
10 changes: 6 additions & 4 deletions lib/src/interfaces/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
export type OptionDataObject = { [value: string]: number | string | boolean };
export interface OptionRowData {
label?: string;
text: string;
value: string | number | boolean;
type?: 'option' | 'optgroup';
divider?: string;
disabled?: boolean;
selected?: boolean | number;
visible?: boolean | string;
type?: 'option' | 'optgroup';
_key?: string;
_value?: string | number | boolean;
}

export interface OptGroupRowData extends OptionRowData {
children: Array<OptionRowData | OptGroupRowData>;
export interface OptGroupRowData extends Omit<OptionRowData, 'text' | 'value'> {
label: string;
value?: string | number | boolean;
children: Array<OptionRowData>;
}

export interface VirtualScrollOption {
Expand Down
6 changes: 3 additions & 3 deletions lib/src/interfaces/multipleSelectOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface MultipleSelectOption extends MultipleSelectLocale {
countSelectedText?: string;

/** provide custom data */
data?: any | any[];
data?: { [value: string]: number | string | boolean } | Array<number | string | boolean | OptionRowData | OptGroupRowData>;

/** Delimiter to be displayed between each option */
displayDelimiter: string;
Expand Down Expand Up @@ -153,10 +153,10 @@ export interface MultipleSelectOption extends MultipleSelectLocale {
styler: (value: OptionRowData | OptGroupRowData) => string | boolean | null;

/** Returns HTML label attribute of a DOM element */
labelTemplate: (elm: any) => any;
labelTemplate: (elm: any) => string;

/** Returns HTML text template of a DOM element */
textTemplate: (elm: any) => any;
textTemplate: (elm: any) => string;

// --
// Events
Expand Down
66 changes: 66 additions & 0 deletions lib/vite-locales.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { defineConfig } from 'vite';
import { resolve } from 'path';
import path from 'node:path';
import glob from 'glob';

const dirname = path.dirname(__filename);
const localeFiles: string[] = glob.sync('src/locales/**/*.ts');
const localeEntryPoints: string[] = [];
const locales: string[] = [resolve(dirname, `src/locales/all-locales-index.ts`)];
const localeInputs: { [locale: string]: string } = {
all: resolve(dirname, `src/locales/all-locales-index.ts`),
};

for (const localeFile of localeFiles) {
// eslint-disable-next-line no-unused-vars
const [_, locale] = localeFile.match(/multiple-select-(.*)\.ts$/) || [];
if (locale && locale.length === 5) {
// locales.push(locale);
localeInputs[locale] = resolve(dirname, `src/locales/multiple-select-${locale}.ts`);
localeEntryPoints.push(resolve(dirname, `src/locales/multiple-select-${locale}.ts`));
}
}

export default defineConfig({
base: './',
mode: 'library',
build: {
emptyOutDir: false,
minify: true,
sourcemap: false,
lib: {
entry: locales.map((locale) => resolve(dirname, `src/locales/multiple-select-${locale}.ts`)),
// entry: [
// resolve(dirname, 'src/locales/multiple-select-en-US.ts'),
// resolve(dirname, 'src/locales/multiple-select-es-ES.ts'),
// ],
formats: ['es', 'cjs'],
// name: 'multiple-select-all-locales',
// fileName: ' multiple-select-all-locales',
fileName: (format, entryName) => {
if (entryName === 'all') {
return `multiple-select-all-locales.${format === 'cjs' ? 'cjs' : 'js'}`;
}
return `locales/multiple-select-${entryName}.${format === 'cjs' ? 'cjs' : 'js'}`;
},
},
rollupOptions: {
input: localeInputs,
// input: {
// // inlineDynamicImports: false,
// // all: resolve(dirname, 'src/locales/all-locales-index.ts'),
// 'en-US': resolve(dirname, 'src/locales/multiple-select-en-US.ts'),
// 'es-ES': resolve(dirname, 'src/locales/multiple-select-es-ES.ts'),
// },
// output: [
// {
// format: 'umd',
// name: '[name]',
// inlineDynamicImports: true,
// entryFileNames: '[name].bundle.[format].js',
// // entryFileNames: 'multiple-select.[format].js',
// },
// ],
},
},
});
Loading

0 comments on commit 184dffa

Please sign in to comment.