@retray-dev/ui-kit 10.1.0 → 10.2.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.
Files changed (112) hide show
  1. package/COMPONENTS.md +136 -5
  2. package/README.md +4 -4
  3. package/dist/Accordion.js +1 -1
  4. package/dist/Accordion.mjs +2 -2
  5. package/dist/AlertBanner.js +1 -1
  6. package/dist/AlertBanner.mjs +2 -2
  7. package/dist/AppHeader.js +1 -1
  8. package/dist/AppHeader.mjs +3 -3
  9. package/dist/Badge.js +1 -1
  10. package/dist/Badge.mjs +2 -2
  11. package/dist/Button.js +1 -1
  12. package/dist/Button.mjs +2 -2
  13. package/dist/CategoryStrip.js +1 -1
  14. package/dist/CategoryStrip.mjs +2 -2
  15. package/dist/Chip.js +1 -1
  16. package/dist/Chip.mjs +2 -2
  17. package/dist/ConfirmDialog.js +1 -1
  18. package/dist/ConfirmDialog.mjs +3 -3
  19. package/dist/CurrencyInput.js +1 -1
  20. package/dist/CurrencyInput.mjs +3 -3
  21. package/dist/DetailRow.d.mts +1 -1
  22. package/dist/DetailRow.d.ts +1 -1
  23. package/dist/DetailRow.js +1 -1
  24. package/dist/DetailRow.mjs +2 -2
  25. package/dist/EmptyState.js +1 -1
  26. package/dist/EmptyState.mjs +3 -3
  27. package/dist/ErrorBoundary.js +1 -1
  28. package/dist/ErrorBoundary.mjs +2 -2
  29. package/dist/IconButton.js +1 -1
  30. package/dist/IconButton.mjs +2 -2
  31. package/dist/IconPicker.d.mts +17 -0
  32. package/dist/IconPicker.d.ts +17 -0
  33. package/dist/IconPicker.js +997 -0
  34. package/dist/IconPicker.mjs +7 -0
  35. package/dist/ImageUpload.d.mts +3 -1
  36. package/dist/ImageUpload.d.ts +3 -1
  37. package/dist/ImageUpload.js +28 -10
  38. package/dist/ImageUpload.mjs +1 -1
  39. package/dist/ImageViewer.js +1 -1
  40. package/dist/ImageViewer.mjs +4 -4
  41. package/dist/Input.js +1 -1
  42. package/dist/Input.mjs +2 -2
  43. package/dist/LabelValue.js +1 -1
  44. package/dist/LabelValue.mjs +2 -2
  45. package/dist/ListItem.js +1 -1
  46. package/dist/ListItem.mjs +2 -2
  47. package/dist/MediaCard.js +1 -1
  48. package/dist/MediaCard.mjs +2 -2
  49. package/dist/MenuItem.js +1 -1
  50. package/dist/MenuItem.mjs +2 -2
  51. package/dist/NumberStepper.d.mts +19 -0
  52. package/dist/NumberStepper.d.ts +19 -0
  53. package/dist/NumberStepper.js +410 -0
  54. package/dist/NumberStepper.mjs +9 -0
  55. package/dist/PagerDots.js +1 -1
  56. package/dist/PagerDots.mjs +2 -2
  57. package/dist/PricingCard.js +1 -1
  58. package/dist/PricingCard.mjs +4 -4
  59. package/dist/SelectableGrid.js +1 -1
  60. package/dist/SelectableGrid.mjs +2 -2
  61. package/dist/SheetSelect.js +1 -1
  62. package/dist/SheetSelect.mjs +2 -2
  63. package/dist/TabBar.js +1 -1
  64. package/dist/TabBar.mjs +2 -2
  65. package/dist/Textarea.js +1 -1
  66. package/dist/Textarea.mjs +2 -2
  67. package/dist/Toggle.js +1 -1
  68. package/dist/Toggle.mjs +2 -2
  69. package/dist/chunk-53Z3NYGE.mjs +742 -0
  70. package/dist/{chunk-VQ57HWPL.mjs → chunk-6L4G6PBT.mjs} +1 -1
  71. package/dist/{chunk-6OAZJ577.mjs → chunk-6SECQ2ZF.mjs} +2 -2
  72. package/dist/{chunk-KIHCWCWL.mjs → chunk-7LWRKMF5.mjs} +1 -1
  73. package/dist/{chunk-4I7D47FH.mjs → chunk-AJRVDP2H.mjs} +3 -3
  74. package/dist/{chunk-6MKGPAR2.mjs → chunk-BEMIQXXU.mjs} +1 -1
  75. package/dist/chunk-BUMAMSTZ.mjs +126 -0
  76. package/dist/{chunk-UREA2GYY.mjs → chunk-DYT7BG5I.mjs} +1 -1
  77. package/dist/{chunk-WOEYDUJZ.mjs → chunk-ELXBDILQ.mjs} +2 -2
  78. package/dist/{chunk-A4MDAP7G.mjs → chunk-FCSSQK3L.mjs} +1 -1
  79. package/dist/{chunk-2TFTAWVJ.mjs → chunk-HTHGSXFG.mjs} +1 -1
  80. package/dist/{chunk-VGTDN7SW.mjs → chunk-IX3NYLYQ.mjs} +1 -1
  81. package/dist/{chunk-T7XZ7H7Y.mjs → chunk-KA7LTET3.mjs} +17 -3
  82. package/dist/{chunk-URI2WBIV.mjs → chunk-KOO4WITD.mjs} +1 -1
  83. package/dist/{chunk-JUXSWN54.mjs → chunk-NMU5FMQJ.mjs} +1 -1
  84. package/dist/{chunk-LXJIIOYQ.mjs → chunk-RYZC432S.mjs} +1 -1
  85. package/dist/{chunk-JB67UOB5.mjs → chunk-S2R7UVOE.mjs} +1 -1
  86. package/dist/{chunk-ZUR7AU5R.mjs → chunk-SXLKNTA4.mjs} +1 -1
  87. package/dist/{chunk-3U4SSNWP.mjs → chunk-T2KCAHOS.mjs} +1 -1
  88. package/dist/{chunk-ZJKGQMYH.mjs → chunk-TB6SD2FT.mjs} +1 -1
  89. package/dist/{chunk-AZJF2BLK.mjs → chunk-TBNZHU6C.mjs} +1 -1
  90. package/dist/{chunk-Y4GL2MHX.mjs → chunk-TZDGAP5N.mjs} +28 -10
  91. package/dist/{chunk-CZCQZHG6.mjs → chunk-U2XJFYED.mjs} +1 -1
  92. package/dist/{chunk-TERDKCLE.mjs → chunk-VF2ATYN3.mjs} +1 -1
  93. package/dist/{chunk-OHBNABL5.mjs → chunk-VKID2D2I.mjs} +1 -1
  94. package/dist/{chunk-KZL5VTYK.mjs → chunk-WYEUNUTP.mjs} +1 -1
  95. package/dist/{chunk-DJ7RN37L.mjs → chunk-YJ7I257J.mjs} +1 -1
  96. package/dist/{chunk-NA7PARID.mjs → chunk-Z4VHZ7B5.mjs} +1 -1
  97. package/dist/{chunk-MLF3EZFW.mjs → chunk-Z6SFHN6T.mjs} +1 -1
  98. package/dist/{chunk-4K625MVM.mjs → chunk-ZZ2R6KZ3.mjs} +1 -1
  99. package/dist/index.d.mts +4 -1
  100. package/dist/index.d.ts +4 -1
  101. package/dist/index.js +892 -12
  102. package/dist/index.mjs +33 -31
  103. package/package.json +1 -1
  104. package/src/components/DetailRow/DetailRow.tsx +1 -1
  105. package/src/components/IconPicker/IconPicker.tsx +383 -0
  106. package/src/components/IconPicker/index.ts +1 -0
  107. package/src/components/ImageUpload/ImageUpload.tsx +34 -12
  108. package/src/components/NumberStepper/NumberStepper.tsx +147 -0
  109. package/src/components/NumberStepper/index.ts +1 -0
  110. package/src/index.ts +3 -1
  111. package/src/utils/curatedIcons.ts +286 -0
  112. package/src/utils/icons.ts +20 -2
package/dist/index.js CHANGED
@@ -369,9 +369,9 @@ function configureIconFamilies(families) {
369
369
  activeFamilies = order.length > 0 ? order : ALL_FAMILIES;
370
370
  resolvedCache = null;
371
371
  }
372
- function buildCache() {
372
+ function buildCache(families) {
373
373
  const cache = /* @__PURE__ */ new Map();
374
- for (const family of activeFamilies) {
374
+ for (const family of families ?? activeFamilies) {
375
375
  const glyphMap = family.getGlyphMap();
376
376
  for (const iconName of Object.keys(glyphMap)) {
377
377
  cache.set(iconName, family);
@@ -385,6 +385,20 @@ function resolveFamily(name) {
385
385
  }
386
386
  return resolvedCache.get(name) ?? null;
387
387
  }
388
+ var cachedIconNames = null;
389
+ function getValidIconNames(families) {
390
+ if (families && families.length > 0) {
391
+ const tempFamilies = families.map((n) => ALL_FAMILIES.find((f) => f.name === n)).filter((f) => f !== void 0);
392
+ if (tempFamilies.length === 0) return [];
393
+ const cache = buildCache(tempFamilies);
394
+ return Array.from(cache.keys());
395
+ }
396
+ if (!cachedIconNames) {
397
+ const cache = buildCache();
398
+ cachedIconNames = Array.from(cache.keys());
399
+ }
400
+ return cachedIconNames;
401
+ }
388
402
  function Icon({ name, size, color, family }) {
389
403
  let resolved = null;
390
404
  if (family) {
@@ -5693,6 +5707,7 @@ function ImageUpload({
5693
5707
  onChange,
5694
5708
  loading = false,
5695
5709
  placeholder = "Tap to add image",
5710
+ showPlaceholderText = true,
5696
5711
  width,
5697
5712
  height = 200,
5698
5713
  borderRadius = RADIUS.lg,
@@ -5705,23 +5720,31 @@ function ImageUpload({
5705
5720
  const handlePress = async () => {
5706
5721
  if (disabled || loading) return;
5707
5722
  impactLight();
5708
- let ImagePicker;
5723
+ let picker;
5709
5724
  try {
5710
- ImagePicker = await import('expo-image-picker');
5725
+ const mod = await import('expo-image-picker/build/ExponentImagePicker');
5726
+ picker = mod.default;
5711
5727
  } catch {
5712
- if (__DEV__) console.warn("[ImageUpload] expo-image-picker not installed. Add it as a dependency.");
5713
- return;
5728
+ try {
5729
+ picker = await import('expo-image-picker');
5730
+ } catch {
5731
+ if (__DEV__) console.warn("[ImageUpload] expo-image-picker not installed.");
5732
+ return;
5733
+ }
5714
5734
  }
5715
5735
  if (reactNative.Platform.OS !== "web") {
5716
- const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
5717
- if (status !== "granted") return;
5736
+ try {
5737
+ const { status } = await picker.requestMediaLibraryPermissionsAsync();
5738
+ if (status !== "granted") return;
5739
+ } catch {
5740
+ }
5718
5741
  }
5719
- const result = await ImagePicker.launchImageLibraryAsync({
5742
+ const result = await picker.launchImageLibraryAsync({
5720
5743
  mediaTypes: ["images"],
5721
5744
  allowsEditing: true,
5722
5745
  quality: 0.8
5723
5746
  });
5724
- if (!result.canceled && result.assets[0]) {
5747
+ if (!result.canceled && result.assets?.[0]) {
5725
5748
  onChange?.(result.assets[0].uri);
5726
5749
  }
5727
5750
  };
@@ -5754,7 +5777,15 @@ function ImageUpload({
5754
5777
  style: [reactNative.StyleSheet.absoluteFillObject, { borderRadius }],
5755
5778
  resizeMode
5756
5779
  }
5757
- ) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles46.placeholder }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "image", size: ms(28), color: colors.foregroundMuted }), /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles46.placeholderText, { color: colors.foregroundMuted }], allowFontScaling: true }, placeholder)),
5780
+ ) : /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles46.placeholder }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "image", size: ms(28), color: colors.foregroundMuted }), showPlaceholderText ? /* @__PURE__ */ React25__default.default.createElement(
5781
+ reactNative.Text,
5782
+ {
5783
+ style: [styles46.placeholderText, { color: colors.foregroundMuted }],
5784
+ numberOfLines: 1,
5785
+ allowFontScaling: true
5786
+ },
5787
+ placeholder
5788
+ ) : null),
5758
5789
  loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles46.loadingOverlay, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React25__default.default.createElement(Spinner, { size: "md" })) : null,
5759
5790
  value && !loading ? /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles46.editBadge, pointerEvents: "none" }, /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles46.editBadgeInner, { backgroundColor: colors.overlay }] }, /* @__PURE__ */ React25__default.default.createElement(vectorIcons.Feather, { name: "edit-2", size: ms(12), color: "#fff" }))) : null
5760
5791
  );
@@ -5768,7 +5799,8 @@ var styles46 = reactNative.StyleSheet.create({
5768
5799
  },
5769
5800
  placeholderText: {
5770
5801
  fontFamily: "Sohne-Regular",
5771
- fontSize: ms(13)
5802
+ fontSize: ms(13),
5803
+ textAlign: "center"
5772
5804
  },
5773
5805
  loadingOverlay: {
5774
5806
  ...reactNative.StyleSheet.absoluteFillObject,
@@ -5789,6 +5821,851 @@ var styles46 = reactNative.StyleSheet.create({
5789
5821
  }
5790
5822
  });
5791
5823
 
5824
+ // src/utils/curatedIcons.ts
5825
+ var CURATED_ICONS = [
5826
+ {
5827
+ name: "food",
5828
+ label: "Food",
5829
+ labelEs: "Comida",
5830
+ categoryIcon: "coffee",
5831
+ icons: [
5832
+ // Bebidas
5833
+ "coffee",
5834
+ "wine-glass",
5835
+ "beer",
5836
+ "cocktail",
5837
+ "mug-hot",
5838
+ "glass-cheers",
5839
+ "wine",
5840
+ // Comidas
5841
+ "restaurant",
5842
+ "hamburger",
5843
+ "pizza-slice",
5844
+ "ice-cream",
5845
+ "cake",
5846
+ "egg",
5847
+ "fish",
5848
+ "bread-slice",
5849
+ "cookie",
5850
+ "cheese",
5851
+ "carrot",
5852
+ "hotdog",
5853
+ // Cocina / utilidades
5854
+ "utensils",
5855
+ // Delivery / pedidos
5856
+ "shopping-bag",
5857
+ "clock",
5858
+ "star",
5859
+ "heart",
5860
+ "map-pin",
5861
+ "phone"
5862
+ ]
5863
+ },
5864
+ {
5865
+ name: "sports",
5866
+ label: "Sports",
5867
+ labelEs: "Deportes",
5868
+ categoryIcon: "activity",
5869
+ icons: [
5870
+ // Deportes específicos
5871
+ "futbol",
5872
+ "dumbbell",
5873
+ "running",
5874
+ "bicycle",
5875
+ "heartbeat",
5876
+ "fitness-center",
5877
+ // Competencia / logros
5878
+ "target",
5879
+ "award",
5880
+ "flag",
5881
+ "star",
5882
+ "zap",
5883
+ // Bienestar
5884
+ "heart",
5885
+ "clock",
5886
+ "activity",
5887
+ "sun",
5888
+ "user",
5889
+ "users"
5890
+ ]
5891
+ },
5892
+ {
5893
+ name: "business",
5894
+ label: "Business",
5895
+ labelEs: "Negocios",
5896
+ categoryIcon: "briefcase",
5897
+ icons: [
5898
+ "shopping-cart",
5899
+ "shopping-bag",
5900
+ "credit-card",
5901
+ "dollar-sign",
5902
+ "percent",
5903
+ "briefcase",
5904
+ "truck",
5905
+ "package",
5906
+ "gift",
5907
+ "bar-chart",
5908
+ "bar-chart-2",
5909
+ "pie-chart",
5910
+ "trending-up",
5911
+ "trending-down",
5912
+ "activity",
5913
+ "tag",
5914
+ "bookmark",
5915
+ "pocket"
5916
+ ]
5917
+ },
5918
+ {
5919
+ name: "objects",
5920
+ label: "Objects",
5921
+ labelEs: "Objetos",
5922
+ categoryIcon: "folder",
5923
+ icons: [
5924
+ "file",
5925
+ "file-text",
5926
+ "file-plus",
5927
+ "file-minus",
5928
+ "folder",
5929
+ "folder-plus",
5930
+ "folder-minus",
5931
+ "lock",
5932
+ "unlock",
5933
+ "key",
5934
+ "shield",
5935
+ "shield-off",
5936
+ "settings",
5937
+ "sliders",
5938
+ "toggle-left",
5939
+ "toggle-right",
5940
+ "tool",
5941
+ "printer",
5942
+ "database",
5943
+ "server",
5944
+ "hard-drive",
5945
+ "cpu",
5946
+ "paperclip",
5947
+ "aperture",
5948
+ "box",
5949
+ "radio"
5950
+ ]
5951
+ },
5952
+ {
5953
+ name: "status",
5954
+ label: "Status",
5955
+ labelEs: "Estado",
5956
+ categoryIcon: "alert-circle",
5957
+ icons: [
5958
+ "alert-circle",
5959
+ "alert-triangle",
5960
+ "alert-octagon",
5961
+ "info",
5962
+ "help-circle",
5963
+ "bell",
5964
+ "bell-off",
5965
+ "eye",
5966
+ "eye-off",
5967
+ "flag",
5968
+ "zap",
5969
+ "zap-off",
5970
+ "loader",
5971
+ "clock",
5972
+ "watch"
5973
+ ]
5974
+ },
5975
+ {
5976
+ name: "actions",
5977
+ label: "Actions",
5978
+ labelEs: "Acciones",
5979
+ categoryIcon: "edit-3",
5980
+ icons: [
5981
+ "plus",
5982
+ "plus-circle",
5983
+ "plus-square",
5984
+ "minus",
5985
+ "minus-circle",
5986
+ "minus-square",
5987
+ "x",
5988
+ "x-circle",
5989
+ "x-square",
5990
+ "x-octagon",
5991
+ "check",
5992
+ "check-circle",
5993
+ "check-square",
5994
+ "edit",
5995
+ "edit-2",
5996
+ "edit-3",
5997
+ "trash",
5998
+ "trash-2",
5999
+ "copy",
6000
+ "clipboard",
6001
+ "scissors",
6002
+ "download",
6003
+ "download-cloud",
6004
+ "upload",
6005
+ "upload-cloud",
6006
+ "share",
6007
+ "share-2",
6008
+ "link",
6009
+ "link-2",
6010
+ "search",
6011
+ "zoom-in",
6012
+ "zoom-out",
6013
+ "save",
6014
+ "archive",
6015
+ "log-in",
6016
+ "log-out",
6017
+ "power",
6018
+ "refresh-cw",
6019
+ "rotate-cw",
6020
+ "slash"
6021
+ ]
6022
+ },
6023
+ {
6024
+ name: "communication",
6025
+ label: "Communication",
6026
+ labelEs: "Comunicaci\xF3n",
6027
+ categoryIcon: "message-circle",
6028
+ icons: [
6029
+ "mail",
6030
+ "message-circle",
6031
+ "message-square",
6032
+ "send",
6033
+ "phone",
6034
+ "phone-call",
6035
+ "phone-incoming",
6036
+ "phone-outgoing",
6037
+ "phone-missed",
6038
+ "phone-off",
6039
+ "phone-forwarded",
6040
+ "at-sign",
6041
+ "inbox",
6042
+ "user",
6043
+ "user-plus",
6044
+ "user-minus",
6045
+ "user-check",
6046
+ "user-x",
6047
+ "users",
6048
+ "smile",
6049
+ "frown",
6050
+ "meh",
6051
+ "heart",
6052
+ "thumbs-up",
6053
+ "thumbs-down",
6054
+ "star",
6055
+ "award"
6056
+ ]
6057
+ },
6058
+ {
6059
+ name: "navigation",
6060
+ label: "Navigation",
6061
+ labelEs: "Navegaci\xF3n",
6062
+ categoryIcon: "compass",
6063
+ icons: [
6064
+ "arrow-up",
6065
+ "arrow-down",
6066
+ "arrow-left",
6067
+ "arrow-right",
6068
+ "arrow-up-left",
6069
+ "arrow-up-right",
6070
+ "arrow-down-left",
6071
+ "arrow-down-right",
6072
+ "chevron-up",
6073
+ "chevron-down",
6074
+ "chevron-left",
6075
+ "chevron-right",
6076
+ "chevrons-up",
6077
+ "chevrons-down",
6078
+ "chevrons-left",
6079
+ "chevrons-right",
6080
+ "corner-up-left",
6081
+ "corner-up-right",
6082
+ "corner-down-left",
6083
+ "corner-down-right",
6084
+ "corner-left-up",
6085
+ "corner-left-down",
6086
+ "corner-right-up",
6087
+ "corner-right-down",
6088
+ "refresh-cw",
6089
+ "refresh-ccw",
6090
+ "rotate-cw",
6091
+ "rotate-ccw",
6092
+ "navigation",
6093
+ "navigation-2",
6094
+ "compass",
6095
+ "map",
6096
+ "map-pin",
6097
+ "target",
6098
+ "crosshair",
6099
+ "home",
6100
+ "maximize",
6101
+ "maximize-2",
6102
+ "minimize",
6103
+ "minimize-2",
6104
+ "external-link",
6105
+ "move",
6106
+ "anchor"
6107
+ ]
6108
+ },
6109
+ {
6110
+ name: "media",
6111
+ label: "Media",
6112
+ labelEs: "Medios",
6113
+ categoryIcon: "image",
6114
+ icons: [
6115
+ "image",
6116
+ "film",
6117
+ "video",
6118
+ "video-off",
6119
+ "play",
6120
+ "play-circle",
6121
+ "pause",
6122
+ "pause-circle",
6123
+ "square",
6124
+ "stop-circle",
6125
+ "music",
6126
+ "headphones",
6127
+ "speaker",
6128
+ "camera",
6129
+ "camera-off",
6130
+ "mic",
6131
+ "mic-off",
6132
+ "volume",
6133
+ "volume-1",
6134
+ "volume-2",
6135
+ "volume-x",
6136
+ "fast-forward",
6137
+ "rewind",
6138
+ "skip-forward",
6139
+ "skip-back",
6140
+ "repeat",
6141
+ "shuffle",
6142
+ "disc"
6143
+ ]
6144
+ },
6145
+ {
6146
+ name: "layout",
6147
+ label: "Layout",
6148
+ labelEs: "Dise\xF1o",
6149
+ categoryIcon: "grid",
6150
+ icons: [
6151
+ "menu",
6152
+ "more-horizontal",
6153
+ "more-vertical",
6154
+ "grid",
6155
+ "columns",
6156
+ "sidebar",
6157
+ "layout",
6158
+ "list",
6159
+ "align-left",
6160
+ "align-center",
6161
+ "align-right",
6162
+ "align-justify",
6163
+ "bold",
6164
+ "italic",
6165
+ "underline",
6166
+ "type",
6167
+ "filter",
6168
+ "crop",
6169
+ "layers",
6170
+ "hash",
6171
+ "table",
6172
+ "trello",
6173
+ "circle",
6174
+ "square",
6175
+ "triangle",
6176
+ "hexagon",
6177
+ "octagon",
6178
+ "feather",
6179
+ "pen-tool"
6180
+ ]
6181
+ },
6182
+ {
6183
+ name: "nature",
6184
+ label: "Nature",
6185
+ labelEs: "Naturaleza",
6186
+ categoryIcon: "sun",
6187
+ icons: [
6188
+ "sun",
6189
+ "sunrise",
6190
+ "sunset",
6191
+ "moon",
6192
+ "cloud",
6193
+ "cloud-drizzle",
6194
+ "cloud-lightning",
6195
+ "cloud-off",
6196
+ "cloud-rain",
6197
+ "cloud-snow",
6198
+ "wind",
6199
+ "umbrella",
6200
+ "thermometer",
6201
+ "droplet",
6202
+ "life-buoy"
6203
+ ]
6204
+ },
6205
+ {
6206
+ name: "brands",
6207
+ label: "Brands",
6208
+ labelEs: "Marcas",
6209
+ categoryIcon: "globe",
6210
+ icons: [
6211
+ "github",
6212
+ "gitlab",
6213
+ "twitter",
6214
+ "facebook",
6215
+ "instagram",
6216
+ "linkedin",
6217
+ "youtube",
6218
+ "dribbble",
6219
+ "twitch",
6220
+ "slack",
6221
+ "figma",
6222
+ "framer",
6223
+ "chrome",
6224
+ "codepen",
6225
+ "codesandbox",
6226
+ "globe",
6227
+ "rss",
6228
+ "airplay",
6229
+ "cast",
6230
+ "bluetooth",
6231
+ "wifi",
6232
+ "wifi-off",
6233
+ "battery",
6234
+ "battery-charging",
6235
+ "monitor",
6236
+ "tablet",
6237
+ "smartphone",
6238
+ "tv"
6239
+ ]
6240
+ }
6241
+ ];
6242
+ var ALL_CURATED_ICONS = [
6243
+ ...new Set(CURATED_ICONS.flatMap((c) => c.icons))
6244
+ ];
6245
+
6246
+ // src/components/IconPicker/IconPicker.tsx
6247
+ var NUM_COLUMNS = 6;
6248
+ var GAP = 6;
6249
+ var TRIGGER_SIZE = s(56);
6250
+ var SCREEN_HEIGHT2 = reactNative.Dimensions.get("window").height;
6251
+ function IconCell({ name, selected, size, onPress }) {
6252
+ const { colors } = useTheme();
6253
+ const handlePress = () => {
6254
+ selectionAsync();
6255
+ onPress();
6256
+ };
6257
+ const iconColor = selected ? colors.primaryForeground : colors.foreground;
6258
+ const bg = selected ? colors.primary : "transparent";
6259
+ return /* @__PURE__ */ React25__default.default.createElement(
6260
+ reactNative.TouchableOpacity,
6261
+ {
6262
+ onPress: handlePress,
6263
+ activeOpacity: 0.6,
6264
+ touchSoundDisabled: true,
6265
+ accessibilityRole: "button",
6266
+ accessibilityState: { selected },
6267
+ accessibilityLabel: name,
6268
+ style: [styles47.cell, { width: size, height: size, backgroundColor: bg }]
6269
+ },
6270
+ renderIcon(name, ms(20), iconColor)
6271
+ );
6272
+ }
6273
+ var IconCellMemo = React25__default.default.memo(IconCell);
6274
+ function IconPicker({
6275
+ value,
6276
+ onChange,
6277
+ label,
6278
+ error,
6279
+ hint,
6280
+ disabled = false,
6281
+ numColumns = NUM_COLUMNS,
6282
+ gap = GAP,
6283
+ style
6284
+ }) {
6285
+ const { colors } = useTheme();
6286
+ const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
6287
+ const sheetRef = React25.useRef(null);
6288
+ const catScrollRef = React25.useRef(null);
6289
+ const [open, setOpen] = React25.useState(false);
6290
+ const [activeCategory, setActiveCategory] = React25.useState(null);
6291
+ const [containerWidth, setContainerWidth] = React25.useState(() => reactNative.Dimensions.get("window").width - s(16) * 2);
6292
+ const sheetName = React25.useId();
6293
+ const activeIcons = React25.useMemo(() => {
6294
+ if (activeCategory) {
6295
+ return CURATED_ICONS.find((c) => c.name === activeCategory)?.icons ?? ALL_CURATED_ICONS;
6296
+ }
6297
+ return ALL_CURATED_ICONS;
6298
+ }, [activeCategory]);
6299
+ const gapPx = s(gap);
6300
+ const cellSize = containerWidth > 0 ? Math.floor((containerWidth - gapPx * (numColumns - 1)) / numColumns) : 0;
6301
+ const rows = React25.useMemo(() => {
6302
+ const result = [];
6303
+ for (let i = 0; i < activeIcons.length; i += numColumns) {
6304
+ result.push(activeIcons.slice(i, i + numColumns));
6305
+ }
6306
+ return result;
6307
+ }, [activeIcons, numColumns]);
6308
+ React25.useEffect(() => {
6309
+ if (open) {
6310
+ impactMedium();
6311
+ sheetRef.current?.present();
6312
+ } else {
6313
+ sheetRef.current?.dismiss();
6314
+ }
6315
+ }, [open]);
6316
+ const handleSelect = React25.useCallback(
6317
+ (iconName) => {
6318
+ onChange(iconName);
6319
+ setOpen(false);
6320
+ setActiveCategory(null);
6321
+ },
6322
+ [onChange]
6323
+ );
6324
+ const handleOpen = React25.useCallback(() => {
6325
+ if (disabled) return;
6326
+ setActiveCategory(null);
6327
+ setOpen(true);
6328
+ }, [disabled]);
6329
+ const handleClose = React25.useCallback(() => {
6330
+ setOpen(false);
6331
+ setActiveCategory(null);
6332
+ }, []);
6333
+ const renderBackdrop = React25.useCallback(
6334
+ (props) => /* @__PURE__ */ React25__default.default.createElement(BottomSheet.BottomSheetBackdrop, { ...props, disappearsOnIndex: -1, appearsOnIndex: 0, pressBehavior: "close" }),
6335
+ []
6336
+ );
6337
+ const selectedIcon = value ? renderIcon(value, ms(28), colors.foreground) : null;
6338
+ return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles47.triggerContainer, style] }, label ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles47.triggerLabel, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React25__default.default.createElement(
6339
+ reactNative.TouchableOpacity,
6340
+ {
6341
+ onPress: handleOpen,
6342
+ disabled,
6343
+ activeOpacity: 0.7,
6344
+ touchSoundDisabled: true,
6345
+ accessibilityRole: "button",
6346
+ accessibilityLabel: label ?? "Seleccionar icono",
6347
+ accessibilityState: { disabled },
6348
+ style: [
6349
+ styles47.trigger,
6350
+ {
6351
+ backgroundColor: disabled ? colors.surface : colors.background,
6352
+ width: TRIGGER_SIZE,
6353
+ height: TRIGGER_SIZE,
6354
+ borderColor: error ? colors.destructive : value ? colors.primary : colors.border
6355
+ },
6356
+ disabled && styles47.triggerDisabled
6357
+ ]
6358
+ },
6359
+ selectedIcon ?? renderIcon("plus", ms(24), colors.foregroundMuted)
6360
+ ), error ? /* @__PURE__ */ React25__default.default.createElement(
6361
+ reactNative.Text,
6362
+ {
6363
+ style: [styles47.helperText, { color: colors.destructive }],
6364
+ allowFontScaling: true,
6365
+ accessibilityLiveRegion: "polite"
6366
+ },
6367
+ error
6368
+ ) : null, !error && hint ? /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles47.helperText, { color: colors.foregroundMuted }], allowFontScaling: true }, hint) : null, /* @__PURE__ */ React25__default.default.createElement(
6369
+ BottomSheet.BottomSheetModal,
6370
+ {
6371
+ ref: sheetRef,
6372
+ name: sheetName,
6373
+ onDismiss: handleClose,
6374
+ enableDynamicSizing: true,
6375
+ maxDynamicContentSize: SCREEN_HEIGHT2 * 0.7,
6376
+ backdropComponent: renderBackdrop,
6377
+ backgroundStyle: [styles47.sheetBackground, { backgroundColor: colors.card }],
6378
+ handleIndicatorStyle: [styles47.handle, { backgroundColor: colors.border }],
6379
+ enablePanDownToClose: true,
6380
+ topInset: insets.top,
6381
+ android_keyboardInputMode: "adjustPan"
6382
+ },
6383
+ /* @__PURE__ */ React25__default.default.createElement(
6384
+ BottomSheet.BottomSheetScrollView,
6385
+ {
6386
+ contentContainerStyle: styles47.sheetContent,
6387
+ showsVerticalScrollIndicator: true
6388
+ },
6389
+ /* @__PURE__ */ React25__default.default.createElement(reactNative.Text, { style: [styles47.sectionLabel, { color: colors.foregroundSubtle }], allowFontScaling: true }, "Categor\xEDas"),
6390
+ /* @__PURE__ */ React25__default.default.createElement(
6391
+ reactNativeGestureHandler.ScrollView,
6392
+ {
6393
+ ref: catScrollRef,
6394
+ horizontal: true,
6395
+ showsHorizontalScrollIndicator: false,
6396
+ contentContainerStyle: styles47.categoryStrip,
6397
+ style: styles47.categoryScroll
6398
+ },
6399
+ /* @__PURE__ */ React25__default.default.createElement(
6400
+ reactNative.TouchableOpacity,
6401
+ {
6402
+ onPress: () => setActiveCategory(null),
6403
+ activeOpacity: 0.7,
6404
+ touchSoundDisabled: true,
6405
+ accessibilityRole: "button",
6406
+ accessibilityLabel: "Todos",
6407
+ accessibilityState: { selected: activeCategory === null },
6408
+ style: [
6409
+ styles47.categoryChip,
6410
+ {
6411
+ backgroundColor: activeCategory === null ? colors.primary : colors.surface,
6412
+ borderColor: activeCategory === null ? colors.primary : colors.border
6413
+ }
6414
+ ]
6415
+ },
6416
+ /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles47.categoryChipInner }, renderIcon("grid", ms(14), activeCategory === null ? colors.primaryForeground : colors.foregroundSubtle), /* @__PURE__ */ React25__default.default.createElement(
6417
+ reactNative.Text,
6418
+ {
6419
+ style: [
6420
+ styles47.categoryChipText,
6421
+ { color: activeCategory === null ? colors.primaryForeground : colors.foreground }
6422
+ ],
6423
+ allowFontScaling: true,
6424
+ numberOfLines: 1
6425
+ },
6426
+ "Todos"
6427
+ ))
6428
+ ),
6429
+ CURATED_ICONS.map((cat) => /* @__PURE__ */ React25__default.default.createElement(
6430
+ reactNative.TouchableOpacity,
6431
+ {
6432
+ key: cat.name,
6433
+ onPress: () => setActiveCategory(cat.name),
6434
+ activeOpacity: 0.7,
6435
+ touchSoundDisabled: true,
6436
+ accessibilityRole: "button",
6437
+ accessibilityLabel: cat.labelEs,
6438
+ accessibilityState: { selected: activeCategory === cat.name },
6439
+ style: [
6440
+ styles47.categoryChip,
6441
+ {
6442
+ backgroundColor: activeCategory === cat.name ? colors.primary : colors.surface,
6443
+ borderColor: activeCategory === cat.name ? colors.primary : colors.border
6444
+ }
6445
+ ]
6446
+ },
6447
+ /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles47.categoryChipInner }, renderIcon(cat.categoryIcon, ms(14), activeCategory === cat.name ? colors.primaryForeground : colors.foregroundSubtle), /* @__PURE__ */ React25__default.default.createElement(
6448
+ reactNative.Text,
6449
+ {
6450
+ style: [
6451
+ styles47.categoryChipText,
6452
+ { color: activeCategory === cat.name ? colors.primaryForeground : colors.foreground }
6453
+ ],
6454
+ allowFontScaling: true,
6455
+ numberOfLines: 1
6456
+ },
6457
+ cat.labelEs
6458
+ ))
6459
+ ))
6460
+ ),
6461
+ /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles47.separator, { backgroundColor: colors.border }] }),
6462
+ /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: styles47.gridContainer, onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width) }, cellSize > 0 ? rows.map((row, i) => /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { key: row[0] ?? `row-${i}`, style: [styles47.row, { marginBottom: gapPx }] }, row.map((name) => /* @__PURE__ */ React25__default.default.createElement(
6463
+ IconCellMemo,
6464
+ {
6465
+ key: name,
6466
+ name,
6467
+ selected: value === name,
6468
+ size: cellSize,
6469
+ onPress: () => handleSelect(name)
6470
+ }
6471
+ )), Array.from({ length: numColumns - row.length }).map((_, j) => /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { key: `spacer-${j}`, style: { width: cellSize, height: cellSize } })))) : null)
6472
+ )
6473
+ ));
6474
+ }
6475
+ var styles47 = reactNative.StyleSheet.create({
6476
+ triggerContainer: {
6477
+ gap: vs(8)
6478
+ },
6479
+ triggerLabel: {
6480
+ fontFamily: "Sohne-Medium",
6481
+ fontSize: ms(14)
6482
+ },
6483
+ trigger: {
6484
+ borderRadius: RADIUS.md,
6485
+ borderWidth: 1,
6486
+ alignItems: "center",
6487
+ justifyContent: "center"
6488
+ },
6489
+ triggerDisabled: {
6490
+ opacity: 0.6
6491
+ },
6492
+ helperText: {
6493
+ fontFamily: "Sohne-Regular",
6494
+ fontSize: ms(13)
6495
+ },
6496
+ sheetBackground: {
6497
+ borderTopLeftRadius: ms(16),
6498
+ borderTopRightRadius: ms(16)
6499
+ },
6500
+ handle: {
6501
+ width: s(36),
6502
+ height: vs(4),
6503
+ borderRadius: ms(2)
6504
+ },
6505
+ sheetContent: {
6506
+ paddingHorizontal: s(16),
6507
+ paddingBottom: vs(24)
6508
+ },
6509
+ sectionLabel: {
6510
+ fontFamily: "Sohne-Medium",
6511
+ fontSize: ms(12),
6512
+ marginBottom: vs(8),
6513
+ textTransform: "uppercase",
6514
+ letterSpacing: 0.5
6515
+ },
6516
+ categoryScroll: {
6517
+ flexGrow: 0,
6518
+ flexShrink: 0
6519
+ },
6520
+ categoryStrip: {
6521
+ gap: s(8)
6522
+ },
6523
+ categoryChip: {
6524
+ borderRadius: RADIUS.full,
6525
+ borderWidth: 1,
6526
+ paddingVertical: vs(6),
6527
+ paddingHorizontal: s(12)
6528
+ },
6529
+ categoryChipInner: {
6530
+ flexDirection: "row",
6531
+ alignItems: "center",
6532
+ gap: s(6)
6533
+ },
6534
+ categoryChipText: {
6535
+ fontFamily: "Sohne-Medium",
6536
+ fontSize: ms(12)
6537
+ },
6538
+ separator: {
6539
+ height: reactNative.StyleSheet.hairlineWidth,
6540
+ marginVertical: vs(12)
6541
+ },
6542
+ gridContainer: {},
6543
+ row: {
6544
+ flexDirection: "row",
6545
+ gap: GAP
6546
+ },
6547
+ cell: {
6548
+ borderRadius: RADIUS.md,
6549
+ alignItems: "center",
6550
+ justifyContent: "center"
6551
+ }
6552
+ });
6553
+ var sizeConfig = {
6554
+ sm: { button: s(40), icon: 16, valueFontSize: ms(18), valueLineHeight: mvs(24), valueMinWidth: s(32) },
6555
+ md: { button: s(44), icon: 18, valueFontSize: ms(22), valueLineHeight: mvs(28), valueMinWidth: s(36) },
6556
+ lg: { button: s(52), icon: 22, valueFontSize: ms(26), valueLineHeight: mvs(32), valueMinWidth: s(40) }
6557
+ };
6558
+ function NumberStepperBase({
6559
+ value,
6560
+ onValueChange,
6561
+ min = 1,
6562
+ max = 99,
6563
+ step = 1,
6564
+ size = "md",
6565
+ disabled = false,
6566
+ style,
6567
+ accessibilityLabel
6568
+ }) {
6569
+ const { colors } = useTheme();
6570
+ const canDecrement = value > min && !disabled;
6571
+ const canIncrement = value < max && !disabled;
6572
+ const handleDecrement = () => {
6573
+ if (!canDecrement) return;
6574
+ impactLight();
6575
+ onValueChange(Math.max(min, value - step));
6576
+ };
6577
+ const handleIncrement = () => {
6578
+ if (!canIncrement) return;
6579
+ impactLight();
6580
+ onValueChange(Math.min(max, value + step));
6581
+ };
6582
+ const { button: buttonSize, icon: iconSize, valueFontSize, valueLineHeight, valueMinWidth } = sizeConfig[size];
6583
+ const displayValue = String(value);
6584
+ return /* @__PURE__ */ React25__default.default.createElement(reactNative.View, { style: [styles48.container, style] }, /* @__PURE__ */ React25__default.default.createElement(
6585
+ PressableButton,
6586
+ {
6587
+ style: [
6588
+ styles48.button,
6589
+ {
6590
+ width: buttonSize,
6591
+ height: buttonSize,
6592
+ backgroundColor: colors.surface,
6593
+ borderColor: colors.border
6594
+ },
6595
+ !canDecrement && styles48.buttonDisabled
6596
+ ],
6597
+ enabled: canDecrement,
6598
+ onPress: handleDecrement,
6599
+ rippleColor: "transparent",
6600
+ touchSoundDisabled: true,
6601
+ accessibilityRole: "button",
6602
+ accessibilityLabel: `Decrease, current value ${displayValue}`,
6603
+ accessibilityState: { disabled: !canDecrement }
6604
+ },
6605
+ renderIcon("minus", iconSize, canDecrement ? colors.foreground : colors.foregroundMuted)
6606
+ ), /* @__PURE__ */ React25__default.default.createElement(
6607
+ reactNative.Text,
6608
+ {
6609
+ style: [
6610
+ styles48.value,
6611
+ {
6612
+ color: colors.foreground,
6613
+ fontSize: valueFontSize,
6614
+ lineHeight: valueLineHeight,
6615
+ minWidth: valueMinWidth
6616
+ }
6617
+ ],
6618
+ allowFontScaling: true,
6619
+ accessibilityLabel: accessibilityLabel ?? `Quantity: ${displayValue}`,
6620
+ accessibilityRole: "text"
6621
+ },
6622
+ displayValue
6623
+ ), /* @__PURE__ */ React25__default.default.createElement(
6624
+ PressableButton,
6625
+ {
6626
+ style: [
6627
+ styles48.button,
6628
+ {
6629
+ width: buttonSize,
6630
+ height: buttonSize,
6631
+ backgroundColor: colors.surface,
6632
+ borderColor: colors.border
6633
+ },
6634
+ !canIncrement && styles48.buttonDisabled
6635
+ ],
6636
+ enabled: canIncrement,
6637
+ onPress: handleIncrement,
6638
+ rippleColor: "transparent",
6639
+ touchSoundDisabled: true,
6640
+ accessibilityRole: "button",
6641
+ accessibilityLabel: `Increase, current value ${displayValue}`,
6642
+ accessibilityState: { disabled: !canIncrement }
6643
+ },
6644
+ renderIcon("plus", iconSize, canIncrement ? colors.foreground : colors.foregroundMuted)
6645
+ ));
6646
+ }
6647
+ var NumberStepper = React25__default.default.memo(NumberStepperBase);
6648
+ var styles48 = reactNative.StyleSheet.create({
6649
+ container: {
6650
+ flexDirection: "row",
6651
+ alignItems: "center",
6652
+ gap: s(12)
6653
+ },
6654
+ button: {
6655
+ borderRadius: RADIUS.md,
6656
+ alignItems: "center",
6657
+ justifyContent: "center",
6658
+ borderWidth: 1.5
6659
+ },
6660
+ buttonDisabled: {
6661
+ opacity: 0.35
6662
+ },
6663
+ value: {
6664
+ fontFamily: "Sohne-Medium",
6665
+ textAlign: "center"
6666
+ }
6667
+ });
6668
+
5792
6669
  // src/utils/typography.ts
5793
6670
  function getResponsiveFontSize(text, maxSize, steps = [
5794
6671
  { maxLen: 10, subtract: 0 },
@@ -5882,6 +6759,7 @@ exports.FormSection = FormSection;
5882
6759
  exports.ICON_SIZES = ICON_SIZES;
5883
6760
  exports.Icon = Icon;
5884
6761
  exports.IconButton = IconButton;
6762
+ exports.IconPicker = IconPicker;
5885
6763
  exports.ImageUpload = ImageUpload;
5886
6764
  exports.ImageViewer = ImageViewer;
5887
6765
  exports.Input = Input;
@@ -5896,6 +6774,7 @@ exports.MenuGroupFooter = MenuGroupFooter;
5896
6774
  exports.MenuGroupHeader = MenuGroupHeader;
5897
6775
  exports.MenuItem = MenuItem;
5898
6776
  exports.MonthPicker = MonthPicker;
6777
+ exports.NumberStepper = NumberStepper;
5899
6778
  exports.PagerDots = PagerDots;
5900
6779
  exports.Pressable = Pressable3;
5901
6780
  exports.PricingCard = PricingCard;
@@ -5930,6 +6809,7 @@ exports.defaultDark = defaultDark;
5930
6809
  exports.defaultLight = defaultLight;
5931
6810
  exports.deriveColors = deriveColors;
5932
6811
  exports.getResponsiveFontSize = getResponsiveFontSize;
6812
+ exports.getValidIconNames = getValidIconNames;
5933
6813
  exports.impactHeavy = impactHeavy;
5934
6814
  exports.impactLight = impactLight;
5935
6815
  exports.impactMedium = impactMedium;