@isoline-ui/react-native 0.0.0-stage → 0.1.0-alpha.3
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/LICENSE +22 -0
- package/NOTICE.md +12 -0
- package/README.md +104 -3
- package/dist/amount.d.ts +3 -0
- package/dist/calendar.d.ts +7 -0
- package/dist/components/action-chip.d.ts +9 -0
- package/dist/components/amount-field.d.ts +12 -0
- package/dist/components/avatar.d.ts +17 -0
- package/dist/components/back-button.d.ts +12 -0
- package/dist/components/back-icon.d.ts +3 -0
- package/dist/components/badge.d.ts +13 -0
- package/dist/components/banner.d.ts +14 -0
- package/dist/components/bottom-sheet-native.d.ts +11 -0
- package/dist/components/bottom-sheet-web.d.ts +18 -0
- package/dist/components/bottom-sheet.d.ts +3 -0
- package/dist/components/button-group.d.ts +26 -0
- package/dist/components/button.d.ts +48 -0
- package/dist/components/checkbox.d.ts +12 -0
- package/dist/components/color-picker.d.ts +21 -0
- package/dist/components/context-menu.d.ts +26 -0
- package/dist/components/date-picker.d.ts +64 -0
- package/dist/components/dialog-context.d.ts +2 -0
- package/dist/components/dialog.d.ts +20 -0
- package/dist/components/empty-state.d.ts +15 -0
- package/dist/components/expand-indicator.d.ts +27 -0
- package/dist/components/expressive-shape.d.ts +18 -0
- package/dist/components/fab-menu-legacy.d.ts +31 -0
- package/dist/components/fab-menu.d.ts +21 -0
- package/dist/components/filter-chip.d.ts +69 -0
- package/dist/components/floating-action-button.d.ts +15 -0
- package/dist/components/icon-button.d.ts +40 -0
- package/dist/components/icons.d.ts +18 -0
- package/dist/components/input.d.ts +9 -0
- package/dist/components/keyboard-inset-view.d.ts +15 -0
- package/dist/components/list-controls.d.ts +38 -0
- package/dist/components/loading-indicator.d.ts +9 -0
- package/dist/components/menu-sheet.d.ts +36 -0
- package/dist/components/panel-sheet.d.ts +8 -0
- package/dist/components/password-visibility.d.ts +5 -0
- package/dist/components/popover-layout.d.ts +25 -0
- package/dist/components/popover.d.ts +20 -0
- package/dist/components/pressable.d.ts +12 -0
- package/dist/components/radio-navigation.d.ts +11 -0
- package/dist/components/refresh-control.d.ts +16 -0
- package/dist/components/row-gap.d.ts +9 -0
- package/dist/components/search-field.d.ts +22 -0
- package/dist/components/select-field.d.ts +16 -0
- package/dist/components/settings-list.d.ts +98 -0
- package/dist/components/settings-row.d.ts +13 -0
- package/dist/components/sheet-frame.d.ts +27 -0
- package/dist/components/sheet-lifecycle.d.ts +36 -0
- package/dist/components/sheet-transition.d.ts +36 -0
- package/dist/components/slider.d.ts +21 -0
- package/dist/components/snackbar.d.ts +10 -0
- package/dist/components/split-button.d.ts +38 -0
- package/dist/components/squish.d.ts +20 -0
- package/dist/components/swipeable-row.d.ts +20 -0
- package/dist/components/switch.d.ts +8 -0
- package/dist/components/tab-bar.d.ts +20 -0
- package/dist/components/text-field.d.ts +31 -0
- package/dist/components/text.d.ts +9 -0
- package/dist/components/time-picker.d.ts +40 -0
- package/dist/components/toolbar.d.ts +77 -0
- package/dist/components/top-bar.d.ts +27 -0
- package/dist/components/undo-bar.d.ts +23 -0
- package/dist/components/wavy-progress.d.ts +21 -0
- package/dist/components/zoomable-image.d.ts +18 -0
- package/dist/expressive-shapes.d.ts +8 -0
- package/dist/index.d.ts +62 -0
- package/dist/keyboard.d.ts +2 -0
- package/dist/material.d.ts +11 -0
- package/dist/media.d.ts +11 -0
- package/dist/motion.d.ts +96 -0
- package/dist/platform.d.ts +3 -0
- package/dist/preset-tokens.d.ts +264 -0
- package/dist/provider.d.ts +59 -0
- package/dist/reduced-motion.d.ts +45 -0
- package/dist/selection.d.ts +2 -0
- package/dist/shape.d.ts +99 -0
- package/dist/sheet-physics.d.ts +37 -0
- package/dist/theme.d.ts +103 -0
- package/dist/tokens.d.ts +2 -0
- package/dist/use-keyboard-height.d.ts +10 -0
- package/dist/utils.d.ts +3 -0
- package/nativewind.cjs +68 -0
- package/package.json +63 -6
- package/src/amount.ts +53 -0
- package/src/calendar.ts +42 -0
- package/src/components/action-chip.tsx +64 -0
- package/src/components/amount-field.tsx +49 -0
- package/src/components/avatar.tsx +91 -0
- package/src/components/back-button.tsx +39 -0
- package/src/components/back-icon.tsx +25 -0
- package/src/components/badge.tsx +41 -0
- package/src/components/banner.tsx +63 -0
- package/src/components/bottom-sheet-native.tsx +52 -0
- package/src/components/bottom-sheet-web.tsx +193 -0
- package/src/components/bottom-sheet.tsx +5 -0
- package/src/components/button-group.tsx +326 -0
- package/src/components/button.tsx +337 -0
- package/src/components/checkbox.tsx +71 -0
- package/src/components/color-picker.tsx +115 -0
- package/src/components/context-menu.tsx +149 -0
- package/src/components/date-picker.tsx +466 -0
- package/src/components/dialog-context.ts +3 -0
- package/src/components/dialog.tsx +210 -0
- package/src/components/empty-state.tsx +49 -0
- package/src/components/expand-indicator.tsx +60 -0
- package/src/components/expressive-shape.tsx +37 -0
- package/src/components/fab-menu-legacy.tsx +181 -0
- package/src/components/fab-menu.tsx +90 -0
- package/src/components/filter-chip.tsx +136 -0
- package/src/components/floating-action-button.tsx +79 -0
- package/src/components/icon-button.tsx +127 -0
- package/src/components/icons.tsx +43 -0
- package/src/components/input.tsx +80 -0
- package/src/components/keyboard-inset-view.tsx +28 -0
- package/src/components/list-controls.tsx +134 -0
- package/src/components/loading-indicator.tsx +183 -0
- package/src/components/menu-sheet.tsx +133 -0
- package/src/components/panel-sheet.tsx +90 -0
- package/src/components/password-visibility.tsx +39 -0
- package/src/components/popover-layout.ts +47 -0
- package/src/components/popover.tsx +139 -0
- package/src/components/pressable.tsx +108 -0
- package/src/components/radio-navigation.ts +52 -0
- package/src/components/refresh-control.tsx +39 -0
- package/src/components/row-gap.tsx +13 -0
- package/src/components/search-field.tsx +92 -0
- package/src/components/select-field.tsx +105 -0
- package/src/components/settings-list.tsx +302 -0
- package/src/components/settings-row.tsx +61 -0
- package/src/components/sheet-frame.tsx +250 -0
- package/src/components/sheet-lifecycle.ts +233 -0
- package/src/components/sheet-transition.ts +105 -0
- package/src/components/slider.tsx +185 -0
- package/src/components/snackbar.tsx +97 -0
- package/src/components/split-button.tsx +212 -0
- package/src/components/squish.ts +41 -0
- package/src/components/swipeable-row.tsx +109 -0
- package/src/components/switch.tsx +77 -0
- package/src/components/tab-bar.tsx +195 -0
- package/src/components/text-field.tsx +264 -0
- package/src/components/text.tsx +58 -0
- package/src/components/time-picker.tsx +277 -0
- package/src/components/toolbar.tsx +406 -0
- package/src/components/top-bar.tsx +91 -0
- package/src/components/undo-bar.tsx +137 -0
- package/src/components/wavy-progress.tsx +150 -0
- package/src/components/zoomable-image.tsx +240 -0
- package/src/expressive-shapes.ts +25 -0
- package/src/index.ts +62 -0
- package/src/keyboard.ts +5 -0
- package/src/material.ts +16 -0
- package/src/media.ts +51 -0
- package/src/motion.ts +96 -0
- package/src/platform.ts +13 -0
- package/src/preset-tokens.ts +265 -0
- package/src/provider.tsx +201 -0
- package/src/reduced-motion.ts +50 -0
- package/src/selection.ts +11 -0
- package/src/shape.ts +217 -0
- package/src/sheet-physics.ts +73 -0
- package/src/theme.ts +180 -0
- package/src/tokens.ts +2 -0
- package/src/use-keyboard-height.ts +64 -0
- package/src/utils.ts +7 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Isoline UI contributors
|
|
4
|
+
Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/NOTICE.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Source notices
|
|
2
|
+
|
|
3
|
+
The initial primitives were extracted with the owner's authorisation from the
|
|
4
|
+
UI code maintained for Yours, Inboki and Atlas. Product data, credentials,
|
|
5
|
+
artwork and feature code are not included.
|
|
6
|
+
|
|
7
|
+
The existing MIT notice for 650 Industries, Inc. (Expo) is retained in LICENSE.
|
|
8
|
+
Isoline-specific functional glyphs use simple original SVG paths. App-specific
|
|
9
|
+
Material Symbols icon collections and brand fonts are not bundled.
|
|
10
|
+
|
|
11
|
+
Runtime packages remain subject to their respective licences. Apps consuming
|
|
12
|
+
Isoline should regenerate their dependency licence notices after integration.
|
package/README.md
CHANGED
|
@@ -1,3 +1,104 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# @isoline-ui/react-native
|
|
2
|
+
|
|
3
|
+
Expressive shared UI with platform-aware interaction. Initial alpha distributed through GitHub Releases; not published to npm. The package name does not reserve the npm organisation.
|
|
4
|
+
|
|
5
|
+
## Install the test release
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install https://github.com/isoline-ui/isoline-ui/releases/download/v0.1.0-alpha.0/isoline-ui-react-native-0.1.0-alpha.0.tgz
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The URL is versioned and the package imports as `@isoline-ui/react-native`.
|
|
12
|
+
|
|
13
|
+
## Consumer setup
|
|
14
|
+
|
|
15
|
+
Install the package and the peer dependencies
|
|
16
|
+
matching your Expo SDK. Use `npx expo install` for native peers; do not install
|
|
17
|
+
a second React or React Native runtime.
|
|
18
|
+
|
|
19
|
+
Keep the usual NativeWind Babel/Metro configuration. Add the Isoline preset and
|
|
20
|
+
package source to Tailwind's content scan:
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
const path = require('node:path');
|
|
24
|
+
const ui = path.dirname(require.resolve('@isoline-ui/react-native/package.json'));
|
|
25
|
+
|
|
26
|
+
module.exports = {
|
|
27
|
+
presets: [require('@isoline-ui/react-native/nativewind')],
|
|
28
|
+
content: ['./app/**/*.{ts,tsx}', './src/**/*.{ts,tsx}', path.join(ui, 'src/**/*.{ts,tsx}')],
|
|
29
|
+
};
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Do not overwrite an app's custom fonts or additional semantic roles; extend
|
|
33
|
+
the preset in the consumer. Atlas loads its fonts itself.
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { IsolineProvider, Button, themes } from '@isoline-ui/react-native';
|
|
37
|
+
|
|
38
|
+
export function App() {
|
|
39
|
+
return (
|
|
40
|
+
<IsolineProvider theme={themes.violet.light} labels={{ close: 'Schließen' }}>
|
|
41
|
+
<Button
|
|
42
|
+
label="Speichern"
|
|
43
|
+
onPress={() => {
|
|
44
|
+
/* app action */
|
|
45
|
+
}}
|
|
46
|
+
/>
|
|
47
|
+
</IsolineProvider>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Place the provider inside the app's SafeAreaProvider and GestureHandlerRootView.
|
|
53
|
+
It paints CSS roles for NativeWind and supplies matching colours for native/SVG
|
|
54
|
+
props. Use a theme matching the app's light/dark preference.
|
|
55
|
+
|
|
56
|
+
`extendTheme` returns a new theme from token and typography overrides. Token
|
|
57
|
+
values are HSL channel triplets, not full CSS colour expressions. Dynamic
|
|
58
|
+
Material You roles and Yours' text preferences still require app adapters.
|
|
59
|
+
|
|
60
|
+
Haptics are opt-in: pass `haptics={{ selectionHaptic, impactHaptic }}` from the
|
|
61
|
+
app so its saved preference is honoured. Labels are similarly supplied from
|
|
62
|
+
the app's translations. There is no navigation or persistence dependency.
|
|
63
|
+
|
|
64
|
+
## Packaging
|
|
65
|
+
|
|
66
|
+
`react-native` and default exports point to TypeScript source for Metro.
|
|
67
|
+
`types` point to generated declarations. This is a React Native/Metro package;
|
|
68
|
+
plain Node/browser UI imports are not a supported distribution target.
|
|
69
|
+
Pure helpers can be imported from `@isoline-ui/react-native/tokens`.
|
|
70
|
+
|
|
71
|
+
The package intentionally does not install Expo, native runtimes, app fonts
|
|
72
|
+
or native model/scanner integrations. Native dependency changes require a
|
|
73
|
+
new native app build, not only an OTA update.
|
|
74
|
+
|
|
75
|
+
## iOS, Android and browsers
|
|
76
|
+
|
|
77
|
+
Controls follow the native OS automatically. The `platform="ios" | "android"`
|
|
78
|
+
provider prop selects a browser preview style and is inherited by nested providers;
|
|
79
|
+
it never changes the native device platform. Use Expo web with React Native Web,
|
|
80
|
+
React DOM, NativeWind and the normal native peers. The repository showcase includes
|
|
81
|
+
`npm run web --workspace isoline-showcase` and `export:web`.
|
|
82
|
+
|
|
83
|
+
Register `surfaceComponent={MaterialSurface}` and
|
|
84
|
+
`surfaceGroupComponent={MaterialGroup}` on `IsolineProvider` using the optional
|
|
85
|
+
`@isoline-ui/native` adapters. Core UI works without Expo using solid fallbacks.
|
|
86
|
+
|
|
87
|
+
The shared `MaterialOptions` contract (`material`, `glassStyle`, `tintColor`,
|
|
88
|
+
`fallbackColor`, `interactive`) supports buttons/icon buttons, search, segmented
|
|
89
|
+
controls, pickers, floating/split actions, toolbars, navigation, tabs, popovers,
|
|
90
|
+
context menus and optional overlay surfaces. `TabBar` is controlled; routing
|
|
91
|
+
remains in the app. `Popover` anchors, flips and clamps a scrollable panel.
|
|
92
|
+
Context menus and pickers support disabled and selected options. Action menus
|
|
93
|
+
also support destructive actions.
|
|
94
|
+
|
|
95
|
+
Navigation and anchored menus default to automatic material. Form/action controls,
|
|
96
|
+
dialogs, sheets and snackbars default to solid; opt in per surface. Android stays
|
|
97
|
+
solid Material UI. iOS uses native glass where available and respects Reduce
|
|
98
|
+
Transparency. `SurfaceGroup` uses native `GlassContainer` to blend nearby glass
|
|
99
|
+
surfaces and can animate `gap`, respecting reduced motion. Browser groups animate
|
|
100
|
+
spacing only: CSS backdrop blur approximates glass without native merging or
|
|
101
|
+
refraction. Use a contrasting background to make translucency visible.
|
|
102
|
+
|
|
103
|
+
The new controls require native/device verification in consumer builds; browser
|
|
104
|
+
checks and Metro exports do not verify UIKit rendering or accessibility.
|
package/dist/amount.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Parse a locale-formatted editing value; invalid/partial input stays null. */
|
|
2
|
+
export declare function parseLocalizedAmount(input: string, locale?: string): number | null;
|
|
3
|
+
export declare function formatLocalizedAmount(value: number, locale?: string, fractionDigits?: number): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Gregorian local-date values. UTC arithmetic avoids DST changes and host time zones. */
|
|
2
|
+
export declare function validDate(value: string): boolean;
|
|
3
|
+
export declare function addDays(value: string, amount: number): string;
|
|
4
|
+
export declare function addMonths(month: string, amount: number): string;
|
|
5
|
+
export declare function monthDays(month: string, firstDayOfWeek?: number): string[];
|
|
6
|
+
export declare function formatCalendarDate(date: string, locale?: string, options?: Intl.DateTimeFormatOptions): string;
|
|
7
|
+
export declare function validTime(value: string): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type ButtonProps } from './button.tsx';
|
|
3
|
+
import type { IconProps } from './icons.tsx';
|
|
4
|
+
export interface ActionChipProps extends Omit<ButtonProps, 'children' | 'icon' | 'label' | 'variant' | 'size'> {
|
|
5
|
+
label: string;
|
|
6
|
+
icon?: React.ComponentType<IconProps>;
|
|
7
|
+
tone?: 'neutral' | 'primary' | 'secondary' | 'tertiary';
|
|
8
|
+
}
|
|
9
|
+
export declare function ActionChip({ label, icon: Icon, tone, style, ...props }: ActionChipProps): React.JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TextInput } from 'react-native';
|
|
3
|
+
import { type TextFieldProps } from './text-field.tsx';
|
|
4
|
+
export interface AmountFieldProps extends Omit<TextFieldProps, 'value' | 'onChangeText'> {
|
|
5
|
+
value: string;
|
|
6
|
+
onChangeText: (value: string) => void;
|
|
7
|
+
onAmountChange?: (amount: number | null) => void;
|
|
8
|
+
currency?: string | null;
|
|
9
|
+
locale?: string;
|
|
10
|
+
}
|
|
11
|
+
/** Preserve the editing string, including incomplete decimals; report numeric units separately. */
|
|
12
|
+
export declare const AmountField: React.ForwardRefExoticComponent<AmountFieldProps & React.RefAttributes<React.ElementRef<typeof TextInput>>>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type ImageSourcePropType, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
+
export interface AvatarProps {
|
|
4
|
+
accessibilityLabel: string;
|
|
5
|
+
initials?: string;
|
|
6
|
+
source?: ImageSourcePropType;
|
|
7
|
+
size?: number;
|
|
8
|
+
color?: string;
|
|
9
|
+
foregroundColor?: string;
|
|
10
|
+
accent?: string;
|
|
11
|
+
badge?: React.ReactNode;
|
|
12
|
+
renderImage?: (size: number, onError: () => void) => React.ReactNode;
|
|
13
|
+
style?: StyleProp<ViewStyle>;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Image rendering and initials only: no address book, network lookup or app preference. */
|
|
17
|
+
export declare function Avatar({ accessibilityLabel, initials, source, size, color, foregroundColor, accent, badge, renderImage, style, className, }: AvatarProps): React.JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface BackButtonProps {
|
|
2
|
+
onPress: () => void;
|
|
3
|
+
/** What the row leads back to, e.g. "Inbox", "Settings". Defaults to "Back". */
|
|
4
|
+
label?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The `< Back` row every screen opens with.
|
|
8
|
+
*
|
|
9
|
+
* The arrow is drawn at the header icon size, so it matches the bare back
|
|
10
|
+
* arrow of the screens that use a top bar instead (the reader, compose).
|
|
11
|
+
*/
|
|
12
|
+
export declare function BackButton({ onPress, label }: BackButtonProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface BadgeProps {
|
|
3
|
+
label: string;
|
|
4
|
+
/**
|
|
5
|
+
* Tints the pill and its text, for a badge that stands for something with a
|
|
6
|
+
* colour of its own — a tag. Left unset, the badge is the neutral container
|
|
7
|
+
* colour a folder name gets.
|
|
8
|
+
*/
|
|
9
|
+
color?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
/** A small pill label, such as a folder name sitting beside a message count. */
|
|
13
|
+
export declare function Badge({ label, color, className }: BadgeProps): React.JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type IconProps } from './icons.tsx';
|
|
3
|
+
export interface BannerProps {
|
|
4
|
+
message: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
tone?: 'neutral' | 'info' | 'error';
|
|
7
|
+
icon?: React.ComponentType<IconProps>;
|
|
8
|
+
actionLabel?: string;
|
|
9
|
+
onAction?: () => void;
|
|
10
|
+
onDismiss?: () => void;
|
|
11
|
+
dismissLabel?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function Banner({ message, title, tone, icon: Icon, actionLabel, onAction, onDismiss, dismissLabel, }: BannerProps): React.JSX.Element;
|
|
14
|
+
export declare const InlineNotice: typeof Banner;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type DimensionValue } from 'react-native';
|
|
3
|
+
import { type MaterialOptions } from '../provider.tsx';
|
|
4
|
+
export interface BottomSheetProps extends MaterialOptions {
|
|
5
|
+
visible: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
maxHeight?: DimensionValue;
|
|
8
|
+
onShow?: () => void;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
export declare function BottomSheet({ visible, onClose, maxHeight, onShow, children, ...materialOptions }: BottomSheetProps): React.JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type DimensionValue } from 'react-native';
|
|
3
|
+
import { type MaterialOptions } from '../provider.tsx';
|
|
4
|
+
export interface BottomSheetProps extends MaterialOptions {
|
|
5
|
+
visible: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
/** Caps long lists; the default leaves space for the status bar. */
|
|
8
|
+
maxHeight?: DimensionValue;
|
|
9
|
+
/** Runs once the sheet is on screen, e.g. to focus an input. */
|
|
10
|
+
onShow?: () => void;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* One branded sheet on both platforms. The handle owns the dismiss gesture
|
|
15
|
+
* so it cannot steal scrolling, calendar swipes or drags inside the content.
|
|
16
|
+
* On iOS the panel also follows the keyboard and supports VoiceOver Escape.
|
|
17
|
+
*/
|
|
18
|
+
export declare function BottomSheet({ visible, onClose, maxHeight, onShow, children, material, glassStyle, tintColor, fallbackColor, interactive, }: BottomSheetProps): React.JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type MaterialOptions } from '../provider.tsx';
|
|
3
|
+
export interface ButtonGroupItem<T extends string> {
|
|
4
|
+
id: T;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
label: string;
|
|
7
|
+
icon?: React.ComponentType<{
|
|
8
|
+
size?: number;
|
|
9
|
+
color?: string;
|
|
10
|
+
}>;
|
|
11
|
+
/** Optional trailing count, e.g. unread mail in that view. */
|
|
12
|
+
badge?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ButtonGroupProps<T extends string> extends MaterialOptions {
|
|
15
|
+
items: ButtonGroupItem<T>[];
|
|
16
|
+
value: T;
|
|
17
|
+
onChange: (value: T) => void;
|
|
18
|
+
className?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Drop the label on unselected buttons, leaving icon + badge. Meant for
|
|
21
|
+
* groups where every item carries a badge, so the count alone still
|
|
22
|
+
* identifies it — the selected button keeps the only visible label.
|
|
23
|
+
*/
|
|
24
|
+
compact?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function ButtonGroup<T extends string>({ items, value, onChange, className, compact, material, glassStyle, tintColor, fallbackColor, interactive, }: ButtonGroupProps<T>): React.JSX.Element;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { type MaterialOptions } from '../provider.tsx';
|
|
4
|
+
import type { IconProps } from './icons.tsx';
|
|
5
|
+
import { Pressable } from './pressable.tsx';
|
|
6
|
+
/**
|
|
7
|
+
* Material 3 Expressive button.
|
|
8
|
+
*
|
|
9
|
+
* Colour still carries emphasis — Filled for the one action that matters,
|
|
10
|
+
* Tonal below it, Outlined and Text lower again — but Expressive added two
|
|
11
|
+
* dimensions on top of that:
|
|
12
|
+
*
|
|
13
|
+
* - **Size as hierarchy.** Five sizes from XS to XL, so a primary action can
|
|
14
|
+
* be made important by being *large*, not just by being coloured. The larger
|
|
15
|
+
* sizes are meant to be used; a screen where every button is medium is the
|
|
16
|
+
* thing this is trying to fix.
|
|
17
|
+
* - **Shape as feedback.** Every button morphs between round and square while
|
|
18
|
+
* pressed. The shape change is felt more than it is seen, and it survives on
|
|
19
|
+
* a filled button where a ripple over a saturated fill barely registers.
|
|
20
|
+
*/
|
|
21
|
+
declare const buttonVariants: (props?: ({
|
|
22
|
+
variant?: "default" | "tertiary" | "outline" | "secondary" | "tonal" | "ghost" | "destructive" | null | undefined;
|
|
23
|
+
size?: "s" | "xs" | "m" | "l" | "xl" | "icon" | null | undefined;
|
|
24
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
25
|
+
declare const labelVariants: (props?: ({
|
|
26
|
+
variant?: "default" | "tertiary" | "outline" | "secondary" | "tonal" | "ghost" | "destructive" | null | undefined;
|
|
27
|
+
size?: "s" | "xs" | "m" | "l" | "xl" | "icon" | null | undefined;
|
|
28
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
29
|
+
export type ButtonProps = Omit<React.ComponentProps<typeof Pressable>, 'children'> & VariantProps<typeof buttonVariants> & MaterialOptions & {
|
|
30
|
+
children?: React.ComponentProps<typeof Pressable>['children'];
|
|
31
|
+
pressableClassName?: string;
|
|
32
|
+
label?: string;
|
|
33
|
+
/** A leading symbol, drawn in the label's color. */
|
|
34
|
+
icon?: React.ComponentType<IconProps>;
|
|
35
|
+
/** Resting shape. Pressing morphs to the other one and back. */
|
|
36
|
+
shape?: 'round' | 'square';
|
|
37
|
+
/** Fires a selection tick on press. Off for destructive-adjacent actions. */
|
|
38
|
+
haptic?: boolean;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Pressable with a spring shape-and-scale morph on touch.
|
|
42
|
+
*
|
|
43
|
+
* The press feedback runs on the UI thread through Reanimated rather than
|
|
44
|
+
* through React state, so it stays at 60fps while the JS thread is busy
|
|
45
|
+
* ingesting a sync batch.
|
|
46
|
+
*/
|
|
47
|
+
export declare function Button({ className, material, glassStyle, tintColor, fallbackColor, interactive, pressableClassName, style, variant, size, label, icon: Icon, shape, haptic, children, onPressIn, onPressOut, onPress, ...props }: ButtonProps): React.JSX.Element;
|
|
48
|
+
export { buttonVariants, labelVariants };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
+
export interface CheckboxProps {
|
|
4
|
+
checked: boolean | 'mixed';
|
|
5
|
+
onCheckedChange: (checked: boolean) => void;
|
|
6
|
+
accessibilityLabel: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
style?: StyleProp<ViewStyle>;
|
|
10
|
+
}
|
|
11
|
+
/** Controlled selection; storage and selection of a collection remain caller-owned. */
|
|
12
|
+
export declare function Checkbox({ checked, onCheckedChange, accessibilityLabel, label, disabled, style, }: CheckboxProps): React.JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type MaterialOptions } from '../provider.tsx';
|
|
3
|
+
export interface ColorSwatch {
|
|
4
|
+
value: string;
|
|
5
|
+
label: string;
|
|
6
|
+
color?: string;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ColorSwatchPickerProps {
|
|
10
|
+
value: string | null;
|
|
11
|
+
onChange: (value: string) => void;
|
|
12
|
+
swatches: ColorSwatch[];
|
|
13
|
+
accessibilityLabel: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function ColorSwatchPicker({ value, onChange, swatches, accessibilityLabel, }: ColorSwatchPickerProps): React.JSX.Element;
|
|
16
|
+
export interface ColorPickerSheetProps extends ColorSwatchPickerProps, MaterialOptions {
|
|
17
|
+
visible: boolean;
|
|
18
|
+
onClose: () => void;
|
|
19
|
+
title: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function ColorPickerSheet({ visible, onClose, title, material, glassStyle, tintColor, fallbackColor, interactive, ...props }: ColorPickerSheetProps): React.JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MaterialOptions } from '../material.ts';
|
|
3
|
+
import { type IconProps } from './icons.tsx';
|
|
4
|
+
export interface ContextMenuItem {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
onPress: () => void;
|
|
8
|
+
icon?: React.ComponentType<IconProps>;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
destructive?: boolean;
|
|
11
|
+
selected?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface ContextMenuProps extends MaterialOptions {
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
accessibilityLabel: string;
|
|
16
|
+
items: ContextMenuItem[];
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
onOpenChange?: (open: boolean) => void;
|
|
19
|
+
placement?: 'top' | 'bottom';
|
|
20
|
+
}
|
|
21
|
+
/** Shared anchored menu, not a UIKit context-menu controller or an application router. */
|
|
22
|
+
export declare function ContextMenu({ children, accessibilityLabel, items, disabled, onOpenChange, placement, ...material }: ContextMenuProps): React.JSX.Element;
|
|
23
|
+
export declare function ContextMenuRows({ items, onClose, }: {
|
|
24
|
+
items: ContextMenuItem[];
|
|
25
|
+
onClose: () => void;
|
|
26
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type MaterialOptions } from '../provider.tsx';
|
|
3
|
+
export interface CalendarLabels {
|
|
4
|
+
previousMonth: string;
|
|
5
|
+
nextMonth: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CalendarMark {
|
|
8
|
+
label: string;
|
|
9
|
+
count?: number;
|
|
10
|
+
color?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface MonthCalendarProps {
|
|
13
|
+
value: string | null;
|
|
14
|
+
onChange: (date: string) => void;
|
|
15
|
+
today: string;
|
|
16
|
+
locale?: string;
|
|
17
|
+
month?: string;
|
|
18
|
+
onMonthChange?: (month: string) => void;
|
|
19
|
+
firstDayOfWeek?: number;
|
|
20
|
+
minDate?: string;
|
|
21
|
+
maxDate?: string;
|
|
22
|
+
disabledDates?: readonly string[];
|
|
23
|
+
marks?: Record<string, CalendarMark>;
|
|
24
|
+
labels: CalendarLabels;
|
|
25
|
+
range?: {
|
|
26
|
+
start: string;
|
|
27
|
+
end: string;
|
|
28
|
+
} | null;
|
|
29
|
+
renderDayAccessory?: (date: string, selected: boolean) => React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
/** Date arithmetic and marks are independent from agenda repositories or app clocks. */
|
|
32
|
+
export declare function MonthCalendar({ value, onChange, today, locale, month: controlledMonth, onMonthChange, firstDayOfWeek, minDate, maxDate, disabledDates, marks, labels, range, renderDayAccessory, }: MonthCalendarProps): React.JSX.Element;
|
|
33
|
+
export interface WeekStripProps extends Pick<MonthCalendarProps, 'value' | 'onChange' | 'today' | 'locale' | 'marks' | 'minDate' | 'maxDate'> {
|
|
34
|
+
startDate: string;
|
|
35
|
+
renderDayAccessory?: MonthCalendarProps['renderDayAccessory'];
|
|
36
|
+
}
|
|
37
|
+
export declare function WeekStrip({ startDate, value, onChange, today, locale, marks, minDate, maxDate, renderDayAccessory, }: WeekStripProps): React.JSX.Element;
|
|
38
|
+
export interface QuickDateOption {
|
|
39
|
+
value: string;
|
|
40
|
+
label: string;
|
|
41
|
+
disabled?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface DayPickerProps extends MonthCalendarProps, MaterialOptions {
|
|
44
|
+
quickDates?: QuickDateOption[];
|
|
45
|
+
onClear?: () => void;
|
|
46
|
+
clearLabel?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare function DayPicker({ quickDates, onClear, clearLabel, ...calendar }: DayPickerProps): React.JSX.Element;
|
|
49
|
+
export interface DatePickerSheetProps extends MonthCalendarProps, MaterialOptions {
|
|
50
|
+
visible: boolean;
|
|
51
|
+
onClose: () => void;
|
|
52
|
+
title: string;
|
|
53
|
+
quickDates?: QuickDateOption[];
|
|
54
|
+
onClear?: () => void;
|
|
55
|
+
clearLabel?: string;
|
|
56
|
+
}
|
|
57
|
+
export declare function DatePickerSheet({ visible, onClose, title, quickDates, onClear, clearLabel, material, glassStyle, tintColor, fallbackColor, interactive, ...calendar }: DatePickerSheetProps): React.JSX.Element;
|
|
58
|
+
export interface DateFieldProps extends Omit<DatePickerSheetProps, 'visible' | 'onClose' | 'title' | 'onChange' | 'onClear'> {
|
|
59
|
+
label: string;
|
|
60
|
+
emptyLabel: string;
|
|
61
|
+
onChange: (date: string | null) => void;
|
|
62
|
+
disabled?: boolean;
|
|
63
|
+
}
|
|
64
|
+
export declare function DateField({ label, emptyLabel, onChange, disabled, ...props }: DateFieldProps): React.JSX.Element;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type MaterialOptions } from '../provider.tsx';
|
|
3
|
+
export interface DialogProps extends MaterialOptions {
|
|
4
|
+
visible: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
/** Runs once the dialog is actually on screen — for one that focuses an input. */
|
|
7
|
+
onShow?: () => void;
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The app's Material 3 dialog: a scrim, and a panel centred on screen that
|
|
12
|
+
* scales up into place. Used for a short, focused decision — naming
|
|
13
|
+
* something, confirming an action — where a bottom sheet's list-of-options
|
|
14
|
+
* shape would be the wrong read.
|
|
15
|
+
*/
|
|
16
|
+
export declare function Dialog({ visible, onClose, onShow, children, material, glassStyle, tintColor, fallbackColor, interactive, }: DialogProps): React.JSX.Element;
|
|
17
|
+
/** A dialog's row of text actions, right-aligned per M3. */
|
|
18
|
+
export declare function DialogActions({ children }: {
|
|
19
|
+
children: React.ReactNode;
|
|
20
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import { type ExpressiveShapeName } from './expressive-shape.tsx';
|
|
3
|
+
import type { IconProps } from './icons.tsx';
|
|
4
|
+
/**
|
|
5
|
+
* An empty list's one thing to look at: a large Expressive shape with the
|
|
6
|
+
* symbol of what would be here, a line saying so, and a line saying how to
|
|
7
|
+
* change it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function EmptyState({ icon: Icon, shape, title, body, tone, }: {
|
|
10
|
+
icon: React.ComponentType<IconProps>;
|
|
11
|
+
shape: ExpressiveShapeName;
|
|
12
|
+
title: string;
|
|
13
|
+
body?: string;
|
|
14
|
+
tone?: 'primary' | 'tertiary';
|
|
15
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/** One size for every disclosure chevron, so no two sections look differently foldable. */
|
|
3
|
+
export declare const EXPAND_INDICATOR_SIZE = 20;
|
|
4
|
+
export interface ExpandIndicatorProps {
|
|
5
|
+
expanded: boolean;
|
|
6
|
+
/** Defaults to `onSurfaceVariant`; a chip in its selected tone passes its own. */
|
|
7
|
+
color?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The chevron on anything that opens in place — a message card, its details,
|
|
11
|
+
* the Cc/Bcc fields.
|
|
12
|
+
*
|
|
13
|
+
* Every one of those used to draw its own `ChevronDown` at whatever size
|
|
14
|
+
* suited the spot: 16 on a card, 12 on the details line beneath it, so two
|
|
15
|
+
* disclosures a finger's width apart looked like different kinds of thing.
|
|
16
|
+
* This is the one they share.
|
|
17
|
+
*
|
|
18
|
+
* It turns on the fast spatial spring rather than flipping, and overshoots a
|
|
19
|
+
* little on the way: the Expressive cue that the section is a thing being
|
|
20
|
+
* opened, not a picture being swapped. Reanimated drops the spring for
|
|
21
|
+
* "Remove animations" on its own, and the chevron still ends up pointing the
|
|
22
|
+
* right way — the state is carried by where it ends, not by the movement.
|
|
23
|
+
*
|
|
24
|
+
* Decorative to a screen reader: whatever it sits in owns the tap and says
|
|
25
|
+
* `expanded` itself.
|
|
26
|
+
*/
|
|
27
|
+
export declare function ExpandIndicator({ expanded, color }: ExpandIndicatorProps): React.JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A still member of the Expressive shape library, with something inside it.
|
|
4
|
+
*
|
|
5
|
+
* Expressive leans on a small set of characterful shapes — the 4-leaf clover,
|
|
6
|
+
* the scalloped cookie — to mark the one thing on a screen worth looking at
|
|
7
|
+
* first: an empty state's symbol, a step in a flow. Drawn from the same radial
|
|
8
|
+
* maths the loading indicator morphs (`~/lib/shape`), so the app's shapes are
|
|
9
|
+
* one family.
|
|
10
|
+
*/
|
|
11
|
+
export { type ExpressiveShapeName } from '../expressive-shapes.ts';
|
|
12
|
+
import { type ExpressiveShapeName } from '../expressive-shapes.ts';
|
|
13
|
+
export declare function ExpressiveShape({ shape, size, color, children, }: {
|
|
14
|
+
shape: ExpressiveShapeName;
|
|
15
|
+
size: number;
|
|
16
|
+
color: string;
|
|
17
|
+
children?: React.ReactNode;
|
|
18
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type IconProps } from './icons.tsx';
|
|
3
|
+
export interface FabMenuAction {
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
destructive?: boolean;
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
icon: React.ComponentType<IconProps>;
|
|
9
|
+
run: () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface FabMenuProps {
|
|
12
|
+
bottom: number;
|
|
13
|
+
label: string;
|
|
14
|
+
actions: FabMenuAction[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The button's closed size: the height of the floating navigation bar it
|
|
18
|
+
* sits beside, so the two read as one row — and round, as the bar is.
|
|
19
|
+
*/
|
|
20
|
+
export declare const FAB_MENU_SIZE = 64;
|
|
21
|
+
/**
|
|
22
|
+
* The capture button, as an Expressive FAB menu.
|
|
23
|
+
*
|
|
24
|
+
* Closed, it is the one tinted circle beside the navigation bar (or, in a
|
|
25
|
+
* collection, in the corner). Open, it shrinks into a smaller close button
|
|
26
|
+
* while the ways in — link or text, file, scan, camera — unfold above it one after
|
|
27
|
+
* another, each a full-width pill with its name on it. Everything else dims;
|
|
28
|
+
* nothing about capturing asks where a thing goes. Only ways in: a list is
|
|
29
|
+
* written, not captured, and is started from Collections or a collection's menu.
|
|
30
|
+
*/
|
|
31
|
+
export declare function LegacyFabMenu({ bottom, label, actions }: FabMenuProps): React.JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type IconProps } from './icons.tsx';
|
|
3
|
+
import { type MaterialOptions } from '../provider.tsx';
|
|
4
|
+
export interface FabMenuAction {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
icon: React.ComponentType<IconProps>;
|
|
8
|
+
run: () => void;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
destructive?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface FabMenuProps extends MaterialOptions {
|
|
13
|
+
/** Material of the anchored menu, independent of the floating trigger. */
|
|
14
|
+
menuMaterial?: MaterialOptions['material'];
|
|
15
|
+
bottom: number;
|
|
16
|
+
label: string;
|
|
17
|
+
actions: FabMenuAction[];
|
|
18
|
+
}
|
|
19
|
+
export declare const FAB_MENU_SIZE = 64;
|
|
20
|
+
/** Floating primary action with a safe, anchored overflow surface on native and web. */
|
|
21
|
+
export declare function FabMenu({ bottom, label, actions, material, menuMaterial, glassStyle, tintColor, fallbackColor, interactive, }: FabMenuProps): React.JSX.Element;
|