aport-tools 4.2.0 → 4.2.2
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/forms/InputList.d.ts +84 -0
- package/dist/forms/index.d.ts +1 -0
- package/dist/index.esm.js +225 -19
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +223 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! aport-tools v4.2.
|
1
|
+
/*! aport-tools v4.2.2 | ISC */
|
2
2
|
'use strict';
|
3
3
|
|
4
4
|
var React = require('react');
|
@@ -83,6 +83,16 @@ function __generator(thisArg, body) {
|
|
83
83
|
}
|
84
84
|
}
|
85
85
|
|
86
|
+
function __spreadArray(to, from, pack) {
|
87
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
88
|
+
if (ar || !(i in from)) {
|
89
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
90
|
+
ar[i] = from[i];
|
91
|
+
}
|
92
|
+
}
|
93
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
94
|
+
}
|
95
|
+
|
86
96
|
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
87
97
|
var e = new Error(message);
|
88
98
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
@@ -222,23 +232,23 @@ var ErrorList = function ErrorList(_a) {
|
|
222
232
|
var theme = React.useContext(aportThemes.ThemeContext).theme;
|
223
233
|
var colors = theme.colors;
|
224
234
|
return /*#__PURE__*/React.createElement(reactNative.View, {
|
225
|
-
style: styles$
|
235
|
+
style: styles$6.container
|
226
236
|
}, errors.map(function (error, index) {
|
227
237
|
return /*#__PURE__*/React.createElement(reactNative.View, {
|
228
238
|
key: index,
|
229
|
-
style: styles$
|
239
|
+
style: styles$6.errorItem
|
230
240
|
}, /*#__PURE__*/React.createElement(Text, {
|
231
|
-
style: [styles$
|
241
|
+
style: [styles$6.bullet, {
|
232
242
|
color: colors.error.hex
|
233
243
|
}]
|
234
244
|
}, "\u2022"), /*#__PURE__*/React.createElement(Text, {
|
235
|
-
style: [styles$
|
245
|
+
style: [styles$6.errorText, {
|
236
246
|
color: colors.error.hex
|
237
247
|
}]
|
238
248
|
}, error));
|
239
249
|
}));
|
240
250
|
};
|
241
|
-
var styles$
|
251
|
+
var styles$6 = reactNative.StyleSheet.create({
|
242
252
|
container: {
|
243
253
|
marginTop: 4
|
244
254
|
},
|
@@ -316,13 +326,13 @@ var Input = function Input(_a) {
|
|
316
326
|
setFormValue(name, formattedText);
|
317
327
|
};
|
318
328
|
return /*#__PURE__*/React.createElement(reactNative.View, {
|
319
|
-
style: styles$
|
329
|
+
style: styles$5.container
|
320
330
|
}, /*#__PURE__*/React.createElement(Text, {
|
321
|
-
style: [styles$
|
331
|
+
style: [styles$5.label, {
|
322
332
|
color: colors.text.hex
|
323
333
|
}]
|
324
334
|
}, label), /*#__PURE__*/React.createElement(reactNative.TextInput, __assign({
|
325
|
-
style: [styles$
|
335
|
+
style: [styles$5.input, {
|
326
336
|
backgroundColor: colors.body.hex,
|
327
337
|
borderColor: formErrors[name] ? colors.error.hex : "#CCC",
|
328
338
|
color: colors.text.hex
|
@@ -335,7 +345,7 @@ var Input = function Input(_a) {
|
|
335
345
|
errors: formErrors[name]
|
336
346
|
})));
|
337
347
|
};
|
338
|
-
var styles$
|
348
|
+
var styles$5 = reactNative.StyleSheet.create({
|
339
349
|
container: {
|
340
350
|
marginBottom: 16
|
341
351
|
},
|
@@ -366,11 +376,11 @@ var TextArea = function TextArea(_a) {
|
|
366
376
|
setFormValue(name, text);
|
367
377
|
};
|
368
378
|
return /*#__PURE__*/React.createElement(reactNative.View, {
|
369
|
-
style: styles$
|
379
|
+
style: styles$4.container
|
370
380
|
}, /*#__PURE__*/React.createElement(Text, {
|
371
|
-
style: styles$
|
381
|
+
style: styles$4.label
|
372
382
|
}, label), /*#__PURE__*/React.createElement(reactNative.TextInput, __assign({
|
373
|
-
style: [styles$
|
383
|
+
style: [styles$4.textArea, style],
|
374
384
|
value: formValues[name] || '',
|
375
385
|
onChangeText: handleChange,
|
376
386
|
placeholder: label,
|
@@ -383,7 +393,7 @@ var TextArea = function TextArea(_a) {
|
|
383
393
|
errors: formErrors[name]
|
384
394
|
})));
|
385
395
|
};
|
386
|
-
var styles$
|
396
|
+
var styles$4 = reactNative.StyleSheet.create({
|
387
397
|
container: {
|
388
398
|
marginBottom: 16
|
389
399
|
},
|
@@ -412,18 +422,214 @@ var Label = function Label(_a) {
|
|
412
422
|
var theme = React.useContext(aportThemes.ThemeContext).theme;
|
413
423
|
var colors = theme.colors;
|
414
424
|
return /*#__PURE__*/React.createElement(Text, {
|
415
|
-
style: [styles$
|
425
|
+
style: [styles$3.label, style, {
|
416
426
|
color: colors.text.hex
|
417
427
|
}]
|
418
428
|
}, text);
|
419
429
|
};
|
420
|
-
var styles$
|
430
|
+
var styles$3 = reactNative.StyleSheet.create({
|
421
431
|
label: {
|
422
432
|
marginBottom: 4,
|
423
433
|
fontWeight: '500'
|
424
434
|
}
|
425
435
|
});
|
426
436
|
|
437
|
+
/**
|
438
|
+
* InputList component - A custom dropdown list component for React Native with multi-selection support,
|
439
|
+
* customizable styling, sorting, and configurable close behavior on selection or scrolling.
|
440
|
+
*
|
441
|
+
* @param {string} placeholder - Placeholder text for the input.
|
442
|
+
* @param {object} style - Custom styles for the component.
|
443
|
+
* @param {Option[]} options - Array of options to display in the dropdown.
|
444
|
+
* @param {boolean} multi - Enables multi-selection mode.
|
445
|
+
* @param {boolean} disabled - Disables the dropdown input.
|
446
|
+
* @param {keyof Option} sortBy - Key to sort options by (e.g., 'id').
|
447
|
+
* @param {boolean} separator - If true, adds a separator line between options.
|
448
|
+
* @param {boolean} closeOnScroll - Closes the dropdown if the user scrolls the list.
|
449
|
+
* @param {boolean} closeOnSelect - Closes the dropdown on selection in single-select mode.
|
450
|
+
* @param {number} maxSelection - Maximum number of items selectable in multi-select mode.
|
451
|
+
*/
|
452
|
+
var InputList = function InputList(_a) {
|
453
|
+
var name = _a.name,
|
454
|
+
_b = _a.placeholder,
|
455
|
+
placeholder = _b === void 0 ? "Choose value/s" : _b,
|
456
|
+
style = _a.style,
|
457
|
+
options = _a.options,
|
458
|
+
_c = _a.multi,
|
459
|
+
multi = _c === void 0 ? false : _c,
|
460
|
+
_d = _a.disabled,
|
461
|
+
disabled = _d === void 0 ? false : _d,
|
462
|
+
sortBy = _a.sortBy,
|
463
|
+
_e = _a.separator,
|
464
|
+
separator = _e === void 0 ? false : _e,
|
465
|
+
_f = _a.closeOnScroll,
|
466
|
+
closeOnScroll = _f === void 0 ? false : _f,
|
467
|
+
_g = _a.closeOnSelect,
|
468
|
+
closeOnSelect = _g === void 0 ? true : _g,
|
469
|
+
maxSelection = _a.maxSelection;
|
470
|
+
var _h = useFormContext(),
|
471
|
+
formValues = _h.formValues,
|
472
|
+
setFormValue = _h.setFormValue;
|
473
|
+
var _j = React.useState(false),
|
474
|
+
isDropdownVisible = _j[0],
|
475
|
+
setIsDropdownVisible = _j[1];
|
476
|
+
var selectedOptions = formValues[name] || (multi ? [] : null);
|
477
|
+
var sortedOptions = sortBy ? __spreadArray([], options, true).sort(function (a, b) {
|
478
|
+
return a[sortBy] > b[sortBy] ? 1 : -1;
|
479
|
+
}) : options;
|
480
|
+
var theme = React.useContext(aportThemes.ThemeContext).theme;
|
481
|
+
var colors = theme.colors;
|
482
|
+
/**
|
483
|
+
* Handles selection of an option. Adds or removes the option from selectedOptions based on
|
484
|
+
* multi-selection and maxSelection criteria.
|
485
|
+
* @param {Option} option - The selected option object.
|
486
|
+
*/
|
487
|
+
var handleSelectOption = function handleSelectOption(option) {
|
488
|
+
if (multi) {
|
489
|
+
var alreadySelected = selectedOptions.some(function (opt) {
|
490
|
+
return opt.id === option.id;
|
491
|
+
});
|
492
|
+
// Add or remove item from selected options
|
493
|
+
var updatedSelections = alreadySelected ? selectedOptions.filter(function (opt) {
|
494
|
+
return opt.id !== option.id;
|
495
|
+
}) : __spreadArray(__spreadArray([], selectedOptions, true), [option], false);
|
496
|
+
// Close dropdown if max selection is reached after selecting
|
497
|
+
if (!alreadySelected && maxSelection && updatedSelections.length >= maxSelection) {
|
498
|
+
setIsDropdownVisible(false);
|
499
|
+
}
|
500
|
+
// Update form value
|
501
|
+
setFormValue(name, updatedSelections);
|
502
|
+
} else {
|
503
|
+
setFormValue(name, option);
|
504
|
+
if (closeOnSelect) setIsDropdownVisible(false);
|
505
|
+
}
|
506
|
+
};
|
507
|
+
/**
|
508
|
+
* Renders selected options as a comma-separated string or the placeholder if none selected.
|
509
|
+
* @returns {string} - The display text for selected options or placeholder.
|
510
|
+
*/
|
511
|
+
var renderSelectedText = function renderSelectedText() {
|
512
|
+
if (multi) return selectedOptions.map(function (opt) {
|
513
|
+
return opt.label;
|
514
|
+
}).join(', ') || placeholder;
|
515
|
+
return (selectedOptions === null || selectedOptions === void 0 ? void 0 : selectedOptions.label) || placeholder;
|
516
|
+
};
|
517
|
+
/**
|
518
|
+
* Toggles dropdown visibility. Disables toggle if the component is disabled.
|
519
|
+
*/
|
520
|
+
var toggleDropdown = function toggleDropdown() {
|
521
|
+
if (!disabled) {
|
522
|
+
setIsDropdownVisible(!isDropdownVisible);
|
523
|
+
if (!isDropdownVisible) reactNative.Keyboard.dismiss();
|
524
|
+
}
|
525
|
+
};
|
526
|
+
/**
|
527
|
+
* Closes the dropdown when pressing outside.
|
528
|
+
*/
|
529
|
+
var handleCloseDropdown = React.useCallback(function () {
|
530
|
+
if (isDropdownVisible) setIsDropdownVisible(false);
|
531
|
+
}, [isDropdownVisible]);
|
532
|
+
// Conditionally render item as disabled if max selection reached and item is unselected
|
533
|
+
var isItemDisabled = function isItemDisabled(option) {
|
534
|
+
return multi && maxSelection && selectedOptions.length >= maxSelection && !selectedOptions.some(function (opt) {
|
535
|
+
return opt.id === option.id;
|
536
|
+
});
|
537
|
+
};
|
538
|
+
return /*#__PURE__*/React.createElement(reactNative.View, {
|
539
|
+
style: [styles$2.container, style]
|
540
|
+
}, /*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
|
541
|
+
style: styles$2.inputContainer,
|
542
|
+
onPress: toggleDropdown,
|
543
|
+
disabled: disabled
|
544
|
+
}, /*#__PURE__*/React.createElement(reactNative.Text, {
|
545
|
+
style: {
|
546
|
+
color: colors.text.hex
|
547
|
+
}
|
548
|
+
}, renderSelectedText())), /*#__PURE__*/React.createElement(reactNative.Modal, {
|
549
|
+
visible: isDropdownVisible,
|
550
|
+
transparent: true,
|
551
|
+
animationType: "fade"
|
552
|
+
}, /*#__PURE__*/React.createElement(reactNative.Pressable, {
|
553
|
+
style: styles$2.overlay,
|
554
|
+
onPress: handleCloseDropdown
|
555
|
+
}), /*#__PURE__*/React.createElement(reactNative.View, {
|
556
|
+
style: [styles$2.dropdownContainer, {
|
557
|
+
backgroundColor: colors.body.hex
|
558
|
+
}]
|
559
|
+
}, /*#__PURE__*/React.createElement(reactNative.FlatList, {
|
560
|
+
data: sortedOptions,
|
561
|
+
keyExtractor: function keyExtractor(item) {
|
562
|
+
return item.id.toString();
|
563
|
+
},
|
564
|
+
renderItem: function renderItem(_a) {
|
565
|
+
var item = _a.item;
|
566
|
+
var isSelected = selectedOptions.some(function (opt) {
|
567
|
+
return opt.id === item.id;
|
568
|
+
});
|
569
|
+
var isDisabled = isItemDisabled(item);
|
570
|
+
return /*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
|
571
|
+
onPress: function onPress() {
|
572
|
+
return handleSelectOption(item);
|
573
|
+
},
|
574
|
+
style: [styles$2.optionItem, isSelected ? {
|
575
|
+
backgroundColor: colors.primary.hex
|
576
|
+
} : {}, isDisabled ? styles$2.disabledItem : {}],
|
577
|
+
disabled: !!isDisabled
|
578
|
+
}, /*#__PURE__*/React.createElement(reactNative.Text, {
|
579
|
+
style: [{
|
580
|
+
color: colors.primary.hex
|
581
|
+
}, isDisabled ? styles$2.disabledText : {}]
|
582
|
+
}, item.label));
|
583
|
+
},
|
584
|
+
ItemSeparatorComponent: function ItemSeparatorComponent() {
|
585
|
+
return separator ? /*#__PURE__*/React.createElement(reactNative.View, {
|
586
|
+
style: styles$2.separator
|
587
|
+
}) : null;
|
588
|
+
},
|
589
|
+
scrollEnabled: !closeOnScroll
|
590
|
+
}))));
|
591
|
+
};
|
592
|
+
var styles$2 = reactNative.StyleSheet.create({
|
593
|
+
container: {
|
594
|
+
padding: 8
|
595
|
+
},
|
596
|
+
inputContainer: {
|
597
|
+
padding: 12,
|
598
|
+
borderWidth: 1,
|
599
|
+
borderColor: '#ccc',
|
600
|
+
borderRadius: 5
|
601
|
+
},
|
602
|
+
dropdownContainer: {
|
603
|
+
position: 'absolute',
|
604
|
+
top: '30%',
|
605
|
+
// Center the dropdown vertically
|
606
|
+
alignSelf: 'center',
|
607
|
+
width: '90%',
|
608
|
+
backgroundColor: '#fff',
|
609
|
+
borderRadius: 8,
|
610
|
+
elevation: 5,
|
611
|
+
paddingVertical: 10
|
612
|
+
},
|
613
|
+
optionItem: {
|
614
|
+
padding: 12
|
615
|
+
},
|
616
|
+
disabledItem: {
|
617
|
+
backgroundColor: '#f0f0f0'
|
618
|
+
},
|
619
|
+
disabledText: {
|
620
|
+
color: '#999'
|
621
|
+
},
|
622
|
+
separator: {
|
623
|
+
height: 1,
|
624
|
+
backgroundColor: '#ddd',
|
625
|
+
marginHorizontal: 8
|
626
|
+
},
|
627
|
+
overlay: {
|
628
|
+
flex: 1,
|
629
|
+
backgroundColor: 'rgba(0,0,0,0.3)'
|
630
|
+
}
|
631
|
+
});
|
632
|
+
|
427
633
|
// src/components/Button.tsx
|
428
634
|
/**
|
429
635
|
* Determines the styles based on the button type and whether it is disabled.
|
@@ -607,6 +813,7 @@ exports.Card = Card;
|
|
607
813
|
exports.ErrorList = ErrorList;
|
608
814
|
exports.Form = Form;
|
609
815
|
exports.Input = Input;
|
816
|
+
exports.InputList = InputList;
|
610
817
|
exports.Label = Label;
|
611
818
|
exports.Text = Text;
|
612
819
|
exports.TextArea = TextArea;
|