panelui-native 0.78.0 → 0.79.1
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/lib/module/components/accordion/index.js +13 -1
- package/lib/module/components/accordion/index.js.map +1 -1
- package/lib/module/components/map/index.js +63 -39
- package/lib/module/components/map/index.js.map +1 -1
- package/lib/module/components/map/map-children.js +54 -0
- package/lib/module/components/map/map-children.js.map +1 -0
- package/lib/module/components/map/maplibre.js +31 -3
- package/lib/module/components/map/maplibre.js.map +1 -1
- package/lib/module/components/markdown-editor/index.js +288 -34
- package/lib/module/components/markdown-editor/index.js.map +1 -1
- package/lib/module/components/markdown-editor/markdown-transforms.js +272 -9
- package/lib/module/components/markdown-editor/markdown-transforms.js.map +1 -1
- package/lib/module/components/marquee/index.js +119 -46
- package/lib/module/components/marquee/index.js.map +1 -1
- package/lib/module/components/panelside/index.js +162 -34
- package/lib/module/components/panelside/index.js.map +1 -1
- package/lib/module/components/progress-button/index.js +279 -52
- package/lib/module/components/progress-button/index.js.map +1 -1
- package/lib/module/components/progress-button/progress-button-hold.js +40 -6
- package/lib/module/components/progress-button/progress-button-hold.js.map +1 -1
- package/lib/module/components/theme-selector/index.js +239 -0
- package/lib/module/components/theme-selector/index.js.map +1 -0
- package/lib/module/components/theme-selector/theme-preview.js +320 -0
- package/lib/module/components/theme-selector/theme-preview.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/components/accordion/index.d.ts.map +1 -1
- package/lib/typescript/src/components/map/index.d.ts +8 -4
- package/lib/typescript/src/components/map/index.d.ts.map +1 -1
- package/lib/typescript/src/components/map/map-children.d.ts +41 -0
- package/lib/typescript/src/components/map/map-children.d.ts.map +1 -0
- package/lib/typescript/src/components/map/maplibre.d.ts +8 -4
- package/lib/typescript/src/components/map/maplibre.d.ts.map +1 -1
- package/lib/typescript/src/components/markdown-editor/index.d.ts +64 -5
- package/lib/typescript/src/components/markdown-editor/index.d.ts.map +1 -1
- package/lib/typescript/src/components/markdown-editor/markdown-transforms.d.ts +33 -5
- package/lib/typescript/src/components/markdown-editor/markdown-transforms.d.ts.map +1 -1
- package/lib/typescript/src/components/marquee/index.d.ts.map +1 -1
- package/lib/typescript/src/components/panelside/index.d.ts +79 -4
- package/lib/typescript/src/components/panelside/index.d.ts.map +1 -1
- package/lib/typescript/src/components/progress-button/index.d.ts +29 -13
- package/lib/typescript/src/components/progress-button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/progress-button/progress-button-hold.d.ts +26 -6
- package/lib/typescript/src/components/progress-button/progress-button-hold.d.ts.map +1 -1
- package/lib/typescript/src/components/theme-selector/index.d.ts +107 -0
- package/lib/typescript/src/components/theme-selector/index.d.ts.map +1 -0
- package/lib/typescript/src/components/theme-selector/theme-preview.d.ts +32 -0
- package/lib/typescript/src/components/theme-selector/theme-preview.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/accordion/index.tsx +13 -0
- package/src/components/map/index.tsx +63 -36
- package/src/components/map/map-children.ts +66 -0
- package/src/components/map/maplibre.ts +32 -4
- package/src/components/markdown-editor/index.tsx +413 -35
- package/src/components/markdown-editor/markdown-transforms.ts +274 -10
- package/src/components/marquee/index.tsx +128 -55
- package/src/components/panelside/index.tsx +179 -40
- package/src/components/progress-button/index.tsx +264 -45
- package/src/components/progress-button/progress-button-hold.ts +37 -6
- package/src/components/theme-selector/index.tsx +281 -0
- package/src/components/theme-selector/theme-preview.tsx +205 -0
- package/src/index.ts +15 -0
|
@@ -119,7 +119,7 @@ import { LinearGradient } from 'expo-linear-gradient';
|
|
|
119
119
|
import { EllipsisIcon, IconColorProvider, MenuIcon, SearchIcon } from '../../icons';
|
|
120
120
|
import { Button } from '../button';
|
|
121
121
|
import { AnimatedPressable } from '../../primitives/animated-pressable';
|
|
122
|
-
import { Text, textChildren } from '../../primitives/text';
|
|
122
|
+
import { Text, textChildren, type TextProps } from '../../primitives/text';
|
|
123
123
|
import { useBackHandler } from '../../hooks/use-back-handler';
|
|
124
124
|
import { useDirectionSign } from '../../hooks/use-direction';
|
|
125
125
|
import { cn } from '../../utils/cn';
|
|
@@ -888,17 +888,47 @@ function PanelsideGroupLabel({ className, children, ...props }: PanelsideGroupLa
|
|
|
888
888
|
);
|
|
889
889
|
}
|
|
890
890
|
|
|
891
|
+
/**
|
|
892
|
+
* What a row's parts read off the row, rather than being handed it.
|
|
893
|
+
*
|
|
894
|
+
* A label goes medium and un-muted when the row is the current destination,
|
|
895
|
+
* and an icon takes the matching tint. Passing that to every part would mean
|
|
896
|
+
* `<Panelside.ItemLabel active={active}>` at every call site, with an `active`
|
|
897
|
+
* that has to be kept in step with the row's own.
|
|
898
|
+
*/
|
|
899
|
+
interface PanelsideItemContextValue {
|
|
900
|
+
active: boolean;
|
|
901
|
+
disabled: boolean;
|
|
902
|
+
size: PanelsideItemSize;
|
|
903
|
+
/** The colour an icon in this row should take, resolved once by the row. */
|
|
904
|
+
tint: string | undefined;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
const PanelsideItemContext = createContext<PanelsideItemContextValue | null>(null);
|
|
908
|
+
|
|
909
|
+
function usePanelsideItem(part: string): PanelsideItemContextValue {
|
|
910
|
+
const value = useContext(PanelsideItemContext);
|
|
911
|
+
if (!value) throw new Error(`${part} must be used inside a <Panelside.Item>.`);
|
|
912
|
+
return value;
|
|
913
|
+
}
|
|
914
|
+
|
|
891
915
|
export interface PanelsideItemProps extends Omit<PressableProps, 'children'> {
|
|
892
916
|
className?: string;
|
|
893
|
-
/**
|
|
917
|
+
/**
|
|
918
|
+
* Leading element — an icon, an avatar, a coloured dot. The shorthand for
|
|
919
|
+
* `Panelside.ItemIcon`.
|
|
920
|
+
*/
|
|
894
921
|
icon?: ReactNode;
|
|
895
|
-
/**
|
|
922
|
+
/**
|
|
923
|
+
* The row's text, truncated to one line since chat titles run long. The
|
|
924
|
+
* shorthand for `Panelside.ItemLabel`.
|
|
925
|
+
*/
|
|
896
926
|
label?: string;
|
|
897
927
|
/** Marks the row as the current destination. */
|
|
898
928
|
active?: boolean;
|
|
899
929
|
/**
|
|
900
930
|
* Trailing count or status. A number or string renders as a pill; anything
|
|
901
|
-
* else renders as given.
|
|
931
|
+
* else renders as given. The shorthand for `Panelside.ItemBadge`.
|
|
902
932
|
*/
|
|
903
933
|
badge?: ReactNode;
|
|
904
934
|
disabled?: boolean;
|
|
@@ -908,10 +938,37 @@ export interface PanelsideItemProps extends Omit<PressableProps, 'children'> {
|
|
|
908
938
|
* worth more than two extra rows.
|
|
909
939
|
*/
|
|
910
940
|
size?: PanelsideItemSize;
|
|
911
|
-
/**
|
|
941
|
+
/**
|
|
942
|
+
* The row's contents, written out: `Panelside.ItemIcon`,
|
|
943
|
+
* `Panelside.ItemLabel`, `Panelside.ItemBadge` and `Panelside.Action`, in
|
|
944
|
+
* whatever order the row wants them. Anything else you draw works too.
|
|
945
|
+
*
|
|
946
|
+
* Children and the shorthand props compose — a row can take its label from
|
|
947
|
+
* `label` and still write a trailing `Panelside.Action` as a child.
|
|
948
|
+
*/
|
|
912
949
|
children?: ReactNode;
|
|
913
950
|
}
|
|
914
951
|
|
|
952
|
+
/**
|
|
953
|
+
* One destination, or one conversation.
|
|
954
|
+
*
|
|
955
|
+
* There are two ways to fill it, and they are the same row. The shorthand —
|
|
956
|
+
* `icon`, `label`, `badge` — covers the row every navigation panel has, and is
|
|
957
|
+
* what most call sites should use. The parts cover everything else: two lines
|
|
958
|
+
* of text, a label that is not a string, a badge before the label rather than
|
|
959
|
+
* after it, a trailing control that is not an overflow menu.
|
|
960
|
+
*
|
|
961
|
+
* ```tsx
|
|
962
|
+
* <Panelside.Item icon={<InboxIcon />} label="Inbox" badge={12} />
|
|
963
|
+
*
|
|
964
|
+
* <Panelside.Item active>
|
|
965
|
+
* <Panelside.ItemIcon><Avatar size="xs" src={author.avatar} /></Panelside.ItemIcon>
|
|
966
|
+
* <Panelside.ItemLabel>{thread.title}</Panelside.ItemLabel>
|
|
967
|
+
* <Panelside.ItemBadge>{thread.unread}</Panelside.ItemBadge>
|
|
968
|
+
* <Panelside.Action onPress={rename} />
|
|
969
|
+
* </Panelside.Item>
|
|
970
|
+
* ```
|
|
971
|
+
*/
|
|
915
972
|
function PanelsideItem({
|
|
916
973
|
className,
|
|
917
974
|
icon,
|
|
@@ -934,46 +991,122 @@ function PanelsideItem({
|
|
|
934
991
|
? restTint
|
|
935
992
|
: undefined;
|
|
936
993
|
|
|
994
|
+
const context = useMemo<PanelsideItemContextValue>(
|
|
995
|
+
() => ({ active, disabled, size, tint }),
|
|
996
|
+
[active, disabled, size, tint]
|
|
997
|
+
);
|
|
998
|
+
|
|
999
|
+
/*
|
|
1000
|
+
* The row needs something flexible in the middle or its trailing content
|
|
1001
|
+
* floats next to the icon instead of sitting at the end. A label supplies
|
|
1002
|
+
* that, and a written-out `Panelside.ItemLabel` supplies it too — so the
|
|
1003
|
+
* spacer is only for the row that has neither, which is a row of nothing but
|
|
1004
|
+
* an icon and a badge.
|
|
1005
|
+
*/
|
|
1006
|
+
const filled = label !== undefined || children !== undefined;
|
|
1007
|
+
|
|
937
1008
|
return (
|
|
938
|
-
<
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
1009
|
+
<PanelsideItemContext.Provider value={context}>
|
|
1010
|
+
<AnimatedPressable
|
|
1011
|
+
className={itemVariants({ active, disabled, size, className })}
|
|
1012
|
+
disabled={disabled}
|
|
1013
|
+
accessibilityRole="button"
|
|
1014
|
+
accessibilityState={{ selected: active, disabled }}
|
|
1015
|
+
accessibilityLabel={label}
|
|
1016
|
+
pressScale={0.985}
|
|
1017
|
+
{...props}
|
|
1018
|
+
>
|
|
1019
|
+
{icon ? <PanelsideItemIcon>{icon}</PanelsideItemIcon> : null}
|
|
1020
|
+
|
|
1021
|
+
{label !== undefined ? <PanelsideItemLabel>{label}</PanelsideItemLabel> : null}
|
|
1022
|
+
|
|
1023
|
+
{filled ? null : <View className="flex-1" />}
|
|
1024
|
+
|
|
1025
|
+
{badge !== undefined && badge !== null ? (
|
|
1026
|
+
<PanelsideItemBadge>{badge}</PanelsideItemBadge>
|
|
1027
|
+
) : null}
|
|
1028
|
+
|
|
1029
|
+
{children}
|
|
1030
|
+
</AnimatedPressable>
|
|
1031
|
+
</PanelsideItemContext.Provider>
|
|
1032
|
+
);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
export interface PanelsideItemIconProps extends ViewProps {
|
|
1036
|
+
className?: string;
|
|
1037
|
+
children?: ReactNode;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* The leading slot on a row.
|
|
1042
|
+
*
|
|
1043
|
+
* Whatever is inside it inherits the row's own tint rather than each call site
|
|
1044
|
+
* passing a colour that stops being right the moment the row goes active.
|
|
1045
|
+
*/
|
|
1046
|
+
function PanelsideItemIcon({ className, children, ...props }: PanelsideItemIconProps) {
|
|
1047
|
+
const { tint } = usePanelsideItem('Panelside.ItemIcon');
|
|
1048
|
+
|
|
1049
|
+
// No wrapper unless one was asked for: an icon is already the right size,
|
|
1050
|
+
// and a `View` around it is a layout node between the row and its glyph.
|
|
1051
|
+
if (className === undefined && Object.keys(props).length === 0) {
|
|
1052
|
+
return <IconColorProvider color={tint}>{children}</IconColorProvider>;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
return (
|
|
1056
|
+
<View className={className} {...props}>
|
|
1057
|
+
<IconColorProvider color={tint}>{children}</IconColorProvider>
|
|
1058
|
+
</View>
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
export interface PanelsideItemLabelProps extends TextProps {
|
|
1063
|
+
className?: string;
|
|
1064
|
+
children?: ReactNode;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
/**
|
|
1068
|
+
* The row's text. It takes the flexible middle, so a long title truncates
|
|
1069
|
+
* rather than pushing the badge and the action off the end of the panel.
|
|
1070
|
+
*/
|
|
1071
|
+
function PanelsideItemLabel({ className, children, ...props }: PanelsideItemLabelProps) {
|
|
1072
|
+
const { active } = usePanelsideItem('Panelside.ItemLabel');
|
|
1073
|
+
|
|
1074
|
+
return (
|
|
1075
|
+
<Text
|
|
1076
|
+
size="base"
|
|
1077
|
+
weight={active ? 'medium' : 'normal'}
|
|
1078
|
+
muted={!active}
|
|
1079
|
+
numberOfLines={1}
|
|
1080
|
+
className={cn('flex-1', className)}
|
|
945
1081
|
{...props}
|
|
946
1082
|
>
|
|
947
|
-
{
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
{label ? (
|
|
952
|
-
<Text
|
|
953
|
-
size="base"
|
|
954
|
-
weight={active ? 'medium' : 'normal'}
|
|
955
|
-
muted={!active}
|
|
956
|
-
numberOfLines={1}
|
|
957
|
-
className="flex-1"
|
|
958
|
-
>
|
|
959
|
-
{label}
|
|
960
|
-
</Text>
|
|
961
|
-
) : (
|
|
962
|
-
<View className="flex-1" />
|
|
963
|
-
)}
|
|
1083
|
+
{children}
|
|
1084
|
+
</Text>
|
|
1085
|
+
);
|
|
1086
|
+
}
|
|
964
1087
|
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
</Text>
|
|
970
|
-
</View>
|
|
971
|
-
) : (
|
|
972
|
-
badge
|
|
973
|
-
)}
|
|
1088
|
+
export interface PanelsideItemBadgeProps extends ViewProps {
|
|
1089
|
+
className?: string;
|
|
1090
|
+
children?: ReactNode;
|
|
1091
|
+
}
|
|
974
1092
|
|
|
975
|
-
|
|
976
|
-
|
|
1093
|
+
/**
|
|
1094
|
+
* The trailing count or status on a row. Text becomes a pill; anything else is
|
|
1095
|
+
* drawn as given, so a dot or a chip needs no opting out of the pill.
|
|
1096
|
+
*/
|
|
1097
|
+
function PanelsideItemBadge({ className, children, ...props }: PanelsideItemBadgeProps) {
|
|
1098
|
+
usePanelsideItem('Panelside.ItemBadge');
|
|
1099
|
+
|
|
1100
|
+
if (typeof children !== 'string' && typeof children !== 'number') {
|
|
1101
|
+
return <>{children}</>;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
return (
|
|
1105
|
+
<View className={cn('rounded-full bg-secondary px-2 py-0.5', className)} {...props}>
|
|
1106
|
+
<Text size="xs" muted>
|
|
1107
|
+
{children}
|
|
1108
|
+
</Text>
|
|
1109
|
+
</View>
|
|
977
1110
|
);
|
|
978
1111
|
}
|
|
979
1112
|
|
|
@@ -1456,6 +1589,9 @@ PanelsideContent.displayName = 'Panelside.Content';
|
|
|
1456
1589
|
PanelsideGroup.displayName = 'Panelside.Group';
|
|
1457
1590
|
PanelsideGroupLabel.displayName = 'Panelside.GroupLabel';
|
|
1458
1591
|
PanelsideItem.displayName = 'Panelside.Item';
|
|
1592
|
+
PanelsideItemIcon.displayName = 'Panelside.ItemIcon';
|
|
1593
|
+
PanelsideItemLabel.displayName = 'Panelside.ItemLabel';
|
|
1594
|
+
PanelsideItemBadge.displayName = 'Panelside.ItemBadge';
|
|
1459
1595
|
PanelsideAction.displayName = 'Panelside.Action';
|
|
1460
1596
|
PanelsideFooter.displayName = 'Panelside.Footer';
|
|
1461
1597
|
PanelsideCta.displayName = 'Panelside.Cta';
|
|
@@ -1470,6 +1606,9 @@ export const Panelside = Object.assign(PanelsideRoot, {
|
|
|
1470
1606
|
Group: PanelsideGroup,
|
|
1471
1607
|
GroupLabel: PanelsideGroupLabel,
|
|
1472
1608
|
Item: PanelsideItem,
|
|
1609
|
+
ItemIcon: PanelsideItemIcon,
|
|
1610
|
+
ItemLabel: PanelsideItemLabel,
|
|
1611
|
+
ItemBadge: PanelsideItemBadge,
|
|
1473
1612
|
Action: PanelsideAction,
|
|
1474
1613
|
Footer: PanelsideFooter,
|
|
1475
1614
|
Cta: PanelsideCta,
|