aport-tools 4.2.0 → 4.2.2
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/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;
|