@hzblj/kara-components 0.6.0 → 0.7.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.
- package/CHANGELOG.md +49 -0
- package/README.md +31 -3
- package/lib/module/atoms/checkbox/checkbox.android.js +7 -3
- package/lib/module/atoms/checkbox/checkbox.android.js.map +1 -1
- package/lib/module/atoms/date-picker/date-picker.ios.js +32 -11
- package/lib/module/atoms/date-picker/date-picker.ios.js.map +1 -1
- package/lib/module/atoms/index.js +0 -1
- package/lib/module/atoms/index.js.map +1 -1
- package/lib/module/atoms/rn-flat-list/rn-flat-list.js +10 -9
- package/lib/module/atoms/rn-flat-list/rn-flat-list.js.map +1 -1
- package/lib/module/atoms/rn-section-list/rn-section-list.js +5 -8
- package/lib/module/atoms/rn-section-list/rn-section-list.js.map +1 -1
- package/lib/module/atoms/segmented-control/index.js +1 -1
- package/lib/module/atoms/segmented-control/index.js.map +1 -1
- package/lib/module/atoms/segmented-control/segmented-control.android.js +74 -0
- package/lib/module/atoms/segmented-control/segmented-control.android.js.map +1 -0
- package/lib/module/atoms/segmented-control/segmented-control.ios.js +44 -0
- package/lib/module/atoms/segmented-control/segmented-control.ios.js.map +1 -0
- package/lib/module/atoms/switch/switch.android.js +4 -1
- package/lib/module/atoms/switch/switch.android.js.map +1 -1
- package/lib/module/molecules/search-bar/search-bar.js +15 -2
- package/lib/module/molecules/search-bar/search-bar.js.map +1 -1
- package/lib/module/molecules/tooltip/tooltip.android.js +16 -5
- package/lib/module/molecules/tooltip/tooltip.android.js.map +1 -1
- package/lib/module/organisms/action-sheet/action-sheet.android.js +41 -20
- package/lib/module/organisms/action-sheet/action-sheet.android.js.map +1 -1
- package/lib/module/organisms/action-sheet/action-sheet.ios.js +24 -8
- package/lib/module/organisms/action-sheet/action-sheet.ios.js.map +1 -1
- package/lib/module/organisms/alert/alert.ios.js +15 -2
- package/lib/module/organisms/alert/alert.ios.js.map +1 -1
- package/lib/module/organisms/form/form.android.js +22 -9
- package/lib/module/organisms/form/form.android.js.map +1 -1
- package/lib/module/organisms/swipe-actions/swipe-actions.android.js +125 -11
- package/lib/module/organisms/swipe-actions/swipe-actions.android.js.map +1 -1
- package/lib/module/organisms/swipe-actions/swipe-actions.ios.js +46 -18
- package/lib/module/organisms/swipe-actions/swipe-actions.ios.js.map +1 -1
- package/lib/module/templates/screen/screen.android.js +31 -10
- package/lib/module/templates/screen/screen.android.js.map +1 -1
- package/lib/typescript/atoms/avatar/avatar.types.d.ts +5 -0
- package/lib/typescript/atoms/badge/badge.types.d.ts +3 -0
- package/lib/typescript/atoms/button/button.types.d.ts +12 -0
- package/lib/typescript/atoms/card/card.types.d.ts +6 -0
- package/lib/typescript/atoms/checkbox/checkbox.types.d.ts +5 -0
- package/lib/typescript/atoms/chip/chip.types.d.ts +5 -0
- package/lib/typescript/atoms/color-picker/color-picker.types.d.ts +4 -0
- package/lib/typescript/atoms/date-picker/date-picker.ios.d.ts +6 -1
- package/lib/typescript/atoms/date-picker/date-picker.types.d.ts +14 -0
- package/lib/typescript/atoms/divider/divider.types.d.ts +3 -0
- package/lib/typescript/atoms/fab/fab.types.d.ts +7 -0
- package/lib/typescript/atoms/glass-view/glass-view.types.d.ts +1 -0
- package/lib/typescript/atoms/h-stack/h-stack.types.d.ts +6 -0
- package/lib/typescript/atoms/icon/icon.types.d.ts +8 -0
- package/lib/typescript/atoms/icon-button/icon-button.types.d.ts +5 -0
- package/lib/typescript/atoms/index.d.ts +0 -1
- package/lib/typescript/atoms/island/island.types.d.ts +4 -0
- package/lib/typescript/atoms/list/list.types.d.ts +2 -0
- package/lib/typescript/atoms/picker/picker.types.d.ts +12 -0
- package/lib/typescript/atoms/pressable/pressable.types.d.ts +8 -0
- package/lib/typescript/atoms/progress/progress.types.d.ts +6 -0
- package/lib/typescript/atoms/rn-flat-list/rn-flat-list.d.ts +5 -8
- package/lib/typescript/atoms/rn-flat-list/rn-flat-list.types.d.ts +3 -1
- package/lib/typescript/atoms/rn-scroll-view/rn-scroll-view.types.d.ts +4 -0
- package/lib/typescript/atoms/rn-section-list/rn-section-list.d.ts +2 -8
- package/lib/typescript/atoms/rn-section-list/rn-section-list.types.d.ts +3 -1
- package/lib/typescript/atoms/rn-text/rn-text.types.d.ts +4 -0
- package/lib/typescript/atoms/rn-view/rn-view.types.d.ts +2 -0
- package/lib/typescript/atoms/scroll-view/scroll-view.types.d.ts +4 -0
- package/lib/typescript/atoms/segmented-control/segmented-control.d.ts +1 -6
- package/lib/typescript/atoms/segmented-control/segmented-control.ios.d.ts +7 -0
- package/lib/typescript/atoms/segmented-control/segmented-control.types.d.ts +13 -0
- package/lib/typescript/atoms/skeleton/skeleton.types.d.ts +5 -0
- package/lib/typescript/atoms/slider/slider.types.d.ts +7 -0
- package/lib/typescript/atoms/spacer/spacer.types.d.ts +3 -0
- package/lib/typescript/atoms/surface/surface.types.d.ts +7 -0
- package/lib/typescript/atoms/switch/switch.types.d.ts +8 -0
- package/lib/typescript/atoms/text/text.types.d.ts +12 -0
- package/lib/typescript/atoms/text-field/text-field.types.d.ts +12 -0
- package/lib/typescript/atoms/v-stack/v-stack.types.d.ts +9 -0
- package/lib/typescript/atoms/z-stack/z-stack.types.d.ts +8 -0
- package/lib/typescript/molecules/collapsible/collapsible.types.d.ts +8 -0
- package/lib/typescript/molecules/empty-state/empty-state.types.d.ts +5 -0
- package/lib/typescript/molecules/label/label.types.d.ts +6 -0
- package/lib/typescript/molecules/labeled-content/labeled-content.types.d.ts +6 -0
- package/lib/typescript/molecules/link/link.types.d.ts +6 -0
- package/lib/typescript/molecules/list-item/list-item.types.d.ts +9 -0
- package/lib/typescript/molecules/navigation-bar/navigation-bar.types.d.ts +8 -0
- package/lib/typescript/molecules/pager/pager.types.d.ts +2 -0
- package/lib/typescript/molecules/radio-group/radio-group.types.d.ts +10 -0
- package/lib/typescript/molecules/rn-list-item/rn-list-item.types.d.ts +1 -1
- package/lib/typescript/molecules/rn-tooltip/rn-tooltip.types.d.ts +11 -0
- package/lib/typescript/molecules/scroll-edge-container/scroll-edge-container.types.d.ts +3 -0
- package/lib/typescript/molecules/search-bar/search-bar.types.d.ts +8 -0
- package/lib/typescript/molecules/stepper/stepper.types.d.ts +13 -0
- package/lib/typescript/molecules/tooltip/tooltip.types.d.ts +12 -0
- package/lib/typescript/organisms/action-sheet/action-sheet.types.d.ts +8 -0
- package/lib/typescript/organisms/alert/alert.types.d.ts +11 -0
- package/lib/typescript/organisms/context-menu/context-menu.types.d.ts +4 -0
- package/lib/typescript/organisms/fab-menu/fab-menu.types.d.ts +2 -0
- package/lib/typescript/organisms/form/form.types.d.ts +6 -0
- package/lib/typescript/organisms/menu/menu.types.d.ts +17 -0
- package/lib/typescript/organisms/sheet/sheet.types.d.ts +19 -0
- package/lib/typescript/organisms/snackbar/snackbar.types.d.ts +8 -0
- package/lib/typescript/organisms/swipe-actions/swipe-actions.types.d.ts +36 -13
- package/lib/typescript/templates/screen/screen.types.d.ts +9 -0
- package/package.json +5 -7
- package/src/atoms/avatar/avatar.types.ts +5 -0
- package/src/atoms/badge/badge.types.ts +3 -0
- package/src/atoms/button/button.types.ts +12 -0
- package/src/atoms/card/card.types.ts +6 -0
- package/src/atoms/checkbox/checkbox.android.tsx +7 -3
- package/src/atoms/checkbox/checkbox.types.ts +5 -0
- package/src/atoms/chip/chip.types.ts +5 -0
- package/src/atoms/color-picker/color-picker.types.ts +4 -0
- package/src/atoms/date-picker/date-picker.ios.tsx +33 -13
- package/src/atoms/date-picker/date-picker.types.ts +14 -0
- package/src/atoms/divider/divider.types.ts +3 -0
- package/src/atoms/fab/fab.types.ts +7 -0
- package/src/atoms/glass-view/glass-view.types.ts +1 -0
- package/src/atoms/h-stack/h-stack.types.ts +6 -0
- package/src/atoms/icon/icon.types.ts +8 -0
- package/src/atoms/icon-button/icon-button.types.ts +5 -0
- package/src/atoms/index.ts +0 -1
- package/src/atoms/island/island.types.ts +4 -0
- package/src/atoms/list/list.types.ts +2 -0
- package/src/atoms/picker/picker.types.ts +12 -0
- package/src/atoms/pressable/pressable.types.ts +8 -0
- package/src/atoms/progress/progress.types.ts +6 -0
- package/src/atoms/rn-flat-list/rn-flat-list.tsx +8 -8
- package/src/atoms/rn-flat-list/rn-flat-list.types.ts +3 -1
- package/src/atoms/rn-scroll-view/rn-scroll-view.types.ts +4 -0
- package/src/atoms/rn-section-list/rn-section-list.tsx +5 -8
- package/src/atoms/rn-section-list/rn-section-list.types.ts +3 -1
- package/src/atoms/rn-text/rn-text.types.ts +4 -0
- package/src/atoms/rn-view/rn-view.types.ts +2 -0
- package/src/atoms/scroll-view/scroll-view.types.ts +4 -0
- package/src/atoms/segmented-control/segmented-control.android.tsx +79 -0
- package/src/atoms/segmented-control/segmented-control.ios.tsx +47 -0
- package/src/atoms/segmented-control/segmented-control.types.ts +13 -0
- package/src/atoms/skeleton/skeleton.types.ts +5 -0
- package/src/atoms/slider/slider.types.ts +7 -0
- package/src/atoms/spacer/spacer.types.ts +3 -0
- package/src/atoms/surface/surface.types.ts +7 -0
- package/src/atoms/switch/switch.android.tsx +4 -1
- package/src/atoms/switch/switch.types.ts +8 -0
- package/src/atoms/text/text.types.ts +12 -0
- package/src/atoms/text-field/text-field.types.ts +12 -0
- package/src/atoms/v-stack/v-stack.types.ts +9 -0
- package/src/atoms/z-stack/z-stack.types.ts +8 -0
- package/src/molecules/collapsible/collapsible.types.ts +8 -0
- package/src/molecules/empty-state/empty-state.types.ts +5 -0
- package/src/molecules/label/label.types.ts +6 -0
- package/src/molecules/labeled-content/labeled-content.types.ts +6 -0
- package/src/molecules/link/link.types.ts +6 -0
- package/src/molecules/list-item/list-item.types.ts +9 -0
- package/src/molecules/navigation-bar/navigation-bar.types.ts +8 -0
- package/src/molecules/pager/pager.types.ts +2 -0
- package/src/molecules/radio-group/radio-group.types.ts +10 -0
- package/src/molecules/rn-list-item/rn-list-item.types.ts +1 -1
- package/src/molecules/rn-tooltip/rn-tooltip.types.ts +11 -0
- package/src/molecules/scroll-edge-container/scroll-edge-container.types.ts +3 -0
- package/src/molecules/search-bar/search-bar.tsx +9 -2
- package/src/molecules/search-bar/search-bar.types.ts +8 -0
- package/src/molecules/stepper/stepper.types.ts +13 -0
- package/src/molecules/tooltip/tooltip.android.tsx +17 -9
- package/src/molecules/tooltip/tooltip.types.ts +12 -0
- package/src/organisms/action-sheet/action-sheet.android.tsx +37 -19
- package/src/organisms/action-sheet/action-sheet.ios.tsx +22 -9
- package/src/organisms/action-sheet/action-sheet.types.ts +8 -0
- package/src/organisms/alert/alert.ios.tsx +11 -1
- package/src/organisms/alert/alert.types.ts +11 -0
- package/src/organisms/context-menu/context-menu.types.ts +4 -0
- package/src/organisms/fab-menu/fab-menu.types.ts +2 -0
- package/src/organisms/form/form.android.tsx +15 -7
- package/src/organisms/form/form.types.ts +6 -0
- package/src/organisms/menu/menu.types.ts +17 -0
- package/src/organisms/sheet/sheet.types.ts +19 -0
- package/src/organisms/snackbar/snackbar.types.ts +8 -0
- package/src/organisms/swipe-actions/swipe-actions.android.tsx +129 -9
- package/src/organisms/swipe-actions/swipe-actions.ios.tsx +45 -11
- package/src/organisms/swipe-actions/swipe-actions.types.ts +37 -14
- package/src/templates/screen/screen.android.tsx +33 -12
- package/src/templates/screen/screen.types.ts +9 -0
- package/lib/module/atoms/flash-list/flash-list.js +0 -31
- package/lib/module/atoms/flash-list/flash-list.js.map +0 -1
- package/lib/module/atoms/flash-list/flash-list.types.js +0 -4
- package/lib/module/atoms/flash-list/flash-list.types.js.map +0 -1
- package/lib/module/atoms/flash-list/index.js +0 -5
- package/lib/module/atoms/flash-list/index.js.map +0 -1
- package/lib/module/atoms/segmented-control/segmented-control.js +0 -40
- package/lib/module/atoms/segmented-control/segmented-control.js.map +0 -1
- package/lib/typescript/atoms/flash-list/flash-list.d.ts +0 -8
- package/lib/typescript/atoms/flash-list/flash-list.types.d.ts +0 -18
- package/lib/typescript/atoms/flash-list/index.d.ts +0 -2
- package/src/atoms/flash-list/flash-list.tsx +0 -28
- package/src/atoms/flash-list/flash-list.types.ts +0 -20
- package/src/atoms/flash-list/index.ts +0 -2
- package/src/atoms/segmented-control/segmented-control.tsx +0 -47
|
@@ -11,12 +11,22 @@ export type ButtonStyleName = 'automatic' | 'bordered' | 'borderedProminent' | '
|
|
|
11
11
|
* whatever the surrounding SwiftUI environment provides.
|
|
12
12
|
*/
|
|
13
13
|
export type ButtonControlSize = 'extraLarge' | 'large' | 'mini' | 'regular' | 'small';
|
|
14
|
+
/** A text button — SwiftUI `Button` on iOS, Material's filled button (outlined for `glass`) on Android. */
|
|
14
15
|
export type ButtonProps = {
|
|
16
|
+
/**
|
|
17
|
+
* Replaces the style the variant picks — `borderedProminent` for `accent` and `destructive`, `bordered` for
|
|
18
|
+
* `secondary`, `glass` for `glass`. iOS only — Android ignores it.
|
|
19
|
+
*/
|
|
15
20
|
buttonStyle?: ButtonStyleName;
|
|
21
|
+
/** SwiftUI's control size. `large` by default. iOS only — Android ignores it. */
|
|
16
22
|
controlSize?: ButtonControlSize;
|
|
23
|
+
/** Draws the button in its disabled colours and stops it responding to presses. */
|
|
17
24
|
disabled?: boolean;
|
|
25
|
+
/** The button's text. */
|
|
18
26
|
label: string;
|
|
27
|
+
/** Called when the button is pressed. */
|
|
19
28
|
onPress?: () => void;
|
|
29
|
+
/** Test identifier, forwarded to the native view. */
|
|
20
30
|
testID?: string;
|
|
21
31
|
/**
|
|
22
32
|
* Overrides the variant's own tint. A prominent style takes it as the fill and picks a contrasting
|
|
@@ -24,7 +34,9 @@ export type ButtonProps = {
|
|
|
24
34
|
* the stock `.glass` style — see the iOS implementation.
|
|
25
35
|
*/
|
|
26
36
|
tint?: ColorToken;
|
|
37
|
+
/** The look. `accent` by default. Material has no glass, so on Android `glass` is an outlined button. */
|
|
27
38
|
variant?: ButtonVariant;
|
|
39
|
+
/** Stretches the button to the full width it is offered. On by default. */
|
|
28
40
|
wide?: boolean;
|
|
29
41
|
};
|
|
30
42
|
export type ButtonComponent = (props: ButtonProps) => ReactNode;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { ResponsiveSx } from '@hzblj/kara-sx';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* A raised container — SwiftUI `VStack` / Compose `Column` on `surface.primary`, with a large radius, `s16` padding and
|
|
5
|
+
* the `card` shadow. Any `sx` prop overrides its default.
|
|
6
|
+
*/
|
|
3
7
|
export type CardProps = ResponsiveSx & {
|
|
8
|
+
/** Native views, stacked vertically from the leading edge. */
|
|
4
9
|
children?: ReactNode;
|
|
10
|
+
/** Test identifier, forwarded to the native view. */
|
|
5
11
|
testID?: string;
|
|
6
12
|
};
|
|
7
13
|
export type CardComponent = (props: CardProps) => ReactNode;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
/** Material's `Checkbox` on Android. iOS has none, so there it is a SwiftUI `Toggle` — the same switch as `Switch`. */
|
|
2
3
|
export type CheckboxProps = {
|
|
4
|
+
/** Dims the control and ignores taps. */
|
|
3
5
|
disabled?: boolean;
|
|
6
|
+
/** Text beside the control. On Android the whole labelled row toggles it. */
|
|
4
7
|
label?: string;
|
|
8
|
+
/** Called with the new value when the user toggles it. */
|
|
5
9
|
onValueChange?: (value: boolean) => void;
|
|
10
|
+
/** Whether it is checked. Controlled — update it from `onValueChange`. */
|
|
6
11
|
value: boolean;
|
|
7
12
|
};
|
|
8
13
|
export type CheckboxComponent = (props: CheckboxProps) => ReactNode;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
/** A filter pill on a `Pressable`, not a native control — the React Native tier, so it needs no host. */
|
|
2
3
|
export type ChipProps = {
|
|
4
|
+
/** The text in the pill. */
|
|
3
5
|
label: string;
|
|
6
|
+
/** Called when the chip is pressed, with the `selection` haptic. */
|
|
4
7
|
onPress?: () => void;
|
|
8
|
+
/** Draws the chip in the accent colours. Off by default. */
|
|
5
9
|
selected?: boolean;
|
|
10
|
+
/** Test identifier, forwarded to the view. */
|
|
6
11
|
testID?: string;
|
|
7
12
|
};
|
|
8
13
|
export type ChipComponent = (props: ChipProps) => ReactNode;
|
|
@@ -4,9 +4,13 @@ import type { ReactNode } from 'react';
|
|
|
4
4
|
* renders nothing and says so in dev. Branch on `Platform.OS` if the screen needs a fallback.
|
|
5
5
|
*/
|
|
6
6
|
export type ColorPickerProps = {
|
|
7
|
+
/** Text beside the colour well. */
|
|
7
8
|
label?: string;
|
|
9
|
+
/** Called with the colour the user picks. */
|
|
8
10
|
onValueChange?: (color: string) => void;
|
|
11
|
+
/** Lets the user pick an opacity as well. Off by default. */
|
|
9
12
|
supportsOpacity?: boolean;
|
|
13
|
+
/** Test identifier, forwarded to the native view. */
|
|
10
14
|
testID?: string;
|
|
11
15
|
/** `#RRGGBB` or `#RRGGBBAA`. */
|
|
12
16
|
value: string | null;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import type { DatePickerComponent } from './date-picker.types';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* The system's compact date picker: the value in a pill, and a tap on it opens the calendar popover UIKit owns. Its own
|
|
4
|
+
* host, sized to the pill on both axes — a host that took the width it was given would lay the pill out against the
|
|
5
|
+
* far edge of it, or past its container's — so it drops into a row the way a `Text` does. The label is the caller's,
|
|
6
|
+
* beside it; the calendar is in the accent.
|
|
7
|
+
*/
|
|
3
8
|
export declare const DatePicker: DatePickerComponent;
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
export type DatePickerMode = 'date' | 'datetime' | 'time';
|
|
3
|
+
/**
|
|
4
|
+
* A date or time picker — SwiftUI's compact `DatePicker` on iOS, a field that opens Material's picker dialog on a tap
|
|
5
|
+
* on Android. The React Native tier: it brings its own host and sizes itself to the value, so it sits in a row beside
|
|
6
|
+
* its label like a `Text`.
|
|
7
|
+
*/
|
|
3
8
|
export type DatePickerProps = {
|
|
9
|
+
/** The latest date that can be picked. Android ignores it in `time` mode. */
|
|
4
10
|
max?: Date;
|
|
11
|
+
/** The earliest date that can be picked. Android ignores it in `time` mode. */
|
|
5
12
|
min?: Date;
|
|
13
|
+
/**
|
|
14
|
+
* What it picks. `date` by default. Android has no combined dialog, so there `datetime` picks the date and keeps
|
|
15
|
+
* `value`'s time of day.
|
|
16
|
+
*/
|
|
6
17
|
mode?: DatePickerMode;
|
|
18
|
+
/** Called with the new date — on iOS as it changes, on Android when the dialog is confirmed. */
|
|
7
19
|
onValueChange?: (date: Date) => void;
|
|
20
|
+
/** Test identifier — on the native picker on iOS, on the tappable field on Android. */
|
|
8
21
|
testID?: string;
|
|
22
|
+
/** The selected date. Controlled — update it from `onValueChange`. */
|
|
9
23
|
value: Date;
|
|
10
24
|
};
|
|
11
25
|
export type DatePickerComponent = (props: DatePickerProps) => ReactNode;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { ColorToken } from '@hzblj/kara-theme';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
|
+
/** A horizontal hairline — SwiftUI `Divider` / Compose `HorizontalDivider`. */
|
|
3
4
|
export type DividerProps = {
|
|
5
|
+
/** The line's colour. `border.tertiary` by default. */
|
|
4
6
|
color?: ColorToken;
|
|
7
|
+
/** Test identifier, forwarded to the native view on iOS — Android ignores it. */
|
|
5
8
|
testID?: string;
|
|
6
9
|
};
|
|
7
10
|
export type DividerComponent = (props: DividerProps) => ReactNode;
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { IconName } from '../icon';
|
|
3
|
+
/**
|
|
4
|
+
* A floating action button — Material's `FloatingActionButton` on Android, a 56pt accent circle (a plain SwiftUI
|
|
5
|
+
* `Button`) on iOS. It renders inline; pinning it to a corner is up to the screen.
|
|
6
|
+
*/
|
|
3
7
|
export type FabProps = {
|
|
8
|
+
/** The icon, one of the app's, drawn in `content.on.bg`. */
|
|
4
9
|
name: IconName;
|
|
10
|
+
/** Called when the button is pressed. */
|
|
5
11
|
onPress?: () => void;
|
|
12
|
+
/** Test identifier, forwarded to the native view on iOS — Android ignores it. */
|
|
6
13
|
testID?: string;
|
|
7
14
|
};
|
|
8
15
|
export type FabComponent = (props: FabProps) => ReactNode;
|
|
@@ -11,6 +11,7 @@ export type GlassViewProps = ResponsiveViewSx & {
|
|
|
11
11
|
children?: ReactNode;
|
|
12
12
|
/** Swells toward the finger on touch, carrying the children with it. Wrap the view in a `Pressable` for the press. */
|
|
13
13
|
interactive?: boolean;
|
|
14
|
+
/** Test identifier, forwarded to the view. */
|
|
14
15
|
testID?: string;
|
|
15
16
|
/** Tints the material. Unset leaves it clear. */
|
|
16
17
|
tint?: ColorToken;
|
|
@@ -2,11 +2,17 @@ import type { ResponsiveSx } from '@hzblj/kara-sx';
|
|
|
2
2
|
import type { SpaceSize } from '@hzblj/kara-theme';
|
|
3
3
|
import type { ReactNode } from 'react';
|
|
4
4
|
export type HStackAlign = 'center' | 'end' | 'start';
|
|
5
|
+
/** A horizontal stack — SwiftUI `HStack` / Compose `Row`. */
|
|
5
6
|
export type HStackProps = ResponsiveSx & {
|
|
7
|
+
/** How the children line up vertically — `start` is the top, `end` the bottom. `start` by default. */
|
|
6
8
|
align?: HStackAlign;
|
|
9
|
+
/** Native views, laid out from the leading edge. */
|
|
7
10
|
children?: ReactNode;
|
|
11
|
+
/** Makes the stack pressable — a tap gesture on iOS, a `clickable` with Material's ripple on Android. */
|
|
8
12
|
onPress?: () => void;
|
|
13
|
+
/** The gap between children. Unset, SwiftUI puts its default spacing between them and Compose none. */
|
|
9
14
|
spacing?: SpaceSize;
|
|
15
|
+
/** Test identifier, forwarded to the native view. */
|
|
10
16
|
testID?: string;
|
|
11
17
|
};
|
|
12
18
|
export type HStackComponent = (props: HStackProps) => ReactNode;
|
|
@@ -15,12 +15,20 @@ type DeclaredIconName = keyof KaraIcons & string;
|
|
|
15
15
|
* from the folder fails at every call site. Before that, any string, so a project can adopt icons gradually.
|
|
16
16
|
*/
|
|
17
17
|
export type IconName = [DeclaredIconName] extends [never] ? string : DeclaredIconName;
|
|
18
|
+
/**
|
|
19
|
+
* One of the app's icons, in a host — SwiftUI `Image` from the asset catalog on iOS, Material's `Icon` with the vector
|
|
20
|
+
* drawable on Android. `RnIcon` draws the same asset outside one.
|
|
21
|
+
*/
|
|
18
22
|
export type IconProps = {
|
|
19
23
|
/** What a screen reader says. Unset, the icon is decorative and hidden from it. */
|
|
20
24
|
accessibilityLabel?: string;
|
|
25
|
+
/** The icon's tint. `content.primary` by default. */
|
|
21
26
|
color?: ColorToken;
|
|
27
|
+
/** Which of the app's icons — a key of `KaraIcons`. */
|
|
22
28
|
name: IconName;
|
|
29
|
+
/** Its width and height, a spacing token. `s24` by default. */
|
|
23
30
|
size?: SpaceSize;
|
|
31
|
+
/** Test identifier, forwarded to the native view on iOS — Android ignores it. */
|
|
24
32
|
testID?: string;
|
|
25
33
|
};
|
|
26
34
|
export type IconComponent = (props: IconProps) => ReactNode;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { IconName } from '../icon';
|
|
3
|
+
/** A button that is just an icon — a plain SwiftUI `Button` on iOS, Material's `IconButton` on Android. */
|
|
3
4
|
export type IconButtonProps = {
|
|
5
|
+
/** Draws the icon in `btn.content.disabled` and stops the button responding to presses. */
|
|
4
6
|
disabled?: boolean;
|
|
7
|
+
/** The icon, one of the app's. */
|
|
5
8
|
name: IconName;
|
|
9
|
+
/** Called when the button is pressed. */
|
|
6
10
|
onPress?: () => void;
|
|
11
|
+
/** Test identifier, forwarded to the native view on iOS — Android ignores it. */
|
|
7
12
|
testID?: string;
|
|
8
13
|
};
|
|
9
14
|
export type IconButtonComponent = (props: IconButtonProps) => ReactNode;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
/** A host for native atoms in a React Native layout — the SwiftUI / Compose `Host` an `@expo/ui` tree mounts into. */
|
|
3
4
|
export type IslandProps = {
|
|
5
|
+
/** The native views it hosts. */
|
|
4
6
|
children?: ReactNode;
|
|
5
7
|
/**
|
|
6
8
|
* Sizes the island's height to its native content while the width still comes from the parent, which
|
|
@@ -14,7 +16,9 @@ export type IslandProps = {
|
|
|
14
16
|
* hangs the main thread as soon as the views lay out on screen.
|
|
15
17
|
*/
|
|
16
18
|
matchContents?: boolean;
|
|
19
|
+
/** A React Native style for the host view — its size and placement. It needs a height when `matchContents` is off. */
|
|
17
20
|
style?: StyleProp<ViewStyle>;
|
|
21
|
+
/** Test identifier, forwarded to the host view on iOS — Android ignores it. */
|
|
18
22
|
testID?: string;
|
|
19
23
|
};
|
|
20
24
|
export type IslandComponent = (props: IslandProps) => ReactNode;
|
|
@@ -9,12 +9,14 @@ import type { ReactNode } from 'react';
|
|
|
9
9
|
* the children is one too many: on iOS it becomes an empty row of its own.
|
|
10
10
|
*/
|
|
11
11
|
export type ListProps = {
|
|
12
|
+
/** The rows — native views, one row each. */
|
|
12
13
|
children: ReactNode;
|
|
13
14
|
/**
|
|
14
15
|
* Enables pull-to-refresh. Async on purpose — see `ScrollViewProps.onRefresh`: the spinner runs
|
|
15
16
|
* until the promise settles, so neither platform needs a `refreshing` flag kept in sync by hand.
|
|
16
17
|
*/
|
|
17
18
|
onRefresh?: () => Promise<void>;
|
|
19
|
+
/** Test identifier, forwarded to the native view on iOS — Android ignores it. */
|
|
18
20
|
testID?: string;
|
|
19
21
|
};
|
|
20
22
|
export type ListComponent = (props: ListProps) => ReactNode;
|
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
/** One choice of a `Picker`. */
|
|
2
3
|
export type PickerOption = {
|
|
4
|
+
/** What the user reads. */
|
|
3
5
|
label: string;
|
|
6
|
+
/** What `onValueChange` reports. It also keys the option, so it must be unique. */
|
|
4
7
|
value: string;
|
|
5
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* A single choice from a list — a SwiftUI wheel picker on iOS, Material's exposed dropdown on Android. It brings its
|
|
11
|
+
* own host, so it renders outside `Screen` and `Island` as well.
|
|
12
|
+
*/
|
|
6
13
|
export type PickerProps = {
|
|
14
|
+
/** Stops the user changing the selection, and dims the picker. */
|
|
7
15
|
disabled?: boolean;
|
|
16
|
+
/** Called with the chosen option's `value`. */
|
|
8
17
|
onValueChange?: (value: string) => void;
|
|
18
|
+
/** The choices, in order. */
|
|
9
19
|
options: PickerOption[];
|
|
20
|
+
/** Android: the dropdown field's test tag. iOS: `@expo/ui`'s wheel picker drops it. */
|
|
10
21
|
testID?: string;
|
|
22
|
+
/** The selected option's `value`. Controlled: pass back what `onValueChange` reports. */
|
|
11
23
|
value: string;
|
|
12
24
|
};
|
|
13
25
|
export type PickerComponent = (props: PickerProps) => ReactNode;
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import type { ResponsiveViewSx } from '@hzblj/kara-sx';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
import type { Haptic } from '../../haptics';
|
|
4
|
+
/**
|
|
5
|
+
* React Native's `Pressable`, styled through `sx` like a `Box`: it springs down to 96% while pressed and takes
|
|
6
|
+
* touches 8 points past its edges. The React Native tier — it needs no host.
|
|
7
|
+
*/
|
|
4
8
|
export type PressableProps = ResponsiveViewSx & {
|
|
9
|
+
/** The pressable content. */
|
|
5
10
|
children?: ReactNode;
|
|
11
|
+
/** Ignores presses — no `onPress`, no haptic, no spring. */
|
|
6
12
|
disabled?: boolean;
|
|
7
13
|
/** Played on press. `true` is a `light` impact; a name picks the haptic, e.g. `selection` for a choice. */
|
|
8
14
|
haptic?: boolean | Haptic;
|
|
15
|
+
/** Called when the press is released, after the `haptic` plays. */
|
|
9
16
|
onPress?: () => void;
|
|
17
|
+
/** Test identifier, forwarded to the view. */
|
|
10
18
|
testID?: string;
|
|
11
19
|
};
|
|
12
20
|
export type PressableComponent = (props: PressableProps) => ReactNode;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A progress bar or ring, tinted `fill.accent.primary` — SwiftUI `ProgressView` / Compose's
|
|
4
|
+
* `LinearProgressIndicator` and `CircularProgressIndicator`.
|
|
5
|
+
*/
|
|
2
6
|
export type ProgressProps = {
|
|
7
|
+
/** A circular indicator instead of a bar. Off by default. */
|
|
3
8
|
circular?: boolean;
|
|
9
|
+
/** Between `0` and `1`. Leave it unset for an indeterminate indicator. */
|
|
4
10
|
value?: number;
|
|
5
11
|
};
|
|
6
12
|
export type ProgressComponent = (props: ProgressProps) => ReactNode;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import type { RnFlatListProps } from './rn-flat-list.types';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* ends up drawn where the layout no longer is. `VirtualizedList` renders its cells in normal flow
|
|
9
|
-
* inside a scroll view, using blank spacers for the range it has not rendered, so a hosted view stays
|
|
10
|
-
* exactly where the layout put it. This is `SectionList`'s reason to exist too, without the sections.
|
|
3
|
+
* kara's list for React Native content: React Native's own `VirtualizedList`, styled through `sx`. It renders its
|
|
4
|
+
* cells in normal flow inside a scroll view, with blank spacers for the range it has not rendered, so a row that hosts
|
|
5
|
+
* native views keeps them where the layout put it. A recycling list (absolutely positioned, reused cells) cannot
|
|
6
|
+
* promise that — an `@expo/ui` host survives neither, and draws where the layout no longer is — which is why kara
|
|
7
|
+
* ships none.
|
|
11
8
|
*/
|
|
12
9
|
export declare const RnFlatList: <TItem>({ content, data, renderItem, ...props }: RnFlatListProps<TItem>) => import("react").JSX.Element;
|
|
@@ -2,8 +2,10 @@ import type { ResponsiveViewSx } from '@hzblj/kara-sx';
|
|
|
2
2
|
import type { FlatListProps as RNFlatListProps } from 'react-native';
|
|
3
3
|
/**
|
|
4
4
|
* Top-level `sx` styles the viewport; `content` styles the scrolling content container, so padding and
|
|
5
|
-
* gap belong there — the same split as `RnScrollView`.
|
|
5
|
+
* gap belong there — the same split as `RnScrollView`. `removeClippedSubviews` is off unless you turn it on:
|
|
6
|
+
* Android's default would detach a row's host before it has measured itself, and the row would stay empty.
|
|
6
7
|
*/
|
|
7
8
|
export type RnFlatListProps<TItem> = ResponsiveViewSx & Omit<RNFlatListProps<TItem>, 'contentContainerStyle' | 'style'> & {
|
|
9
|
+
/** Styles the scrolling content container — padding and gap belong here. */
|
|
8
10
|
content?: ResponsiveViewSx;
|
|
9
11
|
};
|
|
@@ -11,9 +11,13 @@ import type { ScrollViewAxis } from '../scroll-view';
|
|
|
11
11
|
* so padding and gap belong there.
|
|
12
12
|
*/
|
|
13
13
|
export type RnScrollViewProps = ResponsiveViewSx & Omit<RNScrollViewProps, 'contentContainerStyle' | 'horizontal' | 'style'> & {
|
|
14
|
+
/** The scroll direction. `vertical` by default. */
|
|
14
15
|
axis?: ScrollViewAxis;
|
|
16
|
+
/** The scrolling content. */
|
|
15
17
|
children?: ReactNode;
|
|
18
|
+
/** Styles the scrolling content container — padding and gap belong here. */
|
|
16
19
|
content?: ResponsiveViewSx;
|
|
20
|
+
/** Shows the scroll indicators. On by default. */
|
|
17
21
|
showsIndicators?: boolean;
|
|
18
22
|
};
|
|
19
23
|
export type RnScrollViewComponent = (props: RnScrollViewProps) => ReactNode;
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import { type DefaultSectionT } from 'react-native';
|
|
2
2
|
import type { RnSectionListProps } from './rn-section-list.types';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* FlashList is the default for lists in this codebase and should stay that way for data rows. This
|
|
7
|
-
* exists for the case it cannot serve: content that hosts native views. FlashList positions its rows
|
|
8
|
-
* absolutely and recycles their cells, and an `@expo/ui` host does not survive either — the hosted
|
|
9
|
-
* view ends up drawn where the layout no longer is. `VirtualizedList` renders its cells in normal flow
|
|
10
|
-
* inside a scroll view, using blank spacers for the range it has not rendered, so a hosted view stays
|
|
11
|
-
* exactly where the layout put it.
|
|
4
|
+
* `RnFlatList` with sections: React Native's own `VirtualizedList`, cells in normal flow inside a scroll view, so a
|
|
5
|
+
* row that hosts native views keeps them where the layout put it.
|
|
12
6
|
*
|
|
13
7
|
* Sticky headers default off, unlike React Native, where they are on for vertical lists. A header that
|
|
14
8
|
* detaches and floats over the content is a deliberate effect, not something a list should do unasked.
|
|
@@ -2,8 +2,10 @@ import type { ResponsiveViewSx } from '@hzblj/kara-sx';
|
|
|
2
2
|
import type { DefaultSectionT, SectionListProps as RNSectionListProps } from 'react-native';
|
|
3
3
|
/**
|
|
4
4
|
* Top-level `sx` styles the viewport; `content` styles the scrolling content container, so padding and
|
|
5
|
-
* gap belong there — the same split as `RnScrollView` and `RnFlatList`.
|
|
5
|
+
* gap belong there — the same split as `RnScrollView` and `RnFlatList`. `removeClippedSubviews` is off unless
|
|
6
|
+
* you turn it on, as in `RnFlatList`: Android's default would leave rows with hosts in them empty.
|
|
6
7
|
*/
|
|
7
8
|
export type RnSectionListProps<TItem, TSection = DefaultSectionT> = ResponsiveViewSx & Omit<RNSectionListProps<TItem, TSection>, 'contentContainerStyle' | 'style'> & {
|
|
9
|
+
/** Styles the scrolling content container — padding and gap belong here. */
|
|
8
10
|
content?: ResponsiveViewSx;
|
|
9
11
|
};
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import type { ColorToken, TextVariant } from '@hzblj/kara-theme';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
import type { TextProps as RNTextProps } from 'react-native';
|
|
4
|
+
/** React Native's `Text` in a theme typography variant — the React Native tier, for text outside a native host. */
|
|
4
5
|
export type RnTextProps = Omit<RNTextProps, 'style'> & {
|
|
6
|
+
/** Horizontal alignment, as React Native's `textAlign`. */
|
|
5
7
|
align?: 'center' | 'left' | 'right';
|
|
8
|
+
/** The text's colour. `content.primary` by default. */
|
|
6
9
|
color?: ColorToken;
|
|
10
|
+
/** The typography variant. `body` by default. */
|
|
7
11
|
variant?: TextVariant;
|
|
8
12
|
};
|
|
9
13
|
export type RnTextComponent = (props: RnTextProps) => ReactNode;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
/** Carries a React Native view into a SwiftUI or Compose tree — `@expo/ui`'s `RNHostView` on both platforms. */
|
|
2
3
|
export type RnViewProps = {
|
|
3
4
|
/**
|
|
4
5
|
* A single React Native *view*. It may not contain React Native text: a bare string becomes a
|
|
@@ -14,6 +15,7 @@ export type RnViewProps = {
|
|
|
14
15
|
* intrinsic size and would otherwise stretch to fill the SwiftUI parent.
|
|
15
16
|
*/
|
|
16
17
|
matchContents?: boolean;
|
|
18
|
+
/** Not forwarded on either platform — give the child its own `testID`. */
|
|
17
19
|
testID?: string;
|
|
18
20
|
};
|
|
19
21
|
export type RnViewComponent = (props: RnViewProps) => ReactNode;
|
|
@@ -7,7 +7,9 @@ export type ScrollViewAxis = 'horizontal' | 'vertical';
|
|
|
7
7
|
* like React Native's `contentContainerStyle` padding and scrolls with the content.
|
|
8
8
|
*/
|
|
9
9
|
export type ScrollViewProps = ResponsiveSx & {
|
|
10
|
+
/** The scroll direction. `vertical` by default. */
|
|
10
11
|
axis?: ScrollViewAxis;
|
|
12
|
+
/** Laid out in a stack along `axis`. */
|
|
11
13
|
children?: ReactNode;
|
|
12
14
|
/**
|
|
13
15
|
* Enables pull-to-refresh. Async on purpose: the spinner runs until the promise settles, which is
|
|
@@ -19,7 +21,9 @@ export type ScrollViewProps = ResponsiveSx & {
|
|
|
19
21
|
onRefresh?: () => Promise<void>;
|
|
20
22
|
/** iOS only — Compose exposes no indicator toggle, so Android always shows the native one. */
|
|
21
23
|
showsIndicators?: boolean;
|
|
24
|
+
/** The space between children. */
|
|
22
25
|
spacing?: SpaceSize;
|
|
26
|
+
/** Test identifier, forwarded to the native view. */
|
|
23
27
|
testID?: string;
|
|
24
28
|
};
|
|
25
29
|
export type ScrollViewComponent = (props: ScrollViewProps) => ReactNode;
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* `UISegmentedControl` on iOS, Material's single-choice segmented buttons on Android. A new segment plays `selection`
|
|
4
|
-
* on Android, whose buttons play nothing of their own; iOS 26's control already gives its own feedback.
|
|
5
|
-
*/
|
|
6
|
-
export declare const SegmentedControl: SegmentedControlComponent;
|
|
1
|
+
export * from './segmented-control.ios';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SegmentedControlComponent } from './segmented-control.types';
|
|
2
|
+
/**
|
|
3
|
+
* kara's own `UISegmentedControl`, with the pill in the accent and white text on it — the system control tints only the
|
|
4
|
+
* pill, and SwiftUI's segmented picker not even that. A plain `UIView` in React Native layout: it needs no host, takes
|
|
5
|
+
* the width it is given and UIKit's height. UIKit plays the control's own feedback.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SegmentedControl: SegmentedControlComponent;
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A row of mutually exclusive segments, the selected one in the accent — kara's own `UISegmentedControl` on iOS,
|
|
4
|
+
* Material's single-choice segmented buttons on Android. It needs no `Screen` or `Island`: iOS is a plain view, Android
|
|
5
|
+
* brings its own host. It takes the width it is given; the height is the platform's.
|
|
6
|
+
*/
|
|
2
7
|
export type SegmentedControlProps = {
|
|
8
|
+
/** Stops the user changing the segment, and dims the control. */
|
|
3
9
|
disabled?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Called with the index and label of the segment the user picked — never for a tap on the one already selected.
|
|
12
|
+
* Android plays `selection`; iOS's control plays its own feedback.
|
|
13
|
+
*/
|
|
4
14
|
onChange?: (index: number, value: string) => void;
|
|
15
|
+
/** The selected segment. Controlled: pass back what `onChange` reports. */
|
|
5
16
|
selectedIndex: number;
|
|
17
|
+
/** Test identifier, on the whole control — reach a segment by its label. */
|
|
6
18
|
testID?: string;
|
|
19
|
+
/** The segments' labels, in order. */
|
|
7
20
|
values: string[];
|
|
8
21
|
};
|
|
9
22
|
export type SegmentedControlComponent = (props: SegmentedControlProps) => ReactNode;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { RadiiSize } from '@hzblj/kara-theme';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
|
+
/** A loading placeholder that pulses in `fill.quaternary` — a React Native view, so it needs no host. */
|
|
3
4
|
export type SkeletonProps = {
|
|
5
|
+
/** The corner radius. `small` by default. */
|
|
4
6
|
borderRadius?: RadiiSize;
|
|
7
|
+
/** In points. */
|
|
5
8
|
height: number;
|
|
9
|
+
/** Test identifier, forwarded to the view. */
|
|
6
10
|
testID?: string;
|
|
11
|
+
/** In points. Leave it unset and it fills the available width. */
|
|
7
12
|
width?: number;
|
|
8
13
|
};
|
|
9
14
|
export type SkeletonComponent = (props: SkeletonProps) => ReactNode;
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
/** SwiftUI `Slider` / Compose's Material `Slider`, tinted `fill.accent.primary`. */
|
|
2
3
|
export type SliderProps = {
|
|
4
|
+
/** Stops the user moving the thumb, and dims the slider. */
|
|
3
5
|
disabled?: boolean;
|
|
6
|
+
/** The upper end. `1` by default. */
|
|
4
7
|
max?: number;
|
|
8
|
+
/** The lower end. `0` by default. */
|
|
5
9
|
min?: number;
|
|
10
|
+
/** Called with the new value as the thumb moves. */
|
|
6
11
|
onValueChange?: (value: number) => void;
|
|
12
|
+
/** The increment between stops; leave it unset for a continuous slider. On Android every stop plays a `tick`. */
|
|
7
13
|
step?: number;
|
|
14
|
+
/** Between `min` and `max`. Controlled: pass back what `onValueChange` reports. */
|
|
8
15
|
value: number;
|
|
9
16
|
};
|
|
10
17
|
export type SliderComponent = (props: SliderProps) => ReactNode;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { SpaceSize } from '@hzblj/kara-theme';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
|
+
/** Takes up the free space in a stack — SwiftUI `Spacer` / Compose `Spacer` with `weight(1)`. */
|
|
3
4
|
export type SpacerProps = {
|
|
5
|
+
/** The least room it takes. iOS holds it along the stack's axis; Android as a minimum height only. */
|
|
4
6
|
min?: SpaceSize;
|
|
7
|
+
/** iOS: forwarded to the native view. Android ignores it. */
|
|
5
8
|
testID?: string;
|
|
6
9
|
};
|
|
7
10
|
export type SpacerComponent = (props: SpacerProps) => ReactNode;
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { ResponsiveSx } from '@hzblj/kara-sx';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* A container padded `s16` and rounded `large` unless told otherwise — a SwiftUI `VStack` on iOS, Material's
|
|
5
|
+
* `Surface` around a `Column` on Android.
|
|
6
|
+
*/
|
|
3
7
|
export type SurfaceProps = ResponsiveSx & {
|
|
8
|
+
/** Stacked vertically, from the leading edge. */
|
|
4
9
|
children?: ReactNode;
|
|
10
|
+
/** iOS wraps the content in a `GlassEffectContainer`; Android raises it to a tonal elevation of `3`. */
|
|
5
11
|
glass?: boolean;
|
|
12
|
+
/** Test identifier, forwarded to the native view. */
|
|
6
13
|
testID?: string;
|
|
7
14
|
};
|
|
8
15
|
export type SurfaceComponent = (props: SurfaceProps) => ReactNode;
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
/** SwiftUI `Toggle` / Compose `Switch`, tinted `fill.accent.primary`. */
|
|
2
3
|
export type SwitchProps = {
|
|
4
|
+
/** Stops the user flipping it, and dims it. */
|
|
3
5
|
disabled?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Shown beside the switch. On Android it makes a full-width row — label at the start, switch at the end — that
|
|
8
|
+
* toggles wherever it is tapped.
|
|
9
|
+
*/
|
|
4
10
|
label?: string;
|
|
11
|
+
/** Called with the new value when the user flips it. On Android a flip plays `toggleOn` / `toggleOff`. */
|
|
5
12
|
onValueChange?: (value: boolean) => void;
|
|
13
|
+
/** Whether it is on. Controlled: pass back what `onValueChange` reports. */
|
|
6
14
|
value: boolean;
|
|
7
15
|
};
|
|
8
16
|
export type SwitchComponent = (props: SwitchProps) => ReactNode;
|
|
@@ -3,14 +3,26 @@ import type { ReactNode } from 'react';
|
|
|
3
3
|
export type TextAlign = 'center' | 'left' | 'right';
|
|
4
4
|
export type TextDecoration = 'none' | 'strikethrough' | 'underline';
|
|
5
5
|
export type TextTransform = 'lowercase' | 'uppercase';
|
|
6
|
+
/** SwiftUI `Text` / Compose `Text` in a theme typography variant — a native atom; outside a host, use `RnText`. */
|
|
6
7
|
export type TextProps = {
|
|
8
|
+
/**
|
|
9
|
+
* How its lines align. iOS reads `left` and `right` as leading and trailing, so they flip in a right-to-left
|
|
10
|
+
* layout; Android keeps them as they are.
|
|
11
|
+
*/
|
|
7
12
|
align?: TextAlign;
|
|
13
|
+
/** The text. */
|
|
8
14
|
children?: ReactNode;
|
|
15
|
+
/** The text's colour. `content.primary` by default. */
|
|
9
16
|
color?: ColorToken;
|
|
17
|
+
/** An underline or a strikethrough. */
|
|
10
18
|
decoration?: TextDecoration;
|
|
19
|
+
/** The most lines it wraps to. iOS truncates the last with an ellipsis; Android clips it. */
|
|
11
20
|
numberOfLines?: number;
|
|
21
|
+
/** Test identifier, forwarded to the native view. */
|
|
12
22
|
testID?: string;
|
|
23
|
+
/** Upper- or lower-cases the text. Android applies it only when `children` is a plain string. */
|
|
13
24
|
transform?: TextTransform;
|
|
25
|
+
/** The typography variant. `body` by default. */
|
|
14
26
|
variant?: TextVariant;
|
|
15
27
|
};
|
|
16
28
|
export type TextComponent = (props: TextProps) => ReactNode;
|