@sincpro/mobile-ui 1.1.0 → 2.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.
Files changed (123) hide show
  1. package/README.md +156 -29
  2. package/dist/Actions/Actions.Button.d.ts +10 -12
  3. package/dist/Actions/Actions.Button.js +9 -11
  4. package/dist/Actions/Actions.Dock.d.ts +20 -0
  5. package/dist/Actions/Actions.Dock.js +89 -0
  6. package/dist/Actions/Actions.FAB.d.ts +1 -2
  7. package/dist/Actions/Actions.FAB.js +5 -7
  8. package/dist/Actions/Actions.IconButton.d.ts +1 -2
  9. package/dist/Actions/Actions.IconButton.js +2 -2
  10. package/dist/Actions/index.d.ts +4 -0
  11. package/dist/Actions/index.js +3 -0
  12. package/dist/Dialog/BottomSheet/BottomSheet.Root.js +22 -34
  13. package/dist/Dialog/Dialog.ActionSheet.js +2 -16
  14. package/dist/Dialog/Dialog.Confirmation.js +7 -5
  15. package/dist/Dialog/Dialog.EditValue.js +3 -1
  16. package/dist/Dialog/Dialog.Sheet.d.ts +3 -3
  17. package/dist/Dialog/Dialog.Sheet.js +18 -25
  18. package/dist/Display/Display.Accordion.js +7 -3
  19. package/dist/Display/Display.AmountSummary.d.ts +28 -0
  20. package/dist/Display/Display.AmountSummary.js +25 -0
  21. package/dist/Display/Display.Carousel.d.ts +27 -4
  22. package/dist/Display/Display.Carousel.js +112 -12
  23. package/dist/Display/Display.ExpoImage.d.ts +8 -0
  24. package/dist/Display/Display.ExpoImage.js +15 -0
  25. package/dist/Display/Display.Image.d.ts +10 -6
  26. package/dist/Display/Display.Image.js +39 -6
  27. package/dist/Display/Display.ListItem.d.ts +1 -2
  28. package/dist/Display/Display.ListItem.js +3 -3
  29. package/dist/Display/Display.Logo.d.ts +2 -2
  30. package/dist/Display/Display.Logo.js +3 -2
  31. package/dist/Display/Display.MediaCard.d.ts +2 -2
  32. package/dist/Display/Display.MediaEmbed.d.ts +2 -2
  33. package/dist/Display/Display.ProductCard.d.ts +2 -2
  34. package/dist/Display/Display.Story.d.ts +3 -3
  35. package/dist/Display/Display.Story.js +5 -4
  36. package/dist/Display/Display.StoryTray.d.ts +4 -4
  37. package/dist/Display/Display.StoryTray.js +3 -2
  38. package/dist/Display/Display.StoryViewer.d.ts +3 -3
  39. package/dist/Display/Display.StoryViewer.js +6 -3
  40. package/dist/Display/index.d.ts +9 -0
  41. package/dist/Display/index.js +4 -0
  42. package/dist/Feedback/Feedback.DomainSplashScreen.d.ts +13 -4
  43. package/dist/Feedback/Feedback.DomainSplashScreen.js +68 -53
  44. package/dist/Feedback/Feedback.EmptyState.d.ts +3 -4
  45. package/dist/Feedback/Feedback.EmptyState.js +4 -3
  46. package/dist/Feedback/Feedback.Error.d.ts +1 -2
  47. package/dist/Feedback/Feedback.Error.js +2 -2
  48. package/dist/Feedback/Feedback.Loading.d.ts +6 -2
  49. package/dist/Feedback/Feedback.Loading.js +2 -2
  50. package/dist/Feedback/Feedback.Progress.d.ts +6 -3
  51. package/dist/Feedback/Feedback.Progress.js +29 -19
  52. package/dist/Feedback/Feedback.ProgressCircle.d.ts +3 -2
  53. package/dist/Feedback/Feedback.ProgressCircle.js +10 -7
  54. package/dist/Feedback/Feedback.Skeleton.d.ts +4 -4
  55. package/dist/Feedback/Feedback.Skeleton.js +15 -3
  56. package/dist/Feedback/Feedback.Spinner.d.ts +3 -3
  57. package/dist/Feedback/Feedback.Spinner.js +40 -9
  58. package/dist/Feedback/Feedback.Splash.d.ts +2 -2
  59. package/dist/Feedback/Feedback.Splash.js +5 -3
  60. package/dist/Feedback/Toast.context.d.ts +64 -3
  61. package/dist/Feedback/Toast.context.js +112 -31
  62. package/dist/Feedback/index.d.ts +15 -1
  63. package/dist/Feedback/index.js +4 -1
  64. package/dist/Form/Form.Checkbox.d.ts +1 -2
  65. package/dist/Form/Form.Checkbox.js +2 -2
  66. package/dist/Form/Form.DatePicker.d.ts +1 -2
  67. package/dist/Form/Form.DatePicker.js +2 -2
  68. package/dist/Form/Form.Dropdown.d.ts +15 -3
  69. package/dist/Form/Form.Dropdown.js +21 -6
  70. package/dist/Form/Form.ErrorSummary.d.ts +23 -0
  71. package/dist/Form/Form.ErrorSummary.js +53 -0
  72. package/dist/Form/Form.Input.d.ts +1 -2
  73. package/dist/Form/Form.Input.js +2 -2
  74. package/dist/Form/Form.Select.d.ts +1 -2
  75. package/dist/Form/Form.Select.js +6 -19
  76. package/dist/Form/index.d.ts +3 -0
  77. package/dist/Form/index.js +2 -0
  78. package/dist/Navigation/Navigation.AppBar.d.ts +2 -6
  79. package/dist/Navigation/Navigation.AppBar.js +9 -7
  80. package/dist/Navigation/Navigation.BottomNav.d.ts +1 -3
  81. package/dist/Navigation/Navigation.BottomNav.js +7 -6
  82. package/dist/Navigation/Navigation.Header.d.ts +2 -2
  83. package/dist/Navigation/Navigation.Menu.js +10 -3
  84. package/dist/Navigation/Navigation.Search.d.ts +41 -0
  85. package/dist/Navigation/Navigation.Search.js +47 -0
  86. package/dist/Navigation/Navigation.SearchBar.d.ts +1 -2
  87. package/dist/Navigation/Navigation.SearchBar.js +16 -19
  88. package/dist/Navigation/Navigation.SegmentedControl.d.ts +11 -3
  89. package/dist/Navigation/Navigation.SegmentedControl.js +29 -16
  90. package/dist/Navigation/index.d.ts +11 -2
  91. package/dist/Navigation/index.js +2 -0
  92. package/dist/branding.d.ts +3 -2
  93. package/dist/primitives/BaseButton.d.ts +10 -12
  94. package/dist/primitives/BaseButton.js +9 -11
  95. package/dist/theme/typography.d.ts +1 -1
  96. package/dist/utils/image.d.ts +3 -0
  97. package/dist/utils/image.js +13 -0
  98. package/dist/utils/keys.d.ts +1 -0
  99. package/dist/utils/keys.js +7 -0
  100. package/dist/utils/progress.d.ts +1 -0
  101. package/dist/utils/progress.js +5 -0
  102. package/dist/utils/reorder.js +2 -5
  103. package/dist/utils/useReducedMotion.d.ts +1 -0
  104. package/dist/utils/useReducedMotion.js +43 -0
  105. package/dist/utils/useSheetTranslation.d.ts +5 -0
  106. package/dist/utils/useSheetTranslation.js +23 -0
  107. package/dist/views/AppSplashView.d.ts +3 -2
  108. package/dist/views/AppSplashView.js +3 -2
  109. package/dist/views/AuthFormView.d.ts +2 -2
  110. package/dist/views/FormViewV2.d.ts +2 -2
  111. package/dist/views/ListViewV2.context.d.ts +3 -1
  112. package/dist/views/ListViewV2.context.js +41 -21
  113. package/dist/views/ListViewV2.d.ts +15 -7
  114. package/dist/views/ListViewV2.js +44 -23
  115. package/dist/views/types/IListView.js +6 -5
  116. package/dist/widgets/CollectionOptions.js +9 -7
  117. package/dist/widgets/FilterBar.d.ts +1 -1
  118. package/dist/widgets/FilterBar.js +1 -1
  119. package/dist/widgets/FilterBuilder.js +7 -7
  120. package/dist/widgets/HomeHeader.d.ts +2 -2
  121. package/dist/widgets/PromoModal.js +3 -1
  122. package/dist/widgets/ScreenHeader.d.ts +2 -2
  123. package/package.json +4 -1
package/README.md CHANGED
@@ -11,7 +11,7 @@ This package is maintained by Sincpro as part of the mobile framework ecosystem.
11
11
  ## Quick Start
12
12
 
13
13
  ```bash
14
- npx expo install @sincpro/mobile-ui
14
+ npx expo install @sincpro/mobile-ui expo-image
15
15
  ```
16
16
 
17
17
  Wire the Tailwind preset, then import by category:
@@ -36,11 +36,7 @@ export default function InvoiceScreen() {
36
36
  <Display.Card>
37
37
  <Display.KeyValue label="Invoice #" value="INV-0042" copyable />
38
38
  <Display.Monetary value={1500.0} variant="dataLarge" />
39
- <Actions.Button
40
- accessibleSizing
41
- onPress={() => toast.success("Invoice sent")}
42
- title="Send Invoice"
43
- />
39
+ <Actions.Button onPress={() => toast.success("Invoice sent")} title="Send Invoice" />
44
40
  </Display.Card>
45
41
  );
46
42
  }
@@ -91,10 +87,23 @@ recoverable error. It uses fictional data and local state, not persistence or a
91
87
 
92
88
  ### Accessible interaction
93
89
 
94
- - `Actions.Button` (including `.Icon`), `Actions.IconButton`, `BaseButton`,
95
- `Feedback.EmptyState`, `Feedback.Error` and `Form.Input` accept `accessibleSizing` to
96
- opt into a minimum 48-point target. Buttons also allow enlarged, multiline labels in
97
- this mode. Existing sizing remains the default for compatibility.
90
+ - Loading feedback respects the live system Reduce Motion setting; `animated={false}`
91
+ keeps `Feedback.Skeleton`, `Progress`, `Spinner` and `Loading` static explicitly.
92
+ Spinners expose a named busy state; progress exposes a percentage only when known.
93
+ Track/indicator styling and native accessibility props remain customizable.
94
+ See the [feedback contract](docs/CATALOG.md#feedback-feedback) and the
95
+ [comparison and priorities](docs/DESIGN-SYSTEM-GAPS.md).
96
+ - v2 requires `expo-image`: `Display.Image`, logos, story media and illustrations share
97
+ the Expo renderer, disk caching, automatic source recycling and Reduce Motion policy.
98
+ `Display.ExpoImage` exposes the direct renderer; `Display.Image` adds error/retry composition.
99
+ See the [breaking migration guide](docs/MIGRATION-V2.md).
100
+ - `ListViewV2.Content` exposes `listProps` for virtualization, `getItemLayout`, viewability
101
+ and `extraData`, plus `listRef` and content styling. `Root hasMore={false}` stops
102
+ pagination; `loadingMore` and refresh pause it. See the
103
+ [mobile performance and usability plan](docs/MOBILE-QUALITY.md).
104
+ - Buttons, icon actions, inputs, selection controls and navigation use their 48-point
105
+ accessible sizing by default. `accessibleSizing` was removed: there is no legacy
106
+ compact-target mode. Labels wrap and follow system scaling; presentation stays configurable.
98
107
  - Supply `accessibilityLabel` for icon-only actions. Loading buttons expose busy/disabled
99
108
  state and retain their accessible name.
100
109
  - `Display.CopyableText` uses a familiar copy icon: tap a short value to copy it.
@@ -113,7 +122,7 @@ recoverable error. It uses fictional data and local state, not persistence or a
113
122
  the keyboard. It preserves typography/tokens and backs the longer-text modes above.
114
123
  On iOS, `Text selectable` alone only exposes full-paragraph copying, not range handles.
115
124
  - Headings and section titles expose native header semantics.
116
- - Checkbox/Select announce control state; their `accessibleSizing` mode enlarges targets.
125
+ - Checkbox/Select announce control state and use accessible targets without an opt-in.
117
126
  - Sheet supports accessible escape and `showCloseButton`; `SwipeableRow visibleActions`
118
127
  supplies a non-gesture alternative. Keep explicit labels for essential actions.
119
128
  - `Dialog/NativeSheet` is an optional Expo 58 native presentation (`@expo/ui` peer);
@@ -122,7 +131,7 @@ recoverable error. It uses fictional data and local state, not persistence or a
122
131
  summaries, cancelable selection, filters applied only on confirmation and archive/undo.
123
132
  - Form/List view refresh always clears the busy state on failure and accepts
124
133
  `onRefreshError` for application recovery without discarding content.
125
- - AppBar, BottomNav and SegmentedControl support accessible sizing; banners expose status
134
+ - AppBar, BottomNav and SegmentedControl use accessible sizing; banners expose status
126
135
  semantics, and confirmation defaults use explicit verbs.
127
136
 
128
137
  The [audit and validation report](docs/UX-AUDIT.md) records scope, evidence and device limits.
@@ -219,8 +228,8 @@ Auto wraps above font scale 1.3, otherwise it scrolls horizontally. Quick chips
219
228
  immediately; the recipe's advanced sheet applies only on confirmation.
220
229
 
221
230
  `Actions.FilterButton variant="mobile"` adds readable wrapping labels and 48-point targets.
222
- `FilterButtonGroup layout="scroll|wrap"` and `Navigation.SearchBar accessibleSizing` are
223
- additive; legacy filter layout and search sizing remain unchanged.
231
+ `FilterButtonGroup layout="scroll|wrap"` supports both layouts. `Navigation.SearchBar`
232
+ uses accessible sizing by default in v2, with no legacy sizing flag.
224
233
  When placing these controls in a host ScrollView, use `keyboardShouldPersistTaps="handled"`
225
234
  so a filter can act on the first tap while the keyboard is open.
226
235
  Use virtualized lists for production-sized collections.
@@ -324,6 +333,15 @@ template layout without a toolbar.
324
333
  Multiline Return remains a newline; dismissing the keyboard does not submit the form.
325
334
  Story: `Patterns/Forms/Keyboard navigation`.
326
335
 
336
+ `Form.ErrorSummary` presents ordered `{ id, label, message }` errors with
337
+ `onSelectError(id)`: the host focuses the corresponding native input ref with `.focus()`.
338
+ Use the same messages inline, keep controlled field drafts mounted, and place the summary
339
+ inside `KeyboardForm`. The first appearance is announced; updates while errors remain do
340
+ not repeatedly interrupt typing. Set `announce={false}` if the host already announces.
341
+ `renderHeader` and `renderErrorContent` replace presentation, not the named selection
342
+ action. Root/item/text props and styles remain customizable.
343
+ Story: `Patterns/Forms/Validation` includes real input refs and custom content.
344
+
327
345
  `ListViewV2.Content` accepts native `keyboardShouldPersistTaps` and `keyboardDismissMode`
328
346
  across populated, empty and error states. Handled row/retry actions receive the first tap
329
347
  while search has focus (`"handled"` by default); pass `"never"` for the old dismiss-first
@@ -391,6 +409,31 @@ host-supplied autocomplete while focused. Choosing a suggestion calls `onSelect`
391
409
  silently rewriting the query. A host may complete a title or create a field-specific
392
410
  condition; it owns matching, request cancellation and stale responses.
393
411
 
412
+ `Navigation.Search` composes that existing field with horizontally scrolling chips,
413
+ advanced filters in a `Dialog/Sheet`, recent searches and suggestions:
414
+
415
+ ```tsx
416
+ <Navigation.Search.Root>
417
+ <Navigation.Search.Field value={query} onChangeText={setQuery} />
418
+ <Navigation.Search.Filters>
419
+ <Actions.FilterButton active title="Todos" onPress={() => {}} variant="mobile" />
420
+ </Navigation.Search.Filters>
421
+ <Navigation.Search.FilterSheet
422
+ activeCount={activeFilterCount}
423
+ onApply={applyFilters}
424
+ onClear={clearDraftFilters}
425
+ >
426
+ <FilterFields />
427
+ </Navigation.Search.FilterSheet>
428
+ <Navigation.Search.History items={recent} onRemove={removeRecent} onSelect={setQuery} />
429
+ </Navigation.Search.Root>
430
+ ```
431
+
432
+ It composes presentation only; the host owns query/filter state, history persistence and
433
+ results. Keep `ListViewV2.Header.Search` when its built-in debounced `onSearch` behavior is
434
+ preferred. Use `Navigation.AppBar` for back/context and `Navigation.Steps` for sequential
435
+ flows rather than adding breadcrumb trails to compact mobile headers.
436
+
394
437
  Story: `Patterns/Collections/Query configuration` exercises actual local filtering,
395
438
  multiple sorting priorities, grouping levels and saving/loading configurations.
396
439
 
@@ -461,7 +504,7 @@ const { control } = useForm<{ email: string; amount: number }>();
461
504
  Queued toast system with promise support — covers the full loading → success / error lifecycle:
462
505
 
463
506
  ```tsx
464
- import { ToastProvider, useToast } from "@sincpro/mobile-ui/Feedback";
507
+ import { Toast, ToastProvider, useToast } from "@sincpro/mobile-ui/Feedback";
465
508
 
466
509
  // 1. Wrap the app once (createAppShell does this automatically)
467
510
  <ToastProvider position="top">{children}</ToastProvider>;
@@ -474,8 +517,62 @@ toast.promise(sendInvoice(), {
474
517
  success: "Invoice sent",
475
518
  error: "Failed to send",
476
519
  });
520
+
521
+ // Compose custom content while keeping the shared toast surface and lifecycle
522
+ toast.show({
523
+ render: ({ dismiss, update }) => (
524
+ <>
525
+ <Toast.Icon variant="loading" />
526
+ <Toast.Content>
527
+ <Toast.Title>Syncing catalog</Toast.Title>
528
+ <Toast.Description>Downloading product images…</Toast.Description>
529
+ </Toast.Content>
530
+ <Toast.Action label="Details" onPress={() => update({ message: "Still syncing…" })} />
531
+ <Toast.Close onPress={dismiss} />
532
+ </>
533
+ ),
534
+ variant: "loading",
535
+ });
477
536
  ```
478
537
 
538
+ Toast cards can also be dismissed with an upward or downward swipe. Custom render content keeps
539
+ the shared card surface, safe-area placement, lifecycle, and swipe behavior.
540
+
541
+ Temporary toasts now show a close action by default too; the `dismissible: false` option explicitly
542
+ removes it. Escape dismisses the default surface. Enter/exit animation follows live
543
+ Reduce Motion; loading uses the common accessible spinner. `Toast.Root` accepts native
544
+ view props/styles; `Toast.Action` and `Toast.Close` accept native pressable props/styles.
545
+ Custom renderers must include their own visible close alternative when appropriate.
546
+
547
+ ### Composable mobile navigation and loading
548
+
549
+ `Display.Carousel` supports short, non-virtualized collections with named 48-point
550
+ previous/next controls, localized page labels and optional controlled `index` /
551
+ `onIndexChange`. Rejected controlled swipes restore the accepted page. Measured trailing
552
+ space lets the last narrow card reach its snap position.
553
+ `renderControls({ index, count, canPrevious, canNext, previous, next, goTo })` replaces the
554
+ controls without replacing index validation or scrolling. Custom controls own their
555
+ accessible labels/disabled state and must provide a non-swipe alternative.
556
+ Use `itemWidth` / `gap` for snap geometry; `itemStyle`, root native props/styles,
557
+ `contentContainerStyle`, dot styles and `paginationTextProps` customize presentation.
558
+ Data keys must be unique, non-empty strings. Use a virtualized list for large datasets.
559
+ Stories: `Components/Data display/Carousel` and `Carousel Customized`.
560
+
561
+ `Feedback.DomainSplashScreen` waits for actual `isLoading={false}`, respecting
562
+ `minDuration`, rather than fabricating progress or finishing after a timer.
563
+ Children remain mounted, preserving drafts, but are inaccessible/non-interactive while
564
+ loading. `onComplete` runs once per completed cycle; timers/animations are cleaned up.
565
+ `renderLoading({ domainName, isLoading, reducedMotion })`, `containerStyle` and
566
+ `overlayStyle` let developers/AI own the visuals without replacing that lifecycle.
567
+ Do not use splash completion as a data-loading signal.
568
+ Story: `Patterns/Feedback/Loading lifecycle`.
569
+
570
+ The shared `useReducedMotion` hook makes one native preference query/subscription for
571
+ all active consumers and cancels stale queries when they leave. RN sheets, menus,
572
+ confirmation/edit dialogs, dropdowns, story viewer, accordion, dock and collection/promo
573
+ overlays follow the live setting; drag interactions remain available.
574
+ This does not certify arbitrary custom renderers or the optional native Sheet engine.
575
+
479
576
  ### Bottom Sheet and Dialogs
480
577
 
481
578
  ```tsx
@@ -525,8 +622,33 @@ import { Display } from "@sincpro/mobile-ui/Display";
525
622
  <Display.Badge variant="success">Paid</Display.Badge>
526
623
  <Display.Monetary amount={1500.00} variant="dataLarge" />
527
624
  <Display.DataTable columns={cols} rows={rows} />
625
+
626
+ <Display.AmountSummary.Root currencySymbol="Bs">
627
+ <Display.AmountSummary.Row label="Subtotal" value={120} />
628
+ <Display.AmountSummary.Row label="Delivery" value={8.5} />
629
+ <Display.AmountSummary.Total label="Total" value={128.5} />
630
+ </Display.AmountSummary.Root>
528
631
  ```
529
632
 
633
+ `AmountSummary` formats and arranges amounts; the app supplies labels, calculations and
634
+ business states. `KeyValue copyable` remains the reusable copy affordance for identifiers.
635
+ `Actions.Dock` defaults to a fixed bottom action bar. Swipe up on its handle or press
636
+ “Más opciones” to reveal additional content above it; the primary action remains fixed.
637
+ The dedicated 48-point handle owns the touch from its start, so an ancestor scroll view
638
+ cannot steal it. Swipe up opens a native modal; swipe down on the panel handle closes it.
639
+ The expanded panel blocks and dims the underlying screen, while the primary action remains
640
+ outside its scrolling content. Back, accessible escape, the collapse button and backdrop
641
+ close it (`dismissOnBackdrop={false}` disables only backdrop dismissal).
642
+ Use `expanded` / `onExpandedChange` for host-controlled state, or `defaultExpanded` for
643
+ uncontrolled initial state. Wrap the app in `SafeAreaProvider`. Keep the collapsed fixed
644
+ bar outside scroll views, within the screen's safe area, and reserve space below list content.
645
+ Inside `FormViewV2.Footer`, set `placement="footer"` to reuse its sticky layout.
646
+ The panel fits its content up to `maxExpandedHeightRatio` (default `0.6`) and available screen
647
+ space; overflow scrolls and the modal avoids the keyboard.
648
+
649
+ This changes the Dock's former inline expansion behavior. See
650
+ [the migration guide](docs/MOBILE_UX_MIGRATION.md) before adopting it in core or host apps.
651
+
530
652
  ---
531
653
 
532
654
  ## Component Catalog
@@ -538,6 +660,7 @@ import { Display } from "@sincpro/mobile-ui/Display";
538
660
  | `Actions.Button` | Primary action — gradient, outline, flat, link variants; optional confirm dialog |
539
661
  | `Actions.IconButton` | Icon-only tap target — ghost, primary, secondary, tertiary variants |
540
662
  | `Actions.FAB` | Floating Action Button — fixed position, optional label |
663
+ | `Actions.Dock` | Fixed primary action with swipe-expandable content and persistent CTA |
541
664
  | `Actions.FilterButton` | Chip-style active/inactive toggle |
542
665
  | `Actions.FilterButtonGroup` | Horizontal scroll container for filter chips |
543
666
 
@@ -548,6 +671,7 @@ import { Display } from "@sincpro/mobile-ui/Display";
548
671
  | `Display.Badge` | Status badge — success, warning, danger, info, neutral |
549
672
  | `Display.Card` | Surface container with optional shadow and padding |
550
673
  | `Display.KeyValue` | Label + value row, optional clipboard copy |
674
+ | `Display.AmountSummary` | Composable monetary rows and total |
551
675
  | `Display.Stat` | KPI cell — label, value, optional trend indicator |
552
676
  | `Display.StatCard` | Card-wrapped KPI |
553
677
  | `Display.Monetary` | Formatted monetary amount using mono typography |
@@ -566,7 +690,7 @@ import { Display } from "@sincpro/mobile-ui/Display";
566
690
  | `Display.CopyableText` | Text with one-tap clipboard copy |
567
691
  | `Display.Logo` | Brand logo (falls back to `setBranding` value) |
568
692
  | `Display.Accordion` | Collapsible content section |
569
- | `Display.Carousel` | Horizontal swipe carousel |
693
+ | `Display.Carousel` | Controlled short carousel with non-swipe alternatives |
570
694
  | `Display.Story` / `StoryTray` / `StoryViewer` | Stories UI pattern |
571
695
  | `Display.MediaCard` | Card with image or video embed |
572
696
  | `Display.Pattern` | Decorative background pattern |
@@ -583,6 +707,7 @@ import { Display } from "@sincpro/mobile-ui/Display";
583
707
  | `Form.FractionalQuantityInput` | Decimal quantity input |
584
708
  | `Form.Select` | Dropdown select (modal-based) |
585
709
  | `Form.Dropdown` | Inline dropdown menu |
710
+ | `Form.ErrorSummary` | Ordered validation errors linked to native field focus |
586
711
  | `Form.RadioButton` | Single-select radio option |
587
712
  | `Form.Checkbox` | Multi-select checkbox |
588
713
  | `Form.Switch` | Toggle switch |
@@ -602,6 +727,7 @@ import { Display } from "@sincpro/mobile-ui/Display";
602
727
  | ------------------------------- | -------------------------------- |
603
728
  | `Feedback.Spinner` | Animated loading spinner |
604
729
  | `Feedback.Loading` | Full-screen loading overlay |
730
+ | `Feedback.DomainSplashScreen` | Customizable real-load lifecycle |
605
731
  | `Feedback.Skeleton` | Content placeholder shimmer |
606
732
  | `Feedback.Progress` | Linear progress bar |
607
733
  | `Feedback.ProgressCircle` | Circular progress indicator |
@@ -614,19 +740,20 @@ import { Display } from "@sincpro/mobile-ui/Display";
614
740
 
615
741
  ### Navigation
616
742
 
617
- | Component | Description |
618
- | --------------------------------- | ------------------------------------- |
619
- | `Navigation.AppBar` | Top navigation bar with action slots |
620
- | `Navigation.BottomNav` | Bottom tab bar |
621
- | `Navigation.Header` | Screen header |
622
- | `Navigation.HeaderToolbar` | Header with left, center, right slots |
623
- | `Navigation.CollapsingHeader` | Header that collapses on scroll |
624
- | `Navigation.FloatingBar` | Floating action bar |
625
- | `Navigation.SearchBar` | Navigation-level search input |
626
- | `Navigation.SegmentedControl` | Segmented control switcher |
627
- | `Navigation.Tabs` | Tab navigation container |
628
- | `Navigation.Steps` | Step indicator / breadcrumb |
629
- | `Navigation.Menu` / `MenuSection` | Dropdown menu with sections |
743
+ | Component | Description |
744
+ | --------------------------------- | ------------------------------------------------- |
745
+ | `Navigation.AppBar` | Top navigation bar with action slots |
746
+ | `Navigation.BottomNav` | Bottom tab bar |
747
+ | `Navigation.Header` | Screen header |
748
+ | `Navigation.HeaderToolbar` | Header with left, center, right slots |
749
+ | `Navigation.CollapsingHeader` | Header that collapses on scroll |
750
+ | `Navigation.FloatingBar` | Floating action bar |
751
+ | `Navigation.SearchBar` | Navigation-level search input |
752
+ | `Navigation.Search` | Compound field, filters, history and filter sheet |
753
+ | `Navigation.SegmentedControl` | Segmented control switcher |
754
+ | `Navigation.Tabs` | Tab navigation container |
755
+ | `Navigation.Steps` | Step indicator / breadcrumb |
756
+ | `Navigation.Menu` / `MenuSection` | Dropdown menu with sections |
630
757
 
631
758
  ### Dialog
632
759
 
@@ -11,18 +11,18 @@ declare const button: import("tailwind-variants").TVReturnType<{
11
11
  outlineDanger: "bg-transparent border border-danger";
12
12
  outlineBlack: "bg-transparent border border-border-strong";
13
13
  flat: "bg-text-primary/10";
14
- link: "bg-transparent min-h-0";
14
+ link: "bg-transparent";
15
15
  transparent: "bg-transparent border border-border-light";
16
16
  };
17
17
  size: {
18
- small: "py-1.5 px-3 min-h-[36px]";
19
- medium: "py-2.5 px-4 min-h-[44px]";
18
+ small: "py-1.5 px-3 min-h-[48px]";
19
+ medium: "py-2.5 px-4 min-h-[48px]";
20
20
  large: "py-3 px-5 min-h-[48px]";
21
21
  };
22
22
  disabled: {
23
23
  true: "opacity-70";
24
24
  };
25
- }, undefined, "rounded-md items-center justify-center flex-row min-h-[44px]", {
25
+ }, undefined, "rounded-md items-center justify-center flex-row min-h-[48px]", {
26
26
  variant: {
27
27
  primary: "bg-accent";
28
28
  accent: "bg-transparent";
@@ -32,12 +32,12 @@ declare const button: import("tailwind-variants").TVReturnType<{
32
32
  outlineDanger: "bg-transparent border border-danger";
33
33
  outlineBlack: "bg-transparent border border-border-strong";
34
34
  flat: "bg-text-primary/10";
35
- link: "bg-transparent min-h-0";
35
+ link: "bg-transparent";
36
36
  transparent: "bg-transparent border border-border-light";
37
37
  };
38
38
  size: {
39
- small: "py-1.5 px-3 min-h-[36px]";
40
- medium: "py-2.5 px-4 min-h-[44px]";
39
+ small: "py-1.5 px-3 min-h-[48px]";
40
+ medium: "py-2.5 px-4 min-h-[48px]";
41
41
  large: "py-3 px-5 min-h-[48px]";
42
42
  };
43
43
  disabled: {
@@ -53,12 +53,12 @@ declare const button: import("tailwind-variants").TVReturnType<{
53
53
  outlineDanger: "bg-transparent border border-danger";
54
54
  outlineBlack: "bg-transparent border border-border-strong";
55
55
  flat: "bg-text-primary/10";
56
- link: "bg-transparent min-h-0";
56
+ link: "bg-transparent";
57
57
  transparent: "bg-transparent border border-border-light";
58
58
  };
59
59
  size: {
60
- small: "py-1.5 px-3 min-h-[36px]";
61
- medium: "py-2.5 px-4 min-h-[44px]";
60
+ small: "py-1.5 px-3 min-h-[48px]";
61
+ medium: "py-2.5 px-4 min-h-[48px]";
62
62
  large: "py-3 px-5 min-h-[48px]";
63
63
  };
64
64
  disabled: {
@@ -138,7 +138,6 @@ export interface ButtonProps extends VariantProps<typeof button>, AccessibilityP
138
138
  className?: string;
139
139
  icon?: React.ReactNode;
140
140
  testID?: string;
141
- accessibleSizing?: boolean;
142
141
  }
143
142
  export interface ButtonIconProps extends VariantProps<typeof buttonIcon>, AccessibilityProps {
144
143
  icon: string;
@@ -148,7 +147,6 @@ export interface ButtonIconProps extends VariantProps<typeof buttonIcon>, Access
148
147
  disabled?: boolean;
149
148
  className?: string;
150
149
  testID?: string;
151
- accessibleSizing?: boolean;
152
150
  }
153
151
  declare const ButtonWithIcon: React.FC<ButtonProps> & {
154
152
  Icon: React.FC<ButtonIconProps>;
@@ -8,7 +8,7 @@ import { useCallback } from "react";
8
8
  import { ActivityIndicator, TouchableOpacity, View } from "react-native";
9
9
  // ─── Style variants ───────────────────────────────────────────────────────────
10
10
  const button = tv({
11
- base: "rounded-md items-center justify-center flex-row min-h-[44px]",
11
+ base: "rounded-md items-center justify-center flex-row min-h-[48px]",
12
12
  variants: {
13
13
  variant: {
14
14
  primary: "bg-accent",
@@ -19,12 +19,12 @@ const button = tv({
19
19
  outlineDanger: "bg-transparent border border-danger",
20
20
  outlineBlack: "bg-transparent border border-border-strong",
21
21
  flat: "bg-text-primary/10",
22
- link: "bg-transparent min-h-0",
22
+ link: "bg-transparent",
23
23
  transparent: "bg-transparent border border-border-light",
24
24
  },
25
25
  size: {
26
- small: "py-1.5 px-3 min-h-[36px]",
27
- medium: "py-2.5 px-4 min-h-[44px]",
26
+ small: "py-1.5 px-3 min-h-[48px]",
27
+ medium: "py-2.5 px-4 min-h-[48px]",
28
28
  large: "py-3 px-5 min-h-[48px]",
29
29
  },
30
30
  disabled: {
@@ -151,7 +151,7 @@ const textVariantMap = {
151
151
  medium: "button",
152
152
  large: "buttonLarge",
153
153
  };
154
- const Button = ({ title, onPress, confirm, variant = "primary", size = "medium", loading = false, disabled = false, className, icon, testID, accessibleSizing = false, accessibilityLabel, accessibilityState, ...accessibilityProps }) => {
154
+ const Button = ({ title, onPress, confirm, variant = "primary", size = "medium", loading = false, disabled = false, className, icon, testID, accessibilityLabel, accessibilityState, ...accessibilityProps }) => {
155
155
  const { show, hide } = useConfirmationContext();
156
156
  const textColorClass = textColor({ variant: variant, disabled });
157
157
  const loadingColorValue = getLoadingColor(variant);
@@ -179,18 +179,16 @@ const Button = ({ title, onPress, confirm, variant = "primary", size = "medium",
179
179
  ...accessibilityState,
180
180
  disabled: disabled || loading,
181
181
  busy: loading,
182
- }, style: accessibleSizing
183
- ? { minHeight: 48, minWidth: 48, justifyContent: "center" }
184
- : undefined, testID: testID, children: loading ? (_jsx(ActivityIndicator, { color: loadingColorValue, size: "small" })) : (_jsx(Typography.Text, { className: textColorClass, variant: textVariantValue, children: title })) }));
182
+ }, style: { minHeight: 48, minWidth: 48, justifyContent: "center" }, testID: testID, children: loading ? (_jsx(ActivityIndicator, { color: loadingColorValue, size: "small" })) : (_jsx(Typography.Text, { allowFontScaling: true, className: textColorClass, style: { flexShrink: 1 }, variant: textVariantValue, children: title })) }));
185
183
  }
186
184
  const emphasize = variant === "primary" || variant === "cta";
187
185
  return (_jsx(TouchableOpacity, { activeOpacity: 0.8, className: button({ variant, size, disabled, className }), disabled: disabled || loading, onPress: handlePress, ...accessibilityProps, accessibilityLabel: accessibilityLabel ?? title, accessibilityRole: "button", accessibilityState: {
188
186
  ...accessibilityState,
189
187
  disabled: disabled || loading,
190
188
  busy: loading,
191
- }, style: accessibleSizing ? { minHeight: 48, minWidth: 48 } : undefined, testID: testID, children: loading ? (_jsx(ActivityIndicator, { color: loadingColorValue, size: "small" })) : (_jsxs(_Fragment, { children: [icon ? _jsx(View, { className: "mr-2", children: icon }) : null, _jsx(Typography.Text, { allowFontScaling: accessibleSizing, className: textColorClass, ellipsizeMode: "tail", numberOfLines: accessibleSizing ? undefined : 1, semibold: emphasize, variant: textVariantValue, children: title })] })) }));
189
+ }, style: { minHeight: 48, minWidth: 48 }, testID: testID, children: loading ? (_jsx(ActivityIndicator, { color: loadingColorValue, size: "small" })) : (_jsxs(_Fragment, { children: [icon ? _jsx(View, { className: "mr-2", children: icon }) : null, _jsx(Typography.Text, { allowFontScaling: true, className: textColorClass, semibold: emphasize, style: { flexShrink: 1 }, variant: textVariantValue, children: title })] })) }));
192
190
  };
193
- const ButtonIcon = ({ icon, onPress, confirm, variant = "primary", size = "medium", loading = false, disabled = false, className, testID, accessibleSizing = false, accessibilityState, ...accessibilityProps }) => {
191
+ const ButtonIcon = ({ icon, onPress, confirm, variant = "primary", size = "medium", loading = false, disabled = false, className, testID, accessibilityState, ...accessibilityProps }) => {
194
192
  const { show, hide } = useConfirmationContext();
195
193
  const iconColorValue = getIconColor(variant, disabled);
196
194
  const iconSizeValue = iconSizeMap[size] ?? 20;
@@ -217,7 +215,7 @@ const ButtonIcon = ({ icon, onPress, confirm, variant = "primary", size = "mediu
217
215
  ...accessibilityState,
218
216
  disabled: disabled || loading,
219
217
  busy: loading,
220
- }, style: accessibleSizing ? { minHeight: 48, minWidth: 48 } : undefined, testID: testID, children: loading ? (_jsx(ActivityIndicator, { color: loadingColorValue, size: "small" })) : (_jsx(Icon, { color: iconColorValue, name: icon, size: iconSizeValue })) }));
218
+ }, style: { minHeight: 48, minWidth: 48 }, testID: testID, children: loading ? (_jsx(ActivityIndicator, { color: loadingColorValue, size: "small" })) : (_jsx(Icon, { color: iconColorValue, name: icon, size: iconSizeValue })) }));
221
219
  };
222
220
  const ButtonWithIcon = Object.assign(Button, { Icon: ButtonIcon });
223
221
  export default ButtonWithIcon;
@@ -0,0 +1,20 @@
1
+ import { type ReactNode } from "react";
2
+ export interface DockProps {
3
+ primaryAction: ReactNode;
4
+ children: ReactNode;
5
+ summary?: ReactNode;
6
+ title?: string;
7
+ moreLabel?: string;
8
+ collapseLabel?: string;
9
+ backdropLabel?: string;
10
+ expanded?: boolean;
11
+ defaultExpanded?: boolean;
12
+ onExpandedChange?: (expanded: boolean) => void;
13
+ dismissOnBackdrop?: boolean;
14
+ maxExpandedHeightRatio?: number;
15
+ placement?: "fixed" | "footer";
16
+ className?: string;
17
+ testID?: string;
18
+ }
19
+ declare function Dock({ primaryAction, children, summary, title, moreLabel, collapseLabel, backdropLabel, expanded: controlledExpanded, defaultExpanded, onExpandedChange, dismissOnBackdrop, maxExpandedHeightRatio, placement, className, testID, }: DockProps): import("react").JSX.Element;
20
+ export default Dock;
@@ -0,0 +1,89 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "nativewind/jsx-runtime";
2
+ /* eslint-disable react-hooks/refs */
3
+ import Icon from "../Display/Display.Icon.js";
4
+ import Pressable from "../primitives/Pressable.js";
5
+ import { themeToVars, useTheme } from "../theme/index.js";
6
+ import { cn } from "../theme/tw.js";
7
+ import { Typography } from "../Typography/index.js";
8
+ import { useReducedMotion } from "../utils/useReducedMotion.js";
9
+ import { vars } from "nativewind";
10
+ import { useEffect, useRef, useState } from "react";
11
+ import { Animated, KeyboardAvoidingView, Modal, PanResponder, Platform, ScrollView, useWindowDimensions, View, } from "react-native";
12
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
13
+ function Dock({ primaryAction, children, summary, title = "Más opciones", moreLabel = "Más opciones", collapseLabel = "Ocultar opciones", backdropLabel = "Cerrar panel", expanded: controlledExpanded, defaultExpanded = false, onExpandedChange, dismissOnBackdrop = true, maxExpandedHeightRatio = 0.6, placement = "fixed", className, testID, }) {
14
+ const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
15
+ const expanded = controlledExpanded ?? internalExpanded;
16
+ const theme = useTheme();
17
+ const reducedMotion = useReducedMotion();
18
+ const insets = useSafeAreaInsets();
19
+ const { height } = useWindowDimensions();
20
+ const [barHeight, setBarHeight] = useState(0);
21
+ const translateY = useRef(new Animated.Value(0)).current;
22
+ const requestExpanded = (next) => {
23
+ if (next === expanded)
24
+ return;
25
+ if (controlledExpanded === undefined)
26
+ setInternalExpanded(next);
27
+ onExpandedChange?.(next);
28
+ };
29
+ const gestureRef = useRef({ expanded, requestExpanded, reducedMotion });
30
+ gestureRef.current = { expanded, requestExpanded, reducedMotion };
31
+ const resolvedRatio = Number.isFinite(maxExpandedHeightRatio)
32
+ ? Math.min(0.9, Math.max(0.1, maxExpandedHeightRatio))
33
+ : 0.6;
34
+ const maxPanelHeight = Math.max(0, Math.min(height * resolvedRatio, height - insets.top - insets.bottom - barHeight));
35
+ const resetDrag = () => {
36
+ translateY.stopAnimation();
37
+ if (gestureRef.current.reducedMotion) {
38
+ translateY.setValue(0);
39
+ return;
40
+ }
41
+ Animated.spring(translateY, {
42
+ toValue: 0,
43
+ useNativeDriver: true,
44
+ damping: 24,
45
+ stiffness: 260,
46
+ }).start();
47
+ };
48
+ useEffect(() => {
49
+ translateY.stopAnimation();
50
+ translateY.setValue(0);
51
+ return () => translateY.stopAnimation();
52
+ }, [expanded, reducedMotion, translateY]);
53
+ const [pan] = useState(() => PanResponder.create({
54
+ onStartShouldSetPanResponder: () => true,
55
+ onPanResponderGrant: () => translateY.stopAnimation(),
56
+ onPanResponderTerminationRequest: () => false,
57
+ onPanResponderMove: (_, gesture) => {
58
+ if (gestureRef.current.expanded)
59
+ translateY.setValue(Math.max(0, gesture.dy));
60
+ },
61
+ onPanResponderRelease: (_, gesture) => {
62
+ const isVertical = Math.abs(gesture.dy) > Math.abs(gesture.dx);
63
+ const shouldChange = gestureRef.current.expanded
64
+ ? gesture.dy > 40 || gesture.vy > 0.5
65
+ : gesture.dy < -40 || gesture.vy < -0.5;
66
+ if (isVertical && shouldChange) {
67
+ gestureRef.current.requestExpanded(!gestureRef.current.expanded);
68
+ }
69
+ resetDrag();
70
+ },
71
+ onPanResponderTerminate: resetDrag,
72
+ }));
73
+ const handle = (_jsx(View, { className: "min-h-12 items-center justify-center", ...pan.panHandlers, testID: testID ? `${testID}-handle` : undefined, children: _jsx(View, { className: "h-1 w-10 rounded-full bg-border-strong" }) }));
74
+ const bar = (_jsxs(View, { className: cn("gap-3 border-t border-border-light bg-bg-card px-4 pb-2", className), onLayout: (event) => setBarHeight(event.nativeEvent.layout.height), testID: testID ? `${testID}-bar` : undefined, children: [!expanded ? handle : null, summary, _jsxs(View, { className: "flex-row items-center gap-3", children: [_jsxs(Pressable, { accessibilityLabel: expanded ? collapseLabel : moreLabel, accessibilityRole: "button", accessibilityState: { expanded }, className: "min-h-12 flex-1 flex-row items-center justify-center gap-1 rounded-lg bg-bg-muted px-3", onPress: () => requestExpanded(!expanded), testID: testID ? `${testID}-more` : undefined, children: [_jsx(Typography.Text, { className: "text-text-primary", variant: "buttonSmall", children: expanded ? collapseLabel : moreLabel }), _jsx(Icon, { color: theme.icon.secondary, name: expanded ? "chevron-down" : "chevron-up", size: 16 })] }), _jsx(View, { className: "flex-1", children: primaryAction })] })] }));
75
+ return (_jsxs(_Fragment, { children: [_jsx(View, { className: cn(placement === "fixed" && "absolute bottom-0 left-0 right-0 z-20"), style: expanded ? { height: barHeight } : undefined, testID: testID, children: !expanded ? bar : null }), _jsx(Modal, { animationType: "none", onRequestClose: () => requestExpanded(false), presentationStyle: "overFullScreen", testID: testID ? `${testID}-modal` : undefined, transparent: true, visible: expanded, children: _jsx(KeyboardAvoidingView, { behavior: Platform.OS === "ios" ? "padding" : "height", style: { flex: 1 }, testID: testID ? `${testID}-keyboard` : undefined, children: _jsxs(View, { accessibilityViewIsModal: true, style: { flex: 1, justifyContent: "flex-end" }, children: [_jsx(Pressable, { accessibilityLabel: backdropLabel, accessibilityRole: "button", className: "absolute inset-0 bg-black/50", disabled: !dismissOnBackdrop, onPress: dismissOnBackdrop ? () => requestExpanded(false) : undefined, testID: testID ? `${testID}-backdrop` : undefined }), _jsxs(View, { onAccessibilityEscape: () => requestExpanded(false), style: [
76
+ vars(themeToVars(theme)),
77
+ {
78
+ paddingBottom: insets.bottom,
79
+ backgroundColor: theme.bg.card,
80
+ maxHeight: height - insets.top,
81
+ flexShrink: 1,
82
+ },
83
+ ], children: [_jsx(View, { style: { overflow: "hidden", flexShrink: 1 }, children: _jsxs(Animated.View, { style: {
84
+ maxHeight: maxPanelHeight,
85
+ flexShrink: 1,
86
+ transform: [{ translateY }],
87
+ }, testID: testID ? `${testID}-expanded-content` : undefined, children: [handle, _jsxs(ScrollView, { contentContainerStyle: { paddingHorizontal: 16, paddingBottom: 16 }, keyboardShouldPersistTaps: "handled", nestedScrollEnabled: true, style: { flexShrink: 1 }, testID: testID ? `${testID}-scroll` : undefined, children: [title ? (_jsx(Typography.Text, { accessibilityRole: "header", className: "pb-2 text-text-primary", semibold: true, variant: "subtitle", children: title })) : null, children] })] }) }), bar] })] }) }) })] }));
88
+ }
89
+ export default Dock;
@@ -6,7 +6,6 @@ export interface FABProps {
6
6
  className?: string;
7
7
  testID?: string;
8
8
  accessibilityLabel?: string;
9
- accessibleSizing?: boolean;
10
9
  }
11
- declare function FAB({ icon, onPress, label, position, className, testID, accessibilityLabel, accessibleSizing, }: FABProps): import("react").JSX.Element;
10
+ declare function FAB({ icon, onPress, label, position, className, testID, accessibilityLabel, }: FABProps): import("react").JSX.Element;
12
11
  export default FAB;
@@ -5,17 +5,15 @@ import { theme } from "../theme/index.js";
5
5
  import { cn } from "../theme/tw.js";
6
6
  import { Typography } from "../Typography/index.js";
7
7
  import { useSafeAreaInsets } from "react-native-safe-area-context";
8
- function FAB({ icon, onPress, label, position = "bottom-right", className, testID, accessibilityLabel, accessibleSizing = false, }) {
8
+ function FAB({ icon, onPress, label, position = "bottom-right", className, testID, accessibilityLabel, }) {
9
9
  const insets = useSafeAreaInsets();
10
- return (_jsxs(Pressable, { accessibilityLabel: accessibilityLabel ?? label ?? "Acción", accessibilityRole: "button", className: cn("absolute flex-row items-center justify-center rounded-full bg-primary", label
11
- ? accessibleSizing
12
- ? "min-h-14 px-5 py-3 gap-2"
13
- : "h-14 px-5 gap-2"
14
- : "w-14 h-14", className), onPress: onPress, style: {
10
+ return (_jsxs(Pressable, { accessibilityLabel: accessibilityLabel ?? label ?? "Acción", accessibilityRole: "button", className: cn("absolute flex-row items-center justify-center rounded-full bg-primary", label ? "min-h-14 px-5 py-3 gap-2" : "w-14 h-14", className), onPress: onPress, style: {
11
+ minHeight: 56,
12
+ minWidth: 56,
15
13
  bottom: insets.bottom + 16,
16
14
  right: position === "bottom-right" ? 16 : undefined,
17
15
  left: position === "bottom-left" ? 16 : undefined,
18
16
  ...theme.shadow.lg,
19
- }, testID: testID, children: [_jsx(Icon, { color: theme.icon.inverse, name: icon, size: 24 }), label ? (_jsx(Typography.Text, { className: "text-text-on-primary font-semibold", style: accessibleSizing ? { flexShrink: 1 } : undefined, children: label })) : null] }));
17
+ }, testID: testID, children: [_jsx(Icon, { color: theme.icon.inverse, name: icon, size: 24 }), label ? (_jsx(Typography.Text, { className: "text-text-on-primary font-semibold", style: { flexShrink: 1 }, children: label })) : null] }));
20
18
  }
21
19
  export default FAB;
@@ -64,7 +64,6 @@ export interface IconButtonProps extends VariantProps<typeof iconButton>, Access
64
64
  iconColor?: string;
65
65
  className?: string;
66
66
  testID?: string;
67
- accessibleSizing?: boolean;
68
67
  }
69
- declare function IconButton({ icon, type, onPress, variant, size, loading, disabled, rounded, iconColor, className, testID, accessibleSizing, accessibilityState, ...accessibilityProps }: IconButtonProps): import("react").JSX.Element;
68
+ declare function IconButton({ icon, type, onPress, variant, size, loading, disabled, rounded, iconColor, className, testID, accessibilityState, ...accessibilityProps }: IconButtonProps): import("react").JSX.Element;
70
69
  export default IconButton;
@@ -31,12 +31,12 @@ const iconButton = tv({
31
31
  disabled: false,
32
32
  },
33
33
  });
34
- function IconButton({ icon, type = "feather", onPress, variant = "ghost", size = "medium", loading = false, disabled = false, rounded = false, iconColor, className, testID, accessibleSizing = false, accessibilityState, ...accessibilityProps }) {
34
+ function IconButton({ icon, type = "feather", onPress, variant = "ghost", size = "medium", loading = false, disabled = false, rounded = false, iconColor, className, testID, accessibilityState, ...accessibilityProps }) {
35
35
  const resolvedColor = iconColor ?? theme.text.accent;
36
36
  return (_jsx(TouchableOpacity, { activeOpacity: 0.7, className: iconButton({ variant, size, rounded, disabled, className }), disabled: disabled || loading, onPress: onPress, ...accessibilityProps, accessibilityRole: "button", accessibilityState: {
37
37
  ...accessibilityState,
38
38
  disabled: disabled || loading,
39
39
  busy: loading,
40
- }, style: accessibleSizing ? { minHeight: 48, minWidth: 48 } : undefined, testID: testID, children: loading ? (_jsx(ActivityIndicator, { color: resolvedColor, size: "small" })) : (_jsx(Icon, { color: resolvedColor, name: icon, size: 24, type: type })) }));
40
+ }, style: { minHeight: 48, minWidth: 48 }, testID: testID, children: loading ? (_jsx(ActivityIndicator, { color: resolvedColor, size: "small" })) : (_jsx(Icon, { color: resolvedColor, name: icon, size: 24, type: type })) }));
41
41
  }
42
42
  export default IconButton;