Skip to content

Commit f9c3db5

Browse files
committed
fix: animations and styling
1 parent e50836e commit f9c3db5

File tree

12 files changed

+180
-78
lines changed

12 files changed

+180
-78
lines changed
Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { VStack } from '@chakra-ui/react';
2-
import React from 'react'
2+
import React from 'react';
33
import { IOForm } from '../../types/response';
44
import { FormView } from './FormView';
55

@@ -9,10 +9,11 @@ interface Props {
99
}
1010

1111
export const CompositeFormView: React.FC<Props> = ({ name, form }) => {
12-
return <VStack gap={2}>
13-
{Object.entries(form).map(([key, value]) => <FormView
14-
key={key}
15-
name={`${name}.${key}`}
16-
view={value} />)}
17-
</VStack>
18-
}
12+
return (
13+
<VStack gap={2} alignItems="stretch">
14+
{Object.entries(form).map(([key, value]) => (
15+
<FormView key={key} name={`${name}.${key}`} view={value} />
16+
))}
17+
</VStack>
18+
);
19+
};
Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,46 @@
1-
import { TableContainer, Table, TableCaption, Thead, Tr, Th, Tbody, Td, Checkbox, Radio, RadioGroup } from '@chakra-ui/react';
2-
import React from 'react'
1+
import {
2+
TableContainer,
3+
Table,
4+
TableCaption,
5+
Thead,
6+
Tr,
7+
Th,
8+
Tbody,
9+
Td,
10+
Checkbox,
11+
Radio,
12+
RadioGroup,
13+
} from '@chakra-ui/react';
14+
import React from 'react';
315

416
interface Props {
517
helperText?: string;
618
name: string;
719
headers: string[];
820
isMultiSelect: boolean;
921
initialSelection?: string[];
10-
rows: { key: string; cells: string[] }[]
22+
rows: { key: string; cells: string[] }[];
1123
}
1224

13-
export const TableInput: React.FC<Props> = ({
14-
name,
15-
headers,
16-
isMultiSelect,
17-
initialSelection,
18-
helperText,
19-
rows,
20-
}) => {
25+
export const TableInput: React.FC<Props> = ({ name, headers, isMultiSelect, initialSelection, helperText, rows }) => {
2126
const renderCheckbox = (rowKey: string) => {
22-
return isMultiSelect ? <Checkbox name={name} value={rowKey} defaultChecked={initialSelection?.includes(rowKey)} /> : <Radio name={name} value={rowKey} defaultChecked={initialSelection?.includes(rowKey)} />;
23-
}
27+
return isMultiSelect ? (
28+
<Checkbox name={name} value={rowKey} defaultChecked={initialSelection?.includes(rowKey)} />
29+
) : (
30+
<Radio name={name} value={rowKey} defaultChecked={initialSelection?.includes(rowKey)} />
31+
);
32+
};
2433

2534
return (
2635
<RadioGroup name={name}>
27-
<TableContainer backgroundColor="white" boxShadow='sm' border="1px solid" borderColor='gray.200' borderRadius='md'>
28-
<Table variant='simple'>
36+
<TableContainer
37+
backgroundColor="white"
38+
boxShadow="sm"
39+
border="1px solid"
40+
borderColor="gray.200"
41+
borderRadius="md"
42+
>
43+
<Table variant="simple">
2944
<TableCaption>{helperText}</TableCaption>
3045
<Thead>
3146
<Tr>
@@ -40,9 +55,7 @@ export const TableInput: React.FC<Props> = ({
4055
{rows.map((row) => (
4156
<Tr key={row.key}>
4257
{/* checkbox */}
43-
<Td>
44-
{renderCheckbox(row.key)}
45-
</Td>
58+
<Td>{renderCheckbox(row.key)}</Td>
4659
{row.cells.map((cell) => (
4760
<Td key={cell}>{cell}</Td>
4861
))}
@@ -52,5 +65,5 @@ export const TableInput: React.FC<Props> = ({
5265
</Table>
5366
</TableContainer>
5467
</RadioGroup>
55-
)
56-
}
68+
);
69+
};

packages/actions-app/app/components/layout/Page.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
import { HStack, Flex, Text, } from '@chakra-ui/react';
1+
import { HStack, Flex, Text } from '@chakra-ui/react';
2+
import { useTransition } from '@remix-run/react';
3+
import { motion } from 'framer-motion';
24

35
import React from 'react';
46

57
interface Props {
68
title?: string[] | string;
79
links?: { link: string; label: string }[];
10+
animationKey?: string;
811
}
912

1013
const HEADER_HEIGHT = '60px';
1114

12-
export const Page: React.FC<React.PropsWithChildren<Props>> = ({ title, children }) => {
15+
export const Page: React.FC<React.PropsWithChildren<Props>> = ({ title, children, animationKey }) => {
16+
const transition = useTransition();
1317
const titles = Array.isArray(title) ? title : [title];
1418
return (
1519
<Flex flexDirection="column" height="100vh">
@@ -23,7 +27,15 @@ export const Page: React.FC<React.PropsWithChildren<Props>> = ({ title, children
2327
</HStack>
2428
</HStack>
2529
<Flex flex={1} backgroundColor="gray.50" p={10}>
26-
{children}
30+
<motion.main
31+
key={animationKey}
32+
initial={{ x: '-10%', opacity: 0 }}
33+
animate={{ x: '0', opacity: 1 }}
34+
exit={{ y: '-10%', opacity: 0 }}
35+
transition={{ duration: 0.4 }}
36+
>
37+
{transition.state !== 'loading' && children}
38+
</motion.main>
2739
</Flex>
2840
</Flex>
2941
);

packages/actions-app/app/components/main/Sidebar.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ interface LinkItemProps {
2222
to: `/${string}`;
2323
}
2424
const LinkItems: LinkItemProps[] = [
25-
{ name: 'Actions', icon: 'fa:home', to: '/actions' },
25+
// { name: 'Actions', icon: 'fa:home', to: '/actions' },
2626
// { name: "Settings", icon: "fa:cog", to: "/settings" },
2727
];
2828

@@ -64,10 +64,11 @@ const SidebarContent = ({ onClose, ...rest }: SidebarProps) => {
6464
w={{ base: 'full', md: 60 }}
6565
pos="fixed"
6666
h="full"
67+
zIndex={2}
6768
{...rest}
6869
>
6970
<Flex h="20" alignItems="center" mx="8" justifyContent="space-between">
70-
<Text fontSize="2xl" fontFamily="monospace" fontWeight="bold">
71+
<Text as={RemixLink} fontSize="2xl" fontFamily="monospace" fontWeight="bold" to={getUrl('/actions')}>
7172
Actions
7273
</Text>
7374
<CloseButton display={{ base: 'flex', md: 'none' }} onClick={onClose} />

packages/actions-app/app/root.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
import { AnimatePresence } from 'framer-motion';
12
import React, { useContext, useEffect } from 'react';
23
import { withEmotionCache } from '@emotion/react';
3-
import { ChakraProvider, GlobalStyle } from '@chakra-ui/react';
4+
import { ChakraProvider } from '@chakra-ui/react';
45
import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration, useCatch, useLoaderData } from '@remix-run/react';
56
import { MetaFunction, LinksFunction, json } from '@remix-run/node';
67

78
import { ServerStyleContext, ClientStyleContext } from './context';
89

910
export const meta: MetaFunction = () => ({
1011
charset: 'utf-8',
11-
title: 'ActionsZ',
12+
title: 'Actions',
1213
viewport: 'width=device-width,initial-scale=1',
1314
});
1415

@@ -78,8 +79,9 @@ export default function App() {
7879
return (
7980
<Document>
8081
<ChakraProvider>
81-
<GlobalStyle />
82-
<Outlet />
82+
<AnimatePresence exitBeforeEnter>
83+
<Outlet />
84+
</AnimatePresence>
8385
</ChakraProvider>
8486
</Document>
8587
);

packages/actions-app/app/routes/actions.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Outlet } from '@remix-run/react';
2-
import type { LoaderFunction } from '@remix-run/server-runtime';
2+
import type { LoaderFunction, MetaFunction } from '@remix-run/server-runtime';
33
import { json } from '@remix-run/server-runtime';
44

55
import { AppContainer } from '../components/main/AppContainer';
@@ -9,6 +9,12 @@ type LoaderData = {
99
userId: string;
1010
};
1111

12+
export const meta: MetaFunction = () => {
13+
return {
14+
title: 'Actions',
15+
};
16+
};
17+
1218
export const loader: LoaderFunction = async ({ request }) => {
1319
const userId = await requireUserId(request);
1420
return json<LoaderData>({ userId });

packages/actions-app/app/routes/actions/$actionId.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Button } from '@chakra-ui/react';
2-
import type { LoaderFunction } from '@remix-run/node';
2+
import type { LoaderFunction, MetaFunction } from '@remix-run/node';
33
import { json } from '@remix-run/node';
4-
import { Link, useLoaderData } from '@remix-run/react';
4+
import { Link, useLoaderData, useLocation } from '@remix-run/react';
55
import invariant from 'tiny-invariant';
66

77
import { Page } from '../../components/layout/Page';
@@ -15,6 +15,12 @@ type LoaderData = {
1515
action: Action;
1616
};
1717

18+
export const meta: MetaFunction<LoaderData> = ({ data }) => {
19+
return {
20+
title: `${data.action.title} | Actions`,
21+
};
22+
};
23+
1824
export const loader: LoaderFunction = async ({ params, context = DEFAULT_CONTEXT }) => {
1925
context = defaultContext(context);
2026
invariant(params.actionId, 'actionId not found');
@@ -27,7 +33,7 @@ export default function ActionDetailsPage() {
2733
const { action, actionId } = useLoaderData() as LoaderData;
2834

2935
return (
30-
<Page title={['Actions', action.title]}>
36+
<Page title={['Actions', action.title]} animationKey={useLocation().pathname}>
3137
<Button as={Link} colorScheme="blue" to={getUrl(`/actions/${actionId}/workflows/new`)}>
3238
New
3339
</Button>

packages/actions-app/app/routes/actions/$actionId.workflows.$workflowId.tsx

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
1-
import { Alert, AlertDescription, AlertIcon, AlertTitle, Button, HStack, SimpleGrid, Spinner, Stack, Stat, StatHelpText, StatLabel, Table, TableContainer, Tbody, Td, Text, Tr, VStack } from '@chakra-ui/react';
2-
import type { ActionFunction, LoaderFunction } from '@remix-run/node';
1+
import {
2+
Alert,
3+
AlertDescription,
4+
AlertIcon,
5+
AlertTitle,
6+
Button,
7+
SimpleGrid,
8+
Table,
9+
TableContainer,
10+
Tbody,
11+
Td,
12+
Text,
13+
Tr,
14+
VStack,
15+
} from '@chakra-ui/react';
16+
import type { ActionFunction, LoaderFunction, MetaFunction } from '@remix-run/node';
317
import { json } from '@remix-run/node';
4-
import { Form, useActionData, useLoaderData, useSearchParams, useTransition } from '@remix-run/react';
18+
import { Form, useActionData, useLoaderData, useLocation, useSearchParams, useTransition } from '@remix-run/react';
519
import invariant from 'tiny-invariant';
620

721
import { FormView } from '../../components/forms/FormView';
@@ -54,6 +68,12 @@ export const action: ActionFunction = async ({ request, params, context }) => {
5468
return json<LoaderData>({ action, ...response });
5569
};
5670

71+
export const meta: MetaFunction<LoaderData> = ({ data }) => {
72+
return {
73+
title: `${data.action.title} | Actions`,
74+
};
75+
};
76+
5777
export default function WorkflowDetailsPage() {
5878
const { view, workflowId, breadcrumbs, action } = useLoaderData() as LoaderData;
5979
const [search] = useSearchParams();
@@ -66,32 +86,34 @@ export default function WorkflowDetailsPage() {
6686
const loading = transition.state === 'loading' || transition.state === 'submitting';
6787

6888
return (
69-
<Page title={['Actions', action.title, `Workflow ${workflowId.slice(0, 8)}`]}>
89+
<Page title={['Actions', action.title, `Workflow ${workflowId.slice(0, 8)}`]} animationKey={useLocation().key}>
7090
<SimpleGrid columns={2} spacing={10}>
7191
<Form method="post">
7292
<VStack alignItems="flex-start" spacing={6}>
73-
{loading && <Spinner size='lg' />}
74-
{!loading && <FormView name={ROOT} view={currentView} />}
75-
{hasNext && !loading && (
76-
<Button colorScheme="teal" variant="solid" type="submit">
93+
<FormView name={ROOT} view={currentView} />
94+
{hasNext && (
95+
<Button isLoading={loading} colorScheme="teal" variant="solid" type="submit">
7796
Submit
7897
</Button>
7998
)}
8099
</VStack>
81100
</Form>
82101
<VStack alignItems="flex-end" spacing={6}>
83-
<TableContainer backgroundColor="white" boxShadow='sm' border="1px solid" borderColor='gray.200' borderRadius='md'>
84-
<Table variant='simple'>
102+
<TableContainer
103+
backgroundColor="white"
104+
boxShadow="sm"
105+
border="1px solid"
106+
borderColor="gray.200"
107+
borderRadius="md"
108+
>
109+
<Table variant="simple">
85110
<Tbody>
86111
{breadcrumbs.map((breadcrumb, idx) => (
87112
<Tr key={`${breadcrumb.key}-${idx}`}>
88-
<Td >
89-
<Text fontWeight={600}>
90-
{breadcrumb.key}
91-
</Text>
92-
</Td>
93-
<Td>{breadcrumb.value}
113+
<Td>
114+
<Text fontWeight={600}>{breadcrumb.key}</Text>
94115
</Td>
116+
<Td>{breadcrumb.value}</Td>
95117
</Tr>
96118
))}
97119
</Tbody>
@@ -101,7 +123,9 @@ export default function WorkflowDetailsPage() {
101123
<Alert status="info" flexDirection="column" alignSelf="flex-start">
102124
<AlertIcon />
103125
<AlertTitle>Debug</AlertTitle>
104-
<AlertDescription sx={{ whiteSpace: 'pre' }}>{JSON.stringify({ view, workflowId, breadcrumbs }, null, 2)}</AlertDescription>
126+
<AlertDescription sx={{ whiteSpace: 'pre' }}>
127+
{JSON.stringify({ view, workflowId, breadcrumbs }, null, 2)}
128+
</AlertDescription>
105129
</Alert>
106130
)}
107131
</VStack>

0 commit comments

Comments
 (0)