diff --git a/example/nextjs/pages/index.tsx b/example/nextjs/pages/index.tsx index 85d773a..3d6ceec 100644 --- a/example/nextjs/pages/index.tsx +++ b/example/nextjs/pages/index.tsx @@ -1,7 +1,8 @@ -import { OpenApi, Sidebar, utils } from "@raystack/chronicle"; +import { OpenApi, Sidebar, utils, Navbar } from "@raystack/chronicle"; import { readApiYaml } from "../utils/index"; import { Inter } from "next/font/google"; import { SidebarConfig, readSidebarConfig } from "@/utils/sidebar"; +import Link from "next/link"; const inter = Inter({ subsets: ["latin"] }); @@ -14,13 +15,35 @@ export const getStaticProps = async () => { export default function Home({ schema, sidebarConfig }: { schema: any; sidebarConfig: SidebarConfig }) { return ( -
-
- +
+ + Products + , + + Solutions + , + ]} + rightActionItems={[ + + Docs + , + + Blogs + , + ]} + /> +
+
+ +
+
+ +
-
- -
); } diff --git a/package-lock.json b/package-lock.json index 556ca7c..e2d7940 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3731,6 +3731,42 @@ } } }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.3.tgz", + "integrity": "sha512-x4Uv0N47ABx3/frJazYXxvMpZeKJe0qmRIgQ2o3lhTqnTVg+CaZfVVO4nQLn3QJcDkTz8icElKffhFng47XIBA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.2.tgz", @@ -4113,6 +4149,10 @@ "resolved": "packages/chronicle", "link": true }, + "node_modules/@raystack/chronicle-parser": { + "resolved": "packages/parser", + "link": true + }, "node_modules/@rollup/plugin-commonjs": { "version": "25.0.2", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.2.tgz", @@ -8313,6 +8353,14 @@ "node": ">=0.10.0" } }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -19265,8 +19313,10 @@ "@apidevtools/json-schema-ref-parser": "^10.1.0", "@apidevtools/swagger-parser": "^10.1.0", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-navigation-menu": "^1.1.3", "@radix-ui/react-select": "^1.2.2", "@radix-ui/react-tabs": "^1.0.4", + "clsx": "^1.2.1", "js-yaml": "^4.1.0", "openapi-to-postmanv2": "^4.14.0", "openapi-types": "^12.1.3", @@ -19309,6 +19359,11 @@ "vite-plugin-node-polyfills": "^0.9.0", "vitest": "^0.32.2" } + }, + "packages/parser": { + "name": "@raystack/chronicle-parser", + "version": "1.0.0", + "license": "Apache-2.0" } } } diff --git a/packages/chronicle/package.json b/packages/chronicle/package.json index 0077cbf..58ee0fa 100644 --- a/packages/chronicle/package.json +++ b/packages/chronicle/package.json @@ -63,8 +63,10 @@ "@apidevtools/json-schema-ref-parser": "^10.1.0", "@apidevtools/swagger-parser": "^10.1.0", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-navigation-menu": "^1.1.3", "@radix-ui/react-select": "^1.2.2", "@radix-ui/react-tabs": "^1.0.4", + "clsx": "^1.2.1", "js-yaml": "^4.1.0", "openapi-to-postmanv2": "^4.14.0", "openapi-types": "^12.1.3", diff --git a/packages/chronicle/src/Container/index.tsx b/packages/chronicle/src/Container/index.tsx new file mode 100644 index 0000000..e69de29 diff --git a/packages/chronicle/src/Navbar/index.tsx b/packages/chronicle/src/Navbar/index.tsx new file mode 100644 index 0000000..c8266d3 --- /dev/null +++ b/packages/chronicle/src/Navbar/index.tsx @@ -0,0 +1,66 @@ +import React, { ReactNode } from "react"; +import styles from "./styles.module.css"; +import * as NavigationMenu from "@radix-ui/react-navigation-menu"; +import { CaretDownIcon } from "@radix-ui/react-icons"; +import clsx from "clsx"; + +interface NavbarProps { + logo?: ReactNode | string; + leftActionItems?: ReactNode[]; + rightActionItems?: ReactNode[]; + className?: string; +} + +interface MenuProps { + label: string; + items: ReactNode[]; + menuPosition?: "left" | "right"; +} + +export function Menu({ label, items, menuPosition }: MenuProps) { + const contentStyle = menuPosition === "right" ? { right: 0 } : { left: 0 }; + return ( +
+ + {label} + + +
    + {items?.map((item, i) => ( + + {item} + + ))} +
+
+
+ ); +} + +export function Root({ logo, leftActionItems = [], rightActionItems = [], className }: NavbarProps) { + return ( +
+
+
{logo}
+ +
    + {leftActionItems?.map((item, i) => ( + + {item} + + ))} +
+
+
+ +
    + {rightActionItems?.map((item, i) => ( + + {item} + + ))} +
+
+
+ ); +} diff --git a/packages/chronicle/src/Navbar/navbar.stories.tsx b/packages/chronicle/src/Navbar/navbar.stories.tsx new file mode 100644 index 0000000..8b1f0fd --- /dev/null +++ b/packages/chronicle/src/Navbar/navbar.stories.tsx @@ -0,0 +1,82 @@ +import React from "react"; +import type { Meta, StoryObj } from "@storybook/react"; +import * as Navbar from "./"; +import { SunIcon } from "@radix-ui/react-icons"; + +const meta: Meta = { + title: "Navbar", + component: Navbar.Root, +}; + +export default meta; +type Story = StoryObj; + +export const TextLogo: Story = { + args: { + logo: "Chronicle", + leftActionItems: [ + + Home + , + + Products + , + + Solutions + , + + Docs + , + + Blogs + , + + Github + , + ]} + />, + ], + rightActionItems: [ + + Docs + , + + Blogs + , + + Github + , + + Docs + , + + Blogs + , + + Github + , + ]} + />, + ], + }, +}; + +export const ComponentLogo: Story = { + args: { + logo: ( + <> + + Chronicle + + ), + }, +}; diff --git a/packages/chronicle/src/Navbar/styles.module.css b/packages/chronicle/src/Navbar/styles.module.css new file mode 100644 index 0000000..a225550 --- /dev/null +++ b/packages/chronicle/src/Navbar/styles.module.css @@ -0,0 +1,59 @@ +.Navbar { + width: 100%; + min-height: 48px; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 16px; + box-sizing: border-box; +} + +.Logo { + display: flex; + align-items: center; + margin-right: 16px; +} + +.ActionItem { + margin: 0 4px; + display: inline-flex; +} + +.List { + list-style: none; + display: flex; + justify-content: center; + position: relative; +} + +.NavigationMenuTrigger { + display: flex; + align-items: center; + justify-content: space-between; + gap: 2px; +} + +.NavigationMenuContent { + position: absolute; + width: max-content; + animation-duration: 250ms; + animation-timing-function: ease; + border: 0.5px solid rgba(0,0,0,0.1); + top: calc(100% + 2px); + padding: 8px; + background-color: white; +} + +.NavigationMenuContentList { + padding: 0; + display: flex; + flex-direction: column; +} + +.NavigationMenuContentListItem { + padding: 0; + display: flex; + flex-direction: column; + padding: 6px 16px; + text-decoration: none; +} \ No newline at end of file diff --git a/packages/chronicle/src/index.tsx b/packages/chronicle/src/index.tsx index 4ec47c6..69ba180 100644 --- a/packages/chronicle/src/index.tsx +++ b/packages/chronicle/src/index.tsx @@ -1,3 +1,4 @@ export * as OpenApi from "./OpenApi"; export * as Sidebar from "./Sidebar"; +export * as Navbar from "./Navbar"; export * as utils from "./utils";