Skip to content

Commit

Permalink
navigator: add wip components (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
truckermudgeon authored Jan 24, 2025
1 parent 6d11eee commit 5aa54c6
Show file tree
Hide file tree
Showing 53 changed files with 8,525 additions and 1,625 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ packages/apps/*/public/sprites*.*
.DS_Store
npm-debug.log*
tsconfig.tsbuildinfo
.eslintcache
.eslintcache
*storybook.log
1 change: 0 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export default [
'out',
'**/build',
'**/public',
'**/vitest.config.ts',
'**/find-route-worker-wrapper.js',
],
},
Expand Down
7,441 changes: 5,819 additions & 1,622 deletions package-lock.json

Large diffs are not rendered by default.

41 changes: 41 additions & 0 deletions packages/apis/navigation/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { z } from 'zod';

export enum PoiType {
COMPANY,
FUEL,
REST,
SERVICE,
DEALER,
RECRUITING,
}

export enum ScopeType {
NEARBY,
ROUTE,
}

export const enum BranchType {
THROUGH,
SLIGHT_LEFT,
LEFT,
SHARP_LEFT,
U_TURN_LEFT,
SLIGHT_RIGHT = 11,
RIGHT,
SHARP_RIGHT,
U_TURN_RIGHT,
MERGE = -1,
}

const RouteSegmentSchema = z.object({
key: z.string(),
lonLats: z.array(z.tuple([z.number(), z.number()])),
distance: z.number(),
time: z.number(),
strategy: z.enum(['shortest', 'smallRoads']),
});

export const RouteSchema = z.object({
id: z.string(),
segments: z.array(RouteSegmentSchema),
});
7 changes: 6 additions & 1 deletion packages/apis/navigation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"scripts": {
"start": "npx tsx index.ts"
},
"exports": {
"./constants": "./constants.ts",
"./types": "./types.ts"
},
"devDependencies": {
"@types/express": "^4.17.21",
"typescript": "^5.4.2"
Expand All @@ -21,6 +25,7 @@
"socket.io": "^4.7.4",
"socket.io-client": "^4.7.4",
"spl.js": "^0.1.0",
"tsx": "^4.7.0"
"tsx": "^4.7.0",
"zod": "^3.24.1"
}
}
39 changes: 39 additions & 0 deletions packages/apis/navigation/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { z } from 'zod';
import type { BranchType, RouteSchema } from './constants';

export interface RouteDirection {
direction: BranchType;
distanceMeters: number;
name?: {
icon?: string;
text?: string;
};
laneHint?: LaneHint;
thenHint?: ThenHint;
}

interface LaneHint {
lanes: {
branches: BranchType[];
activeBranch?: BranchType;
}[];
}

interface ThenHint {
direction: BranchType;
}

export interface SearchResult {
nodeUid: string;
lonLat: [number, number];
distanceMeters: number; // as the crow flies
bearing: number;
name: string;
logoUrl: string;
city: string;
state: string;
isCityStateApproximate: boolean;
facilityUrls: string[];
}

export type Route = z.infer<typeof RouteSchema>;
36 changes: 36 additions & 0 deletions packages/apps/navigator/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { StorybookConfig } from '@storybook/react-vite';

import { dirname, join } from 'path';

/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
function getAbsolutePath(value: string): string {
return dirname(require.resolve(join(value, 'package.json')));
}
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],

addons: [
getAbsolutePath('@storybook/addon-onboarding'),
getAbsolutePath('@storybook/addon-essentials'),
getAbsolutePath('@chromatic-com/storybook'),
getAbsolutePath('@storybook/addon-interactions'),
getAbsolutePath('@storybook/addon-themes'),
],

framework: {
name: getAbsolutePath('@storybook/react-vite'),
options: {},
},

staticDirs: ['../public'],

docs: {},

typescript: {
reactDocgen: 'react-docgen-typescript',
},
};
export default config;
71 changes: 71 additions & 0 deletions packages/apps/navigator/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import '@fontsource/inter';
import { CssBaseline, CssVarsProvider, useColorScheme } from '@mui/joy';
import {
THEME_ID as MATERIAL_THEME_ID,
Experimental_CssVarsProvider as MaterialCssVarsProvider,
experimental_extendTheme as materialExtendTheme,
} from '@mui/material/styles';
import type { Preview, StoryContext } from '@storybook/react';
import type { ReactNode } from 'react';
import * as React from 'react';
import { useEffect } from 'react';

const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},

//tags: ['autodocs'],
};

export const globalTypes = {
theme: {
name: 'Theme',
title: 'Theme',
defaultValue: 'light',
toolbar: {
icon: 'paintbrush',
dynamicTitle: true,
items: [
{ value: 'light', title: 'Light mode' },
{ value: 'dark', title: 'Dark mode' },
],
},
},
};

const materialTheme = materialExtendTheme();

export const decorators = [
(Story: () => React.JSX.Element, context: StoryContext) => {
const { theme } = context.globals;

return (
<MaterialCssVarsProvider theme={{ [MATERIAL_THEME_ID]: materialTheme }}>
<CssVarsProvider>
<CssBaseline />
<ThemedStoryWrapper theme={theme as 'light' | 'dark'}>
<Story />
</ThemedStoryWrapper>
</CssVarsProvider>
</MaterialCssVarsProvider>
);
},
];

const ThemedStoryWrapper = (props: {
children?: ReactNode;
theme: 'light' | 'dark';
}) => {
const { setMode } = useColorScheme();
useEffect(() => setMode(props.theme), [props.theme, setMode]);

return <>{props.children}</>;
};

export default preview;
18 changes: 18 additions & 0 deletions packages/apps/navigator/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1 maximum-scale=1"
/>
<meta name="theme-color" content="#000000" />
<meta name="description" content="Navigator" />
<title>Navigator</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
55 changes: 55 additions & 0 deletions packages/apps/navigator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"private": true,
"name": "@truckermudgeon/navigator-app",
"version": "0.0.0",
"license": "GPL-3.0-or-later",
"type": "module",
"scripts": {
"start": "vite",
"build": "tsc && vite build",
"serve": "vite preview",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"devDependencies": {
"@chromatic-com/storybook": "^3.2.3",
"@storybook/addon-essentials": "^8.5.0",
"@storybook/addon-interactions": "^8.5.0",
"@storybook/addon-onboarding": "^8.5.0",
"@storybook/addon-themes": "^8.5.0",
"@storybook/blocks": "^8.5.0",
"@storybook/react": "^8.5.0",
"@storybook/react-vite": "^8.5.0",
"@storybook/test": "^8.5.0",
"@types/color": "^4.2.0",
"@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18",
"@vitejs/plugin-react": "^4.2.1",
"jsdom": "^25.0.1",
"storybook": "^8.5.0",
"typescript": "^5.4.2",
"vite": "^5.0.11",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-pwa": "^0.21.1",
"vite-tsconfig-paths": "^5.0.1"
},
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@fontsource/inter": "^5.0.16",
"@mui/icons-material": "^5.15.13",
"@mui/joy": "^5.0.0-beta.31",
"@mui/material": "^5.15.13",
"@trpc/client": "^10.45.2",
"@truckermudgeon/base": "^0.0.0",
"@truckermudgeon/ui": "^0.0.0",
"color": "^4.2.3",
"maplibre-gl": "^3.6.2",
"mobx": "^6.12.0",
"mobx-react-lite": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-map-gl": "^7.1.7",
"react-transition-group": "^4.4.5"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import { CollapsibleButtonBar } from './CollapsibleButtonBar';

const meta = {
title: 'Search/Collapsible Route Buttons',
component: CollapsibleButtonBar,
parameters: {
layout: 'centered',
},
} satisfies Meta<typeof CollapsibleButtonBar>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Visible: Story = {
args: {
visible: true,
onDestinationRoutesClick: fn(),
onDestinationGoClick: fn(),
},
};

export const Hidden: Story = {
args: {
visible: false,
onDestinationRoutesClick: fn(),
onDestinationGoClick: fn(),
},
};
41 changes: 41 additions & 0 deletions packages/apps/navigator/src/components/CollapsibleButtonBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { AltRoute } from '@mui/icons-material';
import { Button, ButtonGroup } from '@mui/joy';
import { Collapse } from '@mui/material';

export const CollapsibleButtonBar = (props: {
visible: boolean;
onDestinationRoutesClick: () => void;
onDestinationGoClick: () => void;
}) => {
console.log('render collapsible button bar');
return (
<Collapse in={props.visible}>
<ButtonGroup
variant={'outlined'}
size={'lg'}
buttonFlex={'1 0 50%'}
sx={{ mt: 2, mb: 1 }}
>
<Button
startDecorator={<AltRoute />}
onClick={e => {
props.onDestinationRoutesClick();
e.stopPropagation();
}}
>
Routes
</Button>
<Button
variant={'solid'}
color={'success'}
onClick={e => {
props.onDestinationGoClick();
e.stopPropagation();
}}
>
Go!
</Button>
</ButtonGroup>
</Collapse>
);
};
Loading

0 comments on commit 5aa54c6

Please sign in to comment.