@thewhileloop/whileui 2.0.0 → 3.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 (56) hide show
  1. package/README.md +18 -5
  2. package/dist/blocks/commerce/metric-card.d.ts +9 -29
  3. package/dist/blocks/datepicker/date-range-picker-modal.d.ts +1 -1
  4. package/dist/blocks/datepicker/date-range-picker-modal.js +6 -14
  5. package/dist/blocks/datepicker/datepicker-modal.d.ts +1 -1
  6. package/dist/blocks/datepicker/datepicker-modal.js +6 -12
  7. package/dist/blocks/layout/smart-input.d.ts +3 -2
  8. package/dist/blocks/layout/smart-input.js +33 -18
  9. package/dist/blocks/media/smart-image.d.ts +39 -98
  10. package/dist/blocks/navigation/drawer-menu.js +88 -72
  11. package/dist/components/alert/alert.d.ts +23 -55
  12. package/dist/components/alert/alert.js +1 -1
  13. package/dist/components/alert-dialog/alert-dialog.js +1 -4
  14. package/dist/components/avatar/avatar.d.ts +18 -45
  15. package/dist/components/avatar/avatar.js +1 -1
  16. package/dist/components/badge/badge.d.ts +84 -212
  17. package/dist/components/button/button.d.ts +69 -188
  18. package/dist/components/card/card.d.ts +29 -73
  19. package/dist/components/card/card.js +1 -1
  20. package/dist/components/container/container.d.ts +24 -96
  21. package/dist/components/data-row/data-row.d.ts +18 -38
  22. package/dist/components/data-row/data-row.js +1 -1
  23. package/dist/components/form-field/form-field.d.ts +31 -87
  24. package/dist/components/form-field/form-field.js +1 -1
  25. package/dist/components/hover-card/hover-card.d.ts +3 -2
  26. package/dist/components/input/input.d.ts +12 -31
  27. package/dist/components/label/label.d.ts +3 -3
  28. package/dist/components/labeled-field/labeled-field.d.ts +3 -2
  29. package/dist/components/numeric-input/numeric-input.d.ts +27 -82
  30. package/dist/components/numeric-input/numeric-input.js +69 -78
  31. package/dist/components/otp-input/otp-input.d.ts +21 -65
  32. package/dist/components/popover/popover.d.ts +4 -3
  33. package/dist/components/pressable/pressable.d.ts +3 -3
  34. package/dist/components/progress/progress.d.ts +15 -39
  35. package/dist/components/row/row.d.ts +63 -163
  36. package/dist/components/segmented-control/segmented-control.d.ts +69 -241
  37. package/dist/components/select/select.d.ts +10 -22
  38. package/dist/components/select/select.js +2 -2
  39. package/dist/components/separator/separator.d.ts +3 -3
  40. package/dist/components/skeleton/skeleton.d.ts +9 -29
  41. package/dist/components/spinner/spinner.d.ts +12 -36
  42. package/dist/components/stack/stack.d.ts +63 -163
  43. package/dist/components/tabs/tabs.d.ts +9 -29
  44. package/dist/components/text/text.d.ts +51 -131
  45. package/dist/components/textarea/textarea.d.ts +15 -39
  46. package/dist/components/textarea/textarea.js +1 -1
  47. package/dist/components/toast/toast.d.ts +12 -36
  48. package/dist/components/toggle/toggle.d.ts +42 -138
  49. package/dist/components/toggle-group/toggle-group.d.ts +42 -138
  50. package/dist/components/tooltip/tooltip.d.ts +3 -2
  51. package/dist/components/view/view.d.ts +3 -3
  52. package/dist/lib/ref-types.d.ts +3 -0
  53. package/dist/lib/ref-types.js +1 -0
  54. package/dist/lib/theme-bridge.d.ts +4 -2
  55. package/dist/lib/theme-bridge.js +13 -9
  56. package/package.json +29 -28
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Beautiful, accessible, themeable components built with [Uniwind](https://uniwind.dev) + Tailwind CSS v4.
6
6
 
7
- **Requirements:** React 19+, React Native 0.81+, Expo 52+ (if using Expo). Supports React Native Web.
7
+ **Requirements:** React 19.3+, React Native 0.88+, Expo 58+ (if using Expo). Supports React Native Web.
8
8
 
9
9
  WhileUI has one renderer: React Native. iOS, Android and React Native Web are all
10
10
  production targets — iOS and Android set the interaction baseline. See
@@ -15,7 +15,7 @@ production targets — iOS and Android set the interaction baseline. See
15
15
 
16
16
  ```bash
17
17
  bun add @thewhileloop/whileui
18
- bun add react@^19.0.0 react-native@^0.81.0 uniwind@^1.0.0 tailwindcss@^4.0.0 react-native-reanimated react-native-safe-area-context react-native-screens
18
+ bun add react@^19.3.0 react-native@^0.88.0 uniwind@^1.12.2 tailwindcss@^4.0.0 react-native-reanimated react-native-safe-area-context react-native-screens
19
19
  # Only if you use Select, Popover, Tooltip, or HoverCard:
20
20
  bun add @rn-primitives/portal @rn-primitives/hooks @rn-primitives/slot @rn-primitives/select @rn-primitives/popover @rn-primitives/tooltip @rn-primitives/hover-card
21
21
  ```
@@ -851,7 +851,8 @@ Optional RN fallback tokens (hex/rgb/hsl/named):
851
851
  }
852
852
  ```
853
853
 
854
- Or use the first-party ThemeBridge helper with optional persistence:
854
+ Or use the first-party theme bridge with optional persistence. The hook owns theme
855
+ state and exposes event-driven setters:
855
856
 
856
857
  ```tsx
857
858
  import { useThemeBridge, type ThemeBridgeAdapter } from '@thewhileloop/whileui';
@@ -866,6 +867,16 @@ const adapter: ThemeBridgeAdapter = {
866
867
  const { mode, resolvedTheme, setMode, cycleMode } = useThemeBridge({ adapter });
867
868
  ```
868
869
 
870
+ When another store already owns the mode, mount the controlled bridge once near the
871
+ application root. Change `mode` in the owning event handler; the bridge applies and
872
+ persists it without mirroring state back through a callback effect.
873
+
874
+ ```tsx
875
+ import { ThemeBridge } from '@thewhileloop/whileui';
876
+
877
+ <ThemeBridge mode={mode} adapter={adapter} />;
878
+ ```
879
+
869
880
  ## Focus rings
870
881
 
871
882
  Every interactive component draws a themed focus ring on web. It uses `:focus-visible`,
@@ -1550,7 +1561,8 @@ announces as a heading to assistive technology — as do `DropdownMenuLabel` and
1550
1561
 
1551
1562
  ## SignInForm
1552
1563
 
1553
- Copy from `apps/showcase/templates/auth/sign-in-form.tsx`, then:
1564
+ Copy `sign-in-form.tsx` and its sibling `auth-form-footer.tsx` from
1565
+ `apps/showcase/templates/auth/`, then:
1554
1566
 
1555
1567
  ```tsx
1556
1568
  import { SignInForm } from './templates/auth'; // or your path
@@ -1574,7 +1586,8 @@ import { SignInForm } from './templates/auth'; // or your path
1574
1586
 
1575
1587
  ## SignUpForm
1576
1588
 
1577
- Copy from `apps/showcase/templates/auth/sign-up-form.tsx`, then:
1589
+ Copy `sign-up-form.tsx` and its sibling `auth-form-footer.tsx` from
1590
+ `apps/showcase/templates/auth/`, then:
1578
1591
 
1579
1592
  ```tsx
1580
1593
  import { SignUpForm } from './templates/auth'; // or your path
@@ -3,40 +3,20 @@ import { type ViewProps } from 'react-native';
3
3
  import { type VariantProps } from '../../lib/tv';
4
4
  declare const metricCardVariants: import("tailwind-variants").TVReturnType<{
5
5
  variant: {
6
- default: string;
7
- outlined: string;
6
+ default: "bg-card";
7
+ outlined: "bg-transparent border border-border";
8
8
  };
9
- }, undefined, "", import("tailwind-variants/dist/config.js").TVConfig<{
9
+ }, undefined, "", {
10
10
  variant: {
11
- default: string;
12
- outlined: string;
11
+ default: "bg-card";
12
+ outlined: "bg-transparent border border-border";
13
13
  };
14
- }, {
14
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
15
15
  variant: {
16
- default: string;
17
- outlined: string;
16
+ default: "bg-card";
17
+ outlined: "bg-transparent border border-border";
18
18
  };
19
- }>, {
20
- variant: {
21
- default: string;
22
- outlined: string;
23
- };
24
- }, undefined, import("tailwind-variants").TVReturnType<{
25
- variant: {
26
- default: string;
27
- outlined: string;
28
- };
29
- }, undefined, "", import("tailwind-variants/dist/config.js").TVConfig<{
30
- variant: {
31
- default: string;
32
- outlined: string;
33
- };
34
- }, {
35
- variant: {
36
- default: string;
37
- outlined: string;
38
- };
39
- }>, unknown, unknown, undefined>>;
19
+ }, undefined>>;
40
20
  export interface MetricCardProps extends ViewProps, VariantProps<typeof metricCardVariants> {
41
21
  className?: string;
42
22
  label: string;
@@ -29,7 +29,7 @@ export interface DateRangePickerModalProps extends FrostedSurfaceProps {
29
29
  className?: string;
30
30
  }
31
31
  declare function formatRangeDisplay(range: DateRange | null | undefined): string;
32
- export declare function DateRangePickerModal({ value, onValueChange, open, onOpenChange, minDate, maxDate, theme: customTheme, trigger, title, confirmLabel, className, frosted, blurIntensity, blurTintToken, }: DateRangePickerModalProps): React.JSX.Element;
32
+ export declare function DateRangePickerModal(props: DateRangePickerModalProps): React.JSX.Element;
33
33
  /** Compact trigger showing formatted range. Use as DateRangePickerModal's trigger prop. */
34
34
  export declare function DateRangePickerTrigger({ value, placeholder, className, }: {
35
35
  value?: DateRange | null;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { useCallback, useMemo, useState } from 'react';
3
3
  import { Modal, Pressable, View } from 'react-native';
4
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
5
  import { useUniwind } from 'uniwind';
@@ -47,7 +47,7 @@ function buildMarkedDates(start, end, theme) {
47
47
  }
48
48
  return marked;
49
49
  }
50
- export function DateRangePickerModal({ value, onValueChange, open, onOpenChange, minDate, maxDate, theme: customTheme, trigger, title = 'Select date range', confirmLabel = 'Done', className, frosted = false, blurIntensity, blurTintToken, }) {
50
+ function DateRangePickerModalSession({ value, onValueChange, open, onOpenChange, minDate, maxDate, theme: customTheme, trigger, title = 'Select date range', confirmLabel = 'Done', className, frosted = false, blurIntensity, blurTintToken, }) {
51
51
  const insets = useSafeAreaInsets();
52
52
  const { theme } = useUniwind();
53
53
  const colors = useThemeColors();
@@ -68,18 +68,6 @@ export function DateRangePickerModal({ value, onValueChange, open, onOpenChange,
68
68
  const renderArrow = useCallback((direction) => (_jsx(Text, { className: "font-medium", style: { color: arrowColor, fontSize: arrowFontSize }, children: direction === 'left' ? '<' : '>' })), [arrowColor, arrowFontSize]);
69
69
  const [draftStart, setDraftStart] = useState(value?.start ?? null);
70
70
  const [draftEnd, setDraftEnd] = useState(value?.end ?? null);
71
- const prevOpenRef = useRef(open);
72
- useEffect(() => {
73
- if (open && !prevOpenRef.current) {
74
- setDraftStart(value?.start ?? null);
75
- setDraftEnd(value?.end ?? null);
76
- }
77
- else if (!open && prevOpenRef.current) {
78
- setDraftStart(null);
79
- setDraftEnd(null);
80
- }
81
- prevOpenRef.current = open;
82
- }, [open, value]);
83
71
  const markedDates = useMemo(() => {
84
72
  const color = calendarTheme.selectedDayBackgroundColor;
85
73
  const textColor = calendarTheme.selectedDayTextColor;
@@ -151,6 +139,10 @@ export function DateRangePickerModal({ value, onValueChange, open, onOpenChange,
151
139
  borderWidth: visual.borderWidthHairline,
152
140
  }, children: _jsx(Calendar, { current: draftStart ?? value?.start ?? undefined, onDayPress: handleDayPress, markedDates: markedDates, markingType: "period", minDate: minDate, maxDate: maxDate, theme: calendarTheme, renderArrow: renderArrow, enableSwipeMonths: true }, theme) }) })] }) }) })] }));
153
141
  }
142
+ export function DateRangePickerModal(props) {
143
+ const sessionKey = props.open ? 'open' : 'closed';
144
+ return _jsx(DateRangePickerModalSession, { ...props }, sessionKey);
145
+ }
154
146
  /** Compact trigger showing formatted range. Use as DateRangePickerModal's trigger prop. */
155
147
  export function DateRangePickerTrigger({ value, placeholder = 'Select date range', className, }) {
156
148
  const visual = useVisualTokens();
@@ -25,7 +25,7 @@ export interface DatePickerModalProps extends FrostedSurfaceProps {
25
25
  className?: string;
26
26
  }
27
27
  declare function formatDisplayDate(dateString: string | null | undefined): string;
28
- export declare function DatePickerModal({ value, onValueChange, open, onOpenChange, minDate, maxDate, theme: customTheme, trigger, title, confirmLabel, className, frosted, blurIntensity, blurTintToken, }: DatePickerModalProps): React.JSX.Element;
28
+ export declare function DatePickerModal(props: DatePickerModalProps): React.JSX.Element;
29
29
  /** Compact trigger showing formatted date. Use as DatePickerModal's trigger prop. */
30
30
  export declare function DatePickerTrigger({ value, placeholder, className, }: {
31
31
  value?: string | null;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { useCallback, useMemo, useState } from 'react';
3
3
  import { Modal, Pressable, View } from 'react-native';
4
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
5
  import { useUniwind } from 'uniwind';
@@ -23,7 +23,7 @@ function formatDisplayDate(dateString) {
23
23
  year: 'numeric',
24
24
  });
25
25
  }
26
- export function DatePickerModal({ value, onValueChange, open, onOpenChange, minDate, maxDate, theme: customTheme, trigger, title = 'Select date', confirmLabel = 'Done', className, frosted = false, blurIntensity, blurTintToken, }) {
26
+ function DatePickerModalSession({ value, onValueChange, open, onOpenChange, minDate, maxDate, theme: customTheme, trigger, title = 'Select date', confirmLabel = 'Done', className, frosted = false, blurIntensity, blurTintToken, }) {
27
27
  const insets = useSafeAreaInsets();
28
28
  const { theme } = useUniwind();
29
29
  const colors = useThemeColors();
@@ -43,16 +43,6 @@ export function DatePickerModal({ value, onValueChange, open, onOpenChange, minD
43
43
  const arrowFontSize = typographyStyle(visual, 'body').fontSize;
44
44
  const renderArrow = useCallback((direction) => (_jsx(Text, { className: "font-medium", style: { color: arrowColor, fontSize: arrowFontSize }, children: direction === 'left' ? '<' : '>' })), [arrowColor, arrowFontSize]);
45
45
  const [draftDate, setDraftDate] = useState(value ?? null);
46
- const prevOpenRef = useRef(open);
47
- useEffect(() => {
48
- if (open && !prevOpenRef.current) {
49
- setDraftDate(value ?? null);
50
- }
51
- else if (!open && prevOpenRef.current) {
52
- setDraftDate(null);
53
- }
54
- prevOpenRef.current = open;
55
- }, [open, value]);
56
46
  const markedDates = useMemo(() => {
57
47
  if (!draftDate)
58
48
  return undefined;
@@ -95,6 +85,10 @@ export function DatePickerModal({ value, onValueChange, open, onOpenChange, minD
95
85
  borderWidth: visual.borderWidthHairline,
96
86
  }, children: _jsx(Calendar, { current: draftDate ?? value ?? undefined, onDayPress: handleDayPress, markedDates: markedDates, minDate: minDate, maxDate: maxDate, theme: calendarTheme, renderArrow: renderArrow, enableSwipeMonths: true }, theme) }) })] }) }) })] }));
97
87
  }
88
+ export function DatePickerModal(props) {
89
+ const sessionKey = props.open ? 'open' : 'closed';
90
+ return _jsx(DatePickerModalSession, { ...props }, sessionKey);
91
+ }
98
92
  /** Compact trigger showing formatted date. Use as DatePickerModal's trigger prop. */
99
93
  export function DatePickerTrigger({ value, placeholder = 'Select date', className, }) {
100
94
  const visual = useVisualTokens();
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
- import { TextInput, type TextInputProps } from 'react-native';
2
+ import { type TextInputInstance, type TextInputProps } from 'react-native';
3
+ import type { ForwardRefComponent } from '../../lib/ref-types';
3
4
  export interface SmartInputProps extends TextInputProps {
4
5
  /** Left slot: emoji, attach, etc. */
5
6
  leftSlot?: React.ReactNode;
@@ -24,4 +25,4 @@ export interface SmartInputProps extends TextInputProps {
24
25
  placeholderPauseDuration?: number;
25
26
  placeholderClearInterval?: number;
26
27
  }
27
- export declare const SmartInput: React.ForwardRefExoticComponent<SmartInputProps & React.RefAttributes<TextInput>>;
28
+ export declare const SmartInput: ForwardRefComponent<TextInputInstance, SmartInputProps>;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { forwardRef, useEffect, useRef, useState } from 'react';
3
- import { AccessibilityInfo, View, TextInput } from 'react-native';
3
+ import { AccessibilityInfo, View, TextInput, } from 'react-native';
4
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
5
  import { cn } from '../../lib/cn';
6
6
  import { focusRing } from '../../lib/focus-ring';
@@ -79,6 +79,30 @@ function useRotatingPlaceholder({ active, examplesKey, prefix, typingInterval, p
79
79
  }
80
80
  return animatedPlaceholder || prefix;
81
81
  }
82
+ function useSmartInputPlaceholder({ value, defaultValue, placeholder, examples, prefix, typingInterval, pauseDuration, clearInterval, onChangeText, }) {
83
+ const [uncontrolledHasText, setUncontrolledHasText] = useState(() => Boolean(defaultValue));
84
+ const hasText = value !== undefined ? Boolean(value) : uncontrolledHasText;
85
+ const examplesKey = examples?.join(SEPARATOR) ?? '';
86
+ const animatedPlaceholder = useRotatingPlaceholder({
87
+ active: placeholder === undefined && !hasText && Boolean(examplesKey),
88
+ examplesKey,
89
+ prefix,
90
+ typingInterval,
91
+ pauseDuration,
92
+ clearInterval,
93
+ });
94
+ return {
95
+ placeholder: placeholder ?? (hasText || !examplesKey ? undefined : animatedPlaceholder),
96
+ onChangeText: (text) => {
97
+ if (value === undefined)
98
+ setUncontrolledHasText(Boolean(text));
99
+ onChangeText?.(text);
100
+ },
101
+ };
102
+ }
103
+ function SmartInputSlot({ children }) {
104
+ return children ? _jsx(View, { className: "shrink-0", children: children }) : null;
105
+ }
82
106
  export const SmartInput = forwardRef(function SmartInput({ leftSlot, centerSlot, rightSlot, variant = 'bar', className, inputClassName, submitBehavior = 'newline', safeArea = true, placeholderExamples, placeholderPrefix = 'e.g. ', placeholderTypingInterval = 65, placeholderPauseDuration = 2200, placeholderClearInterval = 25, placeholderTextColor, placeholder, value, defaultValue, onChangeText, editable = true, style, ...props }, ref) {
83
107
  const insets = useSafeAreaInsets();
84
108
  const colors = useThemeColors();
@@ -87,22 +111,17 @@ export const SmartInput = forwardRef(function SmartInput({ leftSlot, centerSlot,
87
111
  const bottomPadding = safeArea
88
112
  ? Math.max(insets.bottom, visual.controlPaddingYSm)
89
113
  : visual.controlPaddingYSm;
90
- // When the field is controlled its owner already holds the answer, so derive it rather
91
- // than mirroring it into state — mirroring cost a frame in which the rotating
92
- // placeholder kept animating over text the user had already typed.
93
- const [uncontrolledHasText, setUncontrolledHasText] = useState(() => Boolean(defaultValue));
94
- const hasText = value !== undefined ? Boolean(value) : uncontrolledHasText;
95
- const examplesKey = placeholderExamples?.join(SEPARATOR) ?? '';
96
- const animatePlaceholder = placeholder === undefined && !hasText && Boolean(examplesKey);
97
- const animatedPlaceholder = useRotatingPlaceholder({
98
- active: animatePlaceholder,
99
- examplesKey,
114
+ const placeholderState = useSmartInputPlaceholder({
115
+ value,
116
+ defaultValue,
117
+ placeholder,
118
+ examples: placeholderExamples,
100
119
  prefix: placeholderPrefix,
101
120
  typingInterval: placeholderTypingInterval,
102
121
  pauseDuration: placeholderPauseDuration,
103
122
  clearInterval: placeholderClearInterval,
123
+ onChangeText,
104
124
  });
105
- const resolvedPlaceholder = placeholder ?? (hasText || !examplesKey ? undefined : animatedPlaceholder);
106
125
  return (_jsxs(View, { className: cn('w-full flex-row items-center gap-2 bg-background', variant === 'bar' && 'border-border', variant === 'card' && 'border-border', className), style: [
107
126
  {
108
127
  paddingHorizontal: visual.controlPaddingXSm,
@@ -117,16 +136,12 @@ export const SmartInput = forwardRef(function SmartInput({ leftSlot, centerSlot,
117
136
  ...shadowStyle(visual, colors, 'md'),
118
137
  }
119
138
  : null,
120
- ], children: [leftSlot && _jsx(View, { className: "shrink-0", children: leftSlot }), centerSlot && _jsx(View, { className: "shrink-0", children: centerSlot }), _jsx(TextInput, { ref: ref, style: [
139
+ ], children: [_jsx(SmartInputSlot, { children: leftSlot }), _jsx(SmartInputSlot, { children: centerSlot }), _jsx(TextInput, { ref: ref, style: [
121
140
  controlRecipe(visual, 'default'),
122
141
  typographyStyle(visual, 'label'),
123
142
  variant === 'bar' ? { borderWidth: visual.borderWidthControl } : null,
124
143
  { maxHeight: visual.smartInputMaxHeight },
125
144
  !editable ? { opacity: interaction.disabledOpacity } : null,
126
145
  style,
127
- ], className: cn('flex-1 text-foreground placeholder:text-muted-foreground', focusRing, variant === 'bar' && 'border-border bg-muted', variant === 'card' && 'bg-transparent', inputClassName), multiline: true, submitBehavior: submitBehavior, textAlignVertical: "top", placeholderTextColor: placeholderTextColor ?? colors.placeholder, placeholder: resolvedPlaceholder, value: value, defaultValue: defaultValue, onChangeText: (text) => {
128
- if (value === undefined)
129
- setUncontrolledHasText(Boolean(text));
130
- onChangeText?.(text);
131
- }, editable: editable, ...props }), rightSlot && _jsx(View, { className: "shrink-0", children: rightSlot })] }));
146
+ ], className: cn('flex-1 text-foreground placeholder:text-muted-foreground', focusRing, variant === 'bar' && 'border-border bg-muted', variant === 'card' && 'bg-transparent', inputClassName), multiline: true, submitBehavior: submitBehavior, textAlignVertical: "top", placeholderTextColor: placeholderTextColor ?? colors.placeholder, placeholder: placeholderState.placeholder, value: value, defaultValue: defaultValue, onChangeText: placeholderState.onChangeText, editable: editable, ...props }), _jsx(SmartInputSlot, { children: rightSlot })] }));
132
147
  });
@@ -1,122 +1,63 @@
1
- import React from 'react';
2
- import { View, type ViewProps, type ImageProps as RNImageProps } from 'react-native';
1
+ import { type ViewInstance, type ViewProps } from 'react-native';
2
+ import { type ImageProps } from 'expo-image';
3
3
  import { type VariantProps } from '../../lib/tv';
4
+ import type { ForwardRefComponent } from '../../lib/ref-types';
4
5
  declare const smartImageVariants: import("tailwind-variants").TVReturnType<{
5
6
  radius: {
6
- none: string;
7
- sm: string;
8
- md: string;
9
- lg: string;
10
- xl: string;
11
- full: string;
7
+ none: "";
8
+ sm: "";
9
+ md: "";
10
+ lg: "";
11
+ xl: "";
12
+ full: "rounded-full";
12
13
  };
13
14
  objectFit: {
14
- cover: string;
15
- contain: string;
16
- fill: string;
17
- 'scale-down': string;
15
+ cover: "object-cover";
16
+ contain: "object-contain";
17
+ fill: "object-fill";
18
+ 'scale-down': "object-scale-down";
18
19
  };
19
- }, undefined, "overflow-hidden", import("tailwind-variants/dist/config.js").TVConfig<{
20
+ }, undefined, "overflow-hidden", {
20
21
  radius: {
21
- none: string;
22
- sm: string;
23
- md: string;
24
- lg: string;
25
- xl: string;
26
- full: string;
22
+ none: "";
23
+ sm: "";
24
+ md: "";
25
+ lg: "";
26
+ xl: "";
27
+ full: "rounded-full";
27
28
  };
28
29
  objectFit: {
29
- cover: string;
30
- contain: string;
31
- fill: string;
32
- 'scale-down': string;
30
+ cover: "object-cover";
31
+ contain: "object-contain";
32
+ fill: "object-fill";
33
+ 'scale-down': "object-scale-down";
33
34
  };
34
- }, {
35
+ }, undefined, import("tailwind-variants").TVReturnTypeLike<{
35
36
  radius: {
36
- none: string;
37
- sm: string;
38
- md: string;
39
- lg: string;
40
- xl: string;
41
- full: string;
37
+ none: "";
38
+ sm: "";
39
+ md: "";
40
+ lg: "";
41
+ xl: "";
42
+ full: "rounded-full";
42
43
  };
43
44
  objectFit: {
44
- cover: string;
45
- contain: string;
46
- fill: string;
47
- 'scale-down': string;
45
+ cover: "object-cover";
46
+ contain: "object-contain";
47
+ fill: "object-fill";
48
+ 'scale-down': "object-scale-down";
48
49
  };
49
- }>, {
50
- radius: {
51
- none: string;
52
- sm: string;
53
- md: string;
54
- lg: string;
55
- xl: string;
56
- full: string;
57
- };
58
- objectFit: {
59
- cover: string;
60
- contain: string;
61
- fill: string;
62
- 'scale-down': string;
63
- };
64
- }, undefined, import("tailwind-variants").TVReturnType<{
65
- radius: {
66
- none: string;
67
- sm: string;
68
- md: string;
69
- lg: string;
70
- xl: string;
71
- full: string;
72
- };
73
- objectFit: {
74
- cover: string;
75
- contain: string;
76
- fill: string;
77
- 'scale-down': string;
78
- };
79
- }, undefined, "overflow-hidden", import("tailwind-variants/dist/config.js").TVConfig<{
80
- radius: {
81
- none: string;
82
- sm: string;
83
- md: string;
84
- lg: string;
85
- xl: string;
86
- full: string;
87
- };
88
- objectFit: {
89
- cover: string;
90
- contain: string;
91
- fill: string;
92
- 'scale-down': string;
93
- };
94
- }, {
95
- radius: {
96
- none: string;
97
- sm: string;
98
- md: string;
99
- lg: string;
100
- xl: string;
101
- full: string;
102
- };
103
- objectFit: {
104
- cover: string;
105
- contain: string;
106
- fill: string;
107
- 'scale-down': string;
108
- };
109
- }>, unknown, unknown, undefined>>;
50
+ }, undefined>>;
110
51
  export interface SmartImageProps extends Omit<ViewProps, 'className'>, VariantProps<typeof smartImageVariants> {
111
52
  className?: string;
112
- source: RNImageProps['source'];
53
+ source: ImageProps['source'];
113
54
  alt: string;
114
55
  skeleton?: boolean;
115
56
  skeletonClassName?: string;
116
57
  transition?: number;
117
58
  onLoad?: () => void;
118
59
  onError?: () => void;
119
- fallbackSource?: RNImageProps['source'];
60
+ fallbackSource?: ImageProps['source'];
120
61
  }
121
- declare const SmartImage: React.ForwardRefExoticComponent<SmartImageProps & React.RefAttributes<View>>;
62
+ declare const SmartImage: ForwardRefComponent<ViewInstance, SmartImageProps>;
122
63
  export { SmartImage, smartImageVariants };