Skip to content

Commit

Permalink
more styling
Browse files Browse the repository at this point in the history
  • Loading branch information
nikgraf committed Jun 7, 2024
1 parent 0bc0f15 commit daa3f9d
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 8 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@ TODO better version where the token is also never exposed to the network so not

## Todos

- styling

- implement todos properly in yjs
- fix font-size for inputs
- fix icons and font-size on ios
- fix input active for iOS
- fix iOS of add item
- show members and invitation link as menu
- split nav into login/register and authed part

- use expo-secure-store for the sessionKey
- encrypt MMKV storage on iOS and Android
- todo list UI & structure
Expand Down
8 changes: 5 additions & 3 deletions apps/app/src/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,17 @@ export default function Layout() {
<Drawer
drawerContent={DrawerContent}
screenOptions={{
// headerShown: false,
drawerType: isPermanentLeftDrawer ? "permanent" : "front",
// drawerType: "permanent",
drawerStyle: {
width: isPermanentLeftDrawer ? 240 : fullWidth,
},
overlayColor: "transparent",

drawerPosition: "left",
headerShown: isPermanentLeftDrawer ? false : true,
// headerLeft: () => {
// return <PanelLeft />;
// },
headerTitle: () => null,
// drawerStyle: {
// width: 240,
// },
Expand Down
1 change: 1 addition & 0 deletions apps/app/src/app/list/[listId].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ const List: React.FC<Props> = () => {
autoCapitalize="none"
autoCorrect={false}
autoComplete="off"
numberOfLines={1}
/>
<Button
className="add"
Expand Down
24 changes: 19 additions & 5 deletions apps/app/src/components/drawerContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ListTodo } from "lucide-react-native";
import * as React from "react";
import { View } from "react-native";
import sodium from "react-native-libsodium";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { Text } from "~/components/ui/text";
import { CreateListForm } from "../components/createListForm";
import { Logout } from "../components/logout";
Expand Down Expand Up @@ -35,23 +36,36 @@ export const DrawerContent: React.FC = () => {
keys = Array.from(new Set([...keys, ...remoteDocumentIds]));
}

const insets = useSafeAreaInsets();

return (
<View className="flex flex-1 flex-col justify-between">
<View>
<View
className="flex flex-1 flex-col justify-between"
style={{
paddingTop: insets.top,
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
}}
>
<View className="gap-4">
<Link href="/login">
<Text>Login</Text>
</Link>
<Link href="/register">Register</Link>

<View>
<View className="flex flex-row px-4 items-center gap-2">
<View className="bg-slate-200 w-10 h-10 rounded-full items-center justify-center">
<Text>{meQuery.data?.username.substring(0, 2)}</Text>
</View>
<Text>{meQuery.data?.username}</Text>
</View>

<View className="p-4">
<View className="px-4">
<CreateListForm />
</View>

<View className="flex flex-col p-2">
<View className="flex flex-col px-2">
{keys.map((docId) => {
if (!locker.content[`document:${docId}`]) {
return null;
Expand Down
95 changes: 95 additions & 0 deletions apps/app/src/rnr/components/primitives/avatar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import * as React from 'react';
import {
ImageErrorEventData,
ImageLoadEventData,
NativeSyntheticEvent,
Image as RNImage,
View,
} from 'react-native';
import * as Slot from '~/components/primitives/slot';
import { ComponentPropsWithAsChild, SlottableViewProps, ViewRef } from '~/components/primitives/types';
import { AvatarImageProps, AvatarRootProps } from './types';

type AvatarState = 'loading' | 'error' | 'loaded';

interface IRootContext extends AvatarRootProps {
status: AvatarState;
setStatus: (status: AvatarState) => void;
}

const RootContext = React.createContext<IRootContext | null>(null);

const Root = React.forwardRef<ViewRef, SlottableViewProps & AvatarRootProps>(
({ asChild, alt, ...viewProps }, ref) => {
const [status, setStatus] = React.useState<AvatarState>('loading');
const Component = asChild ? Slot.View : View;
return (
<RootContext.Provider value={{ alt, status, setStatus }}>
<Component ref={ref} {...viewProps} />
</RootContext.Provider>
);
}
);

Root.displayName = 'RootAvatar';

function useRootContext() {
const context = React.useContext(RootContext);
if (!context) {
throw new Error('Avatar compound components cannot be rendered outside the Avatar component');
}
return context;
}

const Image = React.forwardRef<
React.ElementRef<typeof RNImage>,
Omit<ComponentPropsWithAsChild<typeof RNImage>, 'alt'> & AvatarImageProps
>(
(
{ asChild, onLoad: onLoadProps, onError: onErrorProps, onLoadingStatusChange, ...props },
ref
) => {
const { alt, setStatus, status } = useRootContext();

const onLoad = React.useCallback(
(e: NativeSyntheticEvent<ImageLoadEventData>) => {
setStatus('loaded');
onLoadingStatusChange?.('loaded');
onLoadProps?.(e);
},
[onLoadProps]
);

const onError = React.useCallback(
(e: NativeSyntheticEvent<ImageErrorEventData>) => {
setStatus('error');
onLoadingStatusChange?.('error');
onErrorProps?.(e);
},
[onErrorProps]
);

if (status === 'error') {
return null;
}

const Component = asChild ? Slot.Image : RNImage;
return <Component ref={ref} alt={alt} onLoad={onLoad} onError={onError} {...props} />;
}
);

Image.displayName = 'ImageAvatar';

const Fallback = React.forwardRef<ViewRef, SlottableViewProps>(({ asChild, ...props }, ref) => {
const { alt, status } = useRootContext();

if (status !== 'error') {
return null;
}
const Component = asChild ? Slot.View : View;
return <Component ref={ref} role={'img'} aria-label={alt} {...props} />;
});

Fallback.displayName = 'FallbackAvatar';

export { Fallback, Image, Root };
10 changes: 10 additions & 0 deletions apps/app/src/rnr/components/primitives/avatar/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
interface AvatarRootProps {
alt: string;
}

interface AvatarImageProps {
children?: React.ReactNode;
onLoadingStatusChange?: (status: 'error' | 'loaded') => void;
}

export type { AvatarRootProps, AvatarImageProps };
44 changes: 44 additions & 0 deletions apps/app/src/rnr/components/ui/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as React from 'react';
import * as AvatarPrimitive from '~/components/primitives/avatar';
import { cn } from '~/lib/utils';

const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', className)}
{...props}
/>
));
Avatar.displayName = AvatarPrimitive.Root.displayName;

const AvatarImage = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Image>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Image
ref={ref}
className={cn('aspect-square h-full w-full', className)}
{...props}
/>
));
AvatarImage.displayName = AvatarPrimitive.Image.displayName;

const AvatarFallback = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Fallback>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Fallback
ref={ref}
className={cn(
'flex h-full w-full items-center justify-center rounded-full bg-muted',
className
)}
{...props}
/>
));
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;

export { Avatar, AvatarFallback, AvatarImage };
4 changes: 4 additions & 0 deletions apps/app/src/rnr/lib/icons/PanelLeft.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { PanelLeft } from "lucide-react-native";
import { iconWithClassName } from "./iconWithClassName";
iconWithClassName(PanelLeft);
export { PanelLeft };

0 comments on commit daa3f9d

Please sign in to comment.