simp-select 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/style.css ADDED
@@ -0,0 +1,413 @@
1
+ :root {
2
+ --simpS_bg: white;
3
+ --simpS_pad_hor: 15px;
4
+ --simpS_height_top: 40px;
5
+ --simpS_color: #27272a;
6
+ --simpS_color_light: #eae9e9;
7
+ --simpS_color_cheked: #d9d7d7;
8
+ --simpS_color_yes: green;
9
+ --simpS_color_no: red;
10
+ --simpS_color_placeholder: #5d5c5c;
11
+ --simpS_color_dis: #8b8b8b;
12
+ --simpS_radius: 4px;
13
+ --simpS_f_size: 16px;
14
+ --simpS_f_shadow: 0 0 3px 0 var(--simpS_color);
15
+
16
+
17
+ --simpS_size_check: 20px;
18
+
19
+ --simpS_li_h: 36px;
20
+
21
+ --simpS_btn_h: 34px;
22
+ --simpS_btn_bg: #f9f9f9;
23
+ --simpS_btn_bg_reverse: #eeecec;
24
+
25
+ }
26
+ .SimpleSel {
27
+ position: relative;
28
+ box-sizing: border-box;
29
+ color: var(--simpS_color);
30
+ font-size: var(--simpS_f_size);
31
+ user-select: none;
32
+ }
33
+ .SimpleSel--disabled {
34
+ color: var(--simpS_color_dis);
35
+ opacity: .8;
36
+
37
+ }
38
+
39
+ /* start all setting */
40
+
41
+ .SimpleSel * {
42
+ box-sizing: border-box;
43
+ }
44
+ .SimpleSel :after,
45
+ .SimpleSel :before {
46
+ box-sizing: border-box;
47
+ }
48
+
49
+ .SimpleSel__select_init {
50
+ position: absolute;
51
+ opacity: 0;
52
+ top: 0;
53
+ right: 0;
54
+ width: 100%;
55
+ height: 100%;
56
+ /*z-index: 2;*/
57
+ box-sizing: border-box;
58
+ }
59
+ .SimpleSel__select_init--native {
60
+ z-index: 5;
61
+ }
62
+
63
+ /* end all setting */
64
+
65
+ /* start Buttons */
66
+ .SimpleSel__bottom_control,
67
+ .SimpleSel__control {
68
+ margin: 0;
69
+ width: auto;
70
+ overflow: visible;
71
+ color: inherit;
72
+ font: inherit;
73
+ line-height: normal;
74
+ -webkit-font-smoothing: inherit;
75
+ -moz-osx-font-smoothing: inherit;
76
+ -webkit-appearance: none;
77
+ outline: none;
78
+ cursor: pointer;
79
+
80
+ background-color: var(--simpS_btn_bg);
81
+ padding: 1px 10px;
82
+ text-align: center;
83
+ border-radius: 0;
84
+ border: none;
85
+ display: flex;
86
+ align-content: center;
87
+ align-items: center;
88
+ justify-content: center;
89
+ height: var(--simpS_btn_h);
90
+ }
91
+ .SimpleSel__bottom_control:hover,
92
+ .SimpleSel__control:hover {
93
+ background-color: var(--simpS_btn_bg_reverse);
94
+ }
95
+ /* end Buttons */
96
+
97
+ /* start Checkbox */
98
+ .SimpleSel__select_all__icon,
99
+ .SimpleSel__list_item_icon,
100
+ .SimpleSel__reset_all__icon {
101
+ width: var(--simpS_size_check);
102
+ height: var(--simpS_size_check);
103
+ position: relative;
104
+ border: 1px solid currentColor;
105
+ margin-right: 7px;
106
+ display: flex;
107
+ align-items: center;
108
+ justify-content: center;
109
+ border-radius: var(--simpS_radius);
110
+ }
111
+ .SimpleSel__list_item_icon:before,
112
+ .SimpleSel__select_all__icon:before {
113
+ content: "";
114
+ display: block;
115
+ transition: 0.25s all;
116
+ transform: rotate(45deg) translate(-17%, -10%);
117
+ top: 1px;
118
+ left: 4px;
119
+ /*width: 7px;*/
120
+ width: calc(var(--simpS_size_check) / 3);
121
+ height: calc(var(--simpS_size_check) / 2 + 1px);
122
+ border: solid currentColor;
123
+ border-width: 0 2px 2px 0;
124
+ }
125
+ /* end Checkbox */
126
+
127
+
128
+
129
+ .SimpleSel__top {
130
+ position: relative;
131
+ }
132
+ .SimpleSel__top_body {
133
+ position: relative;
134
+
135
+ height: var(--simpS_height_top);
136
+ padding: 5px 0 5px var(--simpS_pad_hor);
137
+
138
+ background-color: var(--simpS_bg);
139
+ color: currentColor;
140
+ border: 2px solid currentColor;
141
+ border-radius: var(--simpS_radius);
142
+
143
+ display: flex;
144
+ align-items: center;
145
+ justify-content: space-between;
146
+
147
+ cursor: pointer;
148
+ }
149
+
150
+ .SimpleSel--disabled .SimpleSel__top_body {
151
+ cursor: default;
152
+ user-select: none;
153
+ }
154
+
155
+ .SimpleSel__top_body:focus-visible {
156
+ box-shadow: var(--simpS_f_shadow);
157
+ }
158
+
159
+ .SimpleSel__title {
160
+ flex: 1;
161
+ white-space: nowrap;
162
+ overflow: hidden;
163
+ text-overflow: ellipsis;
164
+ text-align: left;
165
+ }
166
+
167
+ .SimpleSel__icon {
168
+ width: var(--simpS_height_top);
169
+ height: var(--simpS_height_top);
170
+ display: flex;
171
+ align-items: center;
172
+ justify-content: center;
173
+ position: relative;
174
+ }
175
+ .SimpleSel__icon:after {
176
+ content: '';
177
+ transition: .25s transform, .25s top;
178
+ width: 0.5em;
179
+ height: 0.5em;
180
+ border-bottom: 2px currentColor solid;
181
+ border-right: 2px currentColor solid;
182
+ display: inline;
183
+ position: absolute;
184
+ transform-origin: left top;
185
+ top: calc(50% - 2px);
186
+ left: 50%;
187
+ transform: rotate(45deg) translate(-50%,-50%);
188
+ }
189
+ .SimpleSel--open .SimpleSel__icon:after {
190
+ top: calc(50% + 2px);
191
+ transform: rotate(225deg) translate(-50%,-50%);
192
+ }
193
+
194
+ .SimpleSel__list_item--not_value,
195
+ .SimpleSel--single[data-count-checked-full="0"] .SimpleSel__title,
196
+ .SimpleSel__title--placeholder {
197
+ color: var(--simpS_color_placeholder);
198
+ }
199
+
200
+
201
+ .SimpleSel__body {
202
+ max-height: 0;
203
+ opacity: 0;
204
+ overflow: hidden;
205
+ overflow-y: auto;
206
+ position: absolute;
207
+ transition: .25s max-height, .1s opacity;
208
+ width: 100%;
209
+ border: 1px solid currentColor;
210
+ z-index: 3;
211
+ border-radius: var(--simpS_radius);
212
+ background-color: var(--simpS_bg);
213
+ }
214
+
215
+ .SimpleSel:not(.SimpleSel--up) .SimpleSel--multi {
216
+ top: 100%;
217
+ margin-top: 2px;
218
+ }
219
+
220
+ .SimpleSel--up:not(.SimpleSel--float) .SimpleSel__body {
221
+ bottom: 100%;
222
+ margin-bottom: 2px;
223
+ }
224
+
225
+ .SimpleSel--open .SimpleSel__body {
226
+ max-height: 230px;
227
+ opacity: 1;
228
+ }
229
+
230
+ .SimpleSel__search{
231
+ width: 100%;
232
+ border-radius: var(--simpS_radius);
233
+ padding: 2px var(--simpS_pad_hor);
234
+ }
235
+ .SimpleSel__search--top {
236
+ position: absolute;
237
+ top: 0;
238
+ left: 0;
239
+ height: 100%;
240
+ opacity: 0;
241
+ display: none;
242
+ }
243
+ .SimpleSel--open .SimpleSel__search--top {
244
+ opacity: 1;
245
+ display: block;
246
+ }
247
+ .SimpleSel__search--dropdown {
248
+ border: none;
249
+ border-bottom: 1px solid currentColor;
250
+ border-radius: 0;
251
+ height: var(--simpS_btn_h);
252
+ }
253
+
254
+ /* controls */
255
+ .SimpleSel__controls {
256
+ display: flex;
257
+ border-bottom: 1px solid currentColor;
258
+ }
259
+ .SimpleSel__control {
260
+ flex: 1;
261
+ }
262
+ .SimpleSel__control + .SimpleSel__control {
263
+ border-left: 1px solid;
264
+ }
265
+ .SimpleSel__select_all__icon {
266
+ color: var(--simpS_color_cheked);
267
+ border-radius: 50%;
268
+ border-color: var(--simpS_color_yes);
269
+ }
270
+ .SimpleSel[data-count-checked-full="0"] .SimpleSel__select_all__icon {
271
+ color: var(--simpS_color_light);
272
+ }
273
+ .SimpleSel[data-check-all-multi="yes"] .SimpleSel__select_all__icon {
274
+ color: var(--simpS_color_yes);
275
+ }
276
+
277
+ .SimpleSel__reset_all__icon {
278
+ position: relative;
279
+ border-radius: 50%;
280
+ color: var(--simpS_color_no);
281
+
282
+ }
283
+ .SimpleSel__reset_all__icon:before, .SimpleSel__reset_all__icon:after {
284
+ position: absolute;
285
+ left: calc(var(--simpS_f_size) / 2);
286
+ content: ' ';
287
+ height: 60%;
288
+ width: 2px;
289
+ background-color: currentColor;
290
+ }
291
+ .SimpleSel__reset_all__icon:before {
292
+ transform: rotate(45deg);
293
+ }
294
+ .SimpleSel__reset_all__icon:after {
295
+ transform: rotate(-45deg);
296
+ }
297
+
298
+
299
+ .SimpleSel__bottom_controls {
300
+ display: flex;
301
+ position: sticky;
302
+ border-top: 1px solid currentColor;
303
+ margin-top: 5px;
304
+ bottom: 0;
305
+ }
306
+ .SimpleSel__bottom_control--hide {
307
+ display: none;
308
+ }
309
+ .SimpleSel__bottom_control {
310
+ flex: 1;
311
+ }
312
+ .SimpleSel__bottom_control--ok{
313
+ text-transform: uppercase;
314
+ }
315
+ .SimpleSel__bottom_control + .SimpleSel__bottom_control {
316
+ border-left: 1px solid ;
317
+ }
318
+
319
+
320
+ /**List*/
321
+ .SimpleSel__list {
322
+ list-style-type: none;
323
+ margin: 0;
324
+ padding: 0;
325
+ }
326
+ .SimpleSel__group_items:not(:first-child) {
327
+ margin-top: 5px;
328
+ }
329
+ .SimpleSel__group_title {
330
+ font-weight: bold;
331
+ display: block;
332
+ padding: 6px 10px ;
333
+ margin-bottom: 2px;
334
+ font-size: 1.02em;
335
+ background-color: var(--simpS_color_light);
336
+ }
337
+
338
+ .SimpleSel__group {
339
+ list-style-type: none;
340
+ margin: 0;
341
+ padding: 0;
342
+ }
343
+
344
+
345
+
346
+ .SimpleSel__list_item {
347
+ cursor: pointer;
348
+ }
349
+ .SimpleSel__list_item:not(:last-child) {
350
+ border-bottom: 1px solid var(--simpS_color_light);
351
+ }
352
+
353
+ .SimpleSel__list_item--disabled {
354
+ opacity: .5;
355
+ cursor: default;
356
+ }
357
+
358
+ .SimpleSel__list_item_body {
359
+ padding: 5px var(--simpS_pad_hor);
360
+ display: flex;
361
+ align-items: center;
362
+ min-height: var(--simpS_li_h);
363
+ }
364
+ .SimpleSel__list_item_body:hover {
365
+ background-color: var(--simpS_color_light);
366
+ }
367
+
368
+ .SimpleSel--single .SimpleSel__list_item--checked {
369
+ background-color: var(--simpS_color_cheked);
370
+ }
371
+
372
+ .SimpleSel__list_item:not(.SimpleSel__list_item--checked) .SimpleSel__list_item_icon:before {
373
+ opacity: 0;
374
+ width: 0;
375
+ height: 0;
376
+ }
377
+
378
+ .SimpleSel__close {
379
+ display: none;
380
+ }
381
+
382
+ /* FLOAT */
383
+ .SimpleSel--body_open {
384
+ overflow: hidden;
385
+ position: relative;
386
+ }
387
+
388
+
389
+ .SimpleSel--float .SimpleSel__body {
390
+ position: fixed;
391
+ max-width: 90%;
392
+ max-height: 90%;
393
+ left: 50%;
394
+ top: 50%;
395
+ overflow: hidden;
396
+ overflow-y: auto;
397
+ transform: translate(-50%, -50%);
398
+ flex-direction: column;
399
+ display: none;
400
+ }
401
+ .SimpleSel--open {
402
+ z-index: 7;
403
+ }
404
+ .SimpleSel--float.SimpleSel--open .SimpleSel__body{
405
+ display: flex;
406
+ }
407
+
408
+ .SimpleSel--float .SimpleSel__bottom_control--hide {
409
+ display: flex;
410
+ }
411
+ .SimpleSel--float .SimpleSel__list {
412
+ flex: 1;
413
+ }
@@ -0,0 +1,26 @@
1
+ export interface IOptionItem {
2
+ id: string;
3
+ title: string;
4
+ value: string | null;
5
+ checked: boolean;
6
+ disabled: boolean;
7
+ position: number;
8
+ isShowFilter: boolean;
9
+ }
10
+ export interface IOptionItems {
11
+ idGroup: string;
12
+ isGroup: boolean;
13
+ titleGroup?: string;
14
+ isDisabledGroup?:boolean
15
+ items: IOptionItem[]
16
+ isShowFilter: boolean;
17
+ }
18
+
19
+ export interface ICreateLiReturn {
20
+ result: string;
21
+ countShow: number
22
+ countChecked: number
23
+ countCheckedFull: number
24
+ }
25
+
26
+ export type selectorType = string | HTMLSelectElement | NodeListOf<HTMLSelectElement> | HTMLSelectElement[];
@@ -0,0 +1,59 @@
1
+ import { SimpleSelectItem } from '../simpleSelectItem';
2
+
3
+ export interface ISimpleSelectLocale {
4
+ noSearch: string;
5
+ searchText: string;
6
+ title: string;
7
+ selected: string;
8
+ all: string;
9
+ ok: string;
10
+ cansel: string;
11
+
12
+ resetAll: string;
13
+ selectAll: string;
14
+ }
15
+ export interface ISimpleSelectOptions {
16
+ countShowSelected: number
17
+
18
+ isConfirmInMulti: boolean;
19
+ isConfirmInMultiOkClickOutside: boolean;
20
+
21
+ isSearch: boolean;
22
+ isSearchInDropdown: boolean;
23
+ nativeOnDevice: string[];
24
+ locale: ISimpleSelectLocale;
25
+
26
+ debounceTime?: number;
27
+
28
+ floatWidth?: number;
29
+
30
+ sepChars: string;
31
+
32
+ selectAll: boolean;
33
+ selectAllAfterClose: boolean;
34
+ resetAll: boolean;
35
+ resetAllAfterClose: boolean;
36
+ isCloneClass: boolean;
37
+
38
+ isUp: boolean;
39
+
40
+ detectNative?: () => boolean;
41
+
42
+ callbackInitialization?: (item:SimpleSelectItem) => void;
43
+ callbackInitialized?: (item:SimpleSelectItem) => void;
44
+ callbackOpen?: (item:SimpleSelectItem) => void;
45
+ callbackClose?: (item:SimpleSelectItem) => void;
46
+ callbackDestroyInit?: (item:SimpleSelectItem) => void;
47
+ callbackDestroy?: (item:SimpleSelectItem) => void;
48
+ callbackChangeSelect?: (e: Event, item:SimpleSelectItem) => void;
49
+
50
+ changeBodyLi?: (liBody:HTMLDivElement, option: HTMLOptionElement) => HTMLElement | string;
51
+ }
52
+ // export interface ISimpleSelectOptions extends Required<ISimpleSelectProps> {
53
+ // }
54
+ export interface IItemLocalOptions {
55
+ id: string;
56
+ isNative: boolean;
57
+ }
58
+
59
+ export type ISimpleSelectProps = Partial<ISimpleSelectOptions>;
@@ -0,0 +1,66 @@
1
+ import { IOptionItem, IOptionItems } from '../types/item.types';
2
+ import { initClass } from '../const/simpleSelection.const';
3
+
4
+ export const toCamelCase = (input:string):string => input.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
5
+
6
+ export const createDataAttr = (name: string):string => `data-${name}`;
7
+
8
+ export const ifTrueDataAttr = (attr: string | null): boolean => {
9
+ if (!attr) {
10
+ return false;
11
+ }
12
+ return attr === 'true' || attr === '1';
13
+ };
14
+
15
+ export function triggerInputEvent(element: HTMLElement, type = 'change') {
16
+ const event = new Event(type, {
17
+ bubbles: true,
18
+ cancelable: true,
19
+ });
20
+ element.dispatchEvent(event);
21
+ }
22
+
23
+ export const getCreateListItem = (item: HTMLSelectElement | HTMLOptGroupElement, idGroup: string, isGroup: boolean) => {
24
+ const options = item.querySelectorAll('option');
25
+ const items:IOptionItem[] = [];
26
+ options.forEach((option, ind) => {
27
+ items.push({
28
+ id: (ind + 1).toString(),
29
+ position: option.index,
30
+ title: option.innerHTML,
31
+ // value: option.value,
32
+ value: option.getAttribute('value'),
33
+ checked: option.selected,
34
+ disabled: option.disabled,
35
+ isShowFilter: true,
36
+ });
37
+ });
38
+ const newItem: IOptionItems = {
39
+ isGroup,
40
+ idGroup,
41
+ items,
42
+ isShowFilter: true,
43
+ };
44
+ if (item instanceof HTMLOptGroupElement) {
45
+ newItem.titleGroup = item.label || '';
46
+ newItem.isDisabledGroup = item.disabled || false;
47
+ }
48
+ return newItem;
49
+ };
50
+
51
+ export const getClass = (cls: string, mod = false, classInit = initClass): string => {
52
+ const sep = mod ? '--' : '__';
53
+ return `${classInit}${sep}${cls}`;
54
+ };
55
+
56
+ export const compareObj = <T1, T2>(obj1:T1, obj2:T2):boolean => JSON.stringify(obj1) === JSON.stringify(obj2);
57
+
58
+ export const cloneObj = <T>(obj:T):T => JSON.parse(JSON.stringify(obj));
59
+
60
+ export const createButton = (): HTMLButtonElement => {
61
+ const btn = document.createElement('button');
62
+ btn.type = 'button';
63
+ btn.tabIndex = -1;
64
+
65
+ return btn;
66
+ };
@@ -0,0 +1,60 @@
1
+ export function store<T>(obj:T) {
2
+ const stateData: Record<string, any> = {};
3
+ const subscribers: Record<string, any> = {}; /** подписка на конкретное свойство */
4
+ let subscribersAll: any = []; /** подписка на все свойства */
5
+
6
+ const getState = (k?:string) => {
7
+ if (!k) {
8
+ return stateData;
9
+ }
10
+ if (!(k in stateData)) {
11
+ return null;
12
+ }
13
+ return stateData[k];
14
+ };
15
+ const setState = (k:string, val:any) => {
16
+ const prevState = { ...stateData };
17
+ const prev = stateData[k] || stateData[k] == 0 ? stateData[k] : null;
18
+ stateData[k] = val;
19
+
20
+ if (k in subscribers) {
21
+ subscribers[k].forEach((cb:any) => cb(val, prev, stateData));
22
+ }
23
+ subscribersAll.forEach((cb:any) => cb(k, prevState, stateData));
24
+ };
25
+ if (obj) {
26
+ Object.keys(obj).forEach((k:string) => {
27
+ // @ts-ignore
28
+ setState(k, obj[k]);
29
+ });
30
+ }
31
+
32
+ return {
33
+ getState,
34
+ setState,
35
+
36
+ subscribe(k:string, cb: any) {
37
+ if (!(k in subscribers)) {
38
+ subscribers[k] = [];
39
+ }
40
+ subscribers[k].push(cb);
41
+ const cur = getState(k);
42
+ cb(cur, null, getState());
43
+ return () => {
44
+ subscribers[k] = subscribers[k].filter((i:any) => i !== cb);
45
+ };
46
+ },
47
+ subscribeAll(cb: any) {
48
+ subscribersAll.push(cb);
49
+ cb(null, null, getState());
50
+ return () => {
51
+ subscribersAll = subscribersAll.filter((i:any) => i !== cb);
52
+ };
53
+ },
54
+ unSubscribe(k:string, cb: any) {
55
+ if (k in subscribers) {
56
+ subscribers[k] = subscribers[k].filter((i: any) => i !== cb);
57
+ }
58
+ },
59
+ };
60
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "CommonJS",
5
+ "lib": ["ESNext", "dom"],
6
+ "declaration": true,
7
+ "outDir": "dist",
8
+ "strict": true,
9
+ "esModuleInterop": true
10
+ },
11
+ "exclude": [
12
+ "node_modules",
13
+ "dist",
14
+ "test"
15
+ ]
16
+ }
@@ -0,0 +1,77 @@
1
+ const path = require('path');
2
+ const HtmlWebpackPlugin = require('html-webpack-plugin')
3
+
4
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5
+ const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
6
+
7
+ module.exports = ({ development }) => ({
8
+ entry: './src/simpleSelect.ts',
9
+ devtool: development ? 'inline-source-map' : false,
10
+ mode: development ? 'development' : 'production',
11
+ output: {
12
+ filename: 'simpleSelect.js',
13
+ path: path.resolve(__dirname, 'dist'),
14
+ library: 'SimpleSelect',
15
+ libraryExport: 'default',
16
+ libraryTarget: 'umd',
17
+ umdNamedDefine: true,
18
+ globalObject: 'typeof self === \'undefined\' ? this : self',
19
+ },
20
+ resolve: {
21
+ extensions: ['.ts', '.css']
22
+ },
23
+ plugins: [
24
+
25
+ new MiniCssExtractPlugin({
26
+ filename: 'style.css',
27
+ }),
28
+ new HtmlWebpackPlugin({
29
+ template: 'src/demo/index.html',
30
+ filename: './demo/index.html',
31
+ scriptLoading: "blocking",
32
+ inject: 'head',
33
+ }),
34
+ new MiniCssExtractPlugin(),
35
+ ],
36
+
37
+ module: {
38
+ rules: [
39
+ {
40
+ test: /\.ts$/,
41
+ exclude: /node_modules/,
42
+ use: ['babel-loader', 'ts-loader'],
43
+ },
44
+ {
45
+ test: /\.css$/,
46
+ use: [
47
+ MiniCssExtractPlugin.loader,
48
+ 'css-loader',
49
+ {
50
+ loader: "postcss-loader",
51
+ options: {
52
+ postcssOptions: {
53
+ plugins: [
54
+ [
55
+ "postcss-preset-env",
56
+ {
57
+ // Options
58
+ },
59
+ ],
60
+ ],
61
+ },
62
+ },
63
+ },
64
+ ],
65
+ }
66
+ ],
67
+ },
68
+
69
+ optimization: {
70
+ minimize: !development,
71
+ minimizer: !development ? [new CssMinimizerPlugin()] : [],
72
+ },
73
+ });
74
+
75
+ /*
76
+
77
+ */