@platform-blocks/ui 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,18 @@
1
1
  import React from 'react';
2
- import type { DocumentPickerAsset } from 'expo-document-picker';
3
2
  import { BaseInputProps } from '../Input/types';
3
+ export interface DocumentPickerAssetLike {
4
+ uri?: string | null;
5
+ name?: string | null;
6
+ size?: number | null;
7
+ mimeType?: string | null;
8
+ type?: string | null;
9
+ file?: File;
10
+ fileCopyUri?: string | null;
11
+ [key: string]: any;
12
+ }
4
13
  export interface FileInputFile {
5
14
  /** File object or document picker asset */
6
- file: File | DocumentPickerAsset;
15
+ file: File | DocumentPickerAssetLike;
7
16
  /** Unique identifier */
8
17
  id: string;
9
18
  /** File name */
@@ -54,7 +63,7 @@ export interface FileInputProps extends BaseInputProps {
54
63
  /** Whether to enable drag and drop */
55
64
  enableDragDrop?: boolean;
56
65
  /** Custom validation function */
57
- validateFile?: (file: File | DocumentPickerAsset) => string | null;
66
+ validateFile?: (file: File | DocumentPickerAssetLike) => string | null;
58
67
  /** Image preview settings */
59
68
  imagePreview?: {
60
69
  /** Enable image previews */
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { HighlightProps } from './types';
3
+ export declare const Highlight: React.FC<HighlightProps>;
4
+ export default Highlight;
@@ -0,0 +1,3 @@
1
+ export { Highlight } from './Highlight';
2
+ export type { HighlightProps } from './types';
3
+ export { Highlight as default } from './Highlight';
@@ -0,0 +1,24 @@
1
+ import type { TextProps } from '../Text/Text';
2
+ import type { PlatformBlocksTheme } from '../../core/theme/types';
3
+ export type HighlightValue = string | number;
4
+ export interface HighlightProps extends TextProps {
5
+ /** Substring or substrings to emphasize within the provided children */
6
+ highlight?: HighlightValue | HighlightValue[];
7
+ /**
8
+ * Optional override for the highlighted segment styles. Accepts either a style object/array
9
+ * or a callback that receives the current theme and returns styles.
10
+ */
11
+ highlightStyles?: any | ((theme: PlatformBlocksTheme) => any);
12
+ /**
13
+ * When provided, overrides the default highlight background/text palette. If the value matches
14
+ * a key from the theme color palettes it will use the related swatch, otherwise the value is
15
+ * treated as a raw color string.
16
+ */
17
+ highlightColor?: string;
18
+ /** Toggle case-sensitive matching (defaults to case-insensitive). */
19
+ caseSensitive?: boolean;
20
+ /** Trim highlight values before matching to ignore accidental whitespace. Defaults to true. */
21
+ trim?: boolean;
22
+ /** Additional props applied to the highlighted Text nodes. */
23
+ highlightProps?: Partial<TextProps>;
24
+ }
@@ -1,4 +1,6 @@
1
1
  import React from 'react';
2
+ import { View } from 'react-native';
3
+ import type { PressableProps } from 'react-native';
2
4
  import type { GestureResponderEvent } from 'react-native';
3
5
  import { SpacingProps } from '../../core/utils';
4
6
  export interface MenuItemButtonProps extends SpacingProps {
@@ -34,6 +36,32 @@ export interface MenuItemButtonProps extends SpacingProps {
34
36
  onPressOut?: (event: GestureResponderEvent) => void;
35
37
  /** Web-only mouse down handler */
36
38
  onMouseDown?: (event: any) => void;
39
+ /** Web-only mouse enter handler */
40
+ onMouseEnter?: (event: any) => void;
41
+ /** Web-only mouse leave handler */
42
+ onMouseLeave?: (event: any) => void;
43
+ /** Pointer hover start handler (web) */
44
+ onHoverIn?: PressableProps['onHoverIn'];
45
+ /** Pointer hover end handler (web) */
46
+ onHoverOut?: PressableProps['onHoverOut'];
47
+ /** Focus handler */
48
+ onFocus?: PressableProps['onFocus'];
49
+ /** Blur handler */
50
+ onBlur?: PressableProps['onBlur'];
51
+ /** Semantic tone for menu styling */
52
+ tone?: 'default' | 'danger' | 'success' | 'warning';
53
+ /** Tone to apply when hovered */
54
+ hoverTone?: 'default' | 'danger' | 'success' | 'warning';
55
+ /** Tone to apply when active/pressed */
56
+ activeTone?: 'default' | 'danger' | 'success' | 'warning';
57
+ /** Override text color for base state */
58
+ textColor?: string;
59
+ /** Override text color when hovered */
60
+ hoverTextColor?: string;
61
+ /** Override text color when active */
62
+ activeTextColor?: string;
63
+ /** Test identifier forwarded to Pressable */
64
+ testID?: string;
37
65
  }
38
- export declare const MenuItemButton: React.FC<MenuItemButtonProps>;
66
+ export declare const MenuItemButton: React.ForwardRefExoticComponent<MenuItemButtonProps & React.RefAttributes<View>>;
39
67
  export default MenuItemButton;
@@ -0,0 +1,14 @@
1
+ import { View } from 'react-native';
2
+ import type { PopoverProps, PopoverTargetProps, PopoverDropdownProps } from './types';
3
+ export declare const Popover: import("../../core/factory").PlatformBlocksComponent<{
4
+ props: PopoverProps;
5
+ ref: View;
6
+ }>;
7
+ export declare const PopoverTarget: import("../../core/factory").PlatformBlocksComponent<{
8
+ props: PopoverTargetProps;
9
+ ref: View;
10
+ }>;
11
+ export declare const PopoverDropdown: import("../../core/factory").PlatformBlocksComponent<{
12
+ props: PopoverDropdownProps;
13
+ ref: View;
14
+ }>;
@@ -0,0 +1,2 @@
1
+ export { Popover, PopoverTarget, PopoverDropdown } from './Popover';
2
+ export type { PopoverProps, PopoverTargetProps, PopoverDropdownProps } from './types';
@@ -0,0 +1,66 @@
1
+ import type { PlatformBlocksTheme } from '../../core/theme/types';
2
+ import type { RadiusValue } from '../../core/theme/radius';
3
+ import type { ShadowValue } from '../../core/theme/shadow';
4
+ interface CreateStylesParams {
5
+ radius?: RadiusValue | number;
6
+ shadow?: ShadowValue;
7
+ arrowSize: number;
8
+ }
9
+ export declare const createPopoverStyles: (theme: PlatformBlocksTheme) => (params: CreateStylesParams) => {
10
+ wrapper: {
11
+ boxShadow?: undefined;
12
+ shadowOffset?: undefined;
13
+ shadowRadius?: undefined;
14
+ shadowColor?: undefined;
15
+ shadowOpacity?: undefined;
16
+ elevation?: undefined;
17
+ position: "relative";
18
+ alignSelf: "flex-start";
19
+ overflow: "visible";
20
+ } | {
21
+ boxShadow: string;
22
+ shadowOffset?: undefined;
23
+ shadowRadius?: undefined;
24
+ shadowColor?: undefined;
25
+ shadowOpacity?: undefined;
26
+ elevation?: undefined;
27
+ position: "relative";
28
+ alignSelf: "flex-start";
29
+ overflow: "visible";
30
+ } | {
31
+ shadowOffset: {
32
+ width: number;
33
+ height: number;
34
+ };
35
+ shadowRadius: number;
36
+ shadowColor: string;
37
+ shadowOpacity: number;
38
+ elevation: number;
39
+ boxShadow?: undefined;
40
+ position: "relative";
41
+ alignSelf: "flex-start";
42
+ overflow: "visible";
43
+ };
44
+ dropdown: {
45
+ overflow: "hidden";
46
+ minWidth: number;
47
+ borderRadius: number;
48
+ borderTopLeftRadius: number;
49
+ borderTopRightRadius: number;
50
+ borderBottomLeftRadius: number;
51
+ borderBottomRightRadius: number;
52
+ backgroundColor: string;
53
+ borderColor: string;
54
+ borderWidth: number;
55
+ };
56
+ arrow: {
57
+ position: "absolute";
58
+ width: number;
59
+ height: number;
60
+ backgroundColor: string;
61
+ transform: {
62
+ rotate: string;
63
+ }[];
64
+ };
65
+ };
66
+ export {};
@@ -0,0 +1,129 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { ViewProps } from 'react-native';
3
+ import type { PlacementType, PositioningOptions } from '../../core/utils/positioning-enhanced';
4
+ import type { RadiusValue } from '../../core/theme/radius';
5
+ import type { ShadowValue } from '../../core/theme/shadow';
6
+ import type { SpacingProps } from '../../core/utils';
7
+ export type FloatingStrategy = 'absolute' | 'fixed';
8
+ export type ArrowPosition = 'center' | 'side';
9
+ export interface PopoverMiddlewares {
10
+ flip?: boolean | {
11
+ padding?: number;
12
+ };
13
+ shift?: boolean | {
14
+ padding?: number;
15
+ };
16
+ inline?: boolean;
17
+ }
18
+ export interface PopoverProps extends SpacingProps {
19
+ children: ReactNode;
20
+ /** Controlled open state */
21
+ opened?: boolean;
22
+ /** Initial open state in uncontrolled mode */
23
+ defaultOpened?: boolean;
24
+ /** Called when open state changes */
25
+ onChange?: (opened: boolean) => void;
26
+ /** Called when popover opens */
27
+ onOpen?: () => void;
28
+ /** Called when popover closes */
29
+ onClose?: () => void;
30
+ /** Called when popover is dismissed via outside click or escape */
31
+ onDismiss?: () => void;
32
+ /** Disable popover entirely */
33
+ disabled?: boolean;
34
+ /** Close when clicking outside */
35
+ closeOnClickOutside?: boolean;
36
+ /** Close when pressing Escape */
37
+ closeOnEscape?: boolean;
38
+ /** Events considered for outside click detection (web only) */
39
+ clickOutsideEvents?: string[];
40
+ /** Trap focus within dropdown (web only) */
41
+ trapFocus?: boolean;
42
+ /** Keep dropdown mounted when hidden */
43
+ keepMounted?: boolean;
44
+ /** Return focus to target after close */
45
+ returnFocus?: boolean;
46
+ /** Render dropdown within portal */
47
+ withinPortal?: boolean;
48
+ /** Render overlay/backdrop */
49
+ withOverlay?: boolean;
50
+ /** Overlay component props */
51
+ overlayProps?: Record<string, unknown>;
52
+ /** Dropdown width, number or 'target' to match target width */
53
+ width?: number | 'target';
54
+ /** Dropdown max-width */
55
+ maxWidth?: number;
56
+ /** Dropdown max-height */
57
+ maxHeight?: number;
58
+ /** Dropdown min-width */
59
+ minWidth?: number;
60
+ /** Dropdown min-height */
61
+ minHeight?: number;
62
+ /** Border radius */
63
+ radius?: RadiusValue | number;
64
+ /** Box shadow */
65
+ shadow?: ShadowValue;
66
+ /** Dropdown z-index */
67
+ zIndex?: number;
68
+ /** Popover position relative to target */
69
+ position?: PlacementType;
70
+ /** Offset from target */
71
+ offset?: number | {
72
+ mainAxis?: number;
73
+ crossAxis?: number;
74
+ };
75
+ /** Floating strategy for positioning */
76
+ floatingStrategy?: FloatingStrategy;
77
+ /** Custom positioning options */
78
+ middlewares?: PopoverMiddlewares;
79
+ /** Prevent flipping/shifting when visible */
80
+ preventPositionChangeWhenVisible?: boolean;
81
+ /** Hide dropdown when target becomes detached */
82
+ hideDetached?: boolean;
83
+ /** Override viewport padding */
84
+ viewport?: PositioningOptions['viewport'];
85
+ /** Override fallback placements */
86
+ fallbackPlacements?: PlacementType[];
87
+ /** Override boundary padding */
88
+ boundary?: number;
89
+ /** Render ARIA roles */
90
+ withRoles?: boolean;
91
+ /** Unique id base for accessibility */
92
+ id?: string;
93
+ /** Render arrow */
94
+ withArrow?: boolean;
95
+ /** Arrow size */
96
+ arrowSize?: number;
97
+ /** Arrow border radius */
98
+ arrowRadius?: number;
99
+ /** Arrow offset */
100
+ arrowOffset?: number;
101
+ /** Arrow position for start/end placements */
102
+ arrowPosition?: ArrowPosition;
103
+ /** Called when dropdown position changes */
104
+ onPositionChange?: (placement: PlacementType) => void;
105
+ /** Test identifier */
106
+ testID?: string;
107
+ }
108
+ export interface PopoverTargetProps {
109
+ children: React.ReactElement;
110
+ popupType?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid';
111
+ refProp?: string;
112
+ /** Additional props merged onto target */
113
+ targetProps?: Record<string, unknown>;
114
+ }
115
+ export interface PopoverDropdownProps extends ViewProps {
116
+ children: ReactNode;
117
+ /** Whether dropdown content should trap focus (web only) */
118
+ trapFocus?: boolean;
119
+ /** Keep dropdown mounted */
120
+ keepMounted?: boolean;
121
+ }
122
+ export interface RegisteredDropdown {
123
+ content: ReactNode;
124
+ style?: PopoverDropdownProps['style'];
125
+ trapFocus: boolean;
126
+ keepMounted?: boolean;
127
+ testID?: string;
128
+ containerProps?: Omit<PopoverDropdownProps, 'children' | 'style' | 'trapFocus' | 'keepMounted' | 'testID'>;
129
+ }
@@ -3,6 +3,7 @@ import { type TextProps } from '../Text';
3
3
  type ShimmerDirection = 'ltr' | 'rtl';
4
4
  export interface ShimmerTextProps extends Omit<TextProps, 'children' | 'color' | 'onLayout'> {
5
5
  children?: React.ReactNode;
6
+ /** Text to render with shimmer effect */
6
7
  text?: string;
7
8
  /** Base text color rendered underneath the shimmer */
8
9
  color?: string;
@@ -3,7 +3,7 @@ import type { SpotlightProps, SpotlightRootProps, SpotlightSearchProps, Spotligh
3
3
  declare function SpotlightRoot({ query, onQueryChange, children, opened, onClose, shortcut, style, }: SpotlightRootProps): React.JSX.Element;
4
4
  declare function SpotlightSearch({ value, onChangeText, leftSection, placeholder, onNavigateUp, onNavigateDown, onSelectAction, onClose, ...props }: SpotlightSearchProps): React.JSX.Element;
5
5
  declare function SpotlightActionsList({ children, scrollable, maxHeight, style, scrollRef, onScrollChange, }: SpotlightActionsListProps): React.JSX.Element;
6
- declare function SpotlightAction({ label, description, leftSection, rightSection, onPress, disabled, selected, children, style, innerRef, }: SpotlightActionProps): React.JSX.Element;
6
+ declare function SpotlightAction({ label, description, leftSection, rightSection, onPress, disabled, selected, children, style, innerRef, highlightQuery, }: SpotlightActionProps): React.JSX.Element;
7
7
  declare function SpotlightActionsGroup({ label, children, style, }: SpotlightActionsGroupProps): React.JSX.Element;
8
8
  declare function SpotlightEmpty({ children, style }: SpotlightEmptyProps): React.JSX.Element;
9
9
  export declare function Spotlight({ actions, nothingFound, highlightQuery, limit, scrollable, maxHeight, // Remove default - let it be calculated dynamically
@@ -1,10 +1,11 @@
1
1
  import React from 'react';
2
+ import type { HighlightProps as HighlightComponentProps } from '../Highlight';
2
3
  interface SpotlightControllerProps {
3
4
  config?: {
4
5
  shortcut?: string | string[] | null;
5
6
  actions?: any[];
6
7
  alwaysMount?: boolean;
7
- highlightQuery?: boolean;
8
+ highlightQuery?: boolean | HighlightComponentProps['highlight'];
8
9
  limit?: number;
9
10
  placeholder?: string;
10
11
  };
@@ -1,10 +1,11 @@
1
1
  import { ViewStyle } from 'react-native';
2
2
  import React from 'react';
3
3
  import { SpotlightItem } from './SpotlightTypes';
4
+ import type { HighlightProps as HighlightComponentProps } from '../Highlight';
4
5
  export interface SpotlightProps {
5
6
  actions: SpotlightItem[];
6
7
  nothingFound?: string;
7
- highlightQuery?: boolean;
8
+ highlightQuery?: boolean | HighlightComponentProps['highlight'];
8
9
  limit?: number;
9
10
  scrollable?: boolean;
10
11
  maxHeight?: number;
@@ -54,6 +55,7 @@ export interface SpotlightActionProps {
54
55
  style?: ViewStyle;
55
56
  innerRef?: any;
56
57
  onLayout?: (e: any) => void;
58
+ highlightQuery?: HighlightComponentProps['highlight'];
57
59
  }
58
60
  export interface SpotlightActionsGroupProps {
59
61
  label: string;
@@ -69,6 +69,8 @@ export interface ToastProps extends SpacingProps, BorderRadiusProps {
69
69
  maxWidth?: number;
70
70
  /** Persist toast until manually dismissed */
71
71
  persistent?: boolean;
72
+ /** Keep toast mounted in the tree when hidden */
73
+ keepMounted?: boolean;
72
74
  /** Animation configuration */
73
75
  animationConfig?: ToastAnimationConfig;
74
76
  /** Swipe to dismiss configuration */
@@ -77,10 +77,12 @@ export { Accordion } from './Accordion';
77
77
  export { Gauge } from './Gauge';
78
78
  export { GradientText } from './GradientText';
79
79
  export { ShimmerText } from './ShimmerText';
80
+ export { Highlight } from './Highlight';
80
81
  export { Title } from './Title/Title';
81
82
  export { TableOfContents } from './TableOfContents/TableOfContents';
82
83
  export { HoverCard } from './HoverCard/HoverCard';
83
84
  export { ContextMenu } from './ContextMenu';
85
+ export { Popover, PopoverTarget, PopoverDropdown } from './Popover';
84
86
  export { Gallery } from './Gallery';
85
87
  export type { AlertProps } from './Alert';
86
88
  export type { AppShellProps } from './AppShell';
@@ -106,6 +108,7 @@ export type { FlexProps } from './Flex';
106
108
  export type { GridProps } from './Grid';
107
109
  export type { GradientTextProps } from './GradientText';
108
110
  export type { ShimmerTextProps } from './ShimmerText';
111
+ export type { HighlightProps } from './Highlight';
109
112
  export type { TreeProps, TreeNode } from './Tree/Tree';
110
113
  export type { TimePickerProps, TimePickerValue } from './TimePicker/types';
111
114
  export type { IconProps, IconSize, IconVariant, IconDefinition, IconRegistry } from './Icon';
@@ -156,6 +159,7 @@ export type { TableOfContentsProps, TocItem } from './TableOfContents/types';
156
159
  export type { StepperProps } from './Stepper';
157
160
  export type { HoverCardProps } from './HoverCard/types';
158
161
  export type { ContextMenuProps, ContextMenuItem } from './ContextMenu/ContextMenu';
162
+ export type { PopoverProps, PopoverTargetProps, PopoverDropdownProps } from './Popover';
159
163
  export type { SegmentedControlProps, SegmentedControlItem, SegmentedControlData } from './SegmentedControl';
160
164
  export type { GalleryProps, GalleryModalProps, GalleryItem } from './Gallery';
161
165
  export * from './Accessibility/AccessibilityHelpers';
@@ -5,10 +5,10 @@ export interface FactoryPayload {
5
5
  ref: any;
6
6
  staticComponents?: Record<string, any>;
7
7
  }
8
- export interface ComponentWithProps<Props = {}> {
9
- withProps: <T extends Partial<Props>>(fixedProps: T) => React.FC<Omit<Props, keyof T>>;
8
+ export interface ComponentWithProps<Props = {}, RefType = any> {
9
+ withProps: <T extends Partial<Props>>(fixedProps: T) => any;
10
10
  }
11
- export interface PlatformBlocksComponent<Payload extends FactoryPayload> extends React.FC<Payload['props']>, ComponentWithProps<Payload['props']> {
11
+ export interface PlatformBlocksComponent<Payload extends FactoryPayload> extends React.ForwardRefExoticComponent<React.PropsWithoutRef<Payload['props']> & React.RefAttributes<Payload['ref']>>, ComponentWithProps<Payload['props'], Payload['ref']> {
12
12
  extend: any;
13
13
  displayName?: string;
14
14
  }
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { PlatformBlocksThemeProviderProps } from './ThemeProvider';
3
+ import type { HighlightProps as HighlightComponentProps } from '../../components/Highlight';
3
4
  import { ThemeModeConfig } from './ThemeModeProvider';
4
5
  export interface PlatformBlocksProviderProps extends Omit<PlatformBlocksThemeProviderProps, 'children'> {
5
6
  /** Your application */
@@ -29,7 +30,7 @@ export interface PlatformBlocksProviderProps extends Omit<PlatformBlocksThemePro
29
30
  actions?: any[];
30
31
  placeholder?: string;
31
32
  limit?: number;
32
- highlightQuery?: boolean;
33
+ highlightQuery?: boolean | HighlightComponentProps['highlight'];
33
34
  /** Render Spotlight even when no actions provided (useful to inject later) */
34
35
  alwaysMount?: boolean;
35
36
  };