@platform-blocks/ui 0.7.3 → 0.8.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.
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { TextInputProps, ViewStyle, StyleProp } from 'react-native';
2
+ import { TextInputProps, TextInputProps as RNTextInputProps, ViewStyle, StyleProp } from 'react-native';
3
3
  import { SpacingProps, LayoutProps } from '../../core/utils';
4
4
  import type { SizeValue } from '../../core/theme/types';
5
5
  import type { RadiusValue } from '../../core/theme/radius';
@@ -109,6 +109,34 @@ export interface AutoCompleteProps extends SpacingProps, LayoutProps {
109
109
  minWidth?: number;
110
110
  /** Additional TextInput props */
111
111
  textInputProps?: Omit<TextInputProps, 'value' | 'onChangeText' | 'placeholder'>;
112
+ /** Text auto-capitalization behavior */
113
+ autoCapitalize?: RNTextInputProps['autoCapitalize'];
114
+ /** Whether to enable auto-correct */
115
+ autoCorrect?: boolean;
116
+ /** Whether to auto-focus on mount */
117
+ autoFocus?: boolean;
118
+ /** Return key type for soft keyboard */
119
+ returnKeyType?: RNTextInputProps['returnKeyType'];
120
+ /** Whether to blur on submit */
121
+ blurOnSubmit?: boolean;
122
+ /** Select all text on focus */
123
+ selectTextOnFocus?: boolean;
124
+ /** iOS text content type for autofill */
125
+ textContentType?: RNTextInputProps['textContentType'];
126
+ /** Text alignment */
127
+ textAlign?: RNTextInputProps['textAlign'];
128
+ /** Whether spell check is enabled */
129
+ spellCheck?: boolean;
130
+ /** Input mode (modern alternative to keyboardType) */
131
+ inputMode?: RNTextInputProps['inputMode'];
132
+ /** Enter key hint */
133
+ enterKeyHint?: RNTextInputProps['enterKeyHint'];
134
+ /** Color of the text selection handles and highlight */
135
+ selectionColor?: string;
136
+ /** Whether to show the soft keyboard on focus */
137
+ showSoftInputOnFocus?: boolean;
138
+ /** Whether the field is editable */
139
+ editable?: boolean;
112
140
  /** Placement preference for the suggestions dropdown (default: 'bottom-start') */
113
141
  placement?: 'auto' | 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end';
114
142
  /** Enable flipping to opposite side when dropdown would go off-screen (default: true) */
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { KeyboardTypeOptions, TextInputProps } from 'react-native';
2
+ import { KeyboardTypeOptions, TextInputProps as RNTextInputProps } from 'react-native';
3
3
  import { SpacingProps } from '../../core/theme/types';
4
4
  import { LayoutProps } from '../../core/utils';
5
5
  import { BorderRadiusProps } from '../../core/theme/radius';
@@ -75,7 +75,7 @@ export interface BaseInputProps extends SpacingProps, LayoutProps, BorderRadiusP
75
75
  /** Identifier used with KeyboardManagerProvider to request refocus */
76
76
  keyboardFocusId?: string;
77
77
  }
78
- export type ExtendedTextInputProps = Omit<TextInputProps, keyof BaseInputProps> & {
78
+ export type ExtendedTextInputProps = Omit<RNTextInputProps, keyof BaseInputProps> & {
79
79
  onKeyDown?: (event: any) => void;
80
80
  onKeyUp?: (event: any) => void;
81
81
  };
@@ -104,6 +104,34 @@ export interface InputProps extends BaseInputProps {
104
104
  textInputProps?: ExtendedTextInputProps;
105
105
  /** Ref to underlying TextInput (focus control) */
106
106
  inputRef?: React.Ref<any>;
107
+ /** Text auto-capitalization behavior */
108
+ autoCapitalize?: RNTextInputProps['autoCapitalize'];
109
+ /** Whether to enable auto-correct */
110
+ autoCorrect?: boolean;
111
+ /** Whether to auto-focus on mount */
112
+ autoFocus?: boolean;
113
+ /** Return key type for soft keyboard */
114
+ returnKeyType?: RNTextInputProps['returnKeyType'];
115
+ /** Whether to blur on submit */
116
+ blurOnSubmit?: boolean;
117
+ /** Select all text on focus */
118
+ selectTextOnFocus?: boolean;
119
+ /** iOS text content type for autofill */
120
+ textContentType?: RNTextInputProps['textContentType'];
121
+ /** Text alignment */
122
+ textAlign?: RNTextInputProps['textAlign'];
123
+ /** Whether spell check is enabled */
124
+ spellCheck?: boolean;
125
+ /** Input mode (modern alternative to keyboardType) */
126
+ inputMode?: RNTextInputProps['inputMode'];
127
+ /** Hint for the enter key */
128
+ enterKeyHint?: RNTextInputProps['enterKeyHint'];
129
+ /** Color of the text selection handles and highlight */
130
+ selectionColor?: string;
131
+ /** Whether to show the soft keyboard on focus */
132
+ showSoftInputOnFocus?: boolean;
133
+ /** Whether the field is read-only (alias for !editable) */
134
+ editable?: boolean;
107
135
  }
108
136
  export interface PasswordInputProps extends Omit<InputProps, 'type' | 'secureTextEntry'> {
109
137
  /** Whether to show password strength indicator */
@@ -23,4 +23,26 @@ export interface KeyboardAwareLayoutProps extends SpacingProps, Omit<KeyboardAvo
23
23
  scrollRef?: React.Ref<ScrollView>;
24
24
  /** Additional props that will be spread onto the internal ScrollView */
25
25
  scrollViewProps?: ScrollViewProps;
26
+ /** Whether scrolling is enabled */
27
+ scrollEnabled?: boolean;
28
+ /** Whether the scroll view bounces past the edge of content (iOS) */
29
+ bounces?: boolean;
30
+ /** Scroll event callback */
31
+ onScroll?: ScrollViewProps['onScroll'];
32
+ /** Throttle interval for scroll events in ms */
33
+ scrollEventThrottle?: number;
34
+ /** Callback when momentum scroll begins */
35
+ onMomentumScrollBegin?: ScrollViewProps['onMomentumScrollBegin'];
36
+ /** Callback when momentum scroll ends */
37
+ onMomentumScrollEnd?: ScrollViewProps['onMomentumScrollEnd'];
38
+ /** Whether to show the vertical scroll indicator */
39
+ showsVerticalScrollIndicator?: boolean;
40
+ /** Whether to show the horizontal scroll indicator */
41
+ showsHorizontalScrollIndicator?: boolean;
42
+ /** Deceleration rate ('normal' | 'fast' | number) */
43
+ decelerationRate?: ScrollViewProps['decelerationRate'];
44
+ /** Over-scroll mode for Android */
45
+ overScrollMode?: ScrollViewProps['overScrollMode'];
46
+ /** Pull-to-refresh control */
47
+ refreshControl?: ScrollViewProps['refreshControl'];
26
48
  }
@@ -1,6 +1,6 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { ViewStyle, StyleProp } from 'react-native';
3
- import type { FlashListProps } from '@shopify/flash-list';
3
+ import type { FlashListProps, ViewToken } from '@shopify/flash-list';
4
4
  import type { SpacingProps } from '../../core/utils/spacing';
5
5
  import type { SizeValue } from '../../core/theme/sizes';
6
6
  export interface MasonryItem {
@@ -36,4 +36,31 @@ export interface MasonryProps extends SpacingProps {
36
36
  emptyContent?: ReactNode;
37
37
  /** Flash list props to pass through */
38
38
  flashListProps?: Partial<Omit<FlashListProps<MasonryItem>, 'data' | 'renderItem' | 'numColumns'>>;
39
+ /** Callback when the end of the list is reached (for pagination / infinite scroll) */
40
+ onEndReached?: ((info: {
41
+ distanceFromEnd: number;
42
+ }) => void) | null;
43
+ /** Distance from end (in pixels) to trigger onEndReached (default: FlashList default) */
44
+ onEndReachedThreshold?: number;
45
+ /** Callback when viewable items change */
46
+ onViewableItemsChanged?: ((info: {
47
+ viewableItems: ViewToken<MasonryItem>[];
48
+ changed: ViewToken<MasonryItem>[];
49
+ }) => void) | null;
50
+ /** Whether scrolling is enabled */
51
+ scrollEnabled?: boolean;
52
+ /** Component rendered when the list is empty */
53
+ ListEmptyComponent?: React.ComponentType<any> | React.ReactElement | null;
54
+ /** Component rendered at the bottom of the list */
55
+ ListFooterComponent?: React.ComponentType<any> | React.ReactElement | null;
56
+ /** Component rendered at the top of the list */
57
+ ListHeaderComponent?: React.ComponentType<any> | React.ReactElement | null;
58
+ /** Estimated size of each item (performance hint) */
59
+ estimatedItemSize?: number;
60
+ /** Pull-to-refresh control */
61
+ refreshControl?: React.ReactElement;
62
+ /** Scroll event callback */
63
+ onScroll?: FlashListProps<MasonryItem>['onScroll'];
64
+ /** Throttle interval for scroll events in ms */
65
+ scrollEventThrottle?: number;
39
66
  }
@@ -1,3 +1,4 @@
1
+ import { TextInputProps as RNTextInputProps } from 'react-native';
1
2
  import { BaseInputProps, ExtendedTextInputProps } from '../Input/types';
2
3
  export interface NumberInputProps extends Omit<BaseInputProps, 'value' | 'onChangeText'> {
3
4
  /** Number value */
@@ -80,6 +81,34 @@ export interface NumberInputProps extends Omit<BaseInputProps, 'value' | 'onChan
80
81
  allowEmpty?: boolean;
81
82
  /** Additional TextInput props */
82
83
  textInputProps?: ExtendedTextInputProps;
84
+ /** Text auto-capitalization behavior */
85
+ autoCapitalize?: RNTextInputProps['autoCapitalize'];
86
+ /** Whether to enable auto-correct */
87
+ autoCorrect?: boolean;
88
+ /** Whether to auto-focus on mount */
89
+ autoFocus?: boolean;
90
+ /** Return key type for soft keyboard */
91
+ returnKeyType?: RNTextInputProps['returnKeyType'];
92
+ /** Whether to blur on submit */
93
+ blurOnSubmit?: boolean;
94
+ /** Select all text on focus */
95
+ selectTextOnFocus?: boolean;
96
+ /** iOS text content type for autofill */
97
+ textContentType?: RNTextInputProps['textContentType'];
98
+ /** Text alignment */
99
+ textAlign?: RNTextInputProps['textAlign'];
100
+ /** Whether spell check is enabled */
101
+ spellCheck?: boolean;
102
+ /** Input mode (modern alternative to keyboardType) */
103
+ inputMode?: RNTextInputProps['inputMode'];
104
+ /** Enter key hint */
105
+ enterKeyHint?: RNTextInputProps['enterKeyHint'];
106
+ /** Color of the text selection handles and highlight */
107
+ selectionColor?: string;
108
+ /** Whether to show the soft keyboard on focus */
109
+ showSoftInputOnFocus?: boolean;
110
+ /** Whether the field is editable */
111
+ editable?: boolean;
83
112
  }
84
113
  export interface NumberInputStyleProps {
85
114
  error?: boolean;
@@ -6,7 +6,7 @@ export interface OverlayProps extends Omit<ViewProps, 'style'> {
6
6
  color?: string;
7
7
  /** Opacity applied to the background color. Defaults to 0.6. */
8
8
  opacity?: number;
9
- /** Mantine-compatible alias for `opacity`. */
9
+ /** Opacity applied to the entire overlay, including gradients and blur effects. Defaults to 1. */
10
10
  backgroundOpacity?: number;
11
11
  /** Web-only CSS gradient string. Falls back to `color` on native platforms. */
12
12
  gradient?: string;
@@ -1,4 +1,4 @@
1
- import { TextInputProps } from 'react-native';
1
+ import { TextInputProps, TextInputProps as RNTextInputProps } from 'react-native';
2
2
  import { BaseInputProps } from '../Input/types';
3
3
  export interface PinInputProps extends Omit<BaseInputProps, 'value' | 'onChangeText'> {
4
4
  /** Number of PIN digits */
@@ -33,6 +33,24 @@ export interface PinInputProps extends Omit<BaseInputProps, 'value' | 'onChangeT
33
33
  onComplete?: (pin: string) => void;
34
34
  /** Additional TextInput props for each input */
35
35
  textInputProps?: Omit<TextInputProps, keyof BaseInputProps>;
36
+ /** Text auto-capitalization behavior */
37
+ autoCapitalize?: RNTextInputProps['autoCapitalize'];
38
+ /** Whether to enable auto-correct */
39
+ autoCorrect?: boolean;
40
+ /** Whether to auto-focus on first input on mount */
41
+ autoFocus?: boolean;
42
+ /** Select all text on focus */
43
+ selectTextOnFocus?: boolean;
44
+ /** iOS text content type for autofill */
45
+ textContentType?: RNTextInputProps['textContentType'];
46
+ /** Text alignment */
47
+ textAlign?: RNTextInputProps['textAlign'];
48
+ /** Whether spell check is enabled */
49
+ spellCheck?: boolean;
50
+ /** Color of the text selection handles and highlight */
51
+ selectionColor?: string;
52
+ /** Whether to show the soft keyboard on focus */
53
+ showSoftInputOnFocus?: boolean;
36
54
  }
37
55
  export interface PinInputStyleProps {
38
56
  error?: boolean;
@@ -1,4 +1,4 @@
1
- import { TextInputProps } from 'react-native';
1
+ import { TextInputProps, TextInputProps as RNTextInputProps } from 'react-native';
2
2
  import { BaseInputProps } from '../Input/types';
3
3
  import { SizeValue } from '../../core/theme/types';
4
4
  export interface TextAreaProps extends BaseInputProps {
@@ -22,6 +22,36 @@ export interface TextAreaProps extends BaseInputProps {
22
22
  resize?: 'none' | 'vertical' | 'horizontal' | 'both';
23
23
  /** Additional TextInput props */
24
24
  textInputProps?: Omit<TextInputProps, keyof BaseInputProps>;
25
+ /** Text auto-capitalization behavior */
26
+ autoCapitalize?: RNTextInputProps['autoCapitalize'];
27
+ /** Whether to enable auto-correct */
28
+ autoCorrect?: boolean;
29
+ /** Whether to auto-focus on mount */
30
+ autoFocus?: boolean;
31
+ /** Return key type for soft keyboard */
32
+ returnKeyType?: RNTextInputProps['returnKeyType'];
33
+ /** Whether to blur on submit */
34
+ blurOnSubmit?: boolean;
35
+ /** Select all text on focus */
36
+ selectTextOnFocus?: boolean;
37
+ /** iOS text content type for autofill */
38
+ textContentType?: RNTextInputProps['textContentType'];
39
+ /** Text alignment */
40
+ textAlign?: RNTextInputProps['textAlign'];
41
+ /** Whether spell check is enabled */
42
+ spellCheck?: boolean;
43
+ /** Input mode (modern alternative to keyboardType) */
44
+ inputMode?: RNTextInputProps['inputMode'];
45
+ /** Enter key hint */
46
+ enterKeyHint?: RNTextInputProps['enterKeyHint'];
47
+ /** Color of the text selection handles and highlight */
48
+ selectionColor?: string;
49
+ /** Whether to show the soft keyboard on focus */
50
+ showSoftInputOnFocus?: boolean;
51
+ /** Whether the field is editable */
52
+ editable?: boolean;
53
+ /** Whether scroll is enabled (multiline) */
54
+ scrollEnabled?: boolean;
25
55
  }
26
56
  export interface TextAreaStyleProps {
27
57
  size: SizeValue;
@@ -1,4 +1,4 @@
1
1
  export type { Factory, FactoryPayload, PlatformBlocksComponent, FactoryOptions } from './factory';
2
2
  export { factory } from './factory';
3
- export type { PolymorphicFactory, PolymorphicFactoryPayload, PolymorphicComponent, PolymorphicComponentProps, PolymorphicRef } from './polymorphicFactory';
3
+ export type { PolymorphicFactory, PolymorphicFactoryPayload, PolymorphicFactoryOptions, PolymorphicComponent, PolymorphicComponentProps, PolymorphicRef } from './polymorphicFactory';
4
4
  export { polymorphicFactory, createPolymorphicComponent } from './polymorphicFactory';
@@ -23,10 +23,18 @@ export interface PolymorphicComponent<Payload extends PolymorphicFactoryPayload>
23
23
  extend: any;
24
24
  displayName?: string;
25
25
  }
26
+ export interface PolymorphicFactoryOptions {
27
+ /** Optional display name applied to the resulting component */
28
+ displayName?: string;
29
+ /** Enable or disable memoization. Defaults to `true`. */
30
+ memo?: boolean;
31
+ /** Optional custom comparison used when memoization is enabled */
32
+ arePropsEqual?: (prevProps: Readonly<any>, nextProps: Readonly<any>) => boolean;
33
+ }
26
34
  /**
27
35
  * Factory function for creating polymorphic PlatformBlocks components
28
36
  */
29
- export declare function polymorphicFactory<Payload extends PolymorphicFactoryPayload>(ui: React.ForwardRefRenderFunction<Payload['defaultRef'], Payload['props']>): PolymorphicComponent<Payload>;
37
+ export declare function polymorphicFactory<Payload extends PolymorphicFactoryPayload>(ui: React.ForwardRefRenderFunction<Payload['defaultRef'], Payload['props']>, options?: PolymorphicFactoryOptions): PolymorphicComponent<Payload>;
30
38
  /**
31
39
  * Creates a polymorphic component from a regular component
32
40
  */
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  export type Breakpoint = 'base' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
2
3
  declare const BREAKPOINTS: {
3
4
  readonly base: 0;
@@ -11,6 +12,14 @@ export type ResponsiveValue<T> = T | Partial<Record<Breakpoint, T>>;
11
12
  export type ResponsiveSize = ResponsiveValue<number>;
12
13
  export type ResponsiveString = ResponsiveValue<string>;
13
14
  export type ResponsiveBoolean = ResponsiveValue<boolean>;
15
+ /**
16
+ * Provider that maintains a single resize / Dimensions listener and shares
17
+ * the current breakpoint with all descendants via context.
18
+ * Mount once near the root of the app (PlatformBlocksProvider does this automatically).
19
+ */
20
+ declare function BreakpointProvider({ children }: {
21
+ children: React.ReactNode;
22
+ }): React.FunctionComponentElement<React.ProviderProps<Breakpoint | null>>;
14
23
  declare const useBreakpoint: () => Breakpoint;
15
24
  declare const useIsMobile: () => boolean;
16
25
  declare const resolveResponsiveValue: <T>(value: ResponsiveValue<T>, currentBreakpoint: Breakpoint) => T;
@@ -19,4 +28,4 @@ declare const createResponsiveStyle: <T extends Record<string, any>>(styleValue:
19
28
  declare const isResponsiveValue: <T>(value: ResponsiveValue<T>) => value is Partial<Record<Breakpoint, T>>;
20
29
  declare const createResponsiveCSS: <T>(property: string, value: ResponsiveValue<T>, unit?: string) => Record<string, any>;
21
30
  declare const getResponsiveSpacing: (value: ResponsiveValue<number | string>, breakpoint: Breakpoint, multiplier?: number) => number;
22
- export { BREAKPOINTS, useBreakpoint, useIsMobile, resolveResponsiveValue, useResponsiveValue, createResponsiveStyle, isResponsiveValue, createResponsiveCSS, getResponsiveSpacing, };
31
+ export { BREAKPOINTS, BreakpointProvider, useBreakpoint, useIsMobile, resolveResponsiveValue, useResponsiveValue, createResponsiveStyle, isResponsiveValue, createResponsiveCSS, getResponsiveSpacing, };
@@ -14,7 +14,8 @@ export interface StyleFactoryConfig {
14
14
  radius?: any;
15
15
  }
16
16
  /**
17
- * Base component style factory
17
+ * Base component style factory — now backed by a bounded cache.
18
+ * Repeated calls with identical theme + config return the same object reference.
18
19
  */
19
20
  export declare function createComponentStyles(theme: PlatformBlocksTheme, config: StyleFactoryConfig): {
20
21
  container: ViewStyle;
@@ -1,5 +1,24 @@
1
1
  import React from 'react';
2
2
  import { PlatformBlocksTheme, PlatformBlocksThemeOverride } from './types';
3
+ /** Visual slice: colors, text, backgrounds, interactive states, colorScheme */
4
+ export interface ThemeVisuals {
5
+ colorScheme: PlatformBlocksTheme['colorScheme'];
6
+ primaryColor: PlatformBlocksTheme['primaryColor'];
7
+ colors: PlatformBlocksTheme['colors'];
8
+ text: PlatformBlocksTheme['text'];
9
+ backgrounds: PlatformBlocksTheme['backgrounds'];
10
+ states: PlatformBlocksTheme['states'];
11
+ }
12
+ /** Layout / token slice: font, spacing, radii, shadows, breakpoints */
13
+ export interface ThemeLayout {
14
+ fontFamily: PlatformBlocksTheme['fontFamily'];
15
+ fontSizes: PlatformBlocksTheme['fontSizes'];
16
+ spacing: PlatformBlocksTheme['spacing'];
17
+ radii: PlatformBlocksTheme['radii'];
18
+ shadows: PlatformBlocksTheme['shadows'];
19
+ breakpoints: PlatformBlocksTheme['breakpoints'];
20
+ designTokens: PlatformBlocksTheme['designTokens'];
21
+ }
3
22
  export interface PlatformBlocksThemeProviderProps {
4
23
  /** Theme override object */
5
24
  theme?: PlatformBlocksThemeOverride;
@@ -10,9 +29,19 @@ export interface PlatformBlocksThemeProviderProps {
10
29
  }
11
30
  export declare function PlatformBlocksThemeProvider({ theme, inherit, children }: PlatformBlocksThemeProviderProps): React.JSX.Element;
12
31
  /**
13
- * Hook to access the current theme
32
+ * Hook to access the current theme (full object — backwards compatible)
14
33
  */
15
34
  export declare function useTheme(): PlatformBlocksTheme;
35
+ /**
36
+ * Granular hook: subscribe only to visual / color-related properties.
37
+ * Components using this will NOT re-render when layout tokens change.
38
+ */
39
+ export declare function useThemeVisuals(): ThemeVisuals;
40
+ /**
41
+ * Granular hook: subscribe only to layout / token properties.
42
+ * Components using this will NOT re-render when colors change.
43
+ */
44
+ export declare function useThemeLayout(): ThemeLayout;
16
45
  /**
17
46
  * Hook that safely returns theme or default theme
18
47
  */