panelui-native 0.49.0 → 0.53.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/lib/module/components/candlestick-chart/index.js +1161 -0
- package/lib/module/components/candlestick-chart/index.js.map +1 -0
- package/lib/module/components/combobox/index.js +73 -7
- package/lib/module/components/combobox/index.js.map +1 -1
- package/lib/module/components/context-menu/index.js +529 -0
- package/lib/module/components/context-menu/index.js.map +1 -0
- package/lib/module/components/menu/index.js +18 -10
- package/lib/module/components/menu/index.js.map +1 -1
- package/lib/module/components/popover/index.js +71 -7
- package/lib/module/components/popover/index.js.map +1 -1
- package/lib/module/components/sortable/index.js +942 -0
- package/lib/module/components/sortable/index.js.map +1 -0
- package/lib/module/components/swipe/index.js +140 -5
- package/lib/module/components/swipe/index.js.map +1 -1
- package/lib/module/components/tabs/index.js +56 -15
- package/lib/module/components/tabs/index.js.map +1 -1
- package/lib/module/components/time-picker/index.js +295 -31
- package/lib/module/components/time-picker/index.js.map +1 -1
- package/lib/module/icons/index.js +29 -0
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/index.js +5 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/haptics.js +19 -0
- package/lib/module/utils/haptics.js.map +1 -1
- package/lib/typescript/src/components/candlestick-chart/index.d.ts +278 -0
- package/lib/typescript/src/components/candlestick-chart/index.d.ts.map +1 -0
- package/lib/typescript/src/components/combobox/index.d.ts.map +1 -1
- package/lib/typescript/src/components/context-menu/index.d.ts +270 -0
- package/lib/typescript/src/components/context-menu/index.d.ts.map +1 -0
- package/lib/typescript/src/components/menu/index.d.ts +20 -20
- package/lib/typescript/src/components/menu/index.d.ts.map +1 -1
- package/lib/typescript/src/components/popover/index.d.ts +51 -1
- package/lib/typescript/src/components/popover/index.d.ts.map +1 -1
- package/lib/typescript/src/components/sortable/index.d.ts +248 -0
- package/lib/typescript/src/components/sortable/index.d.ts.map +1 -0
- package/lib/typescript/src/components/swipe/index.d.ts +35 -0
- package/lib/typescript/src/components/swipe/index.d.ts.map +1 -1
- package/lib/typescript/src/components/tabs/index.d.ts +34 -2
- package/lib/typescript/src/components/tabs/index.d.ts.map +1 -1
- package/lib/typescript/src/components/time-picker/index.d.ts.map +1 -1
- package/lib/typescript/src/icons/index.d.ts +8 -0
- package/lib/typescript/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +5 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/haptics.d.ts +14 -0
- package/lib/typescript/src/utils/haptics.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/candlestick-chart/index.tsx +1360 -0
- package/src/components/combobox/index.tsx +84 -6
- package/src/components/context-menu/index.tsx +658 -0
- package/src/components/menu/index.tsx +17 -10
- package/src/components/popover/index.tsx +94 -6
- package/src/components/sortable/index.tsx +1266 -0
- package/src/components/swipe/index.tsx +165 -3
- package/src/components/tabs/index.tsx +82 -16
- package/src/components/time-picker/index.tsx +330 -35
- package/src/icons/index.tsx +22 -0
- package/src/index.ts +39 -0
- package/src/utils/haptics.ts +21 -0
|
@@ -341,7 +341,7 @@ export interface MenuBackgroundProps extends ViewProps {
|
|
|
341
341
|
* `overflow-hidden` on the panel is what keeps whatever that is inside the
|
|
342
342
|
* corner radius.
|
|
343
343
|
*/
|
|
344
|
-
function MenuBackground({ className, children, ...props }: MenuBackgroundProps) {
|
|
344
|
+
export function MenuBackground({ className, children, ...props }: MenuBackgroundProps) {
|
|
345
345
|
const { background } = menuVariants();
|
|
346
346
|
|
|
347
347
|
return (
|
|
@@ -365,7 +365,7 @@ export interface MenuLabelProps extends ViewProps {
|
|
|
365
365
|
}
|
|
366
366
|
|
|
367
367
|
/** Non-interactive heading over a run of rows. */
|
|
368
|
-
function MenuLabel({ className, inset, children, ...props }: MenuLabelProps) {
|
|
368
|
+
export function MenuLabel({ className, inset, children, ...props }: MenuLabelProps) {
|
|
369
369
|
const { label } = menuVariants({ inset });
|
|
370
370
|
|
|
371
371
|
return (
|
|
@@ -384,7 +384,7 @@ export interface MenuSeparatorProps extends ViewProps {
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
/** Hairline between two runs of rows. */
|
|
387
|
-
function MenuSeparator({ className, ...props }: MenuSeparatorProps) {
|
|
387
|
+
export function MenuSeparator({ className, ...props }: MenuSeparatorProps) {
|
|
388
388
|
const { separator } = menuVariants();
|
|
389
389
|
|
|
390
390
|
return (
|
|
@@ -435,7 +435,7 @@ export interface MenuItemProps extends Omit<PressableProps, 'children' | 'style'
|
|
|
435
435
|
* that a row which is disabled or which opts out via `closeOnSelect` behaves
|
|
436
436
|
* the same either way.
|
|
437
437
|
*/
|
|
438
|
-
function MenuItem({
|
|
438
|
+
export function MenuItem({
|
|
439
439
|
className,
|
|
440
440
|
children,
|
|
441
441
|
icon,
|
|
@@ -540,7 +540,7 @@ export interface MenuCheckboxItemProps extends Omit<MenuItemProps, 'icon' | 'ins
|
|
|
540
540
|
* deliberately so: a set of toggles is nearly always set more than one at a
|
|
541
541
|
* time, and closing after each one turns three taps into six.
|
|
542
542
|
*/
|
|
543
|
-
function MenuCheckboxItem({
|
|
543
|
+
export function MenuCheckboxItem({
|
|
544
544
|
checked = false,
|
|
545
545
|
onCheckedChange,
|
|
546
546
|
onSelect,
|
|
@@ -592,7 +592,7 @@ export interface MenuRadioGroupProps extends ViewProps {
|
|
|
592
592
|
}
|
|
593
593
|
|
|
594
594
|
/** A run of rows of which exactly one is chosen. */
|
|
595
|
-
function MenuRadioGroup({ value, onValueChange, className, children, ...props }: MenuRadioGroupProps) {
|
|
595
|
+
export function MenuRadioGroup({ value, onValueChange, className, children, ...props }: MenuRadioGroupProps) {
|
|
596
596
|
const context = useMemo(
|
|
597
597
|
() => ({ value, select: (next: string) => onValueChange?.(next) }),
|
|
598
598
|
[value, onValueChange]
|
|
@@ -616,7 +616,7 @@ export interface MenuRadioItemProps extends Omit<MenuItemProps, 'icon' | 'inset'
|
|
|
616
616
|
}
|
|
617
617
|
|
|
618
618
|
/** One option inside a `Menu.RadioGroup`. */
|
|
619
|
-
function MenuRadioItem({
|
|
619
|
+
export function MenuRadioItem({
|
|
620
620
|
value,
|
|
621
621
|
indicator = 'check',
|
|
622
622
|
onSelect,
|
|
@@ -694,7 +694,7 @@ export interface MenuSubProps {
|
|
|
694
694
|
}
|
|
695
695
|
|
|
696
696
|
/** Groups a `Menu.SubTrigger` with the rows it reveals. */
|
|
697
|
-
function MenuSub({ children, defaultOpen = false, open, onOpenChange }: MenuSubProps) {
|
|
697
|
+
export function MenuSub({ children, defaultOpen = false, open, onOpenChange }: MenuSubProps) {
|
|
698
698
|
const [internalOpen, setInternalOpen] = useState(defaultOpen);
|
|
699
699
|
const isControlled = open !== undefined;
|
|
700
700
|
const resolved = isControlled ? open : internalOpen;
|
|
@@ -723,7 +723,7 @@ export interface MenuSubTriggerProps
|
|
|
723
723
|
* point down once open, so the row states which way its rows will appear
|
|
724
724
|
* rather than only that it has some.
|
|
725
725
|
*/
|
|
726
|
-
function MenuSubTrigger({ className, children, icon, onSelect, ...props }: MenuSubTriggerProps) {
|
|
726
|
+
export function MenuSubTrigger({ className, children, icon, onSelect, ...props }: MenuSubTriggerProps) {
|
|
727
727
|
const { open, toggle } = useMenuSub('Menu.SubTrigger');
|
|
728
728
|
const sign = useDirectionSign();
|
|
729
729
|
const direction = useDirection();
|
|
@@ -790,7 +790,7 @@ export interface MenuSubContentProps extends ViewProps {
|
|
|
790
790
|
* would otherwise report the animated height back, and the panel would settle
|
|
791
791
|
* at whatever it happened to measure on the first frame.
|
|
792
792
|
*/
|
|
793
|
-
function MenuSubContent({ className, children, ...props }: MenuSubContentProps) {
|
|
793
|
+
export function MenuSubContent({ className, children, ...props }: MenuSubContentProps) {
|
|
794
794
|
const { open } = useMenuSub('Menu.SubContent');
|
|
795
795
|
const reducedMotion = useReducedMotion();
|
|
796
796
|
const [height, setHeight] = useState(0);
|
|
@@ -841,6 +841,13 @@ MenuSub.displayName = 'Menu.Sub';
|
|
|
841
841
|
MenuSubTrigger.displayName = 'Menu.SubTrigger';
|
|
842
842
|
MenuSubContent.displayName = 'Menu.SubContent';
|
|
843
843
|
|
|
844
|
+
/*
|
|
845
|
+
* The parts above are exported individually as well as hung off `Menu`, and the
|
|
846
|
+
* reason is `ContextMenu`: it presents these same components as its own rows, so
|
|
847
|
+
* the emitted type declarations for it have to be able to name them. `Menu` is
|
|
848
|
+
* still the only thing the package exports, so nothing about how these are
|
|
849
|
+
* reached from outside has changed.
|
|
850
|
+
*/
|
|
844
851
|
export const Menu = Object.assign(MenuRoot, {
|
|
845
852
|
Trigger: MenuTrigger,
|
|
846
853
|
Content: MenuContent,
|
|
@@ -72,17 +72,37 @@ const DEFAULT_OFFSET = 8;
|
|
|
72
72
|
const SCREEN_MARGIN = 12;
|
|
73
73
|
/** Side of the arrow square before it is rotated 45°. */
|
|
74
74
|
const ARROW_SIZE = 12;
|
|
75
|
+
/**
|
|
76
|
+
* Headroom the sheet presentation leaves for the close button.
|
|
77
|
+
*
|
|
78
|
+
* That button floats over the sheet's top-end corner rather than sitting in the
|
|
79
|
+
* flow, so nothing below it is pushed out of its way. The sheet's own padding
|
|
80
|
+
* and grabber put the first child 24 points down; the button's lower edge is at
|
|
81
|
+
* 44. This is the difference, plus a little air — enough that a panel's first
|
|
82
|
+
* row clears the button instead of being drawn under it.
|
|
83
|
+
*/
|
|
84
|
+
const SHEET_CLOSE_CLEARANCE = 24;
|
|
75
85
|
|
|
76
86
|
export type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';
|
|
77
87
|
export type PopoverAlign = 'start' | 'center' | 'end';
|
|
78
88
|
|
|
79
|
-
|
|
89
|
+
/**
|
|
90
|
+
* The rectangle the panel is placed against, in window coordinates.
|
|
91
|
+
*
|
|
92
|
+
* Normally the trigger's own bounds. A zero-sized rect is meaningful too: it
|
|
93
|
+
* anchors the panel to a single point, which is what a menu opened by a long
|
|
94
|
+
* press on arbitrary content needs — there the interesting position is where
|
|
95
|
+
* the finger landed, not the bounds of whatever it landed on.
|
|
96
|
+
*/
|
|
97
|
+
export interface PopoverAnchorRect {
|
|
80
98
|
x: number;
|
|
81
99
|
y: number;
|
|
82
100
|
width: number;
|
|
83
101
|
height: number;
|
|
84
102
|
}
|
|
85
103
|
|
|
104
|
+
type TriggerRect = PopoverAnchorRect;
|
|
105
|
+
|
|
86
106
|
interface PopoverContextValue {
|
|
87
107
|
open: boolean;
|
|
88
108
|
setOpen: (open: boolean) => void;
|
|
@@ -110,6 +130,38 @@ function usePopover(component: string): PopoverContextValue {
|
|
|
110
130
|
return context;
|
|
111
131
|
}
|
|
112
132
|
|
|
133
|
+
export interface PopoverAnchorControls {
|
|
134
|
+
open: boolean;
|
|
135
|
+
setOpen: (open: boolean) => void;
|
|
136
|
+
/**
|
|
137
|
+
* Place the panel against an explicit rect rather than against a measured
|
|
138
|
+
* trigger. Pass a zero-sized rect to anchor it to a point.
|
|
139
|
+
*/
|
|
140
|
+
anchorTo: (rect: PopoverAnchorRect) => void;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* For a trigger that opens the panel on something other than a plain press, or
|
|
145
|
+
* anchors it to something other than its own bounds.
|
|
146
|
+
*
|
|
147
|
+
* `Popover.Trigger` covers the ordinary case — press the thing, measure the
|
|
148
|
+
* thing, open next to it. A component built on this one may need neither half
|
|
149
|
+
* of that: a context menu opens on a long press and belongs at the point the
|
|
150
|
+
* finger landed. Rather than have it own a second copy of the placing,
|
|
151
|
+
* flipping and edge-clamping this file already does, it borrows them by
|
|
152
|
+
* setting the anchor itself.
|
|
153
|
+
*
|
|
154
|
+
* Only useful inside a `Popover`, which is the same rule every other part here
|
|
155
|
+
* follows.
|
|
156
|
+
*/
|
|
157
|
+
export function usePopoverAnchor(component: string): PopoverAnchorControls {
|
|
158
|
+
const { open, setOpen, setTrigger } = usePopover(component);
|
|
159
|
+
return useMemo(
|
|
160
|
+
() => ({ open, setOpen, anchorTo: setTrigger }),
|
|
161
|
+
[open, setOpen, setTrigger]
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
113
165
|
export interface PopoverProps {
|
|
114
166
|
children: ReactNode;
|
|
115
167
|
/** Controlled open state. */
|
|
@@ -271,6 +323,18 @@ export interface PopoverContentProps extends ViewProps {
|
|
|
271
323
|
* not, so it is safe to pass either way.
|
|
272
324
|
*/
|
|
273
325
|
blur?: boolean;
|
|
326
|
+
/**
|
|
327
|
+
* Dim the screen behind the panel.
|
|
328
|
+
*
|
|
329
|
+
* Off by default: a popover is a panel *beside* something, and dimming the
|
|
330
|
+
* page says the thing behind it has stopped being available — which is a
|
|
331
|
+
* dialog's claim, not a popover's. Worth turning on when the panel is the
|
|
332
|
+
* only thing that matters while it is up, which is what a menu opened on the
|
|
333
|
+
* content itself is. Ignored under `blur`, which draws its own dim.
|
|
334
|
+
*/
|
|
335
|
+
scrim?: boolean;
|
|
336
|
+
/** The dim's classes, when `scrim` is set. */
|
|
337
|
+
scrimClassName?: string;
|
|
274
338
|
children?: ReactNode;
|
|
275
339
|
}
|
|
276
340
|
|
|
@@ -288,6 +352,8 @@ function PopoverContent({
|
|
|
288
352
|
background,
|
|
289
353
|
dismissible = true,
|
|
290
354
|
blur = false,
|
|
355
|
+
scrim = false,
|
|
356
|
+
scrimClassName = 'bg-black/30',
|
|
291
357
|
children,
|
|
292
358
|
onLayout: onLayoutProp,
|
|
293
359
|
style,
|
|
@@ -342,6 +408,23 @@ function PopoverContent({
|
|
|
342
408
|
? Math.min(Math.max(requestedWidth, minWidth), available)
|
|
343
409
|
: requestedWidth;
|
|
344
410
|
|
|
411
|
+
/*
|
|
412
|
+
* The floor also has to reach a panel sized to its own contents, which is the
|
|
413
|
+
* case it matters most in — a panel with a width already knows how wide it is.
|
|
414
|
+
*
|
|
415
|
+
* Folding it into `width` would be wrong: that pins the panel open at exactly
|
|
416
|
+
* the floor and stops it growing for content that needs more. It is a real
|
|
417
|
+
* minimum instead, left off when there is nothing to enforce so a content-fit
|
|
418
|
+
* panel keeps shrinking to fit.
|
|
419
|
+
*
|
|
420
|
+
* Without this a `content-fit` panel takes its width from whatever inside it
|
|
421
|
+
* is *not* flexible. A row of a flexible label and a fixed glyph collapses to
|
|
422
|
+
* the glyph, and the panel comes up as a strip of icons with the words
|
|
423
|
+
* squeezed out of it.
|
|
424
|
+
*/
|
|
425
|
+
const resolvedMinWidth =
|
|
426
|
+
minWidth === undefined ? undefined : Math.min(minWidth, available);
|
|
427
|
+
|
|
345
428
|
/*
|
|
346
429
|
* The cap is what keeps a tall panel reachable. `place` clamps the panel
|
|
347
430
|
* inside the bounds, but a panel taller than the bounds cannot be clamped
|
|
@@ -434,9 +517,7 @@ function PopoverContent({
|
|
|
434
517
|
width === 'full' || width === 'trigger' ? { width: '100%' } : null,
|
|
435
518
|
typeof width === 'number' ? { width } : null,
|
|
436
519
|
minWidth === undefined ? null : { minWidth },
|
|
437
|
-
|
|
438
|
-
// corner of the sheet rather than sitting in the flow.
|
|
439
|
-
{ paddingTop: 8 },
|
|
520
|
+
{ paddingTop: SHEET_CLOSE_CLEARANCE },
|
|
440
521
|
style,
|
|
441
522
|
]}
|
|
442
523
|
>
|
|
@@ -458,8 +539,14 @@ function PopoverContent({
|
|
|
458
539
|
<PopoverContext.Provider value={context}>
|
|
459
540
|
<View className="absolute inset-0">
|
|
460
541
|
{/* A popover does not dim the screen by default — the backdrop is
|
|
461
|
-
there only to catch the outside tap. `blur` opts into a frost
|
|
462
|
-
|
|
542
|
+
there only to catch the outside tap. `blur` opts into a frost,
|
|
543
|
+
`scrim` into a plain dim; the frost already draws one of its own,
|
|
544
|
+
so asking for both is not two dims. */}
|
|
545
|
+
{blur ? (
|
|
546
|
+
<Scrim blur intensity={20} dimClassName={scrimClassName} />
|
|
547
|
+
) : scrim ? (
|
|
548
|
+
<Scrim dimClassName={scrimClassName} />
|
|
549
|
+
) : null}
|
|
463
550
|
<Pressable
|
|
464
551
|
accessibilityLabel="Close"
|
|
465
552
|
className="absolute inset-0"
|
|
@@ -486,6 +573,7 @@ function PopoverContent({
|
|
|
486
573
|
maxWidth: bounds.right - bounds.left,
|
|
487
574
|
maxHeight: resolvedMaxHeight,
|
|
488
575
|
width: resolvedWidth,
|
|
576
|
+
minWidth: resolvedMinWidth,
|
|
489
577
|
}}
|
|
490
578
|
>
|
|
491
579
|
<Animated.View
|