craft-native 0.0.204 → 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/android/src/index.js +90 -0
- package/dist/android/templates/CraftNativeFlatList.kt.template +117 -0
- package/dist/android/templates/CraftNativeShell.kt.template +42 -10
- package/dist/android/templates/MainActivityNative.kt.template +527 -50
- package/dist/cli.js +1 -1
- package/dist/components/index.d.ts +118 -74
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/ios/src/testing.d.ts +4 -4
- package/dist/ios/templates/CraftHybrid.swift +17 -3
- package/dist/ios/templates/CraftNativeFlatList.swift +64 -0
- package/dist/ios/templates/CraftNativeScreen.swift +307 -43
- package/dist/ios/templates/testing/DriverTests.swift.template +32 -3
- package/package.json +1 -1
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.
|
|
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' | '
|
|
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
|
-
}
|
|
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' | '
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
/**
|
|
528
|
-
|
|
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'
|
|
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
|
-
|
|
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
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
|
@@ -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
|
|
150
|
-
|
|
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)),
|