@gryt/ui-native 0.3.1 → 0.5.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 +9 -1
- package/dist/components/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/components/Checkbox/Checkbox.d.ts +7 -1
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/Checkbox.js +47 -15
- package/dist/components/Dialog/Dialog.d.ts.map +1 -1
- package/dist/components/Dialog/Dialog.js +10 -1
- package/dist/components/Drawer/Drawer.d.ts +0 -7
- package/dist/components/Drawer/Drawer.d.ts.map +1 -1
- package/dist/components/Drawer/Drawer.js +229 -30
- package/dist/components/Progress/Progress.d.ts +11 -17
- package/dist/components/Progress/Progress.d.ts.map +1 -1
- package/dist/components/Progress/Progress.js +66 -22
- package/dist/components/Radio/Radio.d.ts +9 -1
- package/dist/components/Radio/Radio.d.ts.map +1 -1
- package/dist/components/Radio/Radio.js +38 -14
- package/dist/components/ScrollArea/ScrollArea.d.ts +6 -4
- package/dist/components/ScrollArea/ScrollArea.d.ts.map +1 -1
- package/dist/components/ScrollArea/ScrollArea.js +19 -4
- package/dist/components/Sheet/Sheet.d.ts +99 -0
- package/dist/components/Sheet/Sheet.d.ts.map +1 -0
- package/dist/components/Sheet/Sheet.js +201 -0
- package/dist/components/Slider/Slider.d.ts.map +1 -1
- package/dist/components/Slider/Slider.js +33 -0
- package/dist/components/Switch/Switch.d.ts +4 -1
- package/dist/components/Switch/Switch.d.ts.map +1 -1
- package/dist/components/Switch/Switch.js +21 -17
- package/dist/components/Tabs/Tabs.d.ts +38 -13
- package/dist/components/Tabs/Tabs.d.ts.map +1 -1
- package/dist/components/Tabs/Tabs.js +157 -42
- package/dist/components/Toggle/Toggle.d.ts +0 -1
- package/dist/components/Toggle/Toggle.d.ts.map +1 -1
- package/dist/components/Toggle/Toggle.js +15 -1
- package/dist/components/internal/ControlRow.d.ts +54 -0
- package/dist/components/internal/ControlRow.d.ts.map +1 -0
- package/dist/components/internal/ControlRow.js +59 -0
- package/dist/components/internal/dragLock.d.ts +43 -0
- package/dist/components/internal/dragLock.d.ts.map +1 -0
- package/dist/components/internal/dragLock.js +18 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/motion/motion.d.ts +13 -3
- package/dist/motion/motion.d.ts.map +1 -1
- package/dist/motion/motion.js +6 -6
- package/package.json +11 -5
package/README.md
CHANGED
|
@@ -69,7 +69,6 @@ goal, so the honest list is worth more than a claim of parity that isn't one.
|
|
|
69
69
|
| `Button` | Press scale is kept, hover scale is dropped | The web scales to `0.96` on press and `1.03` on hover. Press maps directly onto `onPressIn`/`onPressOut`, so it is here, spring-animated and skipped when reduce-motion is on. |
|
|
70
70
|
| `Button` | `hasPopup` is a prop, not inferred | The web reads `aria-haspopup`, which Base UI sets on a trigger, and skips the scale so the trigger does not drag its own popup sideways while it is being measured. React Native has no such attribute, so a menu trigger has to say so. |
|
|
71
71
|
| `TextField` | Focus changes the border colour instead of drawing an outline | The web's `outline` sits outside the box and shifts nothing. React Native has no outline, and a second ring would move the layout on focus. |
|
|
72
|
-
| `Progress` | Indeterminate renders as an empty track | The web sweeps a partial bar with a CSS keyframe. Doing it here needs an `Animated` loop plus a reduce-motion check, which deserves its own pass rather than a footnote. |
|
|
73
72
|
| `Tooltip` | Opens on long press, closes on release, instead of appearing on hover after a delay | A phone has no hover. This is the same name on a different interaction, and it is the component where 1:1 is least achievable. An interface that needs tooltips to be usable will not survive the port. |
|
|
74
73
|
| *(positioned overlays)* | The popup does not follow a trigger that moves | Floating UI keeps watching the reference element. React Native measures on demand and reports nothing afterwards, so the position is taken once, when the popup opens. If a list scrolls underneath an open menu, the menu stays put. |
|
|
75
74
|
| `Popover` | `Arrow` renders nothing | Base UI positions an arrow against the popup's edge once Floating UI has settled. Here it means a rotated square, a border on two sides only, and knowing which side the popup landed on. Doable, not free, and not done. |
|
|
@@ -89,6 +88,15 @@ goal, so the honest list is worth more than a claim of parity that isn't one.
|
|
|
89
88
|
| `Accordion` | Two glyphs instead of a rotating chevron | Same reasoning as the checkbox tick: rotating one needs a transform and a measurement, and there is no icon set here yet. |
|
|
90
89
|
| `Skeleton` | Does not pulse | A loop running for the length of a request costs battery, and it is the sort of motion reduce-motion users switch off first. A flat block still reads as loading. |
|
|
91
90
|
|
|
91
|
+
## Additions
|
|
92
|
+
|
|
93
|
+
The other direction, and a shorter list. Something here that the web does not
|
|
94
|
+
have needs the same justification as something missing.
|
|
95
|
+
|
|
96
|
+
| Component | Why there is no web counterpart |
|
|
97
|
+
|---|---|
|
|
98
|
+
| `Sheet` | A sheet is what a phone does where the web opens a dialog or slides a drawer, and the two are not the same interaction: it is dragged, it settles at heights the user chooses, and dismissing it is a flick rather than a click on an X. Shipping the web's Dialog on a phone would be 1:1 and wrong; inventing a sheet on the web would be worse. |
|
|
99
|
+
|
|
92
100
|
## Not Node-importable
|
|
93
101
|
|
|
94
102
|
The build is unbundled `tsc` output, which is what Metro wants: it resolves
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlertDialog.d.ts","sourceRoot":"","sources":["../../../src/components/AlertDialog/AlertDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEvF;;;;;;;;;;GAUG;AAIH,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;AAE1E,iBAAS,KAAK,CAAC,KAAK,EAAE,qBAAqB,+BAE1C;AAED,MAAM,MAAM,oBAAoB,GAAG,eAAe,CAAC;AAEnD,eAAO,MAAM,WAAW;;;;gBAUw0B,CAAC;;;;;
|
|
1
|
+
{"version":3,"file":"AlertDialog.d.ts","sourceRoot":"","sources":["../../../src/components/AlertDialog/AlertDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEvF;;;;;;;;;;GAUG;AAIH,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;AAE1E,iBAAS,KAAK,CAAC,KAAK,EAAE,qBAAqB,+BAE1C;AAED,MAAM,MAAM,oBAAoB,GAAG,eAAe,CAAC;AAEnD,eAAO,MAAM,WAAW;;;;gBAUw0B,CAAC;;;;;gBAAovK,CAAC;aAAkB,CAAC;;;gBAAiS,CAAC;aAAkB,CAAC;;;gBAAkiB,CAAC;aAAkB,CAAC;;CADn9N,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
1
2
|
import { type StyleProp, type ViewStyle } from "react-native";
|
|
2
3
|
export type CheckboxTone = "primary" | "secondary" | "neutral" | "danger";
|
|
3
4
|
export interface CheckboxProps {
|
|
@@ -8,6 +9,11 @@ export interface CheckboxProps {
|
|
|
8
9
|
onCheckedChange?: (checked: boolean) => void;
|
|
9
10
|
disabled?: boolean;
|
|
10
11
|
tone?: CheckboxTone;
|
|
12
|
+
/**
|
|
13
|
+
* Tapping this toggles the box, which is what a `<label>` does on the web.
|
|
14
|
+
* See ControlRow for why it is a prop here rather than a wrapper element.
|
|
15
|
+
*/
|
|
16
|
+
label?: ReactNode;
|
|
11
17
|
style?: StyleProp<ViewStyle>;
|
|
12
18
|
accessibilityLabel?: string;
|
|
13
19
|
}
|
|
@@ -20,5 +26,5 @@ export interface CheckboxProps {
|
|
|
20
26
|
* react-native-svg on top. Both are decisions for whoever needs a full icon set,
|
|
21
27
|
* not for a checkbox.
|
|
22
28
|
*/
|
|
23
|
-
export declare function Checkbox({ checked: controlled, defaultChecked, indeterminate, onCheckedChange, disabled, tone, style, accessibilityLabel, }: CheckboxProps): import("react").JSX.Element;
|
|
29
|
+
export declare function Checkbox({ checked: controlled, defaultChecked, indeterminate, onCheckedChange, disabled, tone, label, style, accessibilityLabel, }: CheckboxProps): import("react").JSX.Element;
|
|
24
30
|
//# sourceMappingURL=Checkbox.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAQ,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AASpE,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1E,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sEAAsE;IACtE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EAAE,UAAU,EACnB,cAAsB,EACtB,aAAqB,EACrB,eAAe,EACf,QAAQ,EACR,IAAgB,EAChB,KAAK,EACL,KAAK,EACL,kBAAkB,GACnB,EAAE,aAAa,+BAiFf"}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
import {
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Text } from "react-native";
|
|
4
|
+
import Animated, { useAnimatedStyle, useSharedValue } from "react-native-reanimated";
|
|
5
|
+
import { grytScaleSteps } from "@gryt/theme";
|
|
6
|
+
import { springy } from "../../motion/index.js";
|
|
4
7
|
import { toneRamp, useTheme } from "../../theme/index.js";
|
|
8
|
+
import { useReducedMotion } from "../../hooks/useReducedMotion.js";
|
|
9
|
+
import { ControlRow } from "../internal/ControlRow.js";
|
|
5
10
|
const SIZE = 20;
|
|
6
11
|
/**
|
|
7
12
|
* The tick is a text glyph rather than an icon.
|
|
@@ -12,32 +17,59 @@ const SIZE = 20;
|
|
|
12
17
|
* react-native-svg on top. Both are decisions for whoever needs a full icon set,
|
|
13
18
|
* not for a checkbox.
|
|
14
19
|
*/
|
|
15
|
-
export function Checkbox({ checked: controlled, defaultChecked = false, indeterminate = false, onCheckedChange, disabled, tone = "primary", style, accessibilityLabel, }) {
|
|
20
|
+
export function Checkbox({ checked: controlled, defaultChecked = false, indeterminate = false, onCheckedChange, disabled, tone = "primary", label, style, accessibilityLabel, }) {
|
|
16
21
|
const theme = useTheme();
|
|
22
|
+
const reducedMotion = useReducedMotion();
|
|
17
23
|
const [uncontrolled, setUncontrolled] = useState(defaultChecked);
|
|
18
24
|
const checked = controlled ?? uncontrolled;
|
|
19
25
|
const ramp = toneRamp(theme, tone);
|
|
20
26
|
const filled = checked || indeterminate;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
/**
|
|
28
|
+
* The tick scales from 0, not from something near 1.
|
|
29
|
+
*
|
|
30
|
+
* Straight from the web's comment, and it is not a detail: the spring's
|
|
31
|
+
* overshoot is a percentage of the travel, so 0 → 1 overshoots to 1.12 and
|
|
32
|
+
* visibly springs, while 0.95 → 1 overshoots by 0.006 and does nothing at
|
|
33
|
+
* all. It used to appear instantly here, which is the same bug with the
|
|
34
|
+
* travel set to zero.
|
|
35
|
+
*/
|
|
36
|
+
const tick = useSharedValue(filled ? 1 : 0);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const to = filled ? 1 : 0;
|
|
39
|
+
// eslint-disable-next-line react-hooks/immutability
|
|
40
|
+
tick.value = reducedMotion ? to : springy(to);
|
|
41
|
+
}, [filled, tick, reducedMotion]);
|
|
42
|
+
const tickStyle = useAnimatedStyle(() => ({
|
|
43
|
+
transform: [{ scale: tick.value }],
|
|
44
|
+
opacity: tick.value,
|
|
45
|
+
}));
|
|
46
|
+
return (_jsx(ControlRow, { label: label, onPress: () => {
|
|
25
47
|
const next = !checked;
|
|
26
48
|
if (controlled === undefined)
|
|
27
49
|
setUncontrolled(next);
|
|
28
50
|
onCheckedChange?.(next);
|
|
29
|
-
},
|
|
30
|
-
|
|
51
|
+
}, disabled: disabled, pressScale: grytScaleSteps.checkbox.press, accessibilityRole: "checkbox", accessibilityState: {
|
|
52
|
+
checked: indeterminate ? "mixed" : checked,
|
|
53
|
+
disabled: !!disabled,
|
|
54
|
+
}, accessibilityLabel: accessibilityLabel, style: style, children: _jsx(Animated.View, { style: {
|
|
31
55
|
width: SIZE,
|
|
32
56
|
height: SIZE,
|
|
33
57
|
borderRadius: theme.radius.sm,
|
|
34
58
|
alignItems: "center",
|
|
35
59
|
justifyContent: "center",
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
60
|
+
// The web keeps the border at 1 always and makes it transparent when
|
|
61
|
+
// checked, rather than dropping to 0 — a border that disappears
|
|
62
|
+
// changes the box's size mid-transition.
|
|
63
|
+
borderWidth: 1,
|
|
64
|
+
borderColor: filled ? "transparent" : theme.color.border,
|
|
65
|
+
// Was `transparent`, which is not what the web does: an unchecked box
|
|
66
|
+
// is a filled surface with an outline, not a hole.
|
|
67
|
+
backgroundColor: filled ? ramp[8] : theme.color.surfaceRaised,
|
|
39
68
|
opacity: disabled ? 0.5 : 1,
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
|
|
69
|
+
}, children: _jsx(Animated.View, { style: tickStyle, children: _jsx(Text, { style: {
|
|
70
|
+
color: theme.color.onAccent,
|
|
71
|
+
fontSize: 13,
|
|
72
|
+
fontWeight: "900",
|
|
73
|
+
lineHeight: 15,
|
|
74
|
+
}, children: indeterminate ? "–" : "✓" }) }) }) }));
|
|
43
75
|
}
|
|
@@ -1 +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,+
|
|
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,+BA4GlB;AAYD;;;;;;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"}
|
|
@@ -81,7 +81,16 @@ function Popup({ children, style, dismissible = true, scrollable = true, }) {
|
|
|
81
81
|
justifyContent: "center",
|
|
82
82
|
padding: theme.space(5),
|
|
83
83
|
backgroundColor: "rgba(0,0,0,0.6)",
|
|
84
|
-
}, children: _jsx(
|
|
84
|
+
}, children: _jsx(View, { onStartShouldSetResponder: claimTouch, style: { width: "100%", alignItems: "center", maxHeight: "80%" }, children: body }) }) }));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Claim a touch that no child wanted.
|
|
88
|
+
*
|
|
89
|
+
* Declared once rather than as an inline arrow, so every Dialog is not handing
|
|
90
|
+
* the responder system a new function identity on every render.
|
|
91
|
+
*/
|
|
92
|
+
function claimTouch() {
|
|
93
|
+
return true;
|
|
85
94
|
}
|
|
86
95
|
/**
|
|
87
96
|
* Not rendered.
|
|
@@ -21,13 +21,6 @@ export interface DrawerPopupProps {
|
|
|
21
21
|
dismissible?: boolean;
|
|
22
22
|
style?: StyleProp<ViewStyle>;
|
|
23
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
24
|
declare function Popup({ children, side, size, dismissible, style }: DrawerPopupProps): import("react").JSX.Element;
|
|
32
25
|
declare function Close({ children, style }: {
|
|
33
26
|
children?: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../../src/components/Drawer/Drawer.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../../src/components/Drawer/Drawer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAA2C,MAAM,OAAO,CAAC;AAC/F,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAWtB,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG/E,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAgBrD,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,iBAAS,OAAO,CAAC,EACf,QAAQ,EACR,KAAK,EACN,EAAE;IACD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B,+BAWA;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;AAgBD,iBAAS,KAAK,CAAC,EACb,QAAQ,EACR,IAAa,EACb,IAAU,EACV,WAAkB,EAClB,KAAK,EACN,EAAE,gBAAgB,+BA2RlB;AAED,iBAAS,KAAK,CAAC,EACb,QAAQ,EACR,KAAK,EACN,EAAE;IACD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B,+BAWA;AAED,eAAO,MAAM,MAAM;;;;;;CAA0C,CAAC"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext, useEffect } from "react";
|
|
3
|
-
import { Dimensions, Modal, Pressable } from "react-native";
|
|
4
|
-
import Animated, { useAnimatedStyle, useSharedValue } from "react-native-reanimated";
|
|
2
|
+
import { createContext, useContext, useEffect, useRef, useState } from "react";
|
|
3
|
+
import { Dimensions, PanResponder, Modal, Pressable } from "react-native";
|
|
4
|
+
import Animated, { runOnJS, useAnimatedStyle, useSharedValue } from "react-native-reanimated";
|
|
5
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
5
6
|
import { useReducedMotion } from "../../hooks/useReducedMotion.js";
|
|
6
|
-
import {
|
|
7
|
+
import { grytDrawerBleed } from "@gryt/theme";
|
|
8
|
+
import { durations, travel as travelTo } from "../../motion/index.js";
|
|
7
9
|
import { useOpenState } from "../../overlay/useOpenState.js";
|
|
8
10
|
import { useTheme } from "../../theme/index.js";
|
|
9
11
|
const DrawerContext = createContext(null);
|
|
@@ -31,45 +33,233 @@ function Portal({ children }) {
|
|
|
31
33
|
* panel, so this one animates even though Collapsible and Skeleton do not.
|
|
32
34
|
* Reduce-motion still turns it off: the drawer arrives in place instead.
|
|
33
35
|
*/
|
|
36
|
+
/**
|
|
37
|
+
* The scrim takes an animated opacity, so it has to be an animated component.
|
|
38
|
+
* Declared once at module scope — `createAnimatedComponent` inside a render
|
|
39
|
+
* makes a new component type every time, which remounts the subtree.
|
|
40
|
+
*/
|
|
41
|
+
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
|
|
34
42
|
function Popup({ children, side = "left", size = 0.8, dismissible = true, style }) {
|
|
35
43
|
const { open, setOpen } = useDrawer("Popup");
|
|
36
44
|
const theme = useTheme();
|
|
45
|
+
/**
|
|
46
|
+
* The phone's own furniture, which a drawer has to stay clear of.
|
|
47
|
+
*
|
|
48
|
+
* A panel from the side is full height by definition, so its first row sits
|
|
49
|
+
* under the Dynamic Island and its last under the home indicator unless it
|
|
50
|
+
* says otherwise. A panel from the bottom only has the second problem.
|
|
51
|
+
*
|
|
52
|
+
* This is the same call GRYT-402 made for `Sheet`, and it belongs here for
|
|
53
|
+
* the same reason: every caller would otherwise write the same two lines, and
|
|
54
|
+
* the one that forgets ships a drawer with its heading under the clock. That
|
|
55
|
+
* is how the mobile shell's server switcher first looked.
|
|
56
|
+
*/
|
|
57
|
+
const insets = useSafeAreaInsets();
|
|
37
58
|
const reducedMotion = useReducedMotion();
|
|
38
59
|
const screen = Dimensions.get("window");
|
|
39
60
|
const vertical = side === "bottom";
|
|
40
61
|
const extent = vertical ? screen.height * size : screen.width * size;
|
|
41
62
|
const progress = useSharedValue(0);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
63
|
+
/**
|
|
64
|
+
* The panel is built `grytDrawerBleed` larger than it needs to be and hangs
|
|
65
|
+
* that much off-screen, with matching padding so the content sits where it
|
|
66
|
+
* would have.
|
|
67
|
+
*
|
|
68
|
+
* The spring overshoots — that is what makes it a spring — and it settles
|
|
69
|
+
* onto its target from both directions. A panel sized exactly to its resting
|
|
70
|
+
* place therefore shows a seam of backdrop down its edge on the undershoot,
|
|
71
|
+
* for a frame or two, every time it opens. The web has had this since the
|
|
72
|
+
* Drawer was written, as `--gryt-drawer-bleed`; this side did not.
|
|
73
|
+
*
|
|
74
|
+
* `grytDrawerBleed` rather than a local 64, and `bleedTokens.test.ts` in
|
|
75
|
+
* @gryt/ui keeps it equal to what theme.css says. Two overhangs that must
|
|
76
|
+
* match is how they stop matching.
|
|
77
|
+
*/
|
|
78
|
+
const bleed = grytDrawerBleed;
|
|
79
|
+
const panelExtent = extent + bleed;
|
|
80
|
+
// Measured against the bleed panel, so the panel's *visible* edge lands
|
|
81
|
+
// exactly off-screen rather than the overhang doing it.
|
|
82
|
+
const hidden = side === "right" ? panelExtent : side === "left" ? -panelExtent : panelExtent;
|
|
83
|
+
/**
|
|
84
|
+
* 700ms on the *tight* curve, and this changed on both platforms at once.
|
|
85
|
+
*
|
|
86
|
+
* It used to be the overshooting one, matching the web, with a note saying
|
|
87
|
+
* that a panel travelling its own width is exactly the case
|
|
88
|
+
* `--ease-spring-tight` was added for — and that if it ever felt wrong on a
|
|
89
|
+
* device, the web was what was wrong and both should change together.
|
|
90
|
+
*
|
|
91
|
+
* It felt wrong on a device. A full-height panel arriving with a 12%
|
|
92
|
+
* overshoot reads as aggressive rather than lively, because the overshoot is
|
|
93
|
+
* a percentage of the travel and the travel here is most of the screen. The
|
|
94
|
+
* same 12% on a 20px switch thumb is texture; on a 320pt panel it is a slam.
|
|
95
|
+
*
|
|
96
|
+
* `@gryt/ui`'s Drawer moved to `ease-spring-tight` in the same change.
|
|
97
|
+
*/
|
|
98
|
+
/**
|
|
99
|
+
* Mounted for longer than it is open, so the panel can animate out.
|
|
100
|
+
*
|
|
101
|
+
* React Native's `Modal` unmounts the moment `visible` goes false, and the
|
|
102
|
+
* close was also snapping `progress` straight to 0 rather than animating it
|
|
103
|
+
* — so a dismissed drawer did not slide away, it simply stopped existing.
|
|
104
|
+
* Both halves had to change: animate the close, and stay mounted until that
|
|
105
|
+
* animation has finished.
|
|
106
|
+
*/
|
|
107
|
+
const [mounted, setMounted] = useState(open);
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (open)
|
|
110
|
+
setMounted(true);
|
|
111
|
+
}, [open]);
|
|
47
112
|
useEffect(() => {
|
|
113
|
+
if (!mounted)
|
|
114
|
+
return;
|
|
115
|
+
if (reducedMotion) {
|
|
116
|
+
// eslint-disable-next-line react-hooks/immutability
|
|
117
|
+
progress.value = open ? 1 : 0;
|
|
118
|
+
if (!open)
|
|
119
|
+
setMounted(false);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
48
122
|
// eslint-disable-next-line react-hooks/immutability
|
|
49
|
-
progress.value =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
123
|
+
progress.value = travelTo(open ? 1 : 0, { duration: durations.springSoft }, (finished) => {
|
|
124
|
+
"worklet";
|
|
125
|
+
// Unmount only once the panel is actually gone, and only if the
|
|
126
|
+
// animation ran to the end — an interrupted close means it was
|
|
127
|
+
// reopened, and unmounting then would take the drawer away as it
|
|
128
|
+
// arrives.
|
|
129
|
+
if (finished && !open)
|
|
130
|
+
runOnJS(setMounted)(false);
|
|
131
|
+
});
|
|
132
|
+
}, [open, mounted, progress, reducedMotion]);
|
|
133
|
+
/**
|
|
134
|
+
* How far the finger has dragged the panel away from open, in points.
|
|
135
|
+
*
|
|
136
|
+
* Separate from `progress` rather than folded into it. `progress` is
|
|
137
|
+
* animated on the spring, and a drag has to track the finger exactly —
|
|
138
|
+
* feeding a gesture through an overshooting curve makes the panel lead and
|
|
139
|
+
* lag the thumb, which reads as the drawer being slippery.
|
|
140
|
+
*/
|
|
141
|
+
const drag = useSharedValue(0);
|
|
142
|
+
const panelStyle = useAnimatedStyle(() => {
|
|
143
|
+
const travel = hidden + (0 - hidden) * progress.value + drag.value;
|
|
144
|
+
return {
|
|
145
|
+
// Transform only. The panel slides; it does not fade. This used to carry
|
|
146
|
+
// `opacity: progress.value`, which the web's Popup does not — it declares
|
|
147
|
+
// `transition-transform` and nothing else — and a panel that fades as it
|
|
148
|
+
// arrives reads as a dialog rather than a drawer.
|
|
149
|
+
transform: [vertical ? { translateY: travel } : { translateX: travel }]
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
/**
|
|
153
|
+
* The scrim fades with the panel, and thins as it is dragged away.
|
|
154
|
+
*
|
|
155
|
+
* It was a flat `rgba(0,0,0,0.6)` that appeared and vanished with the Modal,
|
|
156
|
+
* so a drawer animating out sat under a full-strength scrim for the whole
|
|
157
|
+
* 700ms and then the scrim blinked off. The web has animated this from the
|
|
158
|
+
* start — `transition-opacity` on the same duration and curve — and it also
|
|
159
|
+
* tracks the swipe, with a comment saying not to "leave a full-strength
|
|
160
|
+
* scrim over a half-gone sheet".
|
|
161
|
+
*
|
|
162
|
+
* Both halves are here: `progress` fades it in and out, and the drag term
|
|
163
|
+
* thins it in proportion to how far the panel has been pushed off.
|
|
164
|
+
*/
|
|
165
|
+
const scrimStyle = useAnimatedStyle(() => {
|
|
166
|
+
const dragged = extent > 0 ? Math.min(1, Math.abs(drag.value) / extent) : 0;
|
|
167
|
+
return { opacity: progress.value * (1 - dragged) };
|
|
168
|
+
});
|
|
169
|
+
/**
|
|
170
|
+
* Swipe to dismiss, which the web has had from Base UI's drawer primitive
|
|
171
|
+
* and this did not have at all (GRYT-395). A drawer you cannot push back is
|
|
172
|
+
* the thing a drawer is for.
|
|
173
|
+
*
|
|
174
|
+
* `PanResponder` rather than react-native-gesture-handler: the Slider proved
|
|
175
|
+
* this path works from this package's prebuilt output today, and an attempt
|
|
176
|
+
* at gesture-handler from here failed for reasons still not understood
|
|
177
|
+
* (GRYT-393). This is not the place to retry that.
|
|
178
|
+
*/
|
|
179
|
+
const gesture = useRef({ extent, side, vertical, dismissible, setOpen });
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
gesture.current = { extent, side, vertical, dismissible, setOpen };
|
|
182
|
+
}, [extent, side, vertical, dismissible, setOpen]);
|
|
183
|
+
/* eslint-disable react-hooks/refs */
|
|
184
|
+
const [responder] = useState(() => PanResponder.create({
|
|
185
|
+
// Claimed on move, not on start. Claiming on start would swallow every
|
|
186
|
+
// tap on the panel's own content — buttons inside a drawer would stop
|
|
187
|
+
// working, which is a far worse bug than not being able to swipe.
|
|
188
|
+
onStartShouldSetPanResponder: () => false,
|
|
189
|
+
onMoveShouldSetPanResponder: (_e, g) => {
|
|
190
|
+
if (!gesture.current.dismissible)
|
|
191
|
+
return false;
|
|
192
|
+
// Only once the drag is clearly along the axis the panel closes on,
|
|
193
|
+
// and clearly a drag rather than a slow press. Anything else belongs
|
|
194
|
+
// to whatever is inside.
|
|
195
|
+
const along = gesture.current.vertical ? g.dy : g.dx;
|
|
196
|
+
const across = gesture.current.vertical ? g.dx : g.dy;
|
|
197
|
+
return Math.abs(along) > 8 && Math.abs(along) > Math.abs(across);
|
|
198
|
+
},
|
|
199
|
+
// Once it is ours it stays ours, for the same reason the Slider needs
|
|
200
|
+
// this: the default is to grant, and a ScrollView inside the drawer
|
|
201
|
+
// would take the drag back mid-swipe.
|
|
202
|
+
onPanResponderTerminationRequest: () => false,
|
|
203
|
+
onPanResponderMove: (_e, g) => {
|
|
204
|
+
const { vertical: v, side: sd } = gesture.current;
|
|
205
|
+
const raw = v ? g.dy : g.dx;
|
|
206
|
+
// Clamped to the closing direction. Dragging a left drawer rightwards
|
|
207
|
+
// should do nothing, not tear it off its edge.
|
|
208
|
+
const closing = sd === "left" ? Math.min(0, raw) : Math.max(0, raw);
|
|
209
|
+
// eslint-disable-next-line react-hooks/immutability
|
|
210
|
+
drag.value = closing;
|
|
211
|
+
},
|
|
212
|
+
onPanResponderRelease: (_e, g) => {
|
|
213
|
+
const { vertical: v, side: sd, extent: ex } = gesture.current;
|
|
214
|
+
const moved = Math.abs(v ? g.dy : g.dx);
|
|
215
|
+
const speed = Math.abs(v ? g.vy : g.vx);
|
|
216
|
+
// Half the panel, or a flick. The velocity term is what makes a short
|
|
217
|
+
// sharp swipe work — without it you have to drag the whole way, which
|
|
218
|
+
// is the difference between a drawer and a slow puzzle.
|
|
219
|
+
const dismiss = moved > ex / 2 || speed > 0.5;
|
|
220
|
+
if (dismiss) {
|
|
221
|
+
gesture.current.setOpen(false);
|
|
222
|
+
// Left where it is: the close animation runs from here, and resetting
|
|
223
|
+
// it first would snap the panel back before it left.
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
// eslint-disable-next-line react-hooks/immutability
|
|
227
|
+
drag.value = travelTo(0, { duration: durations.springSoft });
|
|
228
|
+
},
|
|
229
|
+
onPanResponderTerminate: () => {
|
|
230
|
+
// eslint-disable-next-line react-hooks/immutability
|
|
231
|
+
drag.value = travelTo(0, { duration: durations.springSoft });
|
|
232
|
+
}
|
|
63
233
|
}));
|
|
64
|
-
|
|
234
|
+
/* eslint-enable react-hooks/refs */
|
|
235
|
+
// Cleared once the panel is closed, so the next open does not start from
|
|
236
|
+
// wherever the last swipe left it.
|
|
237
|
+
useEffect(() => {
|
|
238
|
+
if (!open) {
|
|
239
|
+
// eslint-disable-next-line react-hooks/immutability
|
|
240
|
+
drag.value = 0;
|
|
241
|
+
}
|
|
242
|
+
}, [open, drag]);
|
|
243
|
+
return (_jsx(Modal, { visible: mounted, transparent: true, animationType: "none", onRequestClose: dismissible ? () => setOpen(false) : undefined, children: _jsx(AnimatedPressable, { onPress: dismissible ? () => setOpen(false) : undefined, style: [{ flex: 1, backgroundColor: "rgba(0,0,0,0.6)" }, scrimStyle], children: _jsx(Animated.View, { accessibilityViewIsModal: true, ...responder.panHandlers, style: [
|
|
65
244
|
{
|
|
66
245
|
position: "absolute",
|
|
246
|
+
// The overhang hangs *off* the edge the panel comes from, which
|
|
247
|
+
// is the only direction that helps. It used to be added to the
|
|
248
|
+
// width instead, so the panel grew inwards — 64pt more of the
|
|
249
|
+
// screen covered, and the seam it was meant to hide still there,
|
|
250
|
+
// because the gap opens on the entering edge and that is the edge
|
|
251
|
+
// the extra material was not on.
|
|
67
252
|
top: side === "bottom" ? undefined : 0,
|
|
68
|
-
bottom: 0,
|
|
69
|
-
left: side === "right" ? undefined : 0,
|
|
70
|
-
right: side === "left" ? undefined : 0,
|
|
71
|
-
width: vertical ? "100%" :
|
|
72
|
-
height: vertical ?
|
|
253
|
+
bottom: vertical ? -bleed : 0,
|
|
254
|
+
left: side === "right" ? undefined : side === "left" ? -bleed : 0,
|
|
255
|
+
right: side === "left" ? undefined : side === "right" ? -bleed : 0,
|
|
256
|
+
width: vertical ? "100%" : panelExtent,
|
|
257
|
+
height: vertical ? panelExtent : "100%",
|
|
258
|
+
// Puts the content back where it would have been without the
|
|
259
|
+
// overhang, so `size` still means what it says.
|
|
260
|
+
paddingLeft: side === "left" ? bleed : 0,
|
|
261
|
+
paddingRight: side === "right" ? bleed : 0,
|
|
262
|
+
paddingBottom: vertical ? bleed : 0,
|
|
73
263
|
backgroundColor: theme.color.surface,
|
|
74
264
|
borderColor: theme.color.border,
|
|
75
265
|
borderRightWidth: side === "left" ? 1 : 0,
|
|
@@ -79,7 +269,16 @@ function Popup({ children, side = "left", size = 0.8, dismissible = true, style
|
|
|
79
269
|
borderTopRightRadius: vertical ? theme.radius.lg : 0
|
|
80
270
|
},
|
|
81
271
|
panelStyle
|
|
82
|
-
], children: _jsx(Pressable, { onPress: () => { }, style: [
|
|
272
|
+
], children: _jsx(Pressable, { onPress: () => { }, style: [
|
|
273
|
+
{
|
|
274
|
+
flex: 1,
|
|
275
|
+
// Before the caller's style, so a drawer that wants to run
|
|
276
|
+
// under the island — a full-bleed image, say — still can.
|
|
277
|
+
paddingTop: vertical ? 0 : insets.top,
|
|
278
|
+
paddingBottom: insets.bottom
|
|
279
|
+
},
|
|
280
|
+
style
|
|
281
|
+
], children: children }) }) }) }));
|
|
83
282
|
}
|
|
84
283
|
function Close({ children, style }) {
|
|
85
284
|
const { setOpen } = useDrawer("Close");
|
|
@@ -6,24 +6,18 @@ export interface ProgressProps {
|
|
|
6
6
|
style?: StyleProp<ViewStyle>;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* Determinate
|
|
9
|
+
* Determinate travel follows the web deliberately: 300ms on ease-out rather
|
|
10
|
+
* than the spring. A progress bar is a reading, and the spring's 12% overshoot
|
|
11
|
+
* on a jump to 100% runs past the end of the track and comes back — which reads
|
|
12
|
+
* as the job finishing, unfinishing, then finishing.
|
|
10
13
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* So both platforms agree, and both are missing the feature. Implementing it
|
|
20
|
-
* belongs on both at once — GRYT-382 — rather than here, where it would make
|
|
21
|
-
* React Native the one that behaves differently.
|
|
22
|
-
*
|
|
23
|
-
* The travel that *is* implemented follows the web deliberately: 300ms on
|
|
24
|
-
* ease-out rather than the spring. A progress bar is a reading, and the
|
|
25
|
-
* spring's 12% overshoot on a jump to 100% runs past the end of the track and
|
|
26
|
-
* comes back — which reads as the job finishing, unfinishing, then finishing.
|
|
14
|
+
* Indeterminate is a partial bar sweeping the track on a loop, at
|
|
15
|
+
* `grytDurations.sweep`, from the same description the web's keyframe follows.
|
|
16
|
+
* Both were empty until GRYT-382: the web passed `value={null}` to Base UI,
|
|
17
|
+
* which leaves the indicator's width unset, and nothing styled it. This file
|
|
18
|
+
* previously called that a parity exception, which it was not — both platforms
|
|
19
|
+
* were missing the same feature, and writing it down as one-sided is what
|
|
20
|
+
* closed the question for a while.
|
|
27
21
|
*/
|
|
28
22
|
export declare function Progress({ value, tone, style }: ProgressProps): import("react").JSX.Element;
|
|
29
23
|
//# sourceMappingURL=Progress.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../../src/components/Progress/Progress.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../../src/components/Progress/Progress.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAatB,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACnD,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B;AAKD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAe,EAAE,KAAK,EAAE,EAAE,aAAa,+BA0FxE"}
|