Skip to content

Commit

Permalink
feat(web): setup basic widget ui (#1302)
Browse files Browse the repository at this point in the history
  • Loading branch information
airslice authored Dec 11, 2024
1 parent 05953eb commit daa169c
Show file tree
Hide file tree
Showing 20 changed files with 1,756 additions and 1,018 deletions.
31 changes: 31 additions & 0 deletions server/pkg/builtin/manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2318,6 +2318,37 @@ extensions:
- id: creditUrl
type: url
title: Credit Url
- id: googleMapSearch
type: widget
name: Google Map Search (Experimental)
description: A widget that allows you to search for a location on the map using Google Maps.
singleOnly: true
widgetLayout:
defaultLocation:
zone: outer
section: left
area: top
schema:
groups:
- id: default
title: Google Map Search Widget
fields:
- id: apiToken
type: string
title: API Token
description: Google Maps API Key
- id: appearance
title: Appearance
fields:
- id: theme
type: string
title: Theme
defaultValue: light
choices:
- key: light
label: Light
- key: dark
label: Dark
- id: story
name: Story
type: story
Expand Down
21 changes: 21 additions & 0 deletions web/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "@reearth-widget-ui/styles/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": "tw-"
},
"aliases": {
"components": "@reearth-widget-ui/components",
"utils": "@reearth-widget-ui/utils",
"ui": "@reearth-widget-ui/components/ui",
"lib": "@reearth-widget-ui/lib",
"hooks": "@reearth-widget-ui/hooks"
},
"iconLibrary": "lucide"
}
9 changes: 9 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"@vitejs/plugin-react-swc": "3.5.0",
"@vitest/coverage-v8": "0.34.6",
"@welldone-software/why-did-you-render": "8.0.3",
"autoprefixer": "10.4.20",
"del-cli": "5.1.0",
"dotenv": "16.4.5",
"eslint": "9.9.1",
Expand All @@ -84,11 +85,13 @@
"jsdom": "25.0.0",
"lint-staged": "15.2.10",
"npm-run-all": "4.1.5",
"postcss": "8.4.49",
"prettier": "3.3.3",
"read-env": "2.0.0",
"rollup": "4.21.2",
"rollup-plugin-visualizer": "5.12.0",
"storybook": "8.2.9",
"tailwindcss": "3.4.15",
"ts-node": "10.9.2",
"type-fest": "4.26.0",
"typescript": "5.5.4",
Expand Down Expand Up @@ -124,6 +127,7 @@
"@lexical/utils": "0.12.0",
"@monaco-editor/react": "4.6.0",
"@popperjs/core": "2.11.8",
"@radix-ui/react-slot": "1.1.0",
"@reearth/core": "0.0.7-alpha.22",
"@rot1024/use-transition": "1.0.0",
"@sentry/browser": "7.77.0",
Expand All @@ -134,6 +138,8 @@
"aws-amplify": "5.3.11",
"axios": "1.7.7",
"cesium": "1.118.0",
"class-variance-authority": "0.7.1",
"clsx": "2.1.1",
"core-js": "3.38.1",
"crypto-js": "4.2.0",
"dayjs": "1.11.13",
Expand All @@ -149,6 +155,7 @@
"lexical": "0.12.2",
"localforage": "1.10.0",
"lodash-es": "4.17.21",
"lucide-react": "0.462.0",
"quickjs-emscripten": "0.24.0",
"quickjs-emscripten-sync": "1.5.2",
"rc-slider": "9.7.5",
Expand All @@ -173,6 +180,8 @@
"react18-json-view": "0.2.8",
"remark-gfm": "4.0.0",
"sortablejs": "1.15.3",
"tailwind-merge": "2.5.5",
"tailwindcss-animate": "1.0.7",
"tinycolor2": "1.6.0",
"ts-easing": "0.2.0",
"use-file-input": "1.0.0",
Expand Down
6 changes: 6 additions & 0 deletions web/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
1 change: 1 addition & 0 deletions web/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { AuthProvider } from "./services/auth";
import { Provider as GqlProvider } from "./services/gql";
import { AppRoutes } from "./services/routing";
import { Provider as ThemeProvider } from "./services/theme";
import "@reearth-widget-ui/styles/globals.css";

export default function App() {
return (
Expand Down
1 change: 1 addition & 0 deletions web/src/beta/features/Navbar/useRightSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const TabButton = styled("button")<{ selected?: boolean }>(
alignItems: "flex-start",
justifyContent: "center",
padding: `${theme.spacing.smallest}px ${theme.spacing.small}px`,
fontSize: `${theme.fonts.sizes.body}px`,
gap: theme.spacing.small,
borderRadius: theme.radius.small,
color: selected ? theme.content.main : theme.content.weak,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Card } from "@reearth/beta/lib/reearth-widget-ui/components/ui/card";
import { Input } from "@reearth/beta/lib/reearth-widget-ui/components/ui/input";
import { Search } from "lucide-react";
import { FC, useMemo } from "react";

import type { ComponentProps as WidgetProps } from "../..";
import { CommonBuiltInWidgetProperty } from "../types";

type Property = CommonBuiltInWidgetProperty & {
default?: {
apiToken?: string;
};
};
type GoogleMapSearchProps = WidgetProps<Property>;

const GoogleMapSearch: FC<GoogleMapSearchProps> = ({ widget }) => {
const theme = useMemo(
() => widget.property?.appearance?.theme ?? "light",
[widget.property?.appearance?.theme]
);

return (
<div className={theme}>
<Card className="tw-pl-3 tw-w-[400px] tw-flex tw-items-center tw-bg-background tw-text-foreground tw-rounded-md tw-border-0">
<span className="tw-text-foreground">
<Search className="tw-w-5 tw-h-5" />
</span>
<Input
className={"tw-border-0"}
placeholder="Type a keyword to search..."
/>
</Card>
</div>
);
};

export default GoogleMapSearch;
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import {
BUTTON_BUILTIN_WIDGET_ID,
DATA_ATTRIBUTION_WIDGET_ID,
GOOGLE_MAP_SEARCH_BUILTIN_WIDGET_ID,
NAVIGATOR_BUILTIN_WIDGET_ID
} from "@reearth/services/api/widgetsApi/utils";
import { config } from "@reearth/services/config";
import { merge } from "lodash-es";

import Button from "./Button";
import DataAttribution from "./DataAttribution";
import GoogleMapSearch from "./GoogleMapSearch";
import Navigator from "./Navigator";
// import Timeline from "./Timeline";
import {
Component,
unsafeBuiltinWidgets,
Expand All @@ -18,9 +19,9 @@ import {

export type ReEarthBuiltinWidgets<T = unknown> = Record<
| typeof BUTTON_BUILTIN_WIDGET_ID
// | typeof TIMELINE_BUILTIN_WIDGET_ID
| typeof NAVIGATOR_BUILTIN_WIDGET_ID
| typeof DATA_ATTRIBUTION_WIDGET_ID,
| typeof DATA_ATTRIBUTION_WIDGET_ID
| typeof GOOGLE_MAP_SEARCH_BUILTIN_WIDGET_ID,
T
>;

Expand All @@ -30,23 +31,21 @@ export type BuiltinWidgets<T = unknown> = ReEarthBuiltinWidgets<T> &
const REEARTH_BUILTIN_WIDGET_OPTIONS: BuiltinWidgets<{ animation?: boolean }> =
{
[BUTTON_BUILTIN_WIDGET_ID]: {},
// [TIMELINE_BUILTIN_WIDGET_ID]: {
// animation: true,
// },
[NAVIGATOR_BUILTIN_WIDGET_ID]: {
animation: true
},
[DATA_ATTRIBUTION_WIDGET_ID]: {}
[DATA_ATTRIBUTION_WIDGET_ID]: {},
[GOOGLE_MAP_SEARCH_BUILTIN_WIDGET_ID]: {}
};

const BUILTIN_WIDGET_OPTIONS: BuiltinWidgets<{ animation?: boolean }> =
REEARTH_BUILTIN_WIDGET_OPTIONS;

const reearthBuiltin: BuiltinWidgets<Component> = {
[BUTTON_BUILTIN_WIDGET_ID]: Button,
// [TIMELINE_BUILTIN_WIDGET_ID]: Timeline,
[NAVIGATOR_BUILTIN_WIDGET_ID]: Navigator,
[DATA_ATTRIBUTION_WIDGET_ID]: DataAttribution
[DATA_ATTRIBUTION_WIDGET_ID]: DataAttribution,
[GOOGLE_MAP_SEARCH_BUILTIN_WIDGET_ID]: GoogleMapSearch
};

let cachedBuiltin:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type CommonBuiltInWidgetProperty = {
appearance?: {
theme?: "light" | "dark";
};
};
1 change: 1 addition & 0 deletions web/src/beta/lib/reearth-ui/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const StyledButton = styled("button")<{
? `${theme.primary.main}`
: `${theme.dangerous.main}`
}`,
fontSize: `${theme.fonts.sizes.body}px`,
padding:
size === "small"
? iconButton
Expand Down
56 changes: 56 additions & 0 deletions web/src/beta/lib/reearth-widget-ui/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Slot } from "@radix-ui/react-slot";
import { cn } from "@reearth-widget-ui/utils";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";

const buttonVariants = cva(
"tw-inline-flex tw-items-center tw-justify-center tw-gap-2 tw-whitespace-nowrap tw-rounded-md tw-text-sm tw-font-medium tw-transition-colors focus-visible:tw-outline-none focus-visible:tw-ring-1 focus-visible:tw-ring-ring disabled:tw-pointer-events-none disabled:tw-opacity-50 [&_svg]:tw-pointer-events-none [&_svg]:tw-size-4 [&_svg]:tw-shrink-0",
{
variants: {
variant: {
default:
"tw-bg-primary tw-text-primary-foreground tw-shadow hover:tw-bg-primary/90",
destructive:
"tw-bg-destructive tw-text-destructive-foreground tw-shadow-sm hover:tw-bg-destructive/90",
outline:
"tw-border tw-border-input tw-bg-background tw-shadow-sm hover:tw-bg-accent hover:tw-text-accent-foreground",
secondary:
"tw-bg-secondary tw-text-secondary-foreground tw-shadow-sm hover:tw-bg-secondary/80",
ghost: "hover:tw-bg-accent hover:tw-text-accent-foreground",
link: "tw-text-primary tw-underline-offset-4 hover:tw-underline"
},
size: {
default: "tw-h-9 tw-px-4 tw-py-2",
sm: "tw-h-8 tw-rounded-md tw-px-3 tw-text-xs",
lg: "tw-h-10 tw-rounded-md tw-px-8",
icon: "tw-h-9 tw-w-9"
}
},
defaultVariants: {
variant: "default",
size: "default"
}
}
);

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = "Button";

export { Button, buttonVariants };
85 changes: 85 additions & 0 deletions web/src/beta/lib/reearth-widget-ui/components/ui/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { cn } from "@reearth-widget-ui/utils";
import * as React from "react";

const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"tw-rounded-md tw-border tw-bg-card tw-text-card-foreground tw-shadow",
className
)}
{...props}
/>
));
Card.displayName = "Card";

const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("tw-flex tw-flex-col tw-space-y-1.5 tw-p-6", className)}
{...props}
/>
));
CardHeader.displayName = "CardHeader";

const CardTitle = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"tw-font-semibold tw-leading-none tw-tracking-tight",
className
)}
{...props}
/>
));
CardTitle.displayName = "CardTitle";

const CardDescription = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("tw-text-sm tw-text-muted-foreground", className)}
{...props}
/>
));
CardDescription.displayName = "CardDescription";

const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("tw-p-6 tw-pt-0", className)} {...props} />
));
CardContent.displayName = "CardContent";

const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("tw-flex tw-items-center tw-p-6 tw-pt-0", className)}
{...props}
/>
));
CardFooter.displayName = "CardFooter";

export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardDescription,
CardContent
};
Loading

0 comments on commit daa169c

Please sign in to comment.