A design system in a box. hip-ui.tngl.io/docs/introduction
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

breadcrumbs

+333 -15
+5 -3
.cursor/rules/hip-component.mdc
··· 2 2 alwaysApply: false 3 3 --- 4 4 5 + You are an expert design system engineer who is well versed in both https://stylexjs.com/ and https://react-spectrum.adobe.com/react-aria/getting-started.html. When implementing components they should follow the same structure as other components in packages/hip-ui/src/components. 6 + 5 7 To create a new hip component follow these steps: 6 8 7 9 1. First ask if there is some docs for a headless component to look at 8 10 2. create a component in packages/hip-ui/src/components 9 11 3. Create a config for that component 10 - 4. Write it's config in the new component's dir 12 + 4. Write its config in the new component's dir 11 13 5. Add the config to packages/hip-ui/src/cli/install 12 14 6. Run the build 13 15 7. Run `pnpm hip install --all` in the apps/docs dir ··· 15 17 16 18 ## Rules 17 19 18 - - Prefer using packages/hip-ui/src/components/flex and packages/hip-ui/src/components/grid over css 20 + - Prefer using packages/hip-ui/src/components/flex and packages/hip-ui/src/components/grid over css for things layout related 19 21 - Use icon from lucide-react 20 - - Prefer re-using existing component rather than redefining them inside each component 22 + - Prefer re-using existing component rather than redefining them
+9 -4
README.md
··· 20 20 - [ ] Alert / Callout 21 21 - [ ] Carousel 22 22 - [ ] Empty 23 - - [ ] Input Group 24 23 - [ ] Input OTP 25 24 - [ ] Resizable 26 25 - [ ] Skeleton ··· 36 35 - [ ] Drawer 37 36 - [ ] Sheet 38 37 39 - - [ ] Breadcrumb 40 38 - [ ] Disclosure 41 39 - [ ] Disclosure Group 42 - - [ ] Field 43 40 - [ ] Form 44 41 - [ ] Grid List 45 - - [ ] Item 46 42 - [ ] Menubar 47 43 - [ ] Navigation Menu 48 44 - [ ] Spinner ··· 50 46 - [ ] Toolbar 51 47 - [ ] Toast 52 48 49 + ### Maybe 50 + 51 + - [ ] Field 52 + - [ ] Item 53 + 54 + ### Done 55 + 56 + - [x] Input Group 57 + - [x] Breadcrumb 53 58 - [x] Range Date Picker 54 59 - [x] Date Picker 55 60 - [x] Calendar
+98
apps/docs/src/components/breadcrumbs/index.tsx
··· 1 + import * as stylex from "@stylexjs/stylex"; 2 + import { ChevronRight } from "lucide-react"; 3 + import { 4 + Breadcrumbs as AriaBreadcrumbs, 5 + BreadcrumbsProps as AriaBreadcrumbsProps, 6 + Breadcrumb as AriaBreadcrumb, 7 + BreadcrumbProps as AriaBreadcrumbProps, 8 + } from "react-aria-components"; 9 + 10 + import { uiColor } from "../theme/semantic-color.stylex"; 11 + import { spacing } from "../theme/spacing.stylex"; 12 + import { StyleXComponentProps } from "../theme/types"; 13 + import { fontWeight } from "../theme/typography.stylex"; 14 + 15 + const styles = stylex.create({ 16 + breadcrumbs: { 17 + alignItems: "center", 18 + display: "flex", 19 + gap: spacing["1"], 20 + listStyle: "none", 21 + margin: 0, 22 + padding: 0, 23 + }, 24 + breadcrumb: { 25 + alignItems: "center", 26 + color: { 27 + default: uiColor.text2, 28 + ":is([data-current])": uiColor.text1, 29 + }, 30 + display: "flex", 31 + fontWeight: { 32 + default: fontWeight.normal, 33 + ":is([data-current])": fontWeight.medium, 34 + }, 35 + gap: spacing["1"], 36 + }, 37 + separator: { 38 + alignItems: "center", 39 + color: uiColor.text2, 40 + display: { 41 + default: "flex", 42 + ":is([data-breadcrumb]:last-child *)": "none", 43 + }, 44 + opacity: { 45 + ":is([data-disabled])": 0.5, 46 + }, 47 + }, 48 + disabled: { 49 + opacity: 0.5, 50 + pointerEvents: "none", 51 + }, 52 + }); 53 + 54 + export interface BreadcrumbsProps<T extends object = object> 55 + extends StyleXComponentProps<Omit<AriaBreadcrumbsProps<T>, "children">> { 56 + isDisabled?: boolean; 57 + children?: React.ReactNode; 58 + } 59 + 60 + export interface BreadcrumbProps 61 + extends StyleXComponentProps<Omit<AriaBreadcrumbProps, "children">> { 62 + children?: React.ReactNode; 63 + } 64 + 65 + export function Breadcrumbs<T extends object = object>({ 66 + style, 67 + isDisabled, 68 + ...props 69 + }: BreadcrumbsProps<T>) { 70 + return ( 71 + <AriaBreadcrumbs 72 + {...props} 73 + data-disabled={isDisabled ? "" : undefined} 74 + {...stylex.props( 75 + styles.breadcrumbs, 76 + isDisabled && styles.disabled, 77 + style, 78 + )} 79 + /> 80 + ); 81 + } 82 + 83 + export function Breadcrumb({ style, ...props }: BreadcrumbProps) { 84 + return ( 85 + <AriaBreadcrumb 86 + {...props} 87 + {...stylex.props(styles.breadcrumb, style)} 88 + data-breadcrumb 89 + > 90 + {props.children} 91 + <ChevronRight 92 + size={16} 93 + aria-hidden="true" 94 + {...stylex.props(styles.separator)} 95 + /> 96 + </AriaBreadcrumb> 97 + ); 98 + }
+14 -4
apps/docs/src/components/link/index.tsx
··· 5 5 Link as AriaLink, 6 6 } from "react-aria-components"; 7 7 8 - import { primaryColor } from "../theme/semantic-color.stylex"; 8 + import { primaryColor, uiColor } from "../theme/semantic-color.stylex"; 9 + import { spacing } from "../theme/spacing.stylex"; 9 10 import { StyleXComponentProps } from "../theme/types"; 10 11 import { fontFamily, fontWeight } from "../theme/typography.stylex"; 11 12 import { LinkContext } from "./link-context"; 12 13 13 14 const styles = stylex.create({ 14 15 link: { 15 - color: primaryColor.text2, 16 - cursor: "pointer", 16 + color: { 17 + default: primaryColor.text2, 18 + ":is([data-breadcrumb] *)": uiColor.text1, 19 + ":is([data-breadcrumb][data-current] *)": uiColor.text2, 20 + }, 21 + cursor: { 22 + default: "default", 23 + ":is([data-hovered])": "pointer", 24 + }, 17 25 fontFamily: fontFamily["sans"], 18 26 fontWeight: fontWeight["normal"], 19 27 textDecoration: { 20 28 default: "none", 21 - ":hover": "underline", 29 + ":is([data-hovered])": "underline", 30 + ":is([data-breadcrumb] *)": "none", 22 31 }, 32 + textUnderlineOffset: spacing["1"], 23 33 }, 24 34 }); 25 35
+40
apps/docs/src/docs/components/breadcrumbs.mdx
··· 1 + --- 2 + title: Breadcrumbs 3 + description: Breadcrumbs display a hierarchy of links to the current page or resource in an application. 4 + --- 5 + 6 + import { PropDocs } from '../../lib/PropDocs' 7 + import { Example } from '../../lib/Example' 8 + import { Basic } from '../../examples/breadcrumbs/basic' 9 + import { Disabled } from '../../examples/breadcrumbs/disabled' 10 + 11 + <Example src={Basic} /> 12 + 13 + ## Installation 14 + 15 + Run the following command to add the breadcrumbs component to your project. 16 + 17 + ```bash 18 + pnpm hip install breadcrumbs 19 + ``` 20 + 21 + ## Props 22 + 23 + This component is built using the [React Aria Breadcrumbs](https://react-spectrum.adobe.com/react-aria/Breadcrumbs.html). 24 + 25 + <PropDocs components={["Breadcrumbs", "Breadcrumb"]} /> 26 + 27 + ## Features 28 + 29 + ### Disabled State 30 + 31 + Breadcrumbs can be disabled to prevent interaction. 32 + 33 + <Example src={Disabled} /> 34 + 35 + ## Related Components 36 + 37 + - [Link](/docs/components/link) - For individual navigation links 38 + - [Button](/docs/components/button) - For action buttons 39 + - [IconButton](/docs/components/icon-button) - For icon-only navigation buttons 40 +
+18
apps/docs/src/examples/breadcrumbs/basic.tsx
··· 1 + import { Breadcrumbs, Breadcrumb } from "@/components/breadcrumbs"; 2 + import { Link } from "@/components/link"; 3 + 4 + export function Basic() { 5 + return ( 6 + <Breadcrumbs> 7 + <Breadcrumb> 8 + <Link href="/">Home</Link> 9 + </Breadcrumb> 10 + <Breadcrumb> 11 + <Link href="/react-aria/">React Aria</Link> 12 + </Breadcrumb> 13 + <Breadcrumb> 14 + <Link>Breadcrumbs</Link> 15 + </Breadcrumb> 16 + </Breadcrumbs> 17 + ); 18 + }
+18
apps/docs/src/examples/breadcrumbs/disabled.tsx
··· 1 + import { Breadcrumbs, Breadcrumb } from "@/components/breadcrumbs"; 2 + import { Link } from "@/components/link"; 3 + 4 + export function Disabled() { 5 + return ( 6 + <Breadcrumbs isDisabled> 7 + <Breadcrumb> 8 + <Link href="/">Home</Link> 9 + </Breadcrumb> 10 + <Breadcrumb> 11 + <Link href="/react-aria/">React Aria</Link> 12 + </Breadcrumb> 13 + <Breadcrumb> 14 + <Link>Breadcrumbs</Link> 15 + </Breadcrumb> 16 + </Breadcrumbs> 17 + ); 18 + }
+2
packages/hip-ui/src/cli/install.tsx
··· 12 12 import { aspectRatioConfig } from "../components/aspect-ratio/aspect-ratio-config.js"; 13 13 import { avatarConfig } from "../components/avatar/avatar-config.js"; 14 14 import { badgeConfig } from "../components/badge/badge-config.js"; 15 + import { breadcrumbsConfig } from "../components/breadcrumbs/breadcrumbs-config.js"; 15 16 import { buttonGroupConfig } from "../components/button-group/button-group-config.js"; 16 17 import { buttonConfig } from "../components/button/button-config.js"; 17 18 import { calendarConfig } from "../components/calendar/calendar-config.js"; ··· 106 107 dialogConfig, 107 108 avatarConfig, 108 109 badgeConfig, 110 + breadcrumbsConfig, 109 111 gridConfig, 110 112 switchConfig, 111 113 aspectRatioConfig,
+17
packages/hip-ui/src/components/breadcrumbs/breadcrumbs-config.ts
··· 1 + import { ComponentConfig } from "../../types"; 2 + 3 + export const breadcrumbsConfig: ComponentConfig = { 4 + name: "breadcrumbs", 5 + filepath: "./index.tsx", 6 + hipDependencies: [ 7 + "../theme/semantic-color.stylex.tsx", 8 + "../theme/spacing.stylex.tsx", 9 + "../theme/typography.stylex.tsx", 10 + "../link/index.tsx", 11 + ], 12 + dependencies: { 13 + "react-aria-components": "^1.13.0", 14 + "lucide-react": "^0.263.1", 15 + }, 16 + }; 17 +
+98
packages/hip-ui/src/components/breadcrumbs/index.tsx
··· 1 + import * as stylex from "@stylexjs/stylex"; 2 + import { ChevronRight } from "lucide-react"; 3 + import { 4 + Breadcrumbs as AriaBreadcrumbs, 5 + BreadcrumbsProps as AriaBreadcrumbsProps, 6 + Breadcrumb as AriaBreadcrumb, 7 + BreadcrumbProps as AriaBreadcrumbProps, 8 + } from "react-aria-components"; 9 + 10 + import { uiColor } from "../theme/semantic-color.stylex"; 11 + import { spacing } from "../theme/spacing.stylex"; 12 + import { StyleXComponentProps } from "../theme/types"; 13 + import { fontWeight } from "../theme/typography.stylex"; 14 + 15 + const styles = stylex.create({ 16 + breadcrumbs: { 17 + alignItems: "center", 18 + display: "flex", 19 + gap: spacing["1"], 20 + listStyle: "none", 21 + margin: 0, 22 + padding: 0, 23 + }, 24 + breadcrumb: { 25 + alignItems: "center", 26 + color: { 27 + default: uiColor.text2, 28 + ":is([data-current])": uiColor.text1, 29 + }, 30 + display: "flex", 31 + fontWeight: { 32 + default: fontWeight.normal, 33 + ":is([data-current])": fontWeight.medium, 34 + }, 35 + gap: spacing["1"], 36 + }, 37 + separator: { 38 + alignItems: "center", 39 + color: uiColor.text2, 40 + display: { 41 + default: "flex", 42 + ":is([data-breadcrumb]:last-child *)": "none", 43 + }, 44 + opacity: { 45 + ":is([data-disabled])": 0.5, 46 + }, 47 + }, 48 + disabled: { 49 + opacity: 0.5, 50 + pointerEvents: "none", 51 + }, 52 + }); 53 + 54 + export interface BreadcrumbsProps<T extends object = object> 55 + extends StyleXComponentProps<Omit<AriaBreadcrumbsProps<T>, "children">> { 56 + isDisabled?: boolean; 57 + children?: React.ReactNode; 58 + } 59 + 60 + export interface BreadcrumbProps 61 + extends StyleXComponentProps<Omit<AriaBreadcrumbProps, "children">> { 62 + children?: React.ReactNode; 63 + } 64 + 65 + export function Breadcrumbs<T extends object = object>({ 66 + style, 67 + isDisabled, 68 + ...props 69 + }: BreadcrumbsProps<T>) { 70 + return ( 71 + <AriaBreadcrumbs 72 + {...props} 73 + data-disabled={isDisabled ? "" : undefined} 74 + {...stylex.props( 75 + styles.breadcrumbs, 76 + isDisabled && styles.disabled, 77 + style, 78 + )} 79 + /> 80 + ); 81 + } 82 + 83 + export function Breadcrumb({ style, ...props }: BreadcrumbProps) { 84 + return ( 85 + <AriaBreadcrumb 86 + {...props} 87 + {...stylex.props(styles.breadcrumb, style)} 88 + data-breadcrumb 89 + > 90 + {props.children} 91 + <ChevronRight 92 + size={16} 93 + aria-hidden="true" 94 + {...stylex.props(styles.separator)} 95 + /> 96 + </AriaBreadcrumb> 97 + ); 98 + }
+14 -4
packages/hip-ui/src/components/link/index.tsx
··· 5 5 Link as AriaLink, 6 6 } from "react-aria-components"; 7 7 8 - import { primaryColor } from "../theme/semantic-color.stylex"; 8 + import { primaryColor, uiColor } from "../theme/semantic-color.stylex"; 9 + import { spacing } from "../theme/spacing.stylex"; 9 10 import { StyleXComponentProps } from "../theme/types"; 10 11 import { fontFamily, fontWeight } from "../theme/typography.stylex"; 11 12 import { LinkContext } from "./link-context"; 12 13 13 14 const styles = stylex.create({ 14 15 link: { 15 - color: primaryColor.text2, 16 - cursor: "pointer", 16 + color: { 17 + default: primaryColor.text2, 18 + ":is([data-breadcrumb] *)": uiColor.text1, 19 + ":is([data-breadcrumb][data-current] *)": uiColor.text2, 20 + }, 21 + cursor: { 22 + default: "default", 23 + ":is([data-hovered])": "pointer", 24 + }, 17 25 fontFamily: fontFamily["sans"], 18 26 fontWeight: fontWeight["normal"], 19 27 textDecoration: { 20 28 default: "none", 21 - ":hover": "underline", 29 + ":is([data-hovered])": "underline", 30 + ":is([data-breadcrumb] *)": "none", 22 31 }, 32 + textUnderlineOffset: spacing["1"], 23 33 }, 24 34 }); 25 35