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.

copy buttons

+206 -20
+9 -1
apps/docs/src/components/icon-button/index.tsx
··· 30 30 variant?: ButtonVariant; 31 31 size?: Size; 32 32 label: string; 33 + tooltipOpen?: boolean; 34 + onTooltipOpenChange?: (isOpen: boolean) => void; 33 35 } 34 36 35 37 export const IconButton = ({ ··· 37 39 size: sizeProp, 38 40 label, 39 41 style, 42 + tooltipOpen, 43 + onTooltipOpenChange, 40 44 ...props 41 45 }: IconButtonProps) => { 42 46 const size = sizeProp || use(SizeContext); 43 47 44 48 return ( 45 - <Tooltip text={label}> 49 + <Tooltip 50 + text={label} 51 + isOpen={tooltipOpen} 52 + onOpenChange={onTooltipOpenChange} 53 + > 46 54 <Button size={size} style={[styles[size], style]} {...props}> 47 55 {children} 48 56 </Button>
+24 -1
apps/docs/src/docs/foundations/shadow.mdx
··· 1 1 --- 2 2 title: Shadow 3 3 description: Use elevation to create a sense of depth in the UI. 4 - --- 4 + --- 5 + 6 + import { Shadow } from "../../examples/foundations/shadow"; 7 + 8 + ## Usage 9 + 10 + To use the shadow, you can use the `shadow` object. 11 + 12 + ```tsx 13 + import { shadow } from "@/components/theme/shadow.stylex"; 14 + 15 + const styles = stylex.create({ 16 + example: { 17 + boxShadow: shadow["sm"], 18 + }, 19 + }); 20 + ``` 21 + 22 + ## Scale 23 + 24 + The following is the default scale of shadow. 25 + It can be customized by editing the `shadow` object in the `shadow.stylex.tsx` file. 26 + 27 + <Shadow />
+4 -4
apps/docs/src/examples/checkbox/basic.tsx
··· 2 2 3 3 export function Basic() { 4 4 return ( 5 - <CheckboxGroup label="Preferences"> 6 - <Checkbox>Email notifications</Checkbox> 7 - <Checkbox>SMS notifications</Checkbox> 8 - <Checkbox>Push notifications</Checkbox> 5 + <CheckboxGroup label="Preferences" defaultValue={["email", "sms"]}> 6 + <Checkbox value="email">Email notifications</Checkbox> 7 + <Checkbox value="sms">SMS notifications</Checkbox> 8 + <Checkbox value="push">Push notifications</Checkbox> 9 9 </CheckboxGroup> 10 10 ); 11 11 }
+2 -3
apps/docs/src/examples/checkbox/with-description.tsx
··· 1 1 import { Checkbox, CheckboxGroup } from "@/components/checkbox"; 2 - import { Flex } from "@/components/flex"; 3 2 4 3 export function CheckboxWithDescription() { 5 4 return ( 6 5 <CheckboxGroup label="Notifications"> 7 - <Checkbox> 6 + <Checkbox value="email"> 8 7 <div> 9 8 <div>Email notifications</div> 10 9 <div style={{ fontSize: "0.875rem", color: "#666" }}> ··· 12 11 </div> 13 12 </div> 14 13 </Checkbox> 15 - <Checkbox> 14 + <Checkbox value="sms"> 16 15 <div> 17 16 <div>SMS notifications</div> 18 17 <div style={{ fontSize: "0.875rem", color: "#666" }}>
+45
apps/docs/src/examples/foundations/shadow.tsx
··· 1 + import { Flex } from "@/components/flex"; 2 + import { shadow } from "@/components/theme/shadow.stylex"; 3 + import { spacing } from "../../components/theme/spacing.stylex"; 4 + import { Text } from "@/components/typography/text"; 5 + import * as stylex from "@stylexjs/stylex"; 6 + import { radius } from "../../components/theme/radius.stylex"; 7 + import { uiColor } from "../../components/theme/semantic-color.stylex"; 8 + import { Grid } from "@/components/grid"; 9 + 10 + const styles = stylex.create({ 11 + wrapper: { 12 + marginTop: spacing["12"], 13 + marginBottom: spacing["12"], 14 + }, 15 + box: { 16 + height: spacing["32"], 17 + width: spacing["32"], 18 + borderRadius: radius.lg, 19 + borderWidth: 1, 20 + borderStyle: "solid", 21 + borderColor: uiColor.border3, 22 + }, 23 + }); 24 + 25 + const sortedShadow = Object.entries(shadow).filter( 26 + ([key]) => !key.startsWith("__"), 27 + ); 28 + 29 + export function Shadow() { 30 + return ( 31 + <Grid columns="repeat(3, 1fr)" columnGap="8" style={styles.wrapper}> 32 + {sortedShadow.map(([key, value]) => ( 33 + <Flex 34 + key={key} 35 + align="center" 36 + justify="center" 37 + gap="2" 38 + style={[styles.box, { boxShadow: value }]} 39 + > 40 + <Text>{key}</Text> 41 + </Flex> 42 + ))} 43 + </Grid> 44 + ); 45 + }
+56
apps/docs/src/lib/CopyToClipboardButton.tsx
··· 1 + import { IconButton } from "@/components/icon-button"; 2 + import { Copy } from "lucide-react"; 3 + import * as stylex from "@stylexjs/stylex"; 4 + import { useRef, useState } from "react"; 5 + 6 + export function CopyToClipboardButton({ 7 + style, 8 + text, 9 + }: { 10 + style: stylex.StyleXStyles; 11 + text: string; 12 + }) { 13 + const [tooltipText, setTooltipText] = useState("Copy to clipboard"); 14 + const [tooltipOpen, setTooltipOpen] = useState(false); 15 + const timeoutRef = useRef<NodeJS.Timeout | null>(null); 16 + const changeTextTimeoutRef = useRef<NodeJS.Timeout | null>(null); 17 + const handleCopy = () => { 18 + if (changeTextTimeoutRef.current) { 19 + clearTimeout(changeTextTimeoutRef.current); 20 + changeTextTimeoutRef.current = null; 21 + } 22 + if (timeoutRef.current) { 23 + clearTimeout(timeoutRef.current); 24 + timeoutRef.current = null; 25 + } 26 + navigator.clipboard.writeText(text); 27 + setTooltipText("Copied ✓"); 28 + setTooltipOpen(true); 29 + timeoutRef.current = setTimeout(() => { 30 + timeoutRef.current = null; 31 + 32 + setTooltipOpen(false); 33 + 34 + changeTextTimeoutRef.current = setTimeout(() => { 35 + setTooltipText("Copy to clipboard"); 36 + changeTextTimeoutRef.current = null; 37 + }, 200); 38 + }, 2000); 39 + }; 40 + 41 + return ( 42 + <IconButton 43 + label={tooltipText} 44 + tooltipOpen={tooltipOpen} 45 + onTooltipOpenChange={(isOpen) => 46 + !timeoutRef.current && setTooltipOpen(isOpen) 47 + } 48 + variant="tertiary" 49 + style={[style]} 50 + size="sm" 51 + onClick={handleCopy} 52 + > 53 + <Copy /> 54 + </IconButton> 55 + ); 56 + }
+28 -7
apps/docs/src/lib/Example.tsx
··· 5 5 import { spacing } from "../components/theme/spacing.stylex"; 6 6 import { radius } from "../components/theme/radius.stylex"; 7 7 import { uiColor } from "../components/theme/semantic-color.stylex"; 8 + import { CopyToClipboardButton } from "./CopyToClipboardButton"; 9 + import { useEffect, useRef, useState } from "react"; 8 10 9 11 const styles = stylex.create({ 10 12 card: { ··· 22 24 justifyContent: "center", 23 25 backgroundColor: uiColor.bgSubtle, 24 26 }, 27 + codeWrapper: { 28 + position: "relative", 29 + borderTopWidth: 1, 30 + borderTopStyle: "solid", 31 + borderTopColor: uiColor.border2, 32 + }, 25 33 code: { 26 34 ":is(*) pre": { 27 35 margin: 0, ··· 31 39 paddingRight: spacing["4"], 32 40 borderBottomLeftRadius: radius["lg"], 33 41 borderBottomRightRadius: radius["lg"], 34 - borderTopWidth: 1, 35 - borderTopStyle: "solid", 36 - borderTopColor: uiColor.border2, 37 42 }, 38 43 ":is(*) code": {}, 44 + }, 45 + copyButton: { 46 + position: "absolute", 47 + top: spacing["3"], 48 + right: spacing["3"], 39 49 }, 40 50 }); 41 51 ··· 45 55 src: (() => React.JSX.Element) & { slug: string }; 46 56 }) { 47 57 const code = examples[Component.slug]; 58 + const ref = useRef<HTMLDivElement>(null); 59 + const [textContent, setTextContent] = useState("error"); 60 + 61 + useEffect(() => { 62 + setTextContent(ref.current?.textContent ?? "error"); 63 + }, [code]); 48 64 49 65 return ( 50 66 <Card style={styles.card}> ··· 52 68 <div {...stylex.props(styles.preview)}> 53 69 <Component /> 54 70 </div> 55 - <div 56 - {...stylex.props(styles.code)} 57 - dangerouslySetInnerHTML={{ __html: code }} 58 - /> 71 + 72 + <div {...stylex.props(styles.codeWrapper)}> 73 + <div 74 + ref={ref} 75 + {...stylex.props(styles.code)} 76 + dangerouslySetInnerHTML={{ __html: code }} 77 + /> 78 + <CopyToClipboardButton style={styles.copyButton} text={textContent} /> 79 + </div> 59 80 </Flex> 60 81 </Card> 61 82 );
+29 -3
apps/docs/src/routes/docs.$.tsx
··· 20 20 import { spacing } from "../components/theme/spacing.stylex"; 21 21 import { radius } from "../components/theme/radius.stylex"; 22 22 import { uiColor } from "../components/theme/semantic-color.stylex"; 23 + import { IconButton } from "@/components/icon-button"; 24 + import { Copy } from "lucide-react"; 25 + import { CopyToClipboardButton } from "@/lib/CopyToClipboardButton"; 26 + import { useEffect, useRef, useState } from "react"; 23 27 24 28 const styles = stylex.create({ 25 29 main: { ··· 30 34 paddingRight: spacing["16"], 31 35 }, 32 36 pre: { 37 + position: "relative", 33 38 marginTop: spacing["8"], 34 39 marginBottom: spacing["8"], 35 40 padding: spacing["4"], ··· 37 42 borderWidth: 1, 38 43 borderStyle: "solid", 39 44 borderColor: uiColor.border2, 45 + }, 46 + copyButton: { 47 + position: "absolute", 48 + top: "50%", 49 + right: spacing["3"], 50 + transform: "translateY(-50%)", 40 51 }, 41 52 h1: { 42 53 marginTop: spacing["8"], ··· 77 88 return <TypographyLink {...props} />; 78 89 } 79 90 91 + function Pre({ children, ...props }: React.ComponentProps<"pre">) { 92 + const [textContent, setTextContent] = useState("error"); 93 + const ref = useRef<HTMLPreElement>(null); 94 + 95 + useEffect(() => { 96 + console.log(ref.current?.textContent); 97 + setTextContent(ref.current?.textContent ?? "error"); 98 + }, [ref]); 99 + 100 + return ( 101 + <pre ref={ref} {...props} {...stylex.props(styles.pre)} data-testid="code"> 102 + {children} 103 + <CopyToClipboardButton style={styles.copyButton} text={textContent} /> 104 + </pre> 105 + ); 106 + } 107 + 80 108 const components: MDXComponents = { 81 - pre: (props) => ( 82 - <pre {...props} {...stylex.props(styles.pre)} data-testid="code" /> 83 - ), 109 + pre: Pre, 84 110 h1: (props) => <Heading1 {...props} {...stylex.props(styles.h1)} />, 85 111 h2: (props) => <Heading2 {...props} {...stylex.props(styles.h2)} />, 86 112 h3: (props) => <Heading3 {...props} {...stylex.props(styles.h3)} />,
+9 -1
packages/hip-ui/src/components/icon-button/index.tsx
··· 30 30 variant?: ButtonVariant; 31 31 size?: Size; 32 32 label: string; 33 + tooltipOpen?: boolean; 34 + onTooltipOpenChange?: (isOpen: boolean) => void; 33 35 } 34 36 35 37 export const IconButton = ({ ··· 37 39 size: sizeProp, 38 40 label, 39 41 style, 42 + tooltipOpen, 43 + onTooltipOpenChange, 40 44 ...props 41 45 }: IconButtonProps) => { 42 46 const size = sizeProp || use(SizeContext); 43 47 44 48 return ( 45 - <Tooltip text={label}> 49 + <Tooltip 50 + text={label} 51 + isOpen={tooltipOpen} 52 + onOpenChange={onTooltipOpenChange} 53 + > 46 54 <Button size={size} style={[styles[size], style]} {...props}> 47 55 {children} 48 56 </Button>