aport-tools 4.2.0 → 4.2.1

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/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! aport-tools v4.2.0 | ISC */
1
+ /*! aport-tools v4.2.1 | 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$5.container
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$5.errorItem
239
+ style: styles$6.errorItem
230
240
  }, /*#__PURE__*/React.createElement(Text, {
231
- style: [styles$5.bullet, {
241
+ style: [styles$6.bullet, {
232
242
  color: colors.error.hex
233
243
  }]
234
244
  }, "\u2022"), /*#__PURE__*/React.createElement(Text, {
235
- style: [styles$5.errorText, {
245
+ style: [styles$6.errorText, {
236
246
  color: colors.error.hex
237
247
  }]
238
248
  }, error));
239
249
  }));
240
250
  };
241
- var styles$5 = reactNative.StyleSheet.create({
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$4.container
329
+ style: styles$5.container
320
330
  }, /*#__PURE__*/React.createElement(Text, {
321
- style: [styles$4.label, {
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$4.input, {
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$4 = reactNative.StyleSheet.create({
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$3.container
379
+ style: styles$4.container
370
380
  }, /*#__PURE__*/React.createElement(Text, {
371
- style: styles$3.label
381
+ style: styles$4.label
372
382
  }, label), /*#__PURE__*/React.createElement(reactNative.TextInput, __assign({
373
- style: [styles$3.textArea, style],
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$3 = reactNative.StyleSheet.create({
396
+ var styles$4 = reactNative.StyleSheet.create({
387
397
  container: {
388
398
  marginBottom: 16
389
399
  },
@@ -412,18 +422,191 @@ 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$2.label, style, {
425
+ style: [styles$3.label, style, {
416
426
  color: colors.text.hex
417
427
  }]
418
428
  }, text);
419
429
  };
420
- var styles$2 = reactNative.StyleSheet.create({
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
+ var updatedSelections = alreadySelected ? selectedOptions.filter(function (opt) {
493
+ return opt.id !== option.id;
494
+ }) : __spreadArray(__spreadArray([], selectedOptions, true), [option], false);
495
+ // Close dropdown if max selection reached
496
+ if (!alreadySelected && maxSelection && updatedSelections.length >= maxSelection) {
497
+ setIsDropdownVisible(false);
498
+ }
499
+ // Update form value with selected items
500
+ setFormValue(name, updatedSelections);
501
+ } else {
502
+ setFormValue(name, option);
503
+ if (closeOnSelect) setIsDropdownVisible(false);
504
+ }
505
+ };
506
+ /**
507
+ * Renders selected options as a comma-separated string or the placeholder if none selected.
508
+ * @returns {string} - The display text for selected options or placeholder.
509
+ */
510
+ var renderSelectedText = function renderSelectedText() {
511
+ if (multi) return selectedOptions.map(function (opt) {
512
+ return opt.label;
513
+ }).join(', ') || placeholder;
514
+ return (selectedOptions === null || selectedOptions === void 0 ? void 0 : selectedOptions.label) || placeholder;
515
+ };
516
+ /**
517
+ * Toggles dropdown visibility. Disables toggle if the component is disabled.
518
+ */
519
+ var toggleDropdown = function toggleDropdown() {
520
+ if (!disabled) {
521
+ setIsDropdownVisible(!isDropdownVisible);
522
+ if (!isDropdownVisible) reactNative.Keyboard.dismiss();
523
+ }
524
+ };
525
+ /**
526
+ * Closes the dropdown when pressing outside.
527
+ */
528
+ var handleCloseDropdown = React.useCallback(function () {
529
+ if (isDropdownVisible) setIsDropdownVisible(false);
530
+ }, [isDropdownVisible]);
531
+ return /*#__PURE__*/React.createElement(reactNative.View, {
532
+ style: [styles$2.container, style]
533
+ }, /*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
534
+ style: styles$2.inputContainer,
535
+ onPress: toggleDropdown,
536
+ disabled: disabled
537
+ }, /*#__PURE__*/React.createElement(reactNative.Text, {
538
+ style: {
539
+ color: colors.text.hex
540
+ }
541
+ }, renderSelectedText())), /*#__PURE__*/React.createElement(reactNative.Modal, {
542
+ visible: isDropdownVisible,
543
+ transparent: true,
544
+ animationType: "fade"
545
+ }, /*#__PURE__*/React.createElement(reactNative.Pressable, {
546
+ style: styles$2.overlay,
547
+ onPress: handleCloseDropdown
548
+ }), /*#__PURE__*/React.createElement(reactNative.View, {
549
+ style: [styles$2.dropdownContainer, {
550
+ backgroundColor: colors.body.hex
551
+ }]
552
+ }, /*#__PURE__*/React.createElement(reactNative.FlatList, {
553
+ data: sortedOptions,
554
+ keyExtractor: function keyExtractor(item) {
555
+ return item.id.toString();
556
+ },
557
+ renderItem: function renderItem(_a) {
558
+ var item = _a.item;
559
+ return /*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
560
+ onPress: function onPress() {
561
+ return handleSelectOption(item);
562
+ },
563
+ style: styles$2.optionItem
564
+ }, /*#__PURE__*/React.createElement(reactNative.Text, {
565
+ style: {
566
+ color: colors.text.hex
567
+ }
568
+ }, item.label));
569
+ },
570
+ ItemSeparatorComponent: function ItemSeparatorComponent() {
571
+ return separator ? /*#__PURE__*/React.createElement(reactNative.View, {
572
+ style: styles$2.separator
573
+ }) : null;
574
+ },
575
+ scrollEnabled: !closeOnScroll
576
+ }))));
577
+ };
578
+ var styles$2 = reactNative.StyleSheet.create({
579
+ container: {
580
+ padding: 8
581
+ },
582
+ inputContainer: {
583
+ padding: 12,
584
+ borderWidth: 1,
585
+ borderColor: '#ccc',
586
+ borderRadius: 5
587
+ },
588
+ dropdownContainer: {
589
+ position: 'absolute',
590
+ top: 60,
591
+ width: '90%',
592
+ borderRadius: 8,
593
+ elevation: 5,
594
+ alignSelf: 'center'
595
+ },
596
+ optionItem: {
597
+ padding: 12
598
+ },
599
+ separator: {
600
+ height: 1,
601
+ backgroundColor: '#ddd',
602
+ marginHorizontal: 8
603
+ },
604
+ overlay: {
605
+ flex: 1,
606
+ backgroundColor: 'rgba(0,0,0,0.3)'
607
+ }
608
+ });
609
+
427
610
  // src/components/Button.tsx
428
611
  /**
429
612
  * Determines the styles based on the button type and whether it is disabled.
@@ -607,6 +790,7 @@ exports.Card = Card;
607
790
  exports.ErrorList = ErrorList;
608
791
  exports.Form = Form;
609
792
  exports.Input = Input;
793
+ exports.InputList = InputList;
610
794
  exports.Label = Label;
611
795
  exports.Text = Text;
612
796
  exports.TextArea = TextArea;