Implement the select component for mobile

This commit is contained in:
Zoe Roux 2023-12-20 03:17:43 +01:00
parent b406ea6088
commit 2919e07606
3 changed files with 75 additions and 11 deletions

View File

@ -18,23 +18,28 @@
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
*/
import { ComponentProps } from "react";
import { ComponentProps, ReactElement, forwardRef } from "react";
import { Theme, useYoshiki } from "yoshiki/native";
import { PressableFeedback } from "./links";
import { P } from "./text";
import { ts } from "./utils";
import { View } from "react-native";
export const Button = ({
text,
...props
}: { text: string } & ComponentProps<typeof PressableFeedback>) => {
export const Button = forwardRef<
View,
{ text: string; icon?: ReactElement } & ComponentProps<typeof PressableFeedback>
>(function Button({ text, icon, ...props }, ref) {
const { css } = useYoshiki("button");
return (
<PressableFeedback
ref={ref}
{...css(
{
flexGrow: 0,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
overflow: "hidden",
p: ts(0.5),
borderRadius: ts(5),
@ -49,6 +54,7 @@ export const Button = ({
)}
>
<P {...css({ textAlign: "center" }, "text")}>{text}</P>
{icon}
</PressableFeedback>
);
};
});

View File

@ -0,0 +1,51 @@
/*
* Kyoo - A portable and vast media library solution.
* Copyright (c) Kyoo.
*
* See AUTHORS.md and LICENSE file in the project root for full license information.
*
* Kyoo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Kyoo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
*/
import { Icon } from "./icons";
import ExpandMore from "@material-symbols/svg-400/rounded/expand_more-fill.svg";
import { Menu } from "./menu";
import { Button } from "./button";
export const Select = ({
label,
value,
onValueChange,
values,
getLabel,
}: {
label: string;
value: string;
onValueChange: (v: string) => void;
values: string[];
getLabel: (key: string) => string;
}) => {
return (
<Menu Trigger={Button} text={getLabel(value)} icon={<Icon icon={ExpandMore} />}>
{values.map((x) => (
<Menu.Item
key={x}
label={getLabel(x)}
selected={x === value}
onSelect={() => onValueChange(value)}
/>
))}
</Menu>
);
};

View File

@ -19,7 +19,7 @@
*/
import * as RSelect from "@radix-ui/react-select";
import { ReactNode, forwardRef } from "react";
import { forwardRef } from "react";
import { Icon } from "./icons";
import Check from "@material-symbols/svg-400/rounded/check-fill.svg";
import ExpandMore from "@material-symbols/svg-400/rounded/expand_more-fill.svg";
@ -33,15 +33,17 @@ import { P } from "./text";
import { focusReset, ts } from "./utils";
export const Select = ({
children,
label,
value,
onValueChange,
values,
getLabel,
}: {
children: ReactNode;
label: string;
value: string;
onValueChange: (v: string) => void;
values: string[];
getLabel: (key: string) => string;
}) => {
const { css } = useNativeYoshiki();
@ -92,7 +94,11 @@ export const Select = ({
<RSelect.ScrollUpButton asChild>
<Icon icon={ExpandLess} />
</RSelect.ScrollUpButton>
<RSelect.Viewport>{children}</RSelect.Viewport>
<RSelect.Viewport>
{values.map((x) => (
<Item key={x} label={getLabel(x)} value={x} />
))}
</RSelect.Viewport>
<RSelect.ScrollDownButton asChild>
<Icon icon={ExpandMore} />
</RSelect.ScrollDownButton>
@ -126,6 +132,8 @@ const Item = forwardRef<HTMLDivElement, { label: string; value: string }>(functi
{
display: "flex",
alignItems: "center",
paddingTop: "8px",
paddingBottom: "8px",
paddingLeft: "35px",
paddingRight: "25px",
height: "32px",
@ -156,4 +164,3 @@ const Item = forwardRef<HTMLDivElement, { label: string; value: string }>(functi
</>
);
});
Select.Item = Item;