Finish sort menu

This commit is contained in:
Zoe Roux
2023-03-15 12:09:44 +09:00
parent a716fd1e22
commit 33db01cbbf
4 changed files with 111 additions and 210 deletions
+47 -42
View File
@@ -27,10 +27,11 @@ import Close from "@material-symbols/svg-400/rounded/close-fill.svg";
import { Icon, IconButton } from "./icons";
import { PressableFeedback } from "./links";
import { P } from "./text";
import { ContrastArea } from "./themes";
import { ContrastArea, SwitchVariant } from "./themes";
import { ts } from "./utils";
import Check from "@material-symbols/svg-400/rounded/check-fill.svg";
import { useRouter } from "solito/router";
import { SvgProps } from "react-native-svg";
const MenuContext = createContext<((open: boolean) => void) | undefined>(undefined);
@@ -60,48 +61,50 @@ const Menu = <AsProps,>({
{isOpen && (
<Portal>
<ContrastArea mode="user">
{({ css, theme }) => (
<MenuContext.Provider value={setOpen}>
<Pressable
onPress={() => setOpen(false)}
focusable={false}
{...css({ ...StyleSheet.absoluteFillObject, flexGrow: 1, bg: "transparent" })}
/>
<ScrollView
{...css([
{
bg: (theme) => theme.background,
position: "absolute",
bottom: 0,
width: percent(100),
alignSelf: "center",
borderTopLeftRadius: px(26),
borderTopRightRadius: { xs: px(26), xl: 0 },
paddingTop: { xs: px(26), xl: 0 },
marginTop: { xs: px(72), xl: 0 },
},
sm({
maxWidth: px(640),
marginHorizontal: px(56),
}),
xl({
top: 0,
right: 0,
marginRight: 0,
borderBottomLeftRadius: px(26),
}),
])}
>
<IconButton
icon={Close}
color={theme.colors.black}
<SwitchVariant>
{({ css, theme }) => (
<MenuContext.Provider value={setOpen}>
<Pressable
onPress={() => setOpen(false)}
{...css({ alignSelf: "flex-end", display: { xs: "none", xl: "flex" } })}
focusable={false}
{...css({ ...StyleSheet.absoluteFillObject, flexGrow: 1, bg: "transparent" })}
/>
{children}
</ScrollView>
</MenuContext.Provider>
)}
<ScrollView
{...css([
{
bg: (theme) => theme.background,
position: "absolute",
bottom: 0,
width: percent(100),
alignSelf: "center",
borderTopLeftRadius: px(26),
borderTopRightRadius: { xs: px(26), xl: 0 },
paddingTop: { xs: px(26), xl: 0 },
marginTop: { xs: px(72), xl: 0 },
},
sm({
maxWidth: px(640),
marginHorizontal: px(56),
}),
xl({
top: 0,
right: 0,
marginRight: 0,
borderBottomLeftRadius: px(26),
}),
])}
>
<IconButton
icon={Close}
color={theme.colors.black}
onPress={() => setOpen(false)}
{...css({ alignSelf: "flex-end", display: { xs: "none", xl: "flex" } })}
/>
{children}
</ScrollView>
</MenuContext.Provider>
)}
</SwitchVariant>
</ContrastArea>
</Portal>
)}
@@ -114,10 +117,12 @@ const MenuItem = ({
selected,
onSelect,
href,
icon,
...props
}: {
label: string;
selected?: boolean;
icon?: ComponentType<SvgProps>;
} & ({ onSelect: () => void; href?: undefined } | { href: string; onSelect?: undefined })) => {
const { css, theme } = useYoshiki();
const setOpen = useContext(MenuContext);
@@ -141,7 +146,7 @@ const MenuItem = ({
props as any,
)}
>
{selected && <Icon icon={Check} color={theme.paragraph} size={24} />}
{selected && <Icon icon={icon ?? Check} color={theme.paragraph} size={24} />}
<P {...css({ paddingLeft: ts(2) + +!selected * px(24) })}>{label}</P>
</PressableFeedback>
);
+31 -28
View File
@@ -25,10 +25,11 @@ import { PressableProps } from "react-native";
import { useYoshiki } from "yoshiki/web";
import { px, useYoshiki as useNativeYoshiki } from "yoshiki/native";
import { P } from "./text";
import { ContrastArea } from "./themes";
import { ContrastArea, SwitchVariant } from "./themes";
import { Icon } from "./icons";
import Dot from "@material-symbols/svg-400/rounded/fiber_manual_record-fill.svg";
import { focusReset } from "./utils";
import { focusReset, ts } from "./utils";
import { SvgProps } from "react-native-svg";
type YoshikiFunc<T> = (props: ReturnType<typeof useYoshiki>) => T;
const YoshikiProvider = ({ children }: { children: YoshikiFunc<ReactNode> }) => {
@@ -68,26 +69,28 @@ const Menu = <AsProps extends { onPress: PressableProps["onPress"] }>({
<InternalTriger Component={Trigger} ComponentProps={props} />
</DropdownMenu.Trigger>
<ContrastArea mode="user">
<YoshikiProvider>
{({ css }) => (
<DropdownMenu.Portal>
<DropdownMenu.Content
onFocusOutside={(e) => e.stopImmediatePropagation()}
{...css({
bg: (theme) => theme.background,
overflow: "hidden",
minWidth: "220px",
borderRadius: "8px",
boxShadow:
"0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)",
zIndex: 2,
})}
>
{children}
</DropdownMenu.Content>
</DropdownMenu.Portal>
)}
</YoshikiProvider>
<SwitchVariant>
<YoshikiProvider>
{({ css }) => (
<DropdownMenu.Portal>
<DropdownMenu.Content
onFocusOutside={(e) => e.stopImmediatePropagation()}
{...css({
bg: (theme) => theme.background,
overflow: "hidden",
minWidth: "220px",
borderRadius: "8px",
boxShadow:
"0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)",
zIndex: 2,
})}
>
{children}
</DropdownMenu.Content>
</DropdownMenu.Portal>
)}
</YoshikiProvider>
</SwitchVariant>
</ContrastArea>
</DropdownMenu.Root>
);
@@ -122,7 +125,7 @@ const MenuItem = ({
...props
}: {
label: string;
icon?: JSX.Element;
icon?: ComponentType<SvgProps>;
selected?: boolean;
} & ({ onSelect: () => void; href?: undefined } | { href: string; onSelect?: undefined })) => {
const { css: nCss } = useNativeYoshiki();
@@ -132,7 +135,7 @@ const MenuItem = ({
<>
<style jsx global>{`
[data-highlighted] {
background: ${theme.alternate.accent};
background: ${theme.variant.accent};
}
`}</style>
<Item
@@ -151,13 +154,13 @@ const MenuItem = ({
>
{selected && (
<Icon
icon={Dot}
icon={icon ?? Dot}
color={theme.paragraph}
size={px(8)}
{...nCss({ paddingRight: px(8) })}
size={ts(icon ? 2 : 1)}
{...nCss({ paddingRight: ts(1) })}
/>
)}
{<P {...nCss(!selected && { paddingLeft: px(8 * 2) })}>{label}</P>}
{<P {...nCss(!selected && { paddingLeft: ts(1 + (icon ? 2 : 1)) })}>{label}</P>}
</Item>
</>
);