panelui-native 0.83.0 → 0.85.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 +17 -8
- package/lib/module/components/bottom-sheet/index.js +3 -2
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/button/index.js +37 -16
- package/lib/module/components/button/index.js.map +1 -1
- package/lib/module/components/circular-text/circular-text-geometry.js +63 -0
- package/lib/module/components/circular-text/circular-text-geometry.js.map +1 -0
- package/lib/module/components/circular-text/index.js +146 -0
- package/lib/module/components/circular-text/index.js.map +1 -0
- package/lib/module/components/flip-card/index.js +338 -0
- package/lib/module/components/flip-card/index.js.map +1 -0
- package/lib/module/components/marquee/index.js +12 -5
- package/lib/module/components/marquee/index.js.map +1 -1
- package/lib/module/components/panelside/index.js +15 -417
- package/lib/module/components/panelside/index.js.map +1 -1
- package/lib/module/components/popover/index.js +120 -7
- package/lib/module/components/popover/index.js.map +1 -1
- package/lib/module/components/select/index.js +3 -2
- package/lib/module/components/select/index.js.map +1 -1
- package/lib/module/components/slider/index.js +16 -5
- package/lib/module/components/slider/index.js.map +1 -1
- package/lib/module/components/switch/index.js +28 -7
- package/lib/module/components/switch/index.js.map +1 -1
- package/lib/module/icons/index.js +24 -4
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/native/index.js +35 -0
- package/lib/module/native/index.js.map +1 -1
- package/lib/module/native/native-host.js +62 -0
- package/lib/module/native/native-host.js.map +1 -0
- package/lib/module/primitives/glass.js +14 -0
- package/lib/module/primitives/glass.js.map +1 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/src/components/button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/circular-text/circular-text-geometry.d.ts +39 -0
- package/lib/typescript/src/components/circular-text/circular-text-geometry.d.ts.map +1 -0
- package/lib/typescript/src/components/circular-text/index.d.ts +69 -0
- package/lib/typescript/src/components/circular-text/index.d.ts.map +1 -0
- package/lib/typescript/src/components/flip-card/index.d.ts +116 -0
- package/lib/typescript/src/components/flip-card/index.d.ts.map +1 -0
- package/lib/typescript/src/components/marquee/index.d.ts.map +1 -1
- package/lib/typescript/src/components/panelside/index.d.ts +10 -202
- package/lib/typescript/src/components/panelside/index.d.ts.map +1 -1
- package/lib/typescript/src/components/popover/index.d.ts +25 -1
- package/lib/typescript/src/components/popover/index.d.ts.map +1 -1
- package/lib/typescript/src/components/slider/index.d.ts.map +1 -1
- package/lib/typescript/src/components/switch/index.d.ts +0 -4
- package/lib/typescript/src/components/switch/index.d.ts.map +1 -1
- package/lib/typescript/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +3 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native/index.d.ts +67 -10
- package/lib/typescript/src/native/index.d.ts.map +1 -1
- package/lib/typescript/src/native/native-host.d.ts +71 -0
- package/lib/typescript/src/native/native-host.d.ts.map +1 -0
- package/lib/typescript/src/primitives/glass.d.ts.map +1 -1
- package/package.json +11 -1
- package/src/components/bottom-sheet/index.tsx +8 -3
- package/src/components/button/index.tsx +36 -15
- package/src/components/circular-text/circular-text-geometry.ts +80 -0
- package/src/components/circular-text/index.tsx +217 -0
- package/src/components/flip-card/index.tsx +419 -0
- package/src/components/marquee/index.tsx +12 -5
- package/src/components/panelside/index.tsx +16 -604
- package/src/components/popover/index.tsx +146 -4
- package/src/components/select/index.tsx +3 -3
- package/src/components/slider/index.tsx +28 -6
- package/src/components/switch/index.tsx +28 -7
- package/src/icons/index.tsx +23 -2
- package/src/index.ts +10 -6
- package/src/native/index.ts +89 -9
- package/src/native/native-host.tsx +75 -0
- package/src/primitives/glass.tsx +12 -0
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
* accessibility setting on, every spring here resolves instantly to its target
|
|
79
79
|
* rather than travelling.
|
|
80
80
|
*/
|
|
81
|
-
import { Children, cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useMemo,
|
|
82
|
-
import {
|
|
81
|
+
import { Children, cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
82
|
+
import { Platform, Pressable, ScrollView, StyleSheet, TextInput, useWindowDimensions, View } from 'react-native';
|
|
83
83
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
84
84
|
import Animated, { runOnJS, useAnimatedProps, useAnimatedStyle, useDerivedValue, useSharedValue, withSpring } from 'react-native-reanimated';
|
|
85
85
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
@@ -87,18 +87,13 @@ import { tv } from 'tailwind-variants';
|
|
|
87
87
|
import { useCSSVariable } from 'uniwind';
|
|
88
88
|
import { LinearGradient } from 'expo-linear-gradient';
|
|
89
89
|
import { HugeiconsIcon } from '@hugeicons/react-native';
|
|
90
|
-
import Cancel01Icon from '@hugeicons/core-free-icons/Cancel01Icon';
|
|
91
90
|
import Menu01Icon from '@hugeicons/core-free-icons/Menu01Icon';
|
|
92
91
|
import MoreHorizontalIcon from '@hugeicons/core-free-icons/MoreHorizontalIcon';
|
|
93
92
|
import Search01Icon from '@hugeicons/core-free-icons/Search01Icon';
|
|
94
93
|
import { IconColorProvider, useIconColor } from "../../icons/index.js";
|
|
95
|
-
import { BottomSheet, bottomSheetDetentHeight } from "../bottom-sheet/index.js";
|
|
96
94
|
import { Button } from "../button/index.js";
|
|
97
95
|
import { Menu } from "../menu/index.js";
|
|
98
|
-
import { Tabs } from "../tabs/index.js";
|
|
99
|
-
import { getNativeUI } from "../../native/index.js";
|
|
100
96
|
import { AnimatedPressable } from "../../primitives/animated-pressable.js";
|
|
101
|
-
import { KeyboardAvoider } from "../../primitives/keyboard-avoider.js";
|
|
102
97
|
import { Text, textChildren } from "../../primitives/text.js";
|
|
103
98
|
import { useBackHandler } from "../../hooks/use-back-handler.js";
|
|
104
99
|
import { useDirectionSign } from "../../hooks/use-direction.js";
|
|
@@ -377,8 +372,6 @@ export function usePanelside() {
|
|
|
377
372
|
toggle,
|
|
378
373
|
progress,
|
|
379
374
|
docked,
|
|
380
|
-
searchOpen,
|
|
381
|
-
setSearchOpen,
|
|
382
375
|
route,
|
|
383
376
|
navigate
|
|
384
377
|
} = usePanelsideContext('usePanelside');
|
|
@@ -395,8 +388,6 @@ export function usePanelside() {
|
|
|
395
388
|
toggle,
|
|
396
389
|
progress,
|
|
397
390
|
docked,
|
|
398
|
-
searchOpen,
|
|
399
|
-
setSearchOpen,
|
|
400
391
|
route,
|
|
401
392
|
navigate: go
|
|
402
393
|
};
|
|
@@ -438,7 +429,6 @@ function PanelsideRoot({
|
|
|
438
429
|
const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
|
|
439
430
|
const controlled = controlledOpen !== undefined;
|
|
440
431
|
const open = controlled ? controlledOpen : uncontrolledOpen;
|
|
441
|
-
const [searchOpen, setSearchOpen] = useState(false);
|
|
442
432
|
const [uncontrolledRoute, setUncontrolledRoute] = useState(defaultRoute);
|
|
443
433
|
const route = controlledRoute ?? uncontrolledRoute;
|
|
444
434
|
|
|
@@ -587,11 +577,9 @@ function PanelsideRoot({
|
|
|
587
577
|
scale,
|
|
588
578
|
radius,
|
|
589
579
|
dim,
|
|
590
|
-
searchOpen,
|
|
591
|
-
setSearchOpen,
|
|
592
580
|
route,
|
|
593
581
|
navigate
|
|
594
|
-
}), [dim, dismissible, docked, mode, navigate, open, progress, radius, route, scale,
|
|
582
|
+
}), [dim, dismissible, docked, mode, navigate, open, progress, radius, route, scale, setOpen, toggle, width]);
|
|
595
583
|
return /*#__PURE__*/_jsx(PanelsideContext.Provider, {
|
|
596
584
|
value: context,
|
|
597
585
|
children: /*#__PURE__*/_jsx(View, {
|
|
@@ -1531,11 +1519,17 @@ function PanelsideTrigger({
|
|
|
1531
1519
|
* ------------------------------------------------------------------ */
|
|
1532
1520
|
|
|
1533
1521
|
/**
|
|
1534
|
-
* The
|
|
1535
|
-
* `action` slot.
|
|
1522
|
+
* The search button. Goes in `Panelside.Header`'s `action` slot.
|
|
1536
1523
|
*
|
|
1537
|
-
* It
|
|
1538
|
-
*
|
|
1524
|
+
* It draws the control and nothing else: a circle, or the platform's own
|
|
1525
|
+
* button under `native`, with the magnifier already in it. What pressing it
|
|
1526
|
+
* opens is `onPress`'s to decide — a page the scene navigates to, a sheet, a
|
|
1527
|
+
* screen pushed onto the app's own stack.
|
|
1528
|
+
*
|
|
1529
|
+
* That is the same arrangement `Panelside.Trigger` has, and it is here for the
|
|
1530
|
+
* same reason: where search goes is a decision about the app, and a component
|
|
1531
|
+
* that answers it for you is one you have to work around the first time the
|
|
1532
|
+
* answer is different.
|
|
1539
1533
|
*/
|
|
1540
1534
|
function PanelsideSearchTrigger({
|
|
1541
1535
|
className,
|
|
@@ -1547,15 +1541,9 @@ function PanelsideSearchTrigger({
|
|
|
1547
1541
|
onPress,
|
|
1548
1542
|
...props
|
|
1549
1543
|
}) {
|
|
1550
|
-
const {
|
|
1551
|
-
setSearchOpen
|
|
1552
|
-
} = usePanelsideContext('Panelside.SearchTrigger');
|
|
1553
1544
|
const tint = useCSSVariable('--color-foreground');
|
|
1554
1545
|
const color = typeof tint === 'string' ? tint : undefined;
|
|
1555
|
-
const open =
|
|
1556
|
-
onPress?.(event);
|
|
1557
|
-
setSearchOpen(true);
|
|
1558
|
-
}, [onPress, setSearchOpen]);
|
|
1546
|
+
const open = onPress;
|
|
1559
1547
|
const glyph = children ?? /*#__PURE__*/_jsx(Glyph, {
|
|
1560
1548
|
icon: Search01Icon,
|
|
1561
1549
|
size: 18,
|
|
@@ -1589,384 +1577,6 @@ function PanelsideSearchTrigger({
|
|
|
1589
1577
|
})
|
|
1590
1578
|
});
|
|
1591
1579
|
}
|
|
1592
|
-
const PanelsideSearchSheetContext = /*#__PURE__*/createContext(null);
|
|
1593
|
-
function usePanelsideSearchSheet(part) {
|
|
1594
|
-
const value = useContext(PanelsideSearchSheetContext);
|
|
1595
|
-
if (!value) throw new Error(`${part} must be used inside a <Panelside.SearchSheet>.`);
|
|
1596
|
-
return value;
|
|
1597
|
-
}
|
|
1598
|
-
/**
|
|
1599
|
-
* The search surface: tabs, results, and a field at the bottom.
|
|
1600
|
-
*
|
|
1601
|
-
* ```tsx
|
|
1602
|
-
* <Panelside.SearchSheet value={query} onValueChange={setQuery} tab={tab} onTabChange={setTab}>
|
|
1603
|
-
* <Panelside.SearchTabs>
|
|
1604
|
-
* <Panelside.SearchTab value="all" icon={<SparklesIcon size={16} />}>All</Panelside.SearchTab>
|
|
1605
|
-
* <Panelside.SearchTab value="chats" icon={<MessageCircleIcon size={16} />}>Chats</Panelside.SearchTab>
|
|
1606
|
-
* </Panelside.SearchTabs>
|
|
1607
|
-
*
|
|
1608
|
-
* <Panelside.SearchResults>
|
|
1609
|
-
* {hits.map((hit) => (
|
|
1610
|
-
* <Panelside.SearchResult key={hit.id} title={hit.title} description={hit.kind} />
|
|
1611
|
-
* ))}
|
|
1612
|
-
* </Panelside.SearchResults>
|
|
1613
|
-
*
|
|
1614
|
-
* <Panelside.SearchField placeholder="Search chats" />
|
|
1615
|
-
* </Panelside.SearchSheet>
|
|
1616
|
-
* ```
|
|
1617
|
-
*
|
|
1618
|
-
* Put it under `<Panelside>` and outside `Panelside.Panel` — a sheet is
|
|
1619
|
-
* presented over the whole app, and the panel is a layer that slides.
|
|
1620
|
-
*
|
|
1621
|
-
* It reports what was typed and which tab is selected. What counts as a match,
|
|
1622
|
-
* and what a result is, are yours: a search that only read chat titles would
|
|
1623
|
-
* be wrong for the first app that indexes message bodies.
|
|
1624
|
-
*/
|
|
1625
|
-
function PanelsideSearchSheet({
|
|
1626
|
-
className,
|
|
1627
|
-
open: openProp,
|
|
1628
|
-
onOpenChange,
|
|
1629
|
-
value,
|
|
1630
|
-
defaultValue = '',
|
|
1631
|
-
onValueChange,
|
|
1632
|
-
tab,
|
|
1633
|
-
defaultTab = '',
|
|
1634
|
-
onTabChange,
|
|
1635
|
-
native = true,
|
|
1636
|
-
snapPoints,
|
|
1637
|
-
keyboardGap = 10,
|
|
1638
|
-
showClose = true,
|
|
1639
|
-
closeLabel = 'Close search',
|
|
1640
|
-
closeVariant = 'filled',
|
|
1641
|
-
closeNative = false,
|
|
1642
|
-
closeGlass = false,
|
|
1643
|
-
children
|
|
1644
|
-
}) {
|
|
1645
|
-
const {
|
|
1646
|
-
searchOpen,
|
|
1647
|
-
setSearchOpen
|
|
1648
|
-
} = usePanelsideContext('Panelside.SearchSheet');
|
|
1649
|
-
const insets = useSafeAreaInsets();
|
|
1650
|
-
const {
|
|
1651
|
-
height: screenHeight
|
|
1652
|
-
} = useWindowDimensions();
|
|
1653
|
-
const tint = useCSSVariable('--color-foreground');
|
|
1654
|
-
const glyph = typeof tint === 'string' ? tint : undefined;
|
|
1655
|
-
const [uncontrolledQuery, setUncontrolledQuery] = useState(defaultValue);
|
|
1656
|
-
const [uncontrolledTab, setUncontrolledTab] = useState(defaultTab);
|
|
1657
|
-
const open = openProp ?? searchOpen;
|
|
1658
|
-
const query = value ?? uncontrolledQuery;
|
|
1659
|
-
const activeTab = tab ?? uncontrolledTab;
|
|
1660
|
-
|
|
1661
|
-
/*
|
|
1662
|
-
* Closing takes the keyboard with it, wherever the close came from — the
|
|
1663
|
-
* button, a drag on the sheet, or the system back gesture.
|
|
1664
|
-
*
|
|
1665
|
-
* Leaving it to the field's own blur is too late. The field blurs when
|
|
1666
|
-
* `open` goes false, but the sheet is already on its way out by then: the
|
|
1667
|
-
* styled one unmounts its portal after the exit animation, and the platform
|
|
1668
|
-
* one keeps its content mounted and only stops presenting it. Either way the
|
|
1669
|
-
* blur lands on a field nothing can see, and the keyboard stays up until the
|
|
1670
|
-
* system notices for itself, some seconds later, that nothing is focused.
|
|
1671
|
-
*/
|
|
1672
|
-
const setOpen = useCallback(next => {
|
|
1673
|
-
if (!next) Keyboard.dismiss();
|
|
1674
|
-
if (openProp === undefined) setSearchOpen(next);
|
|
1675
|
-
onOpenChange?.(next);
|
|
1676
|
-
}, [onOpenChange, openProp, setSearchOpen]);
|
|
1677
|
-
const setQuery = useCallback(next => {
|
|
1678
|
-
if (value === undefined) setUncontrolledQuery(next);
|
|
1679
|
-
onValueChange?.(next);
|
|
1680
|
-
}, [onValueChange, value]);
|
|
1681
|
-
const setTab = useCallback(next => {
|
|
1682
|
-
if (tab === undefined) setUncontrolledTab(next);
|
|
1683
|
-
onTabChange?.(next);
|
|
1684
|
-
}, [onTabChange, tab]);
|
|
1685
|
-
const close = useCallback(() => setOpen(false), [setOpen]);
|
|
1686
|
-
const detents = snapPoints ?? ['full'];
|
|
1687
|
-
|
|
1688
|
-
/*
|
|
1689
|
-
* What `BottomSheet.Content` pads the bottom of the sheet by. The field
|
|
1690
|
-
* already sits that far above the screen edge, and docking travels by the
|
|
1691
|
-
* keyboard's height less whatever the element has already cleared — so
|
|
1692
|
-
* getting this wrong is a gap under the field, or the field over the
|
|
1693
|
-
* keyboard's top row.
|
|
1694
|
-
*/
|
|
1695
|
-
const bottomInset = Math.max(insets.bottom, SHEET_BOTTOM_PADDING) - keyboardGap;
|
|
1696
|
-
|
|
1697
|
-
/*
|
|
1698
|
-
* A definite height for the column, not `flex-1` against the sheet's own.
|
|
1699
|
-
*
|
|
1700
|
-
* The platform sheet gives its hosted content a *minimum* height, and a
|
|
1701
|
-
* minimum is not something `flex-1` can divide: the results list sizes to
|
|
1702
|
-
* its own rows instead, grows past the sheet, and pushes the field off the
|
|
1703
|
-
* bottom — which is a search surface with no way to type in it. So the
|
|
1704
|
-
* column is told exactly how tall it is, and the list gets the room left
|
|
1705
|
-
* between the tabs and the field.
|
|
1706
|
-
*
|
|
1707
|
-
* Only under the platform sheet. The styled one is laid out by us and has a
|
|
1708
|
-
* real height already, so `flex-1` resolves there and a second opinion about
|
|
1709
|
-
* how tall the sheet is would only be a chance to disagree with it.
|
|
1710
|
-
*/
|
|
1711
|
-
const hosted = native && getNativeUI() !== null;
|
|
1712
|
-
const columnHeight = hosted ? (bottomSheetDetentHeight(detents, screenHeight) ?? screenHeight * 0.9) - SHEET_TOP_PADDING - Math.max(insets.bottom, SHEET_BOTTOM_PADDING) : undefined;
|
|
1713
|
-
const context = useMemo(() => ({
|
|
1714
|
-
open,
|
|
1715
|
-
query,
|
|
1716
|
-
setQuery,
|
|
1717
|
-
tab: activeTab,
|
|
1718
|
-
setTab,
|
|
1719
|
-
close,
|
|
1720
|
-
bottomInset
|
|
1721
|
-
}), [activeTab, bottomInset, close, open, query, setQuery, setTab]);
|
|
1722
|
-
return /*#__PURE__*/_jsx(BottomSheet, {
|
|
1723
|
-
native: native,
|
|
1724
|
-
open: open,
|
|
1725
|
-
onOpenChange: setOpen,
|
|
1726
|
-
snapPoints: detents,
|
|
1727
|
-
children: /*#__PURE__*/_jsx(BottomSheet.Content, {
|
|
1728
|
-
size: "full",
|
|
1729
|
-
showClose: false,
|
|
1730
|
-
className: "gap-0 px-0 pt-3",
|
|
1731
|
-
children: /*#__PURE__*/_jsx(PanelsideSearchSheetContext.Provider, {
|
|
1732
|
-
value: context,
|
|
1733
|
-
children: /*#__PURE__*/_jsxs(View, {
|
|
1734
|
-
className: cn('gap-2', columnHeight === undefined && 'flex-1', className),
|
|
1735
|
-
style: columnHeight === undefined ? undefined : {
|
|
1736
|
-
height: columnHeight
|
|
1737
|
-
},
|
|
1738
|
-
children: [showClose ? /*#__PURE__*/_jsx(View, {
|
|
1739
|
-
className: "flex-row px-4 pb-1",
|
|
1740
|
-
children: closeNative ? /*#__PURE__*/_jsx(Button, {
|
|
1741
|
-
native: true,
|
|
1742
|
-
glass: closeGlass,
|
|
1743
|
-
size: "icon",
|
|
1744
|
-
variant: "ghost",
|
|
1745
|
-
accessibilityLabel: closeLabel,
|
|
1746
|
-
onPress: close,
|
|
1747
|
-
children: /*#__PURE__*/_jsx(Glyph, {
|
|
1748
|
-
icon: Cancel01Icon,
|
|
1749
|
-
size: 17,
|
|
1750
|
-
color: glyph
|
|
1751
|
-
})
|
|
1752
|
-
}) : /*#__PURE__*/_jsx(AnimatedPressable, {
|
|
1753
|
-
onPress: close,
|
|
1754
|
-
accessibilityRole: "button",
|
|
1755
|
-
accessibilityLabel: closeLabel,
|
|
1756
|
-
className: cn('h-9 w-9 items-center justify-center rounded-full', closeVariant === 'outline' ? 'border border-border' : 'bg-secondary'),
|
|
1757
|
-
children: /*#__PURE__*/_jsx(Glyph, {
|
|
1758
|
-
icon: Cancel01Icon,
|
|
1759
|
-
size: 17,
|
|
1760
|
-
color: glyph
|
|
1761
|
-
})
|
|
1762
|
-
})
|
|
1763
|
-
}) : null, children]
|
|
1764
|
-
})
|
|
1765
|
-
})
|
|
1766
|
-
})
|
|
1767
|
-
});
|
|
1768
|
-
}
|
|
1769
|
-
/**
|
|
1770
|
-
* The row across the top of the search sheet, narrowing what is searched.
|
|
1771
|
-
*
|
|
1772
|
-
* The expanding variant: only the selected tab is open, and the rest are their
|
|
1773
|
-
* icons. A row of four full labels takes the whole width to say four words
|
|
1774
|
-
* nobody rereads, and this row has to leave the results the screen.
|
|
1775
|
-
*
|
|
1776
|
-
* Every `Panelside.SearchTab` therefore needs an `icon` — a closed tab has
|
|
1777
|
-
* nothing else to be.
|
|
1778
|
-
*/
|
|
1779
|
-
function PanelsideSearchTabs({
|
|
1780
|
-
className,
|
|
1781
|
-
align = 'center',
|
|
1782
|
-
listClassName,
|
|
1783
|
-
children
|
|
1784
|
-
}) {
|
|
1785
|
-
const {
|
|
1786
|
-
tab,
|
|
1787
|
-
setTab
|
|
1788
|
-
} = usePanelsideSearchSheet('Panelside.SearchTabs');
|
|
1789
|
-
return /*#__PURE__*/_jsx(Tabs, {
|
|
1790
|
-
variant: "expanding",
|
|
1791
|
-
value: tab,
|
|
1792
|
-
onValueChange: setTab,
|
|
1793
|
-
defaultValue: tab,
|
|
1794
|
-
className: cn('px-4 pt-1', className),
|
|
1795
|
-
children: /*#__PURE__*/_jsx(Tabs.List, {
|
|
1796
|
-
className: cn(align === 'center' && 'justify-center', listClassName),
|
|
1797
|
-
children: children
|
|
1798
|
-
})
|
|
1799
|
-
});
|
|
1800
|
-
}
|
|
1801
|
-
function PanelsideSearchTab({
|
|
1802
|
-
className,
|
|
1803
|
-
value,
|
|
1804
|
-
icon,
|
|
1805
|
-
children
|
|
1806
|
-
}) {
|
|
1807
|
-
return (
|
|
1808
|
-
/*#__PURE__*/
|
|
1809
|
-
// A step of padding above the tab row's own. This row is the only control
|
|
1810
|
-
// on a surface that is otherwise a list and a field, and a closed tab here
|
|
1811
|
-
// is a glyph with nothing else to be aimed at by — so it is sized to be
|
|
1812
|
-
// hit rather than to the density a row of labelled tabs can afford.
|
|
1813
|
-
_jsx(Tabs.Trigger, {
|
|
1814
|
-
value: value,
|
|
1815
|
-
icon: icon,
|
|
1816
|
-
className: cn('px-4 py-3', className),
|
|
1817
|
-
children: children
|
|
1818
|
-
})
|
|
1819
|
-
);
|
|
1820
|
-
}
|
|
1821
|
-
/**
|
|
1822
|
-
* The scrolling middle of the search sheet.
|
|
1823
|
-
*
|
|
1824
|
-
* `BottomSheet.Body` rather than a `ScrollView`, so the list's scroll and the
|
|
1825
|
-
* sheet's dismiss drag agree on which of them a downward pull belongs to.
|
|
1826
|
-
*/
|
|
1827
|
-
function PanelsideSearchResults({
|
|
1828
|
-
className,
|
|
1829
|
-
contentContainerClassName,
|
|
1830
|
-
children,
|
|
1831
|
-
...props
|
|
1832
|
-
}) {
|
|
1833
|
-
usePanelsideSearchSheet('Panelside.SearchResults');
|
|
1834
|
-
return /*#__PURE__*/_jsx(BottomSheet.Body, {
|
|
1835
|
-
className: cn('flex-1', className),
|
|
1836
|
-
contentContainerClassName: cn('gap-1 px-4 pb-4 pt-1', contentContainerClassName),
|
|
1837
|
-
keyboardShouldPersistTaps: "handled",
|
|
1838
|
-
keyboardDismissMode: "interactive",
|
|
1839
|
-
...props,
|
|
1840
|
-
children: textChildren(children)
|
|
1841
|
-
});
|
|
1842
|
-
}
|
|
1843
|
-
/**
|
|
1844
|
-
* One hit. A leading thumbnail, a title, and a line saying what it is.
|
|
1845
|
-
*
|
|
1846
|
-
* Taller than a `Panelside.Item`, and deliberately: a navigation row is a
|
|
1847
|
-
* place you already know the name of, and a result is a thing you are deciding
|
|
1848
|
-
* about — the second line is what the decision is made on.
|
|
1849
|
-
*/
|
|
1850
|
-
function PanelsideSearchResult({
|
|
1851
|
-
className,
|
|
1852
|
-
media,
|
|
1853
|
-
title,
|
|
1854
|
-
description,
|
|
1855
|
-
children,
|
|
1856
|
-
...props
|
|
1857
|
-
}) {
|
|
1858
|
-
const tint = useCSSVariable('--color-muted-foreground');
|
|
1859
|
-
const color = typeof tint === 'string' ? tint : undefined;
|
|
1860
|
-
return /*#__PURE__*/_jsxs(AnimatedPressable, {
|
|
1861
|
-
className: cn('flex-row items-center gap-3 rounded-xl px-2 py-2', className),
|
|
1862
|
-
accessibilityRole: "button",
|
|
1863
|
-
accessibilityLabel: title,
|
|
1864
|
-
pressScale: 0.985,
|
|
1865
|
-
...props,
|
|
1866
|
-
children: [media ? /*#__PURE__*/_jsx(View, {
|
|
1867
|
-
className: "h-11 w-11 items-center justify-center overflow-hidden rounded-xl bg-secondary",
|
|
1868
|
-
children: /*#__PURE__*/_jsx(IconColorProvider, {
|
|
1869
|
-
color: color,
|
|
1870
|
-
children: media
|
|
1871
|
-
})
|
|
1872
|
-
}) : null, title !== undefined || description !== undefined ? /*#__PURE__*/_jsxs(View, {
|
|
1873
|
-
className: "flex-1 gap-0.5",
|
|
1874
|
-
children: [title !== undefined ? /*#__PURE__*/_jsx(Text, {
|
|
1875
|
-
size: "base",
|
|
1876
|
-
weight: "medium",
|
|
1877
|
-
numberOfLines: 1,
|
|
1878
|
-
children: title
|
|
1879
|
-
}) : null, description !== undefined ? /*#__PURE__*/_jsx(Text, {
|
|
1880
|
-
size: "sm",
|
|
1881
|
-
muted: true,
|
|
1882
|
-
numberOfLines: 1,
|
|
1883
|
-
children: description
|
|
1884
|
-
}) : null]
|
|
1885
|
-
}) : null, children]
|
|
1886
|
-
});
|
|
1887
|
-
}
|
|
1888
|
-
/**
|
|
1889
|
-
* The field, at the bottom of the sheet, riding the keyboard.
|
|
1890
|
-
*
|
|
1891
|
-
* At the bottom because that is where the thumb is and where the keyboard
|
|
1892
|
-
* comes up: a field at the top of a full-height sheet is at the far end of the
|
|
1893
|
-
* screen from both, and every character typed into it is read at the other
|
|
1894
|
-
* end of a list that is moving.
|
|
1895
|
-
*
|
|
1896
|
-
* The way out of the surface is not here — `Panelside.SearchSheet` draws it at
|
|
1897
|
-
* the leading edge of the top row, so the dismiss control does not move with
|
|
1898
|
-
* the keyboard and is not one mis-tap away from the field.
|
|
1899
|
-
*/
|
|
1900
|
-
function PanelsideSearchField({
|
|
1901
|
-
className,
|
|
1902
|
-
containerClassName,
|
|
1903
|
-
placeholder = 'Search',
|
|
1904
|
-
value,
|
|
1905
|
-
onChangeText,
|
|
1906
|
-
...props
|
|
1907
|
-
}) {
|
|
1908
|
-
const {
|
|
1909
|
-
open,
|
|
1910
|
-
query,
|
|
1911
|
-
setQuery,
|
|
1912
|
-
bottomInset
|
|
1913
|
-
} = usePanelsideSearchSheet('Panelside.SearchField');
|
|
1914
|
-
const placeholderTint = useCSSVariable('--color-muted-foreground');
|
|
1915
|
-
const textTint = useCSSVariable('--color-foreground');
|
|
1916
|
-
const muted = typeof placeholderTint === 'string' ? placeholderTint : undefined;
|
|
1917
|
-
const field = useRef(null);
|
|
1918
|
-
const text = value ?? query;
|
|
1919
|
-
const change = onChangeText ?? setQuery;
|
|
1920
|
-
|
|
1921
|
-
/*
|
|
1922
|
-
* Focus on the transition rather than with `autoFocus`. Under `native` the
|
|
1923
|
-
* sheet's content is mounted for the life of the screen and only
|
|
1924
|
-
* `isPresented` changes, so `autoFocus` fires once — at startup, on a sheet
|
|
1925
|
-
* that is not up — and the keyboard opens over whatever is.
|
|
1926
|
-
*/
|
|
1927
|
-
useEffect(() => {
|
|
1928
|
-
if (open) field.current?.focus();else field.current?.blur();
|
|
1929
|
-
}, [open]);
|
|
1930
|
-
return /*#__PURE__*/_jsx(KeyboardAvoider, {
|
|
1931
|
-
mode: "dock",
|
|
1932
|
-
active: open,
|
|
1933
|
-
bottomInset: bottomInset,
|
|
1934
|
-
className: "w-full px-4 pb-1",
|
|
1935
|
-
children: /*#__PURE__*/_jsxs(View, {
|
|
1936
|
-
className: cn('h-12 w-full flex-row items-center gap-2 rounded-full border border-border bg-surface px-4 shadow-lg', containerClassName),
|
|
1937
|
-
children: [/*#__PURE__*/_jsx(Glyph, {
|
|
1938
|
-
icon: Search01Icon,
|
|
1939
|
-
size: 17,
|
|
1940
|
-
color: muted
|
|
1941
|
-
}), /*#__PURE__*/_jsx(TextInput, {
|
|
1942
|
-
ref: field,
|
|
1943
|
-
value: text,
|
|
1944
|
-
onChangeText: change,
|
|
1945
|
-
placeholder: placeholder,
|
|
1946
|
-
placeholderTextColor: muted
|
|
1947
|
-
/* `text-[16px]` rather than a `text-*` step — see Panelside.Search. */,
|
|
1948
|
-
className: cn('h-full flex-1 font-normal text-[16px] text-foreground', className),
|
|
1949
|
-
style: typeof textTint === 'string' ? {
|
|
1950
|
-
color: textTint
|
|
1951
|
-
} : undefined,
|
|
1952
|
-
accessibilityRole: "search",
|
|
1953
|
-
returnKeyType: "search",
|
|
1954
|
-
...props
|
|
1955
|
-
}), text.length > 0 ? /*#__PURE__*/_jsx(AnimatedPressable, {
|
|
1956
|
-
onPress: () => change(''),
|
|
1957
|
-
hitSlop: 8,
|
|
1958
|
-
accessibilityRole: "button",
|
|
1959
|
-
accessibilityLabel: "Clear search",
|
|
1960
|
-
className: "h-5 w-5 items-center justify-center rounded-full bg-muted",
|
|
1961
|
-
children: /*#__PURE__*/_jsx(Glyph, {
|
|
1962
|
-
icon: Cancel01Icon,
|
|
1963
|
-
size: 12,
|
|
1964
|
-
color: muted
|
|
1965
|
-
})
|
|
1966
|
-
}) : null]
|
|
1967
|
-
})
|
|
1968
|
-
});
|
|
1969
|
-
}
|
|
1970
1580
|
PanelsidePanel.displayName = 'Panelside.Panel';
|
|
1971
1581
|
PanelsideHeader.displayName = 'Panelside.Header';
|
|
1972
1582
|
PanelsideSearch.displayName = 'Panelside.Search';
|
|
@@ -1986,12 +1596,6 @@ PanelsidePages.displayName = 'Panelside.Pages';
|
|
|
1986
1596
|
PanelsidePage.displayName = 'Panelside.Page';
|
|
1987
1597
|
PanelsideTrigger.displayName = 'Panelside.Trigger';
|
|
1988
1598
|
PanelsideSearchTrigger.displayName = 'Panelside.SearchTrigger';
|
|
1989
|
-
PanelsideSearchSheet.displayName = 'Panelside.SearchSheet';
|
|
1990
|
-
PanelsideSearchTabs.displayName = 'Panelside.SearchTabs';
|
|
1991
|
-
PanelsideSearchTab.displayName = 'Panelside.SearchTab';
|
|
1992
|
-
PanelsideSearchResults.displayName = 'Panelside.SearchResults';
|
|
1993
|
-
PanelsideSearchResult.displayName = 'Panelside.SearchResult';
|
|
1994
|
-
PanelsideSearchField.displayName = 'Panelside.SearchField';
|
|
1995
1599
|
export const Panelside = Object.assign(PanelsideRoot, {
|
|
1996
1600
|
Panel: PanelsidePanel,
|
|
1997
1601
|
Header: PanelsideHeader,
|
|
@@ -2011,12 +1615,6 @@ export const Panelside = Object.assign(PanelsideRoot, {
|
|
|
2011
1615
|
Pages: PanelsidePages,
|
|
2012
1616
|
Page: PanelsidePage,
|
|
2013
1617
|
Trigger: PanelsideTrigger,
|
|
2014
|
-
SearchTrigger: PanelsideSearchTrigger
|
|
2015
|
-
SearchSheet: PanelsideSearchSheet,
|
|
2016
|
-
SearchTabs: PanelsideSearchTabs,
|
|
2017
|
-
SearchTab: PanelsideSearchTab,
|
|
2018
|
-
SearchResults: PanelsideSearchResults,
|
|
2019
|
-
SearchResult: PanelsideSearchResult,
|
|
2020
|
-
SearchField: PanelsideSearchField
|
|
1618
|
+
SearchTrigger: PanelsideSearchTrigger
|
|
2021
1619
|
});
|
|
2022
1620
|
//# sourceMappingURL=index.js.map
|