craft-native 0.0.203 → 0.0.205

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.
package/dist/cli.js CHANGED
@@ -3424,7 +3424,7 @@ function pinCraftNativeDependency(packagePath, craftVersion) {
3424
3424
  `);
3425
3425
  }
3426
3426
  // package.json
3427
- var version = "0.0.203";
3427
+ var version = "0.0.205";
3428
3428
 
3429
3429
  // bin/cli.ts
3430
3430
  var spawnedFrom = process6.env[CRAFT_CLI_SPAWN_MARKER];
@@ -86,7 +86,13 @@ export interface LayoutStyle {
86
86
  /** Overflow */
87
87
  overflow?: 'visible' | 'hidden' | 'scroll';
88
88
  /** Display */
89
- display?: 'flex' | 'none';
89
+ display?: 'flex' | 'none' | 'grid';
90
+ /** Equal-width grid track count or CSS-shaped `repeat(N, 1fr)` tracks. */
91
+ gridTemplateColumns?: number | string;
92
+ /** Legacy numeric alias for the grid track count. */
93
+ gridColumns?: number;
94
+ /** Intrinsic or fixed height for automatically-created grid rows. */
95
+ gridAutoRows?: number | string;
90
96
  }
91
97
  /**
92
98
  * Spacing style properties.
@@ -166,6 +172,14 @@ export interface ColorStyle {
166
172
  backgroundColor?: string;
167
173
  /** Opacity */
168
174
  opacity?: number;
175
+ /** Linear-gradient direction used by native hosts. */
176
+ gradientDirection?: 'to-t' | 'to-tr' | 'to-r' | 'to-br' | 'to-b' | 'to-bl' | 'to-l' | 'to-tl';
177
+ /** Linear-gradient start color. */
178
+ gradientFrom?: string;
179
+ /** Optional linear-gradient middle stop. */
180
+ gradientVia?: string;
181
+ /** Linear-gradient end color. */
182
+ gradientTo?: string;
169
183
  }
170
184
  /**
171
185
  * Shadow style properties.
@@ -265,7 +279,7 @@ export type TextStyle = ViewStyle & TextStyleProps;
265
279
  */
266
280
  export interface ImageStyleProps {
267
281
  /** Resize mode */
268
- resizeMode?: 'cover' | 'contain' | 'stretch' | 'repeat' | 'center';
282
+ resizeMode?: 'cover' | 'contain' | 'stretch' | 'center';
269
283
  /** Tint color */
270
284
  tintColor?: string;
271
285
  }
@@ -290,7 +304,9 @@ export interface BaseProps {
290
304
  /** Accessibility state exposed to assistive technologies */
291
305
  accessibilityState?: AccessibilityState;
292
306
  /** Accessibility role */
293
- accessibilityRole?: 'none' | 'button' | 'link' | 'image' | 'text' | 'header' | 'search' | 'menu';
307
+ accessibilityRole?: 'none' | 'button' | 'link' | 'image' | 'text' | 'header' | 'search' | 'adjustable' | 'menu' | 'summary' | 'alert' | 'checkbox' | 'combobox' | 'menuitem' | 'progressbar' | 'radio' | 'tablist' | 'radiogroup' | 'list' | 'menubar' | 'spinbutton' | 'switch' | 'tab' | 'timer' | 'toolbar' | 'scrollbar';
308
+ /** Matches a view across an animated state change. */
309
+ transitionID?: string;
294
310
  /** Children elements */
295
311
  children?: any;
296
312
  }
@@ -307,12 +323,12 @@ export interface ViewProps extends BaseProps {
307
323
  style?: ViewStyle | ViewStyle[];
308
324
  /** Press handler */
309
325
  onPress?: () => void;
326
+ /** DOM-compatible press alias accepted by native hosts. */
327
+ onClick?: () => void;
310
328
  /** Long press handler */
311
329
  onLongPress?: () => void;
312
330
  /** Layout change handler */
313
331
  onLayout?: (event: LayoutEvent) => void;
314
- /** Pointer events behavior */
315
- pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only';
316
332
  }
317
333
  /** Safe-area container props used by native iOS and Android screens. */
318
334
  export interface SafeAreaViewProps extends ViewProps {
@@ -324,6 +340,17 @@ export interface KeyboardAvoidingViewProps extends ViewProps {
324
340
  behavior?: 'height' | 'position' | 'padding';
325
341
  keyboardVerticalOffset?: number;
326
342
  }
343
+ /** Native status-bar appearance for the current screen. */
344
+ export interface StatusBarProps extends BaseProps {
345
+ barStyle?: 'default' | 'light-content' | 'dark-content';
346
+ hidden?: boolean;
347
+ }
348
+ /** Pull-to-refresh control consumed by a parent ScrollView or FlatList. */
349
+ export interface RefreshControlProps extends BaseProps {
350
+ refreshing?: boolean;
351
+ onRefresh?: () => void;
352
+ tintColor?: string;
353
+ }
327
354
  /**
328
355
  * Text component props.
329
356
  */
@@ -334,8 +361,6 @@ export interface TextProps extends BaseProps {
334
361
  numberOfLines?: number;
335
362
  /** Ellipsize mode */
336
363
  ellipsizeMode?: 'head' | 'middle' | 'tail' | 'clip';
337
- /** Selectable text */
338
- selectable?: boolean;
339
364
  /** Press handler */
340
365
  onPress?: () => void;
341
366
  /** Long press handler */
@@ -345,6 +370,7 @@ export interface TextProps extends BaseProps {
345
370
  export interface ButtonProps extends BaseProps {
346
371
  title?: string;
347
372
  onPress?: () => void;
373
+ onClick?: () => void;
348
374
  disabled?: boolean;
349
375
  color?: string;
350
376
  }
@@ -369,10 +395,8 @@ export interface TouchableHighlightProps extends ViewProps {
369
395
  */
370
396
  export type ImageSource = {
371
397
  uri: string;
372
- width?: number;
373
- height?: number;
374
398
  headers?: Record<string, string>;
375
- } | number;
399
+ };
376
400
  /**
377
401
  * Image component props.
378
402
  */
@@ -382,7 +406,7 @@ export interface ImageProps extends BaseProps {
382
406
  /** Style object or array */
383
407
  style?: ImageStyle | ImageStyle[];
384
408
  /** Resize mode */
385
- resizeMode?: 'cover' | 'contain' | 'stretch' | 'repeat' | 'center';
409
+ resizeMode?: 'cover' | 'contain' | 'stretch' | 'center';
386
410
  /** Load start handler */
387
411
  onLoadStart?: () => void;
388
412
  /** Load handler */
@@ -393,10 +417,6 @@ export interface ImageProps extends BaseProps {
393
417
  onError?: (error: Error) => void;
394
418
  /** Default source while loading */
395
419
  defaultSource?: ImageSource;
396
- /** Blur radius */
397
- blurRadius?: number;
398
- /** Fade duration (ms) */
399
- fadeDuration?: number;
400
420
  /** Alt text for accessibility */
401
421
  alt?: string;
402
422
  }
@@ -453,12 +473,15 @@ export interface MapRegion {
453
473
  }
454
474
  export interface MapProps extends BaseProps {
455
475
  region?: MapRegion;
476
+ /** Initial camera region; applied once, then controlled by subsequent props. */
477
+ initialRegion?: MapRegion;
456
478
  fitToBounds?: boolean;
457
479
  showsUserLocation?: boolean;
458
480
  scrollEnabled?: boolean;
459
481
  zoomEnabled?: boolean;
460
482
  rotateEnabled?: boolean;
461
- mapType?: 'standard' | 'satellite' | 'hybrid' | 'terrain';
483
+ /** Map styles implemented consistently by the maintained iOS and Android hosts. */
484
+ mapType?: 'standard' | 'satellite' | 'hybrid';
462
485
  onMarkerPress?: (event: {
463
486
  nativeEvent: {
464
487
  id: string;
@@ -486,7 +509,59 @@ export interface MapMarkerProps extends BaseProps {
486
509
  }) => void;
487
510
  }
488
511
  export interface ImageBackgroundProps extends ImageProps {
489
- imageStyle?: ImageStyle | ImageStyle[];
512
+ }
513
+ /** Shared paint and accessibility props for DOM-free native SVG nodes. */
514
+ export interface SvgPaintProps extends BaseProps {
515
+ style?: ViewStyle | ViewStyle[];
516
+ fill?: string;
517
+ stroke?: string;
518
+ strokeWidth?: number;
519
+ strokeDasharray?: number[] | string;
520
+ strokeDashoffset?: number;
521
+ strokeLinecap?: 'butt' | 'round' | 'square';
522
+ strokeLinejoin?: 'miter' | 'round' | 'bevel';
523
+ strokeMiterlimit?: number;
524
+ strokeOpacity?: number;
525
+ fillOpacity?: number;
526
+ fillRule?: 'nonzero' | 'evenodd';
527
+ vectorEffect?: 'none' | 'non-scaling-stroke';
528
+ color?: string;
529
+ opacity?: number;
530
+ }
531
+ /** Root native SVG drawing surface. */
532
+ export interface SvgProps extends SvgPaintProps {
533
+ viewBox?: [number, number, number, number] | string;
534
+ preserveAspectRatio?: string;
535
+ }
536
+ /** Native SVG group inheriting paint from its parent. */
537
+ export interface GProps extends SvgPaintProps {
538
+ }
539
+ /** Shared generated geometry prop for native SVG shape nodes. */
540
+ export interface SvgShapeProps extends SvgPaintProps {
541
+ geometry?: number[];
542
+ }
543
+ export interface PathProps extends SvgShapeProps {
544
+ }
545
+ export interface LineProps extends SvgShapeProps {
546
+ }
547
+ export interface RectProps extends SvgShapeProps {
548
+ }
549
+ export interface CircleProps extends SvgShapeProps {
550
+ }
551
+ export interface EllipseProps extends SvgShapeProps {
552
+ }
553
+ export interface PolylineProps extends SvgShapeProps {
554
+ }
555
+ export interface PolygonProps extends SvgShapeProps {
556
+ }
557
+ /** Native SVG text painted in the root viewBox. */
558
+ export interface SvgTextProps extends SvgPaintProps {
559
+ x?: number;
560
+ y?: number;
561
+ fontSize?: number;
562
+ fontWeight?: string | number;
563
+ textAnchor?: 'start' | 'middle' | 'end' | string;
564
+ dominantBaseline?: string;
490
565
  }
491
566
  /**
492
567
  * ScrollView component props.
@@ -524,8 +599,18 @@ export interface ScrollViewProps extends ViewProps {
524
599
  keyboardDismissMode?: 'none' | 'on-drag' | 'interactive';
525
600
  /** Keyboard should persist taps */
526
601
  keyboardShouldPersistTaps?: 'always' | 'never' | 'handled';
527
- /** Refresh control component */
528
- refreshControl?: any;
602
+ /** Keep indexed vertical children pinned while scrolling. */
603
+ stickyHeaderIndices?: number[];
604
+ /** Scroll a child into view when this target changes. */
605
+ scrollTarget?: string | {
606
+ id: string;
607
+ animated?: boolean;
608
+ key?: string;
609
+ } | null;
610
+ /** Render content in reverse order along the scroll axis. */
611
+ inverted?: boolean;
612
+ /** Controlled native pull-to-refresh component. */
613
+ refreshControl?: RefreshControlProps;
529
614
  }
530
615
  /**
531
616
  * Pressable component props.
@@ -537,28 +622,6 @@ export interface PressableProps extends ViewProps {
537
622
  onPressIn?: () => void;
538
623
  /** Press out handler */
539
624
  onPressOut?: () => void;
540
- /** Hit slop for touch area */
541
- hitSlop?: number | {
542
- top?: number;
543
- right?: number;
544
- bottom?: number;
545
- left?: number;
546
- };
547
- /** Press retention offset */
548
- pressRetentionOffset?: number | {
549
- top?: number;
550
- right?: number;
551
- bottom?: number;
552
- left?: number;
553
- };
554
- /** Android ripple effect */
555
- android_ripple?: {
556
- color?: string;
557
- borderless?: boolean;
558
- radius?: number;
559
- };
560
- /** Delay for long press */
561
- delayLongPress?: number;
562
625
  }
563
626
  /**
564
627
  * TextInput component props.
@@ -586,6 +649,10 @@ export interface TextInputProps extends BaseProps {
586
649
  autoFocus?: boolean;
587
650
  /** Secure text entry (password) */
588
651
  secureTextEntry?: boolean;
652
+ /** Platform autofill content type (for example `username` or `oneTimeCode`). */
653
+ textContentType?: string;
654
+ /** HTML-style autofill hint (for example `current-password`). */
655
+ autoComplete?: string;
589
656
  /** Multi-line input */
590
657
  multiline?: boolean;
591
658
  /** Number of lines for multiline */
@@ -598,6 +665,8 @@ export interface TextInputProps extends BaseProps {
598
665
  selectionColor?: string;
599
666
  /** Change text handler */
600
667
  onChangeText?: (text: string) => void;
668
+ /** DOM-compatible change alias accepted by native hosts. */
669
+ onChange?: (text: string) => void;
601
670
  /** Focus handler */
602
671
  onFocus?: () => void;
603
672
  /** Blur handler */
@@ -607,11 +676,12 @@ export interface TextInputProps extends BaseProps {
607
676
  /** End editing handler */
608
677
  onEndEditing?: () => void;
609
678
  }
610
- export type KeyboardType = 'default' | 'email-address' | 'numeric' | 'phone-pad' | 'number-pad' | 'decimal-pad' | 'url' | 'web-search' | 'visible-password' | 'ascii-capable' | 'numbers-and-punctuation' | 'name-phone-pad' | 'twitter';
679
+ export type KeyboardType = 'default' | 'email-address' | 'numeric' | 'phone-pad' | 'number-pad' | 'decimal-pad' | 'url' | 'web-search' | 'visible-password';
611
680
  export type ReturnKeyType = 'done' | 'go' | 'next' | 'search' | 'send' | 'join' | 'route' | 'continue' | 'emergency-call' | 'default';
612
681
  export interface SwitchProps extends BaseProps {
613
682
  value?: boolean;
614
683
  onValueChange?: (value: boolean) => void;
684
+ onChange?: (value: boolean) => void;
615
685
  disabled?: boolean;
616
686
  trackColor?: {
617
687
  false?: string;
@@ -626,6 +696,7 @@ export interface CheckboxProps extends BaseProps {
626
696
  indeterminate?: boolean;
627
697
  label?: string;
628
698
  onValueChange?: (value: boolean) => void;
699
+ onChange?: (value: boolean) => void;
629
700
  disabled?: boolean;
630
701
  color?: string;
631
702
  }
@@ -635,6 +706,7 @@ export interface SliderProps extends BaseProps {
635
706
  maximumValue?: number;
636
707
  step?: number;
637
708
  onValueChange?: (value: number) => void;
709
+ onChange?: (value: number) => void;
638
710
  onSlidingComplete?: (value: number) => void;
639
711
  disabled?: boolean;
640
712
  minimumTrackTintColor?: string;
@@ -646,9 +718,11 @@ export interface PickerOption {
646
718
  value: string | number;
647
719
  }
648
720
  export interface PickerProps extends BaseProps {
649
- items: PickerOption[];
721
+ /** Typed options; child options remain supported when omitted. */
722
+ items?: PickerOption[];
650
723
  selectedValue?: string | number;
651
724
  onValueChange?: (value: string | number, index: number) => void;
725
+ onChange?: (value: string | number, index: number) => void;
652
726
  disabled?: boolean;
653
727
  }
654
728
  export interface DatePickerChange {
@@ -662,8 +736,8 @@ export interface DatePickerProps extends BaseProps {
662
736
  minimumDate?: string | number;
663
737
  maximumDate?: string | number;
664
738
  minuteInterval?: number;
665
- display?: 'compact' | 'inline' | 'wheels';
666
739
  onValueChange?: (event: DatePickerChange) => void;
740
+ onChange?: (event: DatePickerChange) => void;
667
741
  disabled?: boolean;
668
742
  }
669
743
  export interface ActivityIndicatorProps extends BaseProps {
@@ -685,28 +759,8 @@ export interface FlatListProps<T> extends ScrollViewProps {
685
759
  }) => any;
686
760
  /** Key extractor function */
687
761
  keyExtractor?: (item: T, index: number) => string;
688
- /** Item separator component */
689
- ItemSeparatorComponent?: any;
690
- /** List header component */
691
- ListHeaderComponent?: any;
692
- /** List footer component */
693
- ListFooterComponent?: any;
694
- /** Empty list component */
695
- ListEmptyComponent?: any;
696
762
  /** Number of columns */
697
763
  numColumns?: number;
698
- /** Initial number to render */
699
- initialNumToRender?: number;
700
- /** Max to render per batch */
701
- maxToRenderPerBatch?: number;
702
- /** Window size */
703
- windowSize?: number;
704
- /** Get item layout for optimization */
705
- getItemLayout?: (data: T[] | null, index: number) => {
706
- length: number;
707
- offset: number;
708
- index: number;
709
- };
710
764
  /** End reached handler */
711
765
  onEndReached?: () => void;
712
766
  /** End reached threshold */
@@ -722,16 +776,6 @@ export interface SectionListSection<T> {
722
776
  title?: string;
723
777
  }
724
778
  export interface SectionListProps<T> extends ScrollViewProps {
725
- sections: SectionListSection<T>[];
726
- renderItem: (info: {
727
- item: T;
728
- index: number;
729
- section: SectionListSection<T>;
730
- }) => any;
731
- renderSectionHeader?: (info: {
732
- section: SectionListSection<T>;
733
- }) => any;
734
- keyExtractor?: (item: T, index: number) => string;
735
779
  }
736
780
  export interface ModalProps extends BaseProps {
737
781
  visible?: boolean;
package/dist/index.cjs CHANGED
@@ -309,7 +309,7 @@ function craftBinaryNotFoundMessage(triedPath) {
309
309
  `);
310
310
  }
311
311
  // package.json
312
- var version = "0.0.203";
312
+ var version = "0.0.205";
313
313
 
314
314
  // src/sdk-version.ts
315
315
  var SDK_VERSION = version;
package/dist/index.d.cts CHANGED
@@ -30,7 +30,7 @@ export * from './utils/index.js';
30
30
  export * from './api/index.js';
31
31
  export * as components from './components/index.js';
32
32
  export { createTahoeSidebar, createArcSidebar, createOrbStackSidebar, sidebarItem, sidebarSection, sidebarSeparator, tahoeStyle, arcStyle, orbstackStyle, createSplitView, SplitViewInstance, createFileBrowser, FileBrowserInstance, createOutlineView, OutlineViewInstance, createTableView, TableViewInstance, showQuickLook, hideQuickLook, canQuickLook, showColorPicker, showFontPicker, showDatePicker, createProgress, ProgressInstance, setToolbar, updateToolbarItem, setToolbarVisible, setTouchBar, updateTouchBarItem, StyleSheet, Animated, } from './components/index.js';
33
- export type { ContextMenuItem, SidebarStyle, SidebarPosition, SidebarHeaderConfig, SidebarFooterConfig, SidebarEventType, SidebarEventMap, SidebarEventHandler, ComponentProps, ComponentInstance, SplitViewOrientation, SplitViewDividerStyle, SplitViewConfig, FileBrowserConfig, FileBrowserSelection, OutlineItem, OutlineViewConfig, TableRow, TableViewConfig, QuickLookConfig, ColorPickerConfig, FontPickerConfig, FontResult, DatePickerConfig, ProgressConfig, ToolbarItem, ToolbarConfig, TouchBarConfig, FlexStyle, LayoutStyle, SpacingStyle, BorderStyle, ColorStyle, ShadowStyle, TransformStyle, ViewStyle, TextStyleProps, TextStyle, ImageStyleProps, ImageStyle, BaseProps, ViewProps, SafeAreaViewProps, KeyboardAvoidingViewProps, TextProps, ButtonProps, LinkProps, TouchableOpacityProps, TouchableHighlightProps, ImageSource, ImageProps, ImageBackgroundProps, IconProps, VideoProps, MapRegion, MapProps, MapPolylineProps, MapMarkerProps, ScrollViewProps, PressableProps, TextInputProps, KeyboardType, ReturnKeyType, SwitchProps, CheckboxProps, SliderProps, PickerOption, PickerProps, DatePickerChange, DatePickerProps, ActivityIndicatorProps, FlatListProps, SectionListSection, SectionListProps, ModalProps, LayoutEvent, ScrollEvent, } from './components/index.js';
33
+ export type { ContextMenuItem, SidebarStyle, SidebarPosition, SidebarHeaderConfig, SidebarFooterConfig, SidebarEventType, SidebarEventMap, SidebarEventHandler, ComponentProps, ComponentInstance, SplitViewOrientation, SplitViewDividerStyle, SplitViewConfig, FileBrowserConfig, FileBrowserSelection, OutlineItem, OutlineViewConfig, TableRow, TableViewConfig, QuickLookConfig, ColorPickerConfig, FontPickerConfig, FontResult, DatePickerConfig, ProgressConfig, ToolbarItem, ToolbarConfig, TouchBarConfig, FlexStyle, LayoutStyle, SpacingStyle, BorderStyle, ColorStyle, ShadowStyle, TransformStyle, ViewStyle, TextStyleProps, TextStyle, ImageStyleProps, ImageStyle, BaseProps, ViewProps, SafeAreaViewProps, KeyboardAvoidingViewProps, StatusBarProps, RefreshControlProps, TextProps, ButtonProps, LinkProps, TouchableOpacityProps, TouchableHighlightProps, ImageSource, ImageProps, ImageBackgroundProps, SvgPaintProps, SvgProps, GProps, SvgShapeProps, PathProps, LineProps, RectProps, CircleProps, EllipseProps, PolylineProps, PolygonProps, SvgTextProps, IconProps, VideoProps, MapRegion, MapProps, MapPolylineProps, MapMarkerProps, ScrollViewProps, PressableProps, TextInputProps, KeyboardType, ReturnKeyType, SwitchProps, CheckboxProps, SliderProps, PickerOption, PickerProps, DatePickerChange, DatePickerProps, ActivityIndicatorProps, FlatListProps, SectionListSection, SectionListProps, ModalProps, LayoutEvent, ScrollEvent, } from './components/index.js';
34
34
  export * from './styles/headwind.js';
35
35
  export * from './styles/index.js';
36
36
  export * from './optimizations/index.js';
package/dist/index.d.ts CHANGED
@@ -30,7 +30,7 @@ export * from './utils/index.js';
30
30
  export * from './api/index.js';
31
31
  export * as components from './components/index.js';
32
32
  export { createTahoeSidebar, createArcSidebar, createOrbStackSidebar, sidebarItem, sidebarSection, sidebarSeparator, tahoeStyle, arcStyle, orbstackStyle, createSplitView, SplitViewInstance, createFileBrowser, FileBrowserInstance, createOutlineView, OutlineViewInstance, createTableView, TableViewInstance, showQuickLook, hideQuickLook, canQuickLook, showColorPicker, showFontPicker, showDatePicker, createProgress, ProgressInstance, setToolbar, updateToolbarItem, setToolbarVisible, setTouchBar, updateTouchBarItem, StyleSheet, Animated, } from './components/index.js';
33
- export type { ContextMenuItem, SidebarStyle, SidebarPosition, SidebarHeaderConfig, SidebarFooterConfig, SidebarEventType, SidebarEventMap, SidebarEventHandler, ComponentProps, ComponentInstance, SplitViewOrientation, SplitViewDividerStyle, SplitViewConfig, FileBrowserConfig, FileBrowserSelection, OutlineItem, OutlineViewConfig, TableRow, TableViewConfig, QuickLookConfig, ColorPickerConfig, FontPickerConfig, FontResult, DatePickerConfig, ProgressConfig, ToolbarItem, ToolbarConfig, TouchBarConfig, FlexStyle, LayoutStyle, SpacingStyle, BorderStyle, ColorStyle, ShadowStyle, TransformStyle, ViewStyle, TextStyleProps, TextStyle, ImageStyleProps, ImageStyle, BaseProps, ViewProps, SafeAreaViewProps, KeyboardAvoidingViewProps, TextProps, ButtonProps, LinkProps, TouchableOpacityProps, TouchableHighlightProps, ImageSource, ImageProps, ImageBackgroundProps, IconProps, VideoProps, MapRegion, MapProps, MapPolylineProps, MapMarkerProps, ScrollViewProps, PressableProps, TextInputProps, KeyboardType, ReturnKeyType, SwitchProps, CheckboxProps, SliderProps, PickerOption, PickerProps, DatePickerChange, DatePickerProps, ActivityIndicatorProps, FlatListProps, SectionListSection, SectionListProps, ModalProps, LayoutEvent, ScrollEvent, } from './components/index.js';
33
+ export type { ContextMenuItem, SidebarStyle, SidebarPosition, SidebarHeaderConfig, SidebarFooterConfig, SidebarEventType, SidebarEventMap, SidebarEventHandler, ComponentProps, ComponentInstance, SplitViewOrientation, SplitViewDividerStyle, SplitViewConfig, FileBrowserConfig, FileBrowserSelection, OutlineItem, OutlineViewConfig, TableRow, TableViewConfig, QuickLookConfig, ColorPickerConfig, FontPickerConfig, FontResult, DatePickerConfig, ProgressConfig, ToolbarItem, ToolbarConfig, TouchBarConfig, FlexStyle, LayoutStyle, SpacingStyle, BorderStyle, ColorStyle, ShadowStyle, TransformStyle, ViewStyle, TextStyleProps, TextStyle, ImageStyleProps, ImageStyle, BaseProps, ViewProps, SafeAreaViewProps, KeyboardAvoidingViewProps, StatusBarProps, RefreshControlProps, TextProps, ButtonProps, LinkProps, TouchableOpacityProps, TouchableHighlightProps, ImageSource, ImageProps, ImageBackgroundProps, SvgPaintProps, SvgProps, GProps, SvgShapeProps, PathProps, LineProps, RectProps, CircleProps, EllipseProps, PolylineProps, PolygonProps, SvgTextProps, IconProps, VideoProps, MapRegion, MapProps, MapPolylineProps, MapMarkerProps, ScrollViewProps, PressableProps, TextInputProps, KeyboardType, ReturnKeyType, SwitchProps, CheckboxProps, SliderProps, PickerOption, PickerProps, DatePickerChange, DatePickerProps, ActivityIndicatorProps, FlatListProps, SectionListSection, SectionListProps, ModalProps, LayoutEvent, ScrollEvent, } from './components/index.js';
34
34
  export * from './styles/headwind.js';
35
35
  export * from './styles/index.js';
36
36
  export * from './optimizations/index.js';
package/dist/index.js CHANGED
@@ -57,7 +57,7 @@ function craftBinaryNotFoundMessage(triedPath) {
57
57
  `);
58
58
  }
59
59
  // package.json
60
- var version = "0.0.203";
60
+ var version = "0.0.205";
61
61
 
62
62
  // src/sdk-version.ts
63
63
  var SDK_VERSION = version;
@@ -11,7 +11,7 @@ export interface SimulatorDriverOptions {
11
11
  /** Generate the reusable XCUITest shell from package templates. No app-owned Swift. */
12
12
  export declare function initSimulatorDriver(options: SimulatorDriverOptions): void;
13
13
  export type SimulatorStep = {
14
- command: 'launch' | 'activate' | 'terminate' | 'home' | 'back' | 'return' | 'unlabelled';
14
+ command: 'launch' | 'activate' | 'terminate' | 'home' | 'back' | 'return' | 'unlabelled' | 'notifications';
15
15
  } | {
16
16
  command: 'background' | 'wait';
17
17
  seconds: number;
@@ -45,14 +45,14 @@ export type SimulatorStep = {
45
45
  id: string;
46
46
  text: string;
47
47
  } | {
48
- command: 'expect' | 'expectexact' | 'expectid';
48
+ command: 'expect' | 'expectexact' | 'expectid' | 'systemexpect';
49
49
  text: string;
50
50
  seconds?: number;
51
51
  } | {
52
- command: 'tap' | 'tapif' | 'tapid' | 'tapexact' | 'type' | 'absent' | 'absentid' | 'selected' | 'tab' | 'scrollto' | 'dismiss' | 'log';
52
+ command: 'tap' | 'tapif' | 'tapid' | 'tapexact' | 'type' | 'absent' | 'absentid' | 'selected' | 'tab' | 'scrollto' | 'dismiss' | 'log' | 'systemtap' | 'systemabsent';
53
53
  text: string;
54
54
  } | {
55
- command: 'shot' | 'tree' | 'audit' | 'exec';
55
+ command: 'shot' | 'tree' | 'audit' | 'exec' | 'systemtree';
56
56
  name: string;
57
57
  } | {
58
58
  command: 'openurl';
@@ -146,8 +146,10 @@ struct CraftHybridRoutes {
146
146
  let scheme = (url.scheme ?? "").lowercased()
147
147
  guard scheme == "http" || scheme == "https",
148
148
  let host = url.host?.lowercased(), !host.isEmpty,
149
- let siteHost = site?.host?.lowercased() else { return false }
150
- return host == siteHost
149
+ let siteScheme = site?.scheme?.lowercased(), scheme == siteScheme,
150
+ let siteHost = site?.host?.lowercased(), host == siteHost,
151
+ url.port == site?.port else { return false }
152
+ return true
151
153
  }
152
154
 
153
155
  /// Where a path no native screen draws opens in an app with no web view:
@@ -979,6 +981,17 @@ final class CraftHybridWebSlot: UIViewController {
979
981
  /// ready. This belongs to the incoming slot, beyond the push animation.
980
982
  private(set) var waitingPageSnapshot: UIView?
981
983
 
984
+ /// A canceled tab swipe may leave this slot hidden after the page has
985
+ /// already reported its destination. Reconcile that route before the
986
+ /// WebView is adopted again, so the slot cannot stay transparent forever.
987
+ @discardableResult
988
+ func markArrivedIfNeeded(_ currentPath: String?) -> Bool {
989
+ guard awaitingPage, let currentPath,
990
+ CraftHybridRoutes.normalize(currentPath) == CraftHybridRoutes.normalize(path) else { return false }
991
+ awaitingPage = false
992
+ return true
993
+ }
994
+
982
995
  func keepPageVisible(_ snapshot: UIView) {
983
996
  waitingPageSnapshot?.removeFromSuperview()
984
997
  snapshot.frame = view.bounds
@@ -1392,7 +1405,7 @@ final class CraftHybridController: UIViewController, UINavigationControllerDeleg
1392
1405
 
1393
1406
  /// The entry for a path: its native screen, or a web entry.
1394
1407
  private func entry(for path: String, isTabRoot: Bool, depth: Int?, params extra: [String: Any] = [:]) -> UIViewController {
1395
- if let match = hybrid.routes.match(path) {
1408
+ if hybrid.isEnabled, let match = hybrid.routes.match(path) {
1396
1409
  var params = self.params(for: path, match)
1397
1410
  extra.forEach { params[$0.key] = $0.value }
1398
1411
  let screen = CraftNativeScreenController(config: config, routeName: match.screen, routeParams: params)
@@ -1441,6 +1454,7 @@ final class CraftHybridController: UIViewController, UINavigationControllerDeleg
1441
1454
  func adoptWeb(into slot: CraftHybridWebSlot, allowHiddenStack: Bool = false) {
1442
1455
  guard let webHost,
1443
1456
  allowHiddenStack || slot.navigationController === visibleStack || visibleStack == nil else { return }
1457
+ slot.markArrivedIfNeeded(hybrid.pagePath)
1444
1458
  attachWeb()
1445
1459
  moveWeb(to: slot, in: slot.view)
1446
1460
  webHost.view.alpha = slot.awaitingPage ? 0 : 1
@@ -158,6 +158,8 @@ final class CraftNativeFlatList: UICollectionView, UICollectionViewDelegateFlowL
158
158
  private var refreshHandler: (() -> Void)?
159
159
  private let keyboardTapGesture = UITapGestureRecognizer()
160
160
  private var keyboardShouldPersistTaps = "never"
161
+ private var scrollTargetKey: String?
162
+ private var pendingScrollTarget: (id: String, animated: Bool, attempts: Int)?
161
163
 
162
164
  init() {
163
165
  let layout = CraftNativeFlatListLayout()
@@ -271,6 +273,37 @@ final class CraftNativeFlatList: UICollectionView, UICollectionViewDelegateFlowL
271
273
  updateItemEstimate()
272
274
  super.layoutSubviews()
273
275
  craftApplyCornerRadius()
276
+ scrollToPendingTarget()
277
+ }
278
+
279
+ /// Scroll to a virtualized row identified by its native testID, id, or key.
280
+ /// The row need not be mounted yet; the data snapshot is enough to find its
281
+ /// index, and UIKit will mount it as part of the scroll.
282
+ func setScrollTarget(_ value: Any?) {
283
+ var id: String?
284
+ var animated = true
285
+ if let text = value as? String {
286
+ id = text
287
+ } else if let target = value as? [String: Any] {
288
+ id = target["id"] as? String
289
+ animated = target["animated"] as? Bool ?? true
290
+ }
291
+ guard let id, !id.isEmpty else {
292
+ scrollTargetKey = nil
293
+ pendingScrollTarget = nil
294
+ return
295
+ }
296
+ let key: String
297
+ if let target = value as? [String: Any],
298
+ let data = try? JSONSerialization.data(withJSONObject: target, options: [.sortedKeys]) {
299
+ key = String(decoding: data, as: UTF8.self)
300
+ } else {
301
+ key = id
302
+ }
303
+ guard key != scrollTargetKey else { return }
304
+ scrollTargetKey = key
305
+ pendingScrollTarget = (id, animated, 0)
306
+ scrollToPendingTarget()
274
307
  }
275
308
 
276
309
  func setContentContainerStyle(_ raw: [String: Any]?) {
@@ -473,6 +506,8 @@ final class CraftNativeFlatList: UICollectionView, UICollectionViewDelegateFlowL
473
506
  onMomentumScrollBegin = nil
474
507
  onMomentumScrollEnd = nil
475
508
  pendingThemeRefresh = false
509
+ scrollTargetKey = nil
510
+ pendingScrollTarget = nil
476
511
  }
477
512
 
478
513
  func refreshThemeDefaults() {
@@ -543,10 +578,39 @@ final class CraftNativeFlatList: UICollectionView, UICollectionViewDelegateFlowL
543
578
  self.refreshThemeDefaults()
544
579
  return
545
580
  }
581
+ self.scrollToPendingTarget()
546
582
  self.evaluateEndReached()
547
583
  }
548
584
  }
549
585
 
586
+ private func targetIndex(for id: String) -> Int? {
587
+ items.firstIndex { item in
588
+ let props = item.node["props"] as? [String: Any] ?? [:]
589
+ return [props["testID"], props["id"], item.node["id"], item.identity]
590
+ .compactMap { $0 as? String }
591
+ .contains(id)
592
+ }
593
+ }
594
+
595
+ private func scrollToPendingTarget() {
596
+ guard let target = pendingScrollTarget else { return }
597
+ guard let index = targetIndex(for: target.id), index < numberOfItems(inSection: 0) else {
598
+ if target.attempts >= 4 {
599
+ // A diffable snapshot may still be applying. Keep the target
600
+ // for finishApplyingSnapshot(), but discard an invalid target
601
+ // once the list is otherwise idle.
602
+ if !isApplyingSnapshot { pendingScrollTarget = nil }
603
+ return
604
+ }
605
+ pendingScrollTarget = (target.id, target.animated, target.attempts + 1)
606
+ DispatchQueue.main.async { [weak self] in self?.scrollToPendingTarget() }
607
+ return
608
+ }
609
+ pendingScrollTarget = nil
610
+ let position: UICollectionView.ScrollPosition = flowLayout.scrollDirection == .horizontal ? .left : .top
611
+ scrollToItem(at: IndexPath(item: index, section: 0), at: position, animated: target.animated)
612
+ }
613
+
550
614
  private func clamped(_ offset: CGPoint) -> CGPoint {
551
615
  CGPoint(
552
616
  x: min(max(-adjustedContentInset.left, offset.x), max(-adjustedContentInset.left, contentSize.width - bounds.width + adjustedContentInset.right)),