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.

Content component

+374 -90
+6 -1
apps/docs/src/components/aspect-ratio/index.tsx
··· 73 73 React.ComponentProps<"img"> 74 74 > {} 75 75 76 - export function AspectRatioImage({ style, ...props }: AspectRatioImageProps) { 76 + export function AspectRatioImage({ 77 + style, 78 + children, 79 + ...props 80 + }: AspectRatioImageProps) { 77 81 return ( 78 82 <div {...stylex.props(styles.imageContainer, style)}> 79 83 {/* eslint-disable-next-line jsx-a11y/alt-text */} 80 84 <img {...props} {...stylex.props(styles.image, style)} /> 85 + {children} 81 86 </div> 82 87 ); 83 88 }
+77
apps/docs/src/components/content/index.tsx
··· 1 + import * as stylex from "@stylexjs/stylex"; 2 + 3 + import { spacing } from "../theme/spacing.stylex"; 4 + import { StyleXComponentProps } from "../theme/types"; 5 + import { lineHeight } from "../theme/typography.stylex"; 6 + 7 + const styles = stylex.create({ 8 + root: { 9 + /* eslint-disable @stylexjs/valid-styles, @stylexjs/no-legacy-contextual-styles */ 10 + 11 + ":is(*) > :is(:has(h1),h1)": { 12 + marginBottom: spacing["8"], 13 + marginTop: spacing["8"], 14 + }, 15 + ":is(*) > :is(:has(h2),h2)": { 16 + marginBottom: spacing["4"], 17 + marginTop: spacing["8"], 18 + }, 19 + ":is(*) > :is(:has(h3),h3)": { 20 + marginBottom: spacing["5"], 21 + marginTop: spacing["8"], 22 + }, 23 + ":is(*) > :is(:has(h4),h4)": { 24 + marginBottom: spacing["8"], 25 + marginTop: spacing["8"], 26 + }, 27 + ":is(*) > :is(:has(h5),h5)": { 28 + marginBottom: spacing["8"], 29 + marginTop: spacing["8"], 30 + }, 31 + ":is(*) > blockquote": { 32 + marginBottom: 0, 33 + marginLeft: spacing["2"], 34 + marginRight: 0, 35 + marginTop: 0, 36 + paddingLeft: spacing["4"], 37 + }, 38 + ":is(*) > p": { 39 + lineHeight: { 40 + default: lineHeight.xl, 41 + ":is(blockquote *)": lineHeight.base, 42 + ":is(li *)": lineHeight.base, 43 + }, 44 + marginBottom: { 45 + default: spacing["5"], 46 + ":is(blockquote *)": spacing["0"], 47 + ":is(li *)": spacing["0"], 48 + }, 49 + marginTop: { 50 + default: spacing["5"], 51 + ":is(blockquote *)": spacing["0"], 52 + ":is(li *)": spacing["0"], 53 + }, 54 + }, 55 + 56 + /* eslint-enable @stylexjs/valid-styles, @stylexjs/no-legacy-contextual-styles */ 57 + }, 58 + }); 59 + 60 + export interface ContentProps extends StyleXComponentProps< 61 + React.ComponentProps<"div"> 62 + > {} 63 + 64 + /** 65 + * A wrapper component that applies content spacing styles to child elements. 66 + * 67 + * @example 68 + * ```tsx 69 + * <Content> 70 + * <h1>Title</h1> 71 + * <p>Paragraph text</p> 72 + * </Content> 73 + * ``` 74 + */ 75 + export const Content = ({ style, ...props }: ContentProps) => { 76 + return <div {...props} {...stylex.props(styles.root, style)} />; 77 + };
+51 -39
apps/docs/src/components/table/index.tsx
··· 1 + import type { 2 + CellProps as AriaCellProps, 3 + ColumnProps as AriaColumnProps, 4 + RowProps as AriaRowProps, 5 + TableBodyProps as AriaTableBodyProps, 6 + TableHeaderProps as AriaTableHeaderProps, 7 + TableProps as AriaTableProps, 8 + DropIndicatorProps, 9 + } from "react-aria-components"; 10 + 1 11 import * as stylex from "@stylexjs/stylex"; 2 12 import { ArrowDown, ArrowUp, GripVertical } from "lucide-react"; 3 13 import { use } from "react"; 4 14 import { 5 - TableBodyProps as AriaTableBodyProps, 6 - TableBody as AriaTableBody, 7 - TableProps as AriaTableProps, 15 + Cell as AriaCell, 16 + Column as AriaColumn, 17 + Row as AriaRow, 8 18 Table as AriaTable, 19 + TableBody as AriaTableBody, 9 20 TableHeader as AriaTableHeader, 10 - TableHeaderProps as AriaTableHeaderProps, 11 - useTableOptions, 12 - Column as AriaColumn, 13 21 Collection, 14 - Row as AriaRow, 15 - RowProps as AriaRowProps, 16 - Cell as AriaCell, 17 - ColumnProps as AriaColumnProps, 18 - CellProps as AriaCellProps, 19 22 ColumnResizer, 20 - DropIndicatorProps, 21 23 DropIndicator, 22 24 TableLayout, 23 25 Virtualizer, 26 + useTableOptions, 24 27 } from "react-aria-components"; 28 + 29 + import type { Size, StyleXComponentProps } from "../theme/types"; 25 30 26 31 import { Checkbox } from "../checkbox"; 27 32 import { SizeContext } from "../context"; ··· 29 34 import { IconButton } from "../icon-button"; 30 35 import { primaryColor, uiColor } from "../theme/color.stylex"; 31 36 import { spacing } from "../theme/spacing.stylex"; 32 - import { Size, StyleXComponentProps } from "../theme/types"; 33 37 import { LabelText } from "../typography"; 34 38 35 39 const styles = stylex.create({ ··· 59 63 justifyContent: "space-between", 60 64 paddingLeft: { 61 65 default: spacing["2"], 62 - ":is(:first-child)": 0, 66 + ":is(:first-child > *)": spacing["2"], 63 67 }, 64 68 }, 65 69 tableBody: {}, ··· 90 94 ":is([data-table-size=md] *)": spacing["2"], 91 95 }, 92 96 paddingLeft: { 93 - default: spacing["2"], 97 + default: spacing["4"], 94 98 ":is([data-table-size=lg] *:not(:first-child))": spacing["4"], 95 99 ":is([data-table-size=md] *:not(:first-child))": spacing["3"], 96 100 }, 97 101 paddingRight: { 98 - default: spacing["2"], 102 + default: spacing["4"], 99 103 ":is([data-table-size=lg] *:not(:last-child))": spacing["4"], 100 104 ":is([data-table-size=md] *:not(:last-child))": spacing["3"], 101 105 }, ··· 178 182 ...props 179 183 }: TableProps) => { 180 184 const size = sizeProp || use(SizeContext); 181 - let table = <AriaTable {...props} {...stylex.props(styles.table, style)} />; 185 + let table = ( 186 + <AriaTable 187 + {...props} 188 + {...stylex.props(styles.table, style)} 189 + data-table-size={size} 190 + /> 191 + ); 182 192 183 193 if (isVirtualized) { 184 194 table = ( ··· 215 225 return ( 216 226 <AriaColumn {...props} {...stylex.props(styles.column, style)}> 217 227 {({ allowsSorting, sortDirection }) => ( 218 - <div {...stylex.props(styles.columnHeader, styles.cellContent)}> 219 - <Flex align="center" gap="1"> 220 - <LabelText 221 - tabIndex={hasResizer ? -1 : undefined} 222 - hasEllipsis={hasEllipsis} 223 - > 224 - {children} 225 - </LabelText> 226 - {allowsSorting && ( 227 - <span aria-hidden="true" className="sort-indicator"> 228 - {sortDirection === "ascending" ? ( 229 - <ArrowUp size={14} /> 230 - ) : sortDirection === "descending" ? ( 231 - <ArrowDown size={14} /> 232 - ) : null} 233 - </span> 228 + <div {...stylex.props(styles.columnHeader)}> 229 + <div {...stylex.props(styles.cellContent, styles.columnHeader)}> 230 + <Flex align="center" gap="1"> 231 + <LabelText 232 + tabIndex={hasResizer ? -1 : undefined} 233 + hasEllipsis={hasEllipsis} 234 + > 235 + {children} 236 + </LabelText> 237 + {allowsSorting && ( 238 + <span aria-hidden="true" className="sort-indicator"> 239 + {sortDirection === "ascending" ? ( 240 + <ArrowUp size={14} /> 241 + ) : sortDirection === "descending" ? ( 242 + <ArrowDown size={14} /> 243 + ) : null} 244 + </span> 245 + )} 246 + </Flex> 247 + {hasResizer && ( 248 + <ColumnResizer {...stylex.props(styles.resizer)}> 249 + <div {...stylex.props(styles.resizerLine)} /> 250 + </ColumnResizer> 234 251 )} 235 - </Flex> 236 - {hasResizer && ( 237 - <ColumnResizer {...stylex.props(styles.resizer)}> 238 - <div {...stylex.props(styles.resizerLine)} /> 239 - </ColumnResizer> 240 - )} 252 + </div> 241 253 </div> 242 254 )} 243 255 </AriaColumn>
+55
apps/docs/src/docs/components/content/content.mdx
··· 1 + --- 2 + title: Content 3 + description: A wrapper component that applies consistent spacing styles to content elements. 4 + --- 5 + 6 + import { PropDocs } from '../../../lib/PropDocs' 7 + import { Example } from '../../../lib/Example' 8 + import { Basic } from '../../../examples/content/basic' 9 + import { WithLists } from '../../../examples/content/with-lists' 10 + import { WithBlockquote } from '../../../examples/content/with-blockquote' 11 + 12 + <Example src={Basic} /> 13 + 14 + ## Installation 15 + 16 + Run the following command to add the content component to your project. 17 + 18 + ```bash 19 + pnpm hip install content 20 + ``` 21 + 22 + ## Props 23 + 24 + <PropDocs components={["Content"]} /> 25 + 26 + ## Features 27 + 28 + ### Automatic Spacing 29 + 30 + The Content component automatically applies consistent margins to child elements: 31 + 32 + - **Headings (h1-h5)**: Top and bottom margins for proper vertical rhythm 33 + - **Paragraphs**: Spacing between paragraphs, with adjusted spacing when nested in lists or blockquotes 34 + - **Blockquotes**: Left border, padding, and zero margins for proper indentation 35 + - **Lists**: Proper spacing maintained for list items 36 + 37 + ### With Lists 38 + 39 + The Content component handles spacing for both ordered and unordered lists: 40 + 41 + <Example src={WithLists} /> 42 + 43 + ### With Blockquotes 44 + 45 + Blockquotes receive special styling with proper indentation and spacing: 46 + 47 + <Example src={WithBlockquote} /> 48 + 49 + 50 + ## Related Components 51 + 52 + - [Typography](/docs/components/content/typography) - For semantic typography components 53 + - [Text](/docs/components/content/text) - For flexible text styling 54 + - [Card](/docs/components/content/card) - For grouping content in containers 55 +
+25
apps/docs/src/examples/content/basic.tsx
··· 1 + import { Content } from "@/components/content"; 2 + import { Body, Heading1, Heading2, Heading3 } from "@/components/typography"; 3 + 4 + export function Basic() { 5 + return ( 6 + <Content> 7 + <Heading1>Main Heading</Heading1> 8 + <Body> 9 + This is a paragraph with proper spacing applied by the Content wrapper. 10 + The Content component automatically applies consistent margins to 11 + headings, paragraphs, and other content elements. 12 + </Body> 13 + <Heading2>Section Heading</Heading2> 14 + <Body> 15 + Another paragraph that demonstrates the spacing between elements. The 16 + Content wrapper ensures consistent vertical rhythm throughout your 17 + content. 18 + </Body> 19 + <Heading3>Subsection</Heading3> 20 + <Body> 21 + Content spacing is automatically handled for all child elements. 22 + </Body> 23 + </Content> 24 + ); 25 + }
+24
apps/docs/src/examples/content/with-blockquote.tsx
··· 1 + import { Content } from "@/components/content"; 2 + import { Blockquote, Body, Heading2 } from "@/components/typography"; 3 + 4 + export function WithBlockquote() { 5 + return ( 6 + <Content> 7 + <Heading2>Blockquote Example</Heading2> 8 + <Body>Here's how blockquotes look within the Content component:</Body> 9 + <Blockquote> 10 + <Body> 11 + This is a blockquote with proper spacing and styling. The Content 12 + component applies consistent margins and padding to blockquotes. 13 + </Body> 14 + <Body> 15 + Multiple paragraphs within a blockquote maintain proper spacing 16 + relative to each other. 17 + </Body> 18 + </Blockquote> 19 + <Body> 20 + Content continues after the blockquote with appropriate spacing. 21 + </Body> 22 + </Content> 23 + ); 24 + }
+32
apps/docs/src/examples/content/with-lists.tsx
··· 1 + import { Content } from "@/components/content"; 2 + import { 3 + Body, 4 + Heading2, 5 + ListItem, 6 + OrderedList, 7 + UnorderedList, 8 + } from "@/components/typography"; 9 + 10 + export function WithLists() { 11 + return ( 12 + <Content> 13 + <Heading2>List Examples</Heading2> 14 + <Body>Here are some examples of lists within the Content component:</Body> 15 + <UnorderedList> 16 + <ListItem>First item in an unordered list</ListItem> 17 + <ListItem>Second item with proper spacing</ListItem> 18 + <ListItem>Third item maintains consistent margins</ListItem> 19 + </UnorderedList> 20 + <Body>And an ordered list:</Body> 21 + <OrderedList> 22 + <ListItem>First step</ListItem> 23 + <ListItem>Second step</ListItem> 24 + <ListItem>Third step</ListItem> 25 + </OrderedList> 26 + <Body> 27 + Paragraphs within lists have adjusted spacing to maintain proper 28 + hierarchy. 29 + </Body> 30 + </Content> 31 + ); 32 + }
+13 -50
apps/docs/src/routes/docs.$.tsx
··· 54 54 import { radius } from "../components/theme/radius.stylex"; 55 55 import { uiColor } from "../components/theme/color.stylex"; 56 56 import { spacing } from "../components/theme/spacing.stylex"; 57 - import { lineHeight } from "../components/theme/typography.stylex"; 57 + import { Content } from "@/components/content"; 58 58 59 59 const TypographyRouterLink = createLink(TypographyLink); 60 60 ··· 90 90 right: spacing["3"], 91 91 top: spacing["2.5"], 92 92 }, 93 - h1: { 94 - marginBottom: spacing["8"], 95 - marginTop: spacing["8"], 96 - }, 97 - h2: { 98 - marginBottom: spacing["4"], 99 - marginTop: spacing["8"], 100 - }, 101 - h3: { 102 - marginBottom: spacing["5"], 103 - marginTop: spacing["8"], 104 - }, 105 - h4: { 106 - marginBottom: spacing["8"], 107 - marginTop: spacing["8"], 108 - }, 109 - h5: { 110 - marginBottom: spacing["8"], 111 - marginTop: spacing["8"], 112 - }, 113 - p: { 114 - lineHeight: { 115 - default: lineHeight.xl, 116 - ":is(li *)": lineHeight.base, 117 - ":is(blockquote *)": lineHeight.base, 118 - }, 119 - marginBottom: { 120 - default: spacing["5"], 121 - ":is(li *)": spacing["0"], 122 - ":is(blockquote *)": spacing["0"], 123 - }, 124 - marginTop: { 125 - default: spacing["5"], 126 - ":is(li *)": spacing["0"], 127 - ":is(blockquote *)": spacing["0"], 128 - }, 129 - }, 130 93 header: { 131 94 marginBottom: spacing["12"], 132 95 }, ··· 249 212 const components: MDXComponents = { 250 213 pre: Pre, 251 214 h1: ({ className: _className, style: _style, ...props }) => ( 252 - <Heading1 {...props} style={styles.h1} /> 215 + <Heading1 {...props} /> 253 216 ), 254 217 h2: ({ className: _className, style: _style, ...props }) => ( 255 - <LinkedHeading id={props.id} style={styles.h2}> 218 + <LinkedHeading id={props.id}> 256 219 <Heading2 {...props} /> 257 220 </LinkedHeading> 258 221 ), 259 222 h3: ({ className: _className, style: _style, ...props }) => ( 260 - <LinkedHeading id={props.id} style={styles.h3}> 223 + <LinkedHeading id={props.id}> 261 224 <Heading3 {...props} /> 262 225 </LinkedHeading> 263 226 ), 264 227 h4: ({ className: _className, style: _style, ...props }) => ( 265 - <LinkedHeading id={props.id} style={styles.h4}> 228 + <LinkedHeading id={props.id}> 266 229 <Heading4 {...props} /> 267 230 </LinkedHeading> 268 231 ), 269 232 h5: ({ className: _className, style: _style, ...props }) => ( 270 - <LinkedHeading id={props.id} style={styles.h5}> 233 + <LinkedHeading id={props.id}> 271 234 <Heading5 {...props} /> 272 235 </LinkedHeading> 273 236 ), 274 237 p: ({ className: _className, style: _style, ...props }) => ( 275 - <Body {...props} style={styles.p} /> 238 + <Body {...props} /> 276 239 ), 277 240 a: ({ className: _className, style: _style, ...props }) => ( 278 241 <Link {...(props as LinkProps)} /> ··· 313 276 throw new Error(`Doc not found: ${_splat ?? "unknown"}`); 314 277 } 315 278 316 - const Content = pages[location.pathname]; 279 + const Page = pages[location.pathname]; 317 280 318 - if (!Content) { 281 + if (!Page) { 319 282 throw new Error(`Content not found: ${location.pathname}`); 320 283 } 321 284 322 285 const isShowcase = location.pathname.includes("showcase"); 323 286 324 287 if (isShowcase) { 325 - return <Content components={components} />; 288 + return <Page components={components} />; 326 289 } 327 290 328 291 return ( ··· 331 294 columnGap="4" 332 295 style={styles.root} 333 296 > 334 - <div {...stylex.props(styles.main)}> 297 + <Content style={styles.main}> 335 298 <Flex direction="column" gap="4" style={styles.header}> 336 299 <Heading1>{doc.title}</Heading1> 337 300 <Text size="xl" variant="secondary"> ··· 339 302 </Text> 340 303 </Flex> 341 304 <Suspense fallback={<div>Loading...</div>}> 342 - <Content components={components} /> 305 + <Page components={components} /> 343 306 </Suspense> 344 - </div> 307 + </Content> 345 308 {toc && <TableOfContents toc={toc} />} 346 309 </Grid> 347 310 );
+2
packages/hip-ui/src/cli/install.tsx
··· 28 28 import { colorWheelConfig } from "../components/color-wheel/color-wheel-config.js"; 29 29 import { comboboxConfig } from "../components/combobox/combobox-config.js"; 30 30 import { commandMenuConfig } from "../components/command-menu/command-menu-config.js"; 31 + import { contentConfig } from "../components/content/content-config.js"; 31 32 import { contextMenuConfig } from "../components/context-menu/context-menu-config.js"; 32 33 import { dateFieldConfig } from "../components/date-field/date-field-config.js"; 33 34 import { datePickerConfig } from "../components/date-picker/date-picker-config.js"; ··· 92 93 buttonConfig, 93 94 flexConfig, 94 95 typographyConfig, 96 + contentConfig, 95 97 tooltipConfig, 96 98 iconButtonConfig, 97 99 popoverConfig,
+12
packages/hip-ui/src/components/content/content-config.ts
··· 1 + import { ComponentConfig } from "../../types"; 2 + 3 + export const contentConfig: ComponentConfig = { 4 + name: "content", 5 + filepath: "./index.tsx", 6 + hipDependencies: [ 7 + "../theme/spacing.stylex.tsx", 8 + "../theme/typography.stylex.tsx", 9 + "../theme/types.ts", 10 + ], 11 + }; 12 +
+77
packages/hip-ui/src/components/content/index.tsx
··· 1 + import * as stylex from "@stylexjs/stylex"; 2 + 3 + import { spacing } from "../theme/spacing.stylex"; 4 + import { StyleXComponentProps } from "../theme/types"; 5 + import { lineHeight } from "../theme/typography.stylex"; 6 + 7 + const styles = stylex.create({ 8 + root: { 9 + /* eslint-disable @stylexjs/valid-styles, @stylexjs/no-legacy-contextual-styles */ 10 + 11 + ":is(*) > :is(:has(h1),h1)": { 12 + marginBottom: spacing["8"], 13 + marginTop: spacing["8"], 14 + }, 15 + ":is(*) > :is(:has(h2),h2)": { 16 + marginBottom: spacing["4"], 17 + marginTop: spacing["8"], 18 + }, 19 + ":is(*) > :is(:has(h3),h3)": { 20 + marginBottom: spacing["5"], 21 + marginTop: spacing["8"], 22 + }, 23 + ":is(*) > :is(:has(h4),h4)": { 24 + marginBottom: spacing["8"], 25 + marginTop: spacing["8"], 26 + }, 27 + ":is(*) > :is(:has(h5),h5)": { 28 + marginBottom: spacing["8"], 29 + marginTop: spacing["8"], 30 + }, 31 + ":is(*) > blockquote": { 32 + marginBottom: 0, 33 + marginLeft: spacing["2"], 34 + marginRight: 0, 35 + marginTop: 0, 36 + paddingLeft: spacing["4"], 37 + }, 38 + ":is(*) > p": { 39 + lineHeight: { 40 + default: lineHeight.xl, 41 + ":is(blockquote *)": lineHeight.base, 42 + ":is(li *)": lineHeight.base, 43 + }, 44 + marginBottom: { 45 + default: spacing["5"], 46 + ":is(blockquote *)": spacing["0"], 47 + ":is(li *)": spacing["0"], 48 + }, 49 + marginTop: { 50 + default: spacing["5"], 51 + ":is(blockquote *)": spacing["0"], 52 + ":is(li *)": spacing["0"], 53 + }, 54 + }, 55 + 56 + /* eslint-enable @stylexjs/valid-styles, @stylexjs/no-legacy-contextual-styles */ 57 + }, 58 + }); 59 + 60 + export interface ContentProps extends StyleXComponentProps< 61 + React.ComponentProps<"div"> 62 + > {} 63 + 64 + /** 65 + * A wrapper component that applies content spacing styles to child elements. 66 + * 67 + * @example 68 + * ```tsx 69 + * <Content> 70 + * <h1>Title</h1> 71 + * <p>Paragraph text</p> 72 + * </Content> 73 + * ``` 74 + */ 75 + export const Content = ({ style, ...props }: ContentProps) => { 76 + return <div {...props} {...stylex.props(styles.root, style)} />; 77 + };