diff --git a/apps/design-system/src/components/docs-page/code-block.tsx b/apps/design-system/src/components/docs-page/code-block.tsx new file mode 100644 index 000000000..29e67d052 --- /dev/null +++ b/apps/design-system/src/components/docs-page/code-block.tsx @@ -0,0 +1,20 @@ +import { FC } from 'react' + +import { MarkdownViewer } from '@harnessio/ui/components' + +export interface CodeBlockProps { + code: string + language?: string +} + +const CodeBlock: FC = ({ code, language = 'typescript tsx' }) => ( + +) + +export default CodeBlock diff --git a/apps/design-system/src/components/docs-page/docs-page.tsx b/apps/design-system/src/components/docs-page/docs-page.tsx index 42fd1bddc..5f3bdaf0b 100644 --- a/apps/design-system/src/components/docs-page/docs-page.tsx +++ b/apps/design-system/src/components/docs-page/docs-page.tsx @@ -1,13 +1,19 @@ +import CodeBlock from './code-block.tsx' import ComponentExample from './component-example' import Example from './example' +import PropsTable from './props-table.tsx' import Root from './root' import Section from './section' +import SubSection from './sub-section.tsx' import Summary from './summary' export const DocsPage = { Root, Summary, Section, + SubSection, Example, - ComponentExample + ComponentExample, + CodeBlock, + PropsTable } diff --git a/apps/design-system/src/components/docs-page/props-table.tsx b/apps/design-system/src/components/docs-page/props-table.tsx new file mode 100644 index 000000000..8b8aeb204 --- /dev/null +++ b/apps/design-system/src/components/docs-page/props-table.tsx @@ -0,0 +1,37 @@ +import { FC } from 'react' + +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@harnessio/ui/components' + +interface PropDescription { + name: string + required?: boolean + defaultValue?: string + description?: string +} + +export interface PropsTableProps { + props: PropDescription[] +} + +const PropsTable: FC = ({ props }) => ( + + + + Prop + Required + Default + + + + {props.map(({ name, required, defaultValue, description }) => ( + + {name} + {required ? 'yup' : 'nope'} + {defaultValue} + + ))} + +
+) + +export default PropsTable diff --git a/apps/design-system/src/components/docs-page/section.module.css b/apps/design-system/src/components/docs-page/section.module.css new file mode 100644 index 000000000..ae4721f4d --- /dev/null +++ b/apps/design-system/src/components/docs-page/section.module.css @@ -0,0 +1,5 @@ +.section { + display: flex; + flex-direction: column; + gap: 1rem; +} diff --git a/apps/design-system/src/components/docs-page/section.tsx b/apps/design-system/src/components/docs-page/section.tsx index 395cdc7b7..0d7d92a0a 100644 --- a/apps/design-system/src/components/docs-page/section.tsx +++ b/apps/design-system/src/components/docs-page/section.tsx @@ -2,13 +2,15 @@ import { FC, PropsWithChildren, ReactNode } from 'react' import { Text } from '@harnessio/ui/components' +import css from './section.module.css' + export interface SectionProps extends PropsWithChildren { title: string description?: ReactNode } const Section: FC = ({ title, description, children }) => ( -
+
{title} diff --git a/apps/design-system/src/components/docs-page/sub-section.tsx b/apps/design-system/src/components/docs-page/sub-section.tsx new file mode 100644 index 000000000..90db2c3a6 --- /dev/null +++ b/apps/design-system/src/components/docs-page/sub-section.tsx @@ -0,0 +1,22 @@ +import { FC, PropsWithChildren, ReactNode } from 'react' + +import { Text } from '@harnessio/ui/components' + +import css from './section.module.css' + +export interface SubSectionProps extends PropsWithChildren { + title: string + description?: ReactNode +} + +const SubSection: FC = ({ title, description, children }) => ( +
+ + {title} + + {description} + {children} +
+) + +export default SubSection diff --git a/apps/design-system/src/pages/view-preview/root-view-wrapper.tsx b/apps/design-system/src/pages/view-preview/root-view-wrapper.tsx index 31551abd9..57549ac17 100644 --- a/apps/design-system/src/pages/view-preview/root-view-wrapper.tsx +++ b/apps/design-system/src/pages/view-preview/root-view-wrapper.tsx @@ -3,16 +3,7 @@ import { Outlet, Route, Routes } from 'react-router-dom' import { noop, useThemeStore, useTranslationsStore } from '@utils/viewUtils' -import { - Breadcrumb, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbSeparator, - Navbar, - NavbarItemType, - Topbar -} from '@harnessio/ui/components' +import { Breadcrumb, Navbar, NavbarItemType, Topbar } from '@harnessio/ui/components' import { SandboxLayout } from '@harnessio/ui/views' const RootViewWrapper: FC> = ({ children, asChild = false }) => { @@ -62,19 +53,19 @@ const RootViewWrapper: FC> = ({ childre
- - - - Lorem - - - - Ipsum - - - Dolor - - + + + + Lorem + + + + Ipsum + + + Dolor + +
diff --git a/apps/design-system/src/subjects/components/breadcrumb.tsx b/apps/design-system/src/subjects/components/breadcrumb.tsx new file mode 100644 index 000000000..35d393157 --- /dev/null +++ b/apps/design-system/src/subjects/components/breadcrumb.tsx @@ -0,0 +1,170 @@ +import { DocsPage } from '@components/docs-page/docs-page' + +const BreadcrumbComponent = () => ( + + +

+ A breadcrumbs is a list of links that help visualize the location of a page within the hierarchical structure of + a site, it allows navigation up to any of the ancestors. +

+
+ + + + + Lorem + + + + + + Ipsum + + + Dolor + + + `} + /> + + +

All parts of the breadcrumb can be imported and composed as required.

+ + + + + Lorem + + + + + + Ipsum + + + Dolor + +`} + /> +
+ + + +

The `Root` component wraps the breadcrumb with a `nav` tag for use as page navigation.

+ +
+ + +

The `List` component adds styling to ensure the breadcrumb is displayed inline as a list.

+ + {/* Pass Breadcrumb.Item, Breadcrumb.Separator and Breadcrumb.Page elements as children */} +`} + /> + +
+ + +

The `Item` component displays its contents as a node within the breadcrumb.

+ + {/* Pass text, JSX elements or Breadcrumb.Link elements as children */} +`} + /> + +
+ + +

+ The `Link` component can be passed as a child to an `Item` component to display a clickable breadcrumb item. +

+ + + Lorem + + + + + + + +`} + /> + +
+ + +

+ The `Page` component displays its contents as a node within the breadcrumb with styling to denote that it is + the current page. +

+ Lorem ipsum`} /> + +
+ + +

The `Separator` component displays a separator between the items of the breadcrumb.

+ + + + Lorem ipsum + + + + > +`} + /> + +
+ + +

The `Ellipsis` component displays an ellipsis for use when there are too many items to display.

+ `} /> + +
+
+
+) + +export default BreadcrumbComponent diff --git a/apps/design-system/src/subjects/components/componentPages.ts b/apps/design-system/src/subjects/components/componentPages.ts index e145a7e8e..12dbeedab 100644 --- a/apps/design-system/src/subjects/components/componentPages.ts +++ b/apps/design-system/src/subjects/components/componentPages.ts @@ -1,8 +1,9 @@ import type { RouteProps } from 'react-router-dom' -import AlertComponent from '@subjects/components/alert' -import BadgeComponent from '@subjects/components/badge' -import ButtonComponent from '@subjects/components/button' +import AlertComponent from './alert' +import BadgeComponent from './badge' +import BreadcrumbComponent from './breadcrumb' +import ButtonComponent from './button' interface ComponentPage { name: string @@ -13,5 +14,6 @@ interface ComponentPage { export const componentPages: ComponentPage[] = [ { name: 'Alert', path: 'alert', Component: AlertComponent }, { name: 'Badge', path: 'badge', Component: BadgeComponent }, + { name: 'Breadcrumb', path: 'breadcrumb', Component: BreadcrumbComponent }, { name: 'Button', path: 'button', Component: ButtonComponent } ] diff --git a/apps/gitness/src/components-v2/breadcrumbs/breadcrumbs.tsx b/apps/gitness/src/components-v2/breadcrumbs/breadcrumbs.tsx index 802f9d66f..3dfca19d2 100644 --- a/apps/gitness/src/components-v2/breadcrumbs/breadcrumbs.tsx +++ b/apps/gitness/src/components-v2/breadcrumbs/breadcrumbs.tsx @@ -1,13 +1,6 @@ import { useMatches } from 'react-router-dom' -import { - Breadcrumb, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbSeparator, - Topbar -} from '@harnessio/ui/components' +import { Breadcrumb, Topbar } from '@harnessio/ui/components' import { CustomHandle } from '../../framework/routing/types' @@ -17,8 +10,8 @@ function Breadcrumbs() { return ( - - + + {matches.map((match, index) => { const { breadcrumb } = (match.handle || {}) as CustomHandle const isFirst = index === 1 @@ -27,18 +20,18 @@ function Breadcrumbs() { if (!breadcrumb) return null return ( - - {!isFirst ? : null} + + {!isFirst ? : null} {isLast ? ( breadcrumb(match.params) ) : ( - {breadcrumb(match.params)} + {breadcrumb(match.params)} )} - + ) })} - - + + ) diff --git a/apps/gitness/src/components/breadcrumbs/breadcrumb-dropdown.tsx b/apps/gitness/src/components/breadcrumbs/breadcrumb-dropdown.tsx index dc10f60f2..240575769 100644 --- a/apps/gitness/src/components/breadcrumbs/breadcrumb-dropdown.tsx +++ b/apps/gitness/src/components/breadcrumbs/breadcrumb-dropdown.tsx @@ -1,8 +1,8 @@ +import { ReactNode } from 'react' import { Link } from 'react-router-dom' import { - BreadcrumbItem, - BreadcrumbLink, + Breadcrumb, DropdownMenu, DropdownMenuContent, DropdownMenuItem, @@ -15,7 +15,7 @@ export interface BreadcrumbDropdownProps { selectedValue?: string | number selectedItem?: { path: string; label: string; value: string | number; key: string } placeholder?: string - icon: React.ReactNode + icon: ReactNode } export const BreadcrumbDropdown = (props: BreadcrumbDropdownProps) => { @@ -23,11 +23,11 @@ export const BreadcrumbDropdown = (props: BreadcrumbDropdownProps) => { const selectedItem = selectedItemProps ?? items.find(item => item.value === selectedValue) return ( - + {icon} - + {selectedItem ? ( {selectedItem.label} @@ -37,7 +37,7 @@ export const BreadcrumbDropdown = (props: BreadcrumbDropdownProps) => { {placeholder} )} - + <> @@ -55,6 +55,6 @@ export const BreadcrumbDropdown = (props: BreadcrumbDropdownProps) => { - + ) } diff --git a/apps/gitness/src/components/breadcrumbs/breadcrumbs.tsx b/apps/gitness/src/components/breadcrumbs/breadcrumbs.tsx index 7cef01237..6005622b5 100644 --- a/apps/gitness/src/components/breadcrumbs/breadcrumbs.tsx +++ b/apps/gitness/src/components/breadcrumbs/breadcrumbs.tsx @@ -1,17 +1,7 @@ import { useMemo } from 'react' import { Link, useLocation, useParams } from 'react-router-dom' -import { - Avatar, - AvatarFallback, - Breadcrumb, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbPage, - BreadcrumbSeparator, - Topbar -} from '@harnessio/ui/components' +import { Avatar, AvatarFallback, Breadcrumb, Topbar } from '@harnessio/ui/components' import { useAppContext } from '../../framework/context/AppContext' import { useGetSpaceURLParam } from '../../framework/hooks/useGetSpaceParam' @@ -70,16 +60,16 @@ export default function Breadcrumbs() { const getBreadcrumbSegment = ({ label, path, isLast }: { label?: string; path: string; isLast: boolean }) => { return ( <> - - + + {!isLast ? ( - + {label} - + ) : ( - {label} + {label} )} - + ) } @@ -87,8 +77,8 @@ export default function Breadcrumbs() { return ( - - + + {spacesBreadcrumbProps ? : null} {isProjectRoute && spaces ? ( @@ -170,8 +160,8 @@ export default function Breadcrumbs() { })} ) : null} - - + + ) diff --git a/apps/gitness/src/routes.tsx b/apps/gitness/src/routes.tsx index 2a3cc2eda..5a55858a9 100644 --- a/apps/gitness/src/routes.tsx +++ b/apps/gitness/src/routes.tsx @@ -1,6 +1,6 @@ import { Navigate } from 'react-router-dom' -import { BreadcrumbSeparator, Text } from '@harnessio/ui/components' +import { Breadcrumb, Text } from '@harnessio/ui/components' import { EmptyPage, RepoSettingsPage, SandboxLayout } from '@harnessio/ui/views' import AppShell from './components-v2/app-shell' @@ -458,7 +458,7 @@ export const routes: CustomRouteObject[] = [ breadcrumb: () => ( <> Account - + Users ) @@ -471,7 +471,7 @@ export const routes: CustomRouteObject[] = [ breadcrumb: () => ( <> User - + Settings ) diff --git a/packages/ui/src/components/breadcrumb.tsx b/packages/ui/src/components/breadcrumb.tsx index 643b5ab48..a7e03df75 100644 --- a/packages/ui/src/components/breadcrumb.tsx +++ b/packages/ui/src/components/breadcrumb.tsx @@ -4,14 +4,14 @@ import { DotsHorizontalIcon } from '@radix-ui/react-icons' import { Slot } from '@radix-ui/react-slot' import { cn } from '@utils/cn' -type BreadcrumbProps = ComponentPropsWithoutRef<'nav'> & { +type BreadcrumbRootProps = ComponentPropsWithoutRef<'nav'> & { separator?: ReactNode } -const Breadcrumb = forwardRef(({ ...props }, ref) => { +const BreadcrumbRoot = forwardRef(({ ...props }, ref) => { return