@gryt/ui-native 0.1.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/README.md +86 -0
- package/dist/components/Accordion/Accordion.d.ts +35 -0
- package/dist/components/Accordion/Accordion.d.ts.map +1 -0
- package/dist/components/Accordion/Accordion.js +66 -0
- package/dist/components/Alert/Alert.d.ts +21 -0
- package/dist/components/Alert/Alert.d.ts.map +1 -0
- package/dist/components/Alert/Alert.js +35 -0
- package/dist/components/AlertDialog/AlertDialog.d.ts +38 -0
- package/dist/components/AlertDialog/AlertDialog.d.ts.map +1 -0
- package/dist/components/AlertDialog/AlertDialog.js +15 -0
- package/dist/components/Avatar/Avatar.d.ts +10 -0
- package/dist/components/Avatar/Avatar.d.ts.map +1 -0
- package/dist/components/Avatar/Avatar.js +57 -0
- package/dist/components/Badge/Badge.d.ts +13 -0
- package/dist/components/Badge/Badge.d.ts.map +1 -0
- package/dist/components/Badge/Badge.js +28 -0
- package/dist/components/Button/Button.d.ts +24 -0
- package/dist/components/Button/Button.d.ts.map +1 -0
- package/dist/components/Button/Button.js +61 -0
- package/dist/components/Card/Card.d.ts +19 -0
- package/dist/components/Card/Card.d.ts.map +1 -0
- package/dist/components/Card/Card.js +45 -0
- package/dist/components/Checkbox/Checkbox.d.ts +24 -0
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox/Checkbox.js +43 -0
- package/dist/components/Chip/Chip.d.ts +17 -0
- package/dist/components/Chip/Chip.d.ts.map +1 -0
- package/dist/components/Chip/Chip.js +38 -0
- package/dist/components/Collapsible/Collapsible.d.ts +31 -0
- package/dist/components/Collapsible/Collapsible.d.ts.map +1 -0
- package/dist/components/Collapsible/Collapsible.js +34 -0
- package/dist/components/Dialog/Dialog.d.ts +67 -0
- package/dist/components/Dialog/Dialog.d.ts.map +1 -0
- package/dist/components/Dialog/Dialog.js +112 -0
- package/dist/components/Divider/Divider.d.ts +16 -0
- package/dist/components/Divider/Divider.d.ts.map +1 -0
- package/dist/components/Divider/Divider.js +21 -0
- package/dist/components/Drawer/Drawer.d.ts +44 -0
- package/dist/components/Drawer/Drawer.d.ts.map +1 -0
- package/dist/components/Drawer/Drawer.js +83 -0
- package/dist/components/Menu/Menu.d.ts +56 -0
- package/dist/components/Menu/Menu.d.ts.map +1 -0
- package/dist/components/Menu/Menu.js +76 -0
- package/dist/components/Meter/Meter.d.ts +21 -0
- package/dist/components/Meter/Meter.d.ts.map +1 -0
- package/dist/components/Meter/Meter.js +32 -0
- package/dist/components/NumberField/NumberField.d.ts +23 -0
- package/dist/components/NumberField/NumberField.d.ts.map +1 -0
- package/dist/components/NumberField/NumberField.js +56 -0
- package/dist/components/OtpField/OtpField.d.ts +24 -0
- package/dist/components/OtpField/OtpField.d.ts.map +1 -0
- package/dist/components/OtpField/OtpField.js +49 -0
- package/dist/components/Popover/Popover.d.ts +48 -0
- package/dist/components/Popover/Popover.d.ts.map +1 -0
- package/dist/components/Popover/Popover.js +54 -0
- package/dist/components/Progress/Progress.d.ts +18 -0
- package/dist/components/Progress/Progress.d.ts.map +1 -0
- package/dist/components/Progress/Progress.js +30 -0
- package/dist/components/Radio/Radio.d.ts +28 -0
- package/dist/components/Radio/Radio.d.ts.map +1 -0
- package/dist/components/Radio/Radio.js +53 -0
- package/dist/components/ScrollArea/ScrollArea.d.ts +22 -0
- package/dist/components/ScrollArea/ScrollArea.d.ts.map +1 -0
- package/dist/components/ScrollArea/ScrollArea.js +17 -0
- package/dist/components/Select/Select.d.ts +34 -0
- package/dist/components/Select/Select.d.ts.map +1 -0
- package/dist/components/Select/Select.js +71 -0
- package/dist/components/Skeleton/Skeleton.d.ts +18 -0
- package/dist/components/Skeleton/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton/Skeleton.js +28 -0
- package/dist/components/Slider/Slider.d.ts +29 -0
- package/dist/components/Slider/Slider.d.ts.map +1 -0
- package/dist/components/Slider/Slider.js +94 -0
- package/dist/components/Spinner/Spinner.d.ts +20 -0
- package/dist/components/Spinner/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner/Spinner.js +18 -0
- package/dist/components/Surface/Surface.d.ts +17 -0
- package/dist/components/Surface/Surface.d.ts.map +1 -0
- package/dist/components/Surface/Surface.js +22 -0
- package/dist/components/Switch/Switch.d.ts +25 -0
- package/dist/components/Switch/Switch.d.ts.map +1 -0
- package/dist/components/Switch/Switch.js +65 -0
- package/dist/components/Tabs/Tabs.d.ts +51 -0
- package/dist/components/Tabs/Tabs.d.ts.map +1 -0
- package/dist/components/Tabs/Tabs.js +82 -0
- package/dist/components/TextField/TextField.d.ts +15 -0
- package/dist/components/TextField/TextField.d.ts.map +1 -0
- package/dist/components/TextField/TextField.js +47 -0
- package/dist/components/Toast/Toast.d.ts +31 -0
- package/dist/components/Toast/Toast.d.ts.map +1 -0
- package/dist/components/Toast/Toast.js +86 -0
- package/dist/components/Toggle/Toggle.d.ts +19 -0
- package/dist/components/Toggle/Toggle.d.ts.map +1 -0
- package/dist/components/Toggle/Toggle.js +41 -0
- package/dist/components/Toolbar/Toolbar.d.ts +25 -0
- package/dist/components/Toolbar/Toolbar.d.ts.map +1 -0
- package/dist/components/Toolbar/Toolbar.js +35 -0
- package/dist/components/Tooltip/Tooltip.d.ts +40 -0
- package/dist/components/Tooltip/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip/Tooltip.js +52 -0
- package/dist/hooks/useReducedMotion.d.ts +10 -0
- package/dist/hooks/useReducedMotion.d.ts.map +1 -0
- package/dist/hooks/useReducedMotion.js +26 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/overlay/AnchoredPopup.d.ts +26 -0
- package/dist/overlay/AnchoredPopup.d.ts.map +1 -0
- package/dist/overlay/AnchoredPopup.js +36 -0
- package/dist/overlay/placePopup.d.ts +51 -0
- package/dist/overlay/placePopup.d.ts.map +1 -0
- package/dist/overlay/placePopup.js +63 -0
- package/dist/overlay/useAnchoredPosition.d.ts +18 -0
- package/dist/overlay/useAnchoredPosition.d.ts.map +1 -0
- package/dist/overlay/useAnchoredPosition.js +25 -0
- package/dist/overlay/useOpenState.d.ts +17 -0
- package/dist/overlay/useOpenState.d.ts.map +1 -0
- package/dist/overlay/useOpenState.js +12 -0
- package/dist/theme/ThemeProvider.d.ts +17 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.js +17 -0
- package/dist/theme/createNativeTheme.d.ts +82 -0
- package/dist/theme/createNativeTheme.d.ts.map +1 -0
- package/dist/theme/createNativeTheme.js +65 -0
- package/dist/theme/index.d.ts +6 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +5 -0
- package/dist/theme/themeContext.d.ts +9 -0
- package/dist/theme/themeContext.d.ts.map +1 -0
- package/dist/theme/themeContext.js +9 -0
- package/dist/theme/tones.d.ts +15 -0
- package/dist/theme/tones.d.ts.map +1 -0
- package/dist/theme/tones.js +11 -0
- package/dist/theme/useTheme.d.ts +8 -0
- package/dist/theme/useTheme.d.ts.map +1 -0
- package/dist/theme/useTheme.js +10 -0
- package/package.json +46 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Pressable, Text } from "react-native";
|
|
4
|
+
import { toneRamp, useTheme } from "../../theme/index.js";
|
|
5
|
+
const SIZE = 20;
|
|
6
|
+
/**
|
|
7
|
+
* The tick is a text glyph rather than an icon.
|
|
8
|
+
*
|
|
9
|
+
* `@gryt/ui` renders a Phosphor `Check`. Pulling an icon library in here would
|
|
10
|
+
* be the first runtime dependency this package has, for one glyph, and
|
|
11
|
+
* `@phosphor-icons/react` renders SVG that React Native cannot mount without
|
|
12
|
+
* react-native-svg on top. Both are decisions for whoever needs a full icon set,
|
|
13
|
+
* not for a checkbox.
|
|
14
|
+
*/
|
|
15
|
+
export function Checkbox({ checked: controlled, defaultChecked = false, indeterminate = false, onCheckedChange, disabled, tone = "primary", style, accessibilityLabel, }) {
|
|
16
|
+
const theme = useTheme();
|
|
17
|
+
const [uncontrolled, setUncontrolled] = useState(defaultChecked);
|
|
18
|
+
const checked = controlled ?? uncontrolled;
|
|
19
|
+
const ramp = toneRamp(theme, tone);
|
|
20
|
+
const filled = checked || indeterminate;
|
|
21
|
+
return (_jsx(Pressable, { accessibilityRole: "checkbox", accessibilityState: {
|
|
22
|
+
checked: indeterminate ? "mixed" : checked,
|
|
23
|
+
disabled: !!disabled,
|
|
24
|
+
}, accessibilityLabel: accessibilityLabel, disabled: disabled, onPress: () => {
|
|
25
|
+
const next = !checked;
|
|
26
|
+
if (controlled === undefined)
|
|
27
|
+
setUncontrolled(next);
|
|
28
|
+
onCheckedChange?.(next);
|
|
29
|
+
}, style: [
|
|
30
|
+
{
|
|
31
|
+
width: SIZE,
|
|
32
|
+
height: SIZE,
|
|
33
|
+
borderRadius: theme.radius.sm,
|
|
34
|
+
alignItems: "center",
|
|
35
|
+
justifyContent: "center",
|
|
36
|
+
borderWidth: filled ? 0 : 1.5,
|
|
37
|
+
borderColor: theme.color.border,
|
|
38
|
+
backgroundColor: filled ? ramp[8] : "transparent",
|
|
39
|
+
opacity: disabled ? 0.5 : 1,
|
|
40
|
+
},
|
|
41
|
+
style,
|
|
42
|
+
], children: filled ? (_jsx(Text, { style: { color: theme.color.bg, fontSize: 13, fontWeight: "900", lineHeight: 15 }, children: indeterminate ? "–" : "✓" })) : null }));
|
|
43
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
2
|
+
export type ChipTone = "neutral" | "accent" | "secondary" | "success" | "danger" | "warning";
|
|
3
|
+
export type ChipVariant = "soft" | "solid" | "outline";
|
|
4
|
+
export interface ChipProps {
|
|
5
|
+
label: string;
|
|
6
|
+
tone?: ChipTone;
|
|
7
|
+
variant?: ChipVariant;
|
|
8
|
+
style?: StyleProp<ViewStyle>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A small status label. No interaction — that is Button's job.
|
|
12
|
+
*
|
|
13
|
+
* Steps 3, 9 and 11 are the same ones `@gryt/ui` picks: 3 is the soft fill, 9
|
|
14
|
+
* is the solid one, 11 is text that passes contrast against both.
|
|
15
|
+
*/
|
|
16
|
+
export declare function Chip({ label, tone, variant, style, }: ChipProps): import("react").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=Chip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../../../src/components/Chip/Chip.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAI1E,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAC7F,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,IAAgB,EAChB,OAAgB,EAChB,KAAK,GACN,EAAE,SAAS,+BA4CX"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Text, View } from "react-native";
|
|
3
|
+
import { useTheme } from "../../theme/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* A small status label. No interaction — that is Button's job.
|
|
6
|
+
*
|
|
7
|
+
* Steps 3, 9 and 11 are the same ones `@gryt/ui` picks: 3 is the soft fill, 9
|
|
8
|
+
* is the solid one, 11 is text that passes contrast against both.
|
|
9
|
+
*/
|
|
10
|
+
export function Chip({ label, tone = "neutral", variant = "soft", style, }) {
|
|
11
|
+
const theme = useTheme();
|
|
12
|
+
const ramp = theme.scales[tone];
|
|
13
|
+
const background = variant === "solid" ? ramp[8] : variant === "soft" ? ramp[2] : "transparent";
|
|
14
|
+
const foreground = variant === "solid"
|
|
15
|
+
? tone === "accent"
|
|
16
|
+
? theme.color.onAccent
|
|
17
|
+
: tone === "secondary"
|
|
18
|
+
? theme.color.onSecondary
|
|
19
|
+
: tone === "danger"
|
|
20
|
+
? theme.color.onDanger
|
|
21
|
+
: theme.color.bg
|
|
22
|
+
: ramp[10];
|
|
23
|
+
return (_jsx(View, { style: [
|
|
24
|
+
{
|
|
25
|
+
alignSelf: "flex-start",
|
|
26
|
+
flexDirection: "row",
|
|
27
|
+
alignItems: "center",
|
|
28
|
+
backgroundColor: background,
|
|
29
|
+
borderRadius: theme.radius.full,
|
|
30
|
+
paddingHorizontal: theme.space(2.5),
|
|
31
|
+
paddingVertical: theme.space(1),
|
|
32
|
+
...(variant === "outline"
|
|
33
|
+
? { borderWidth: 1, borderColor: ramp[6] }
|
|
34
|
+
: null),
|
|
35
|
+
},
|
|
36
|
+
style,
|
|
37
|
+
], children: _jsx(Text, { numberOfLines: 1, style: { color: foreground, fontSize: 12, fontWeight: "600" }, children: label }) }));
|
|
38
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import { type OpenStateProps } from "../../overlay/useOpenState.js";
|
|
4
|
+
export interface CollapsibleRootProps extends OpenStateProps {
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
style?: StyleProp<ViewStyle>;
|
|
7
|
+
}
|
|
8
|
+
declare function Root({ children, style, ...openProps }: CollapsibleRootProps): import("react").JSX.Element;
|
|
9
|
+
declare function Trigger({ children, style }: {
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
style?: StyleProp<ViewStyle>;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
/**
|
|
14
|
+
* Unmounted when closed, rather than animated to zero height.
|
|
15
|
+
*
|
|
16
|
+
* The web animates the panel's height, which needs the content measured first.
|
|
17
|
+
* React Native can do it with `onLayout` plus `Animated`, and it costs a frame
|
|
18
|
+
* of the content rendered at the wrong size before the measurement lands. Not
|
|
19
|
+
* worth it for the first pass, and it is in the exceptions table.
|
|
20
|
+
*/
|
|
21
|
+
declare function Panel({ children, style }: {
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
style?: StyleProp<ViewStyle>;
|
|
24
|
+
}): import("react").JSX.Element | null;
|
|
25
|
+
export declare const Collapsible: {
|
|
26
|
+
Root: typeof Root;
|
|
27
|
+
Trigger: typeof Trigger;
|
|
28
|
+
Panel: typeof Panel;
|
|
29
|
+
};
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=Collapsible.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Collapsible.d.ts","sourceRoot":"","sources":["../../../src/components/Collapsible/Collapsible.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE/E,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAe/E,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,SAAS,EAAE,EAAE,oBAAoB,+BAOpE;AAED,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAY3F;AAED;;;;;;;GAOG;AACH,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,sCAIzF;AAED,eAAO,MAAM,WAAW;;;;CAA2B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
import { Pressable, View } from "react-native";
|
|
4
|
+
import { useOpenState } from "../../overlay/useOpenState.js";
|
|
5
|
+
const CollapsibleContext = createContext(null);
|
|
6
|
+
function useCollapsible(part) {
|
|
7
|
+
const value = useContext(CollapsibleContext);
|
|
8
|
+
if (!value)
|
|
9
|
+
throw new Error(`Collapsible.${part} must be rendered inside Collapsible.Root.`);
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
function Root({ children, style, ...openProps }) {
|
|
13
|
+
const state = useOpenState(openProps);
|
|
14
|
+
return (_jsx(CollapsibleContext.Provider, { value: state, children: _jsx(View, { style: style, children: children }) }));
|
|
15
|
+
}
|
|
16
|
+
function Trigger({ children, style }) {
|
|
17
|
+
const { open, setOpen } = useCollapsible("Trigger");
|
|
18
|
+
return (_jsx(Pressable, { accessibilityRole: "button", accessibilityState: { expanded: open }, onPress: () => setOpen(!open), style: style, children: children }));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Unmounted when closed, rather than animated to zero height.
|
|
22
|
+
*
|
|
23
|
+
* The web animates the panel's height, which needs the content measured first.
|
|
24
|
+
* React Native can do it with `onLayout` plus `Animated`, and it costs a frame
|
|
25
|
+
* of the content rendered at the wrong size before the measurement lands. Not
|
|
26
|
+
* worth it for the first pass, and it is in the exceptions table.
|
|
27
|
+
*/
|
|
28
|
+
function Panel({ children, style }) {
|
|
29
|
+
const { open } = useCollapsible("Panel");
|
|
30
|
+
if (!open)
|
|
31
|
+
return null;
|
|
32
|
+
return _jsx(View, { style: style, children: children });
|
|
33
|
+
}
|
|
34
|
+
export const Collapsible = { Root, Trigger, Panel };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type StyleProp, type TextStyle, type ViewStyle } from "react-native";
|
|
3
|
+
import { type OpenStateProps } from "../../overlay/useOpenState.js";
|
|
4
|
+
export interface DialogRootProps extends OpenStateProps {
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
declare function Root({ children, ...openProps }: DialogRootProps): import("react").JSX.Element;
|
|
8
|
+
export interface DialogTriggerProps {
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
style?: StyleProp<ViewStyle>;
|
|
11
|
+
}
|
|
12
|
+
declare function Trigger({ children, style }: DialogTriggerProps): import("react").JSX.Element;
|
|
13
|
+
/**
|
|
14
|
+
* A passthrough.
|
|
15
|
+
*
|
|
16
|
+
* On the web a portal is how the popup escapes overflow and stacking contexts.
|
|
17
|
+
* React Native's `Modal` already renders above everything, so there is nothing
|
|
18
|
+
* to escape. It exists so call sites keep the same shape.
|
|
19
|
+
*/
|
|
20
|
+
declare function Portal({ children }: {
|
|
21
|
+
children?: ReactNode;
|
|
22
|
+
}): import("react").JSX.Element;
|
|
23
|
+
export interface DialogPopupProps {
|
|
24
|
+
children?: ReactNode;
|
|
25
|
+
style?: StyleProp<ViewStyle>;
|
|
26
|
+
dismissible?: boolean;
|
|
27
|
+
/** Long content scrolls rather than growing past the screen. */
|
|
28
|
+
scrollable?: boolean;
|
|
29
|
+
}
|
|
30
|
+
declare function Popup({ children, style, dismissible, scrollable, }: DialogPopupProps): import("react").JSX.Element;
|
|
31
|
+
/**
|
|
32
|
+
* Not rendered.
|
|
33
|
+
*
|
|
34
|
+
* The scrim is drawn by Popup, because React Native's Modal owns that layer and
|
|
35
|
+
* a separate backdrop element would have nothing to render into. Kept so call
|
|
36
|
+
* sites written against `@gryt/ui` do not have to drop a line.
|
|
37
|
+
*/
|
|
38
|
+
declare function Backdrop(): null;
|
|
39
|
+
declare function Title({ children, style }: {
|
|
40
|
+
children?: ReactNode;
|
|
41
|
+
style?: StyleProp<TextStyle>;
|
|
42
|
+
}): import("react").JSX.Element;
|
|
43
|
+
declare function Description({ children, style }: {
|
|
44
|
+
children?: ReactNode;
|
|
45
|
+
style?: StyleProp<TextStyle>;
|
|
46
|
+
}): import("react").JSX.Element;
|
|
47
|
+
declare function Footer({ children, style }: {
|
|
48
|
+
children?: ReactNode;
|
|
49
|
+
style?: StyleProp<ViewStyle>;
|
|
50
|
+
}): import("react").JSX.Element;
|
|
51
|
+
declare function Close({ children, style }: {
|
|
52
|
+
children?: ReactNode;
|
|
53
|
+
style?: StyleProp<ViewStyle>;
|
|
54
|
+
}): import("react").JSX.Element;
|
|
55
|
+
export declare const Dialog: {
|
|
56
|
+
Root: typeof Root;
|
|
57
|
+
Trigger: typeof Trigger;
|
|
58
|
+
Portal: typeof Portal;
|
|
59
|
+
Backdrop: typeof Backdrop;
|
|
60
|
+
Popup: typeof Popup;
|
|
61
|
+
Title: typeof Title;
|
|
62
|
+
Description: typeof Description;
|
|
63
|
+
Footer: typeof Footer;
|
|
64
|
+
Close: typeof Close;
|
|
65
|
+
};
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=Dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../src/components/Dialog/Dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EAML,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AA2B/E,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,EAAE,eAAe,+BAKxD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,kBAAkB,+BAOvD;AAED;;;;;;GAMG;AACH,iBAAS,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAErD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gEAAgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,iBAAS,KAAK,CAAC,EACb,QAAQ,EACR,KAAK,EACL,WAAkB,EAClB,UAAiB,GAClB,EAAE,gBAAgB,+BA+DlB;AAED;;;;;;GAMG;AACH,iBAAS,QAAQ,IAAI,IAAI,CAExB;AAED,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAUzF;AAED,iBAAS,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAO/F;AAED,iBAAS,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAY1F;AAED,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAOzF;AAED,eAAO,MAAM,MAAM;;;;;;;;;;CAUlB,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
import { Modal, Pressable, ScrollView, Text, View, } from "react-native";
|
|
4
|
+
import { useOpenState } from "../../overlay/useOpenState.js";
|
|
5
|
+
import { useTheme } from "../../theme/index.js";
|
|
6
|
+
const DialogContext = createContext(null);
|
|
7
|
+
function useDialog(part) {
|
|
8
|
+
const value = useContext(DialogContext);
|
|
9
|
+
if (!value) {
|
|
10
|
+
throw new Error(`Dialog.${part} must be rendered inside Dialog.Root.`);
|
|
11
|
+
}
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
function Root({ children, ...openProps }) {
|
|
15
|
+
const state = useOpenState(openProps);
|
|
16
|
+
return (_jsx(DialogContext.Provider, { value: state, children: children }));
|
|
17
|
+
}
|
|
18
|
+
function Trigger({ children, style }) {
|
|
19
|
+
const { setOpen } = useDialog("Trigger");
|
|
20
|
+
return (_jsx(Pressable, { accessibilityRole: "button", onPress: () => setOpen(true), style: style, children: children }));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A passthrough.
|
|
24
|
+
*
|
|
25
|
+
* On the web a portal is how the popup escapes overflow and stacking contexts.
|
|
26
|
+
* React Native's `Modal` already renders above everything, so there is nothing
|
|
27
|
+
* to escape. It exists so call sites keep the same shape.
|
|
28
|
+
*/
|
|
29
|
+
function Portal({ children }) {
|
|
30
|
+
return _jsx(_Fragment, { children: children });
|
|
31
|
+
}
|
|
32
|
+
function Popup({ children, style, dismissible = true, scrollable = true, }) {
|
|
33
|
+
const { open, setOpen } = useDialog("Popup");
|
|
34
|
+
const theme = useTheme();
|
|
35
|
+
const body = (_jsx(View
|
|
36
|
+
// iOS hides everything behind a modal from VoiceOver with this; Android
|
|
37
|
+
// gets the same effect from Modal itself.
|
|
38
|
+
, {
|
|
39
|
+
// iOS hides everything behind a modal from VoiceOver with this; Android
|
|
40
|
+
// gets the same effect from Modal itself.
|
|
41
|
+
accessibilityViewIsModal: true, style: [
|
|
42
|
+
{
|
|
43
|
+
width: "100%",
|
|
44
|
+
maxWidth: 480,
|
|
45
|
+
maxHeight: "80%",
|
|
46
|
+
backgroundColor: theme.color.surfaceRaised,
|
|
47
|
+
borderRadius: theme.radius.lg,
|
|
48
|
+
borderWidth: 1,
|
|
49
|
+
borderColor: theme.color.border,
|
|
50
|
+
padding: theme.space(5),
|
|
51
|
+
gap: theme.space(3),
|
|
52
|
+
},
|
|
53
|
+
style,
|
|
54
|
+
], children: scrollable ? (_jsx(ScrollView, { contentContainerStyle: { gap: theme.space(3) }, children: children })) : (children) }));
|
|
55
|
+
return (_jsx(Modal, { visible: open, transparent: true, animationType: "fade",
|
|
56
|
+
// Android's hardware back button, which is the closest thing a phone has
|
|
57
|
+
// to the Escape key Base UI listens for. AlertDialog turns it off for the
|
|
58
|
+
// same reason it turns off the scrim: neither is an answer.
|
|
59
|
+
onRequestClose: dismissible ? () => setOpen(false) : undefined, children: _jsx(Pressable
|
|
60
|
+
// The scrim doubles as the outside-press target, which is how Base UI
|
|
61
|
+
// dismisses too.
|
|
62
|
+
, {
|
|
63
|
+
// The scrim doubles as the outside-press target, which is how Base UI
|
|
64
|
+
// dismisses too.
|
|
65
|
+
onPress: dismissible ? () => setOpen(false) : undefined, style: {
|
|
66
|
+
flex: 1,
|
|
67
|
+
alignItems: "center",
|
|
68
|
+
justifyContent: "center",
|
|
69
|
+
padding: theme.space(5),
|
|
70
|
+
backgroundColor: "rgba(0,0,0,0.6)",
|
|
71
|
+
}, children: _jsx(Pressable, { onPress: () => { }, style: { width: "100%", alignItems: "center" }, children: body }) }) }));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Not rendered.
|
|
75
|
+
*
|
|
76
|
+
* The scrim is drawn by Popup, because React Native's Modal owns that layer and
|
|
77
|
+
* a separate backdrop element would have nothing to render into. Kept so call
|
|
78
|
+
* sites written against `@gryt/ui` do not have to drop a line.
|
|
79
|
+
*/
|
|
80
|
+
function Backdrop() {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
function Title({ children, style }) {
|
|
84
|
+
const theme = useTheme();
|
|
85
|
+
return (_jsx(Text, { accessibilityRole: "header", style: [{ color: theme.color.text, fontSize: 18, fontWeight: "600" }, style], children: children }));
|
|
86
|
+
}
|
|
87
|
+
function Description({ children, style }) {
|
|
88
|
+
const theme = useTheme();
|
|
89
|
+
return (_jsx(Text, { style: [{ color: theme.color.muted, fontSize: 14, lineHeight: 20 }, style], children: children }));
|
|
90
|
+
}
|
|
91
|
+
function Footer({ children, style }) {
|
|
92
|
+
const theme = useTheme();
|
|
93
|
+
return (_jsx(View, { style: [
|
|
94
|
+
{ flexDirection: "row", justifyContent: "flex-end", gap: theme.space(3) },
|
|
95
|
+
style,
|
|
96
|
+
], children: children }));
|
|
97
|
+
}
|
|
98
|
+
function Close({ children, style }) {
|
|
99
|
+
const { setOpen } = useDialog("Close");
|
|
100
|
+
return (_jsx(Pressable, { accessibilityRole: "button", onPress: () => setOpen(false), style: style, children: children }));
|
|
101
|
+
}
|
|
102
|
+
export const Dialog = {
|
|
103
|
+
Root,
|
|
104
|
+
Trigger,
|
|
105
|
+
Portal,
|
|
106
|
+
Backdrop,
|
|
107
|
+
Popup,
|
|
108
|
+
Title,
|
|
109
|
+
Description,
|
|
110
|
+
Footer,
|
|
111
|
+
Close,
|
|
112
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
2
|
+
export interface DividerProps {
|
|
3
|
+
orientation?: "horizontal" | "vertical";
|
|
4
|
+
/** Inset from both ends, in 4pt steps. */
|
|
5
|
+
inset?: number;
|
|
6
|
+
style?: StyleProp<ViewStyle>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A hairline.
|
|
10
|
+
*
|
|
11
|
+
* The web uses 1px. Here it is `1` in device-independent points, which lands on
|
|
12
|
+
* one physical pixel on a 1x screen and stays a hairline on 2x and 3x — the same
|
|
13
|
+
* thing the web gets from a 1px border on a retina display.
|
|
14
|
+
*/
|
|
15
|
+
export declare function Divider({ orientation, inset, style, }: DividerProps): import("react").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=Divider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Divider.d.ts","sourceRoot":"","sources":["../../../src/components/Divider/Divider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAIpE,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,EACtB,WAA0B,EAC1B,KAAS,EACT,KAAK,GACN,EAAE,YAAY,+BAgBd"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { useTheme } from "../../theme/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* A hairline.
|
|
6
|
+
*
|
|
7
|
+
* The web uses 1px. Here it is `1` in device-independent points, which lands on
|
|
8
|
+
* one physical pixel on a 1x screen and stays a hairline on 2x and 3x — the same
|
|
9
|
+
* thing the web gets from a 1px border on a retina display.
|
|
10
|
+
*/
|
|
11
|
+
export function Divider({ orientation = "horizontal", inset = 0, style, }) {
|
|
12
|
+
const theme = useTheme();
|
|
13
|
+
const gap = theme.space(inset);
|
|
14
|
+
return (_jsx(View, { accessibilityRole: "none", style: [
|
|
15
|
+
orientation === "horizontal"
|
|
16
|
+
? { height: 1, alignSelf: "stretch", marginHorizontal: gap }
|
|
17
|
+
: { width: 1, alignSelf: "stretch", marginVertical: gap },
|
|
18
|
+
{ backgroundColor: theme.color.border },
|
|
19
|
+
style,
|
|
20
|
+
] }));
|
|
21
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import { type OpenStateProps } from "../../overlay/useOpenState.js";
|
|
4
|
+
export type DrawerSide = "left" | "right" | "bottom";
|
|
5
|
+
export interface DrawerRootProps extends OpenStateProps {
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
declare function Root({ children, ...openProps }: DrawerRootProps): import("react").JSX.Element;
|
|
9
|
+
declare function Trigger({ children, style }: {
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
style?: StyleProp<ViewStyle>;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
declare function Portal({ children }: {
|
|
14
|
+
children?: ReactNode;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
export interface DrawerPopupProps {
|
|
17
|
+
children?: ReactNode;
|
|
18
|
+
side?: DrawerSide;
|
|
19
|
+
/** Fraction of the screen, 0 to 1. */
|
|
20
|
+
size?: number;
|
|
21
|
+
dismissible?: boolean;
|
|
22
|
+
style?: StyleProp<ViewStyle>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Slides in from an edge, which is the one place an animation is not decoration.
|
|
26
|
+
*
|
|
27
|
+
* A drawer that appears without moving reads as a screen change rather than a
|
|
28
|
+
* panel, so this one animates even though Collapsible and Skeleton do not.
|
|
29
|
+
* Reduce-motion still turns it off: the drawer arrives in place instead.
|
|
30
|
+
*/
|
|
31
|
+
declare function Popup({ children, side, size, dismissible, style, }: DrawerPopupProps): import("react").JSX.Element;
|
|
32
|
+
declare function Close({ children, style }: {
|
|
33
|
+
children?: ReactNode;
|
|
34
|
+
style?: StyleProp<ViewStyle>;
|
|
35
|
+
}): import("react").JSX.Element;
|
|
36
|
+
export declare const Drawer: {
|
|
37
|
+
Root: typeof Root;
|
|
38
|
+
Trigger: typeof Trigger;
|
|
39
|
+
Portal: typeof Portal;
|
|
40
|
+
Popup: typeof Popup;
|
|
41
|
+
Close: typeof Close;
|
|
42
|
+
};
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=Drawer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../../src/components/Drawer/Drawer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvF,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG/E,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAerD,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,EAAE,eAAe,+BAGxD;AAED,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAO3F;AAED,iBAAS,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAErD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,iBAAS,KAAK,CAAC,EACb,QAAQ,EACR,IAAa,EACb,IAAU,EACV,WAAkB,EAClB,KAAK,GACN,EAAE,gBAAgB,+BAuElB;AAED,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAOzF;AAED,eAAO,MAAM,MAAM;;;;;;CAA0C,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
3
|
+
import { Animated, Dimensions, Modal, Pressable, } from "react-native";
|
|
4
|
+
import { useReducedMotion } from "../../hooks/useReducedMotion.js";
|
|
5
|
+
import { useOpenState } from "../../overlay/useOpenState.js";
|
|
6
|
+
import { useTheme } from "../../theme/index.js";
|
|
7
|
+
const DrawerContext = createContext(null);
|
|
8
|
+
function useDrawer(part) {
|
|
9
|
+
const value = useContext(DrawerContext);
|
|
10
|
+
if (!value)
|
|
11
|
+
throw new Error(`Drawer.${part} must be rendered inside Drawer.Root.`);
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
function Root({ children, ...openProps }) {
|
|
15
|
+
const state = useOpenState(openProps);
|
|
16
|
+
return _jsx(DrawerContext.Provider, { value: state, children: children });
|
|
17
|
+
}
|
|
18
|
+
function Trigger({ children, style }) {
|
|
19
|
+
const { setOpen } = useDrawer("Trigger");
|
|
20
|
+
return (_jsx(Pressable, { accessibilityRole: "button", onPress: () => setOpen(true), style: style, children: children }));
|
|
21
|
+
}
|
|
22
|
+
function Portal({ children }) {
|
|
23
|
+
return _jsx(_Fragment, { children: children });
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Slides in from an edge, which is the one place an animation is not decoration.
|
|
27
|
+
*
|
|
28
|
+
* A drawer that appears without moving reads as a screen change rather than a
|
|
29
|
+
* panel, so this one animates even though Collapsible and Skeleton do not.
|
|
30
|
+
* Reduce-motion still turns it off: the drawer arrives in place instead.
|
|
31
|
+
*/
|
|
32
|
+
function Popup({ children, side = "left", size = 0.8, dismissible = true, style, }) {
|
|
33
|
+
const { open, setOpen } = useDrawer("Popup");
|
|
34
|
+
const theme = useTheme();
|
|
35
|
+
const reducedMotion = useReducedMotion();
|
|
36
|
+
const screen = Dimensions.get("window");
|
|
37
|
+
const vertical = side === "bottom";
|
|
38
|
+
const extent = vertical ? screen.height * size : screen.width * size;
|
|
39
|
+
const [progress] = useState(() => new Animated.Value(0));
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (!open) {
|
|
42
|
+
progress.setValue(0);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (reducedMotion) {
|
|
46
|
+
progress.setValue(1);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
Animated.spring(progress, {
|
|
50
|
+
toValue: 1,
|
|
51
|
+
useNativeDriver: true,
|
|
52
|
+
speed: 20,
|
|
53
|
+
bounciness: 0,
|
|
54
|
+
}).start();
|
|
55
|
+
}, [open, progress, reducedMotion]);
|
|
56
|
+
const hidden = side === "right" ? extent : side === "left" ? -extent : extent;
|
|
57
|
+
const translate = progress.interpolate({
|
|
58
|
+
inputRange: [0, 1],
|
|
59
|
+
outputRange: [hidden, 0],
|
|
60
|
+
});
|
|
61
|
+
return (_jsx(Modal, { visible: open, transparent: true, animationType: "none", onRequestClose: dismissible ? () => setOpen(false) : undefined, children: _jsx(Pressable, { onPress: dismissible ? () => setOpen(false) : undefined, style: { flex: 1, backgroundColor: "rgba(0,0,0,0.6)" }, children: _jsx(Animated.View, { accessibilityViewIsModal: true, style: {
|
|
62
|
+
position: "absolute",
|
|
63
|
+
top: side === "bottom" ? undefined : 0,
|
|
64
|
+
bottom: 0,
|
|
65
|
+
left: side === "right" ? undefined : 0,
|
|
66
|
+
right: side === "left" ? undefined : 0,
|
|
67
|
+
width: vertical ? "100%" : extent,
|
|
68
|
+
height: vertical ? extent : "100%",
|
|
69
|
+
backgroundColor: theme.color.surface,
|
|
70
|
+
borderColor: theme.color.border,
|
|
71
|
+
borderRightWidth: side === "left" ? 1 : 0,
|
|
72
|
+
borderLeftWidth: side === "right" ? 1 : 0,
|
|
73
|
+
borderTopWidth: vertical ? 1 : 0,
|
|
74
|
+
borderTopLeftRadius: vertical ? theme.radius.lg : 0,
|
|
75
|
+
borderTopRightRadius: vertical ? theme.radius.lg : 0,
|
|
76
|
+
transform: [vertical ? { translateY: translate } : { translateX: translate }],
|
|
77
|
+
}, children: _jsx(Pressable, { onPress: () => { }, style: [{ flex: 1 }, style], children: children }) }) }) }));
|
|
78
|
+
}
|
|
79
|
+
function Close({ children, style }) {
|
|
80
|
+
const { setOpen } = useDrawer("Close");
|
|
81
|
+
return (_jsx(Pressable, { accessibilityRole: "button", onPress: () => setOpen(false), style: style, children: children }));
|
|
82
|
+
}
|
|
83
|
+
export const Drawer = { Root, Trigger, Portal, Popup, Close };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import type { Align, Side } from "../../overlay/placePopup.js";
|
|
4
|
+
import { type OpenStateProps } from "../../overlay/useOpenState.js";
|
|
5
|
+
export interface MenuRootProps extends OpenStateProps {
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
declare function Root({ children, ...openProps }: MenuRootProps): import("react").JSX.Element;
|
|
9
|
+
declare function Trigger({ children, style }: {
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
style?: StyleProp<ViewStyle>;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
declare function Portal({ children }: {
|
|
14
|
+
children?: ReactNode;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
16
|
+
/**
|
|
17
|
+
* Kept as a passthrough for shape.
|
|
18
|
+
*
|
|
19
|
+
* Base UI splits Positioner from Popup so the positioned box and the styled box
|
|
20
|
+
* are separate elements. Here AnchoredPopup is both, because there is no
|
|
21
|
+
* stacking context to escape and nothing gained by the extra view.
|
|
22
|
+
*/
|
|
23
|
+
declare function Positioner({ children }: {
|
|
24
|
+
children?: ReactNode;
|
|
25
|
+
}): import("react").JSX.Element;
|
|
26
|
+
export interface MenuPopupProps {
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
side?: Side;
|
|
29
|
+
align?: Align;
|
|
30
|
+
sideOffset?: number;
|
|
31
|
+
style?: StyleProp<ViewStyle>;
|
|
32
|
+
}
|
|
33
|
+
declare function Popup({ children, style, ...options }: MenuPopupProps): import("react").JSX.Element;
|
|
34
|
+
export interface MenuItemProps {
|
|
35
|
+
children?: ReactNode;
|
|
36
|
+
onPress?: () => void;
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
/** Renders in the danger ramp, for destructive actions. */
|
|
39
|
+
destructive?: boolean;
|
|
40
|
+
style?: StyleProp<ViewStyle>;
|
|
41
|
+
}
|
|
42
|
+
declare function Item({ children, onPress, disabled, destructive, style }: MenuItemProps): import("react").JSX.Element;
|
|
43
|
+
declare function Separator({ style }: {
|
|
44
|
+
style?: StyleProp<ViewStyle>;
|
|
45
|
+
}): import("react").JSX.Element;
|
|
46
|
+
export declare const Menu: {
|
|
47
|
+
Root: typeof Root;
|
|
48
|
+
Trigger: typeof Trigger;
|
|
49
|
+
Portal: typeof Portal;
|
|
50
|
+
Positioner: typeof Positioner;
|
|
51
|
+
Popup: typeof Popup;
|
|
52
|
+
Item: typeof Item;
|
|
53
|
+
Separator: typeof Separator;
|
|
54
|
+
};
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=Menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../../src/components/Menu/Menu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACvF,OAAO,EAAyB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAGrF,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAkB/E,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,EAAE,aAAa,+BAQtD;AAED,iBAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAY3F;AAED,iBAAS,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAErD;AAED;;;;;;GAMG;AACH,iBAAS,UAAU,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAEzD;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,iBAAS,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,EAAE,cAAc,+BAe7D;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAED,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,aAAa,+BAuC/E;AAED,iBAAS,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,+BAU7D;AAED,eAAO,MAAM,IAAI;;;;;;;;CAAgE,CAAC"}
|