gucci
This commit is contained in:
parent
67fae70c83
commit
6c3b3e80b0
42
README.md
42
README.md
|
|
@ -1,6 +1,46 @@
|
|||
# 🐺 howl
|
||||
|
||||
Howl is a fork of `werewolf-ui`, without any Tailwind.
|
||||
Howl is a fork of `werewolf-ui`, without any Tailwind. A minimal, zero-dependency React component library.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bun install howl
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { Button, VStack, Text } from "howl"
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<VStack>
|
||||
<Text>Hello, world!</Text>
|
||||
<Button>Click me</Button>
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
- **Avatar** - Profile image component
|
||||
- **Box** - Container components (Box, RedBox, GreenBox, BlueBox, GrayBox)
|
||||
- **Button** - Button component
|
||||
- **Divider** - Horizontal divider
|
||||
- **Grid** - Grid layout
|
||||
- **Icon** - Icon display using lucide-static
|
||||
- **IconLink** - Icon with link functionality
|
||||
- **Image** - Image component
|
||||
- **Input** - Text input field
|
||||
- **Placeholder** - Placeholder component
|
||||
- **Section** - Section container
|
||||
- **Select** - Dropdown select input
|
||||
- **Stack** - Layout components (VStack, HStack)
|
||||
- **Text** - Text components (H1, H2, H3, H4, H5, Text, SmallText)
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
bun install
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { Section } from "./section"
|
||||
import { H2, Text } from "./text"
|
||||
import "hono/jsx"
|
||||
import type { FC, JSX } from "hono/jsx"
|
||||
import { VStack, HStack } from "./stack"
|
||||
|
|
@ -32,17 +34,17 @@ export const Test = () => {
|
|||
]
|
||||
|
||||
return (
|
||||
<VStack gap={8} style={{ padding: "24px" }}>
|
||||
<Section>
|
||||
{/* Size variations */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Size Variations</h2>
|
||||
<H2>Size Variations</H2>
|
||||
<HStack gap={4}>
|
||||
{[24, 32, 48, 64, 96].map((size) => (
|
||||
<VStack key={size} h="center" gap={2}>
|
||||
<Avatar src={sampleImages[0]!} size={size} alt="Sample" />
|
||||
<p style={{ fontSize: "14px" }}>
|
||||
<Text>
|
||||
{size}x{size}
|
||||
</p>
|
||||
</Text>
|
||||
</VStack>
|
||||
))}
|
||||
</HStack>
|
||||
|
|
@ -50,27 +52,27 @@ export const Test = () => {
|
|||
|
||||
{/* Rounded vs Square */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Rounded vs Square</h2>
|
||||
<H2>Rounded vs Square</H2>
|
||||
<HStack gap={6}>
|
||||
<VStack h="center" gap={2}>
|
||||
<Avatar src={sampleImages[0]!} size={64} alt="Sample" />
|
||||
<p style={{ fontSize: "14px" }}>Square</p>
|
||||
<Text>Square</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Avatar src={sampleImages[0]!} size={64} rounded alt="Sample" />
|
||||
<p style={{ fontSize: "14px" }}>Rounded</p>
|
||||
<Text>Rounded</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</VStack>
|
||||
|
||||
{/* Different images */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Different Images</h2>
|
||||
<H2>Different Images</H2>
|
||||
<HStack gap={4}>
|
||||
{sampleImages.map((src, index) => (
|
||||
<VStack key={src} h="center" gap={2}>
|
||||
<Avatar src={src} size={64} rounded alt={`Sample ${index + 1}`} />
|
||||
<p style={{ fontSize: "14px" }}>Image {index + 1}</p>
|
||||
<Text>Image {index + 1}</Text>
|
||||
</VStack>
|
||||
))}
|
||||
</HStack>
|
||||
|
|
@ -78,7 +80,7 @@ export const Test = () => {
|
|||
|
||||
{/* Custom styles */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>With Custom Styles</h2>
|
||||
<H2>With Custom Styles</H2>
|
||||
<HStack gap={6}>
|
||||
<VStack h="center" gap={2}>
|
||||
<Avatar
|
||||
|
|
@ -88,7 +90,7 @@ export const Test = () => {
|
|||
style={{ border: "4px solid #3b82f6" }}
|
||||
alt="With border"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>With Border</p>
|
||||
<Text>With Border</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Avatar
|
||||
|
|
@ -98,7 +100,7 @@ export const Test = () => {
|
|||
style={{ boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)" }}
|
||||
alt="With shadow"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>With Shadow</p>
|
||||
<Text>With Shadow</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Avatar
|
||||
|
|
@ -108,10 +110,10 @@ export const Test = () => {
|
|||
style={{ border: "4px solid #22c55e", boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)" }}
|
||||
alt="Border + shadow"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>Border + Shadow</p>
|
||||
<Text>Border + Shadow</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
84
src/box.tsx
Normal file
84
src/box.tsx
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import "hono/jsx"
|
||||
import type { FC, PropsWithChildren, JSX } from "hono/jsx"
|
||||
|
||||
type BoxProps = PropsWithChildren & {
|
||||
bg?: string
|
||||
color?: string
|
||||
p?: number
|
||||
style?: JSX.CSSProperties
|
||||
}
|
||||
|
||||
export const Box: FC<BoxProps> = ({ children, bg, color, p, style }) => {
|
||||
const boxStyle: JSX.CSSProperties = {
|
||||
backgroundColor: bg,
|
||||
color: color,
|
||||
padding: p ? `${p}px` : undefined,
|
||||
...style,
|
||||
}
|
||||
|
||||
return <div style={boxStyle}>{children}</div>
|
||||
}
|
||||
|
||||
// Common demo box colors
|
||||
export const RedBox: FC<PropsWithChildren> = ({ children }) => (
|
||||
<Box bg="#ef4444" p={4} style={{ textAlign: "center" }}>
|
||||
{children}
|
||||
</Box>
|
||||
)
|
||||
|
||||
export const GreenBox: FC<PropsWithChildren> = ({ children }) => (
|
||||
<Box bg="#22c55e" p={4} style={{ textAlign: "center" }}>
|
||||
{children}
|
||||
</Box>
|
||||
)
|
||||
|
||||
export const BlueBox: FC<PropsWithChildren> = ({ children }) => (
|
||||
<Box bg="#3b82f6" p={4} style={{ textAlign: "center" }}>
|
||||
{children}
|
||||
</Box>
|
||||
)
|
||||
|
||||
export const GrayBox: FC<PropsWithChildren & { style?: JSX.CSSProperties }> = ({ children, style }) => (
|
||||
<Box bg="#f3f4f6" p={16} style={style}>
|
||||
{children}
|
||||
</Box>
|
||||
)
|
||||
|
||||
export const Test = () => {
|
||||
return (
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: "32px", padding: "24px" }}>
|
||||
<div>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold", marginBottom: "16px" }}>Box Component</h2>
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
|
||||
<Box bg="#3b82f6" color="#ffffff" p={16}>
|
||||
Basic Box with custom background and text color
|
||||
</Box>
|
||||
<Box p={8} style={{ border: "2px solid #d1d5db", borderRadius: "8px" }}>
|
||||
Box with padding and border
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold", marginBottom: "16px" }}>Color Variants</h2>
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
|
||||
<RedBox>Red Box</RedBox>
|
||||
<GreenBox>Green Box</GreenBox>
|
||||
<BlueBox>Blue Box</BlueBox>
|
||||
<GrayBox>Gray Box</GrayBox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold", marginBottom: "16px" }}>Nested Boxes</h2>
|
||||
<Box bg="#f3f4f6" p={16}>
|
||||
<Box bg="#e5e7eb" p={12}>
|
||||
<Box bg="#d1d5db" p={8}>
|
||||
Nested boxes demonstration
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import "hono/jsx"
|
||||
import type { JSX, FC } from "hono/jsx"
|
||||
import { VStack, HStack } from "./stack"
|
||||
import { Section } from "./section"
|
||||
import { H2 } from "./text"
|
||||
|
||||
export type ButtonProps = JSX.IntrinsicElements["button"] & {
|
||||
variant?: "primary" | "secondary" | "outline" | "ghost" | "destructive"
|
||||
|
|
@ -68,7 +70,7 @@ export const Button: FC<ButtonProps> = (props) => {
|
|||
...baseStyles,
|
||||
...variantStyles[variant],
|
||||
...sizeStyles[size],
|
||||
...(style || {}),
|
||||
...(style as JSX.CSSProperties),
|
||||
}
|
||||
|
||||
return <button {...buttonProps} style={combinedStyles} />
|
||||
|
|
@ -76,10 +78,10 @@ export const Button: FC<ButtonProps> = (props) => {
|
|||
|
||||
export const Test = () => {
|
||||
return (
|
||||
<VStack gap={8} style={{ padding: "24px" }}>
|
||||
<Section>
|
||||
{/* Variants */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Button Variants</h2>
|
||||
<H2>Button Variants</H2>
|
||||
<HStack gap={4}>
|
||||
<Button variant="primary">Primary</Button>
|
||||
<Button variant="secondary">Secondary</Button>
|
||||
|
|
@ -91,7 +93,7 @@ export const Test = () => {
|
|||
|
||||
{/* Sizes */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Button Sizes</h2>
|
||||
<H2>Button Sizes</H2>
|
||||
<HStack gap={4} v="end">
|
||||
<Button size="sm">Small</Button>
|
||||
<Button size="md">Medium</Button>
|
||||
|
|
@ -101,7 +103,7 @@ export const Test = () => {
|
|||
|
||||
{/* With custom content */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Custom Content</h2>
|
||||
<H2>Custom Content</H2>
|
||||
<HStack gap={4}>
|
||||
<Button variant="primary">
|
||||
<span>🚀</span>
|
||||
|
|
@ -116,7 +118,7 @@ export const Test = () => {
|
|||
|
||||
{/* Native attributes work */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Native Attributes</h2>
|
||||
<H2>Native Attributes</H2>
|
||||
<HStack gap={4}>
|
||||
<Button onClick={() => alert("Clicked!")} variant="primary">
|
||||
Click Me
|
||||
|
|
@ -129,6 +131,6 @@ export const Test = () => {
|
|||
</Button>
|
||||
</HStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { Section } from "./section"
|
||||
import { H2 } from "./text"
|
||||
import "hono/jsx"
|
||||
import type { FC, PropsWithChildren, JSX } from "hono/jsx"
|
||||
import { VStack } from "./stack"
|
||||
|
|
@ -41,8 +43,8 @@ export const Divider: FC<DividerProps> = ({ children, style }) => {
|
|||
|
||||
export const Test = () => {
|
||||
return (
|
||||
<VStack gap={4} style={{ padding: "16px", maxWidth: "448px" }}>
|
||||
<h2 style={{ fontSize: "18px", fontWeight: "bold" }}>Divider Examples</h2>
|
||||
<Section gap={4} maxWidth="448px" style={{ padding: "16px" }}>
|
||||
<H2>Divider Examples</H2>
|
||||
|
||||
<VStack gap={0}>
|
||||
<p>Would you like to continue</p>
|
||||
|
|
@ -56,6 +58,6 @@ export const Test = () => {
|
|||
<Divider />
|
||||
<p>So cool, so straight!</p>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
26
src/grid.tsx
26
src/grid.tsx
|
|
@ -3,6 +3,8 @@ import "hono/jsx"
|
|||
import type { FC, PropsWithChildren, JSX } from "hono/jsx"
|
||||
import { VStack } from "./stack"
|
||||
import { Button } from "./button"
|
||||
import { Section } from "./section"
|
||||
import { H2, H3 } from "./text"
|
||||
|
||||
type GridProps = PropsWithChildren & {
|
||||
cols?: GridCols
|
||||
|
|
@ -69,13 +71,13 @@ const justifyItemsMap = {
|
|||
|
||||
export const Test = () => {
|
||||
return (
|
||||
<VStack gap={4} style={{ padding: "16px" }}>
|
||||
<Section gap={4} style={{ padding: "16px" }}>
|
||||
<VStack gap={6}>
|
||||
<h2 style={{ fontSize: "18px", fontWeight: "bold" }}>Grid Examples</h2>
|
||||
<H2>Grid Examples</H2>
|
||||
|
||||
{/* Simple 3-column grid */}
|
||||
<VStack gap={2}>
|
||||
<h3 style={{ fontSize: "16px", fontWeight: "600" }}>Simple 3 columns: cols=3</h3>
|
||||
<H3>Simple 3 columns: cols=3</H3>
|
||||
<Grid cols={3} gap={4}>
|
||||
<div style={{ backgroundColor: "#fecaca", padding: "16px", textAlign: "center" }}>Item 1</div>
|
||||
<div style={{ backgroundColor: "#bbf7d0", padding: "16px", textAlign: "center" }}>Item 2</div>
|
||||
|
|
@ -88,9 +90,7 @@ export const Test = () => {
|
|||
|
||||
{/* Responsive grid */}
|
||||
<VStack gap={2}>
|
||||
<h3 style={{ fontSize: "16px", fontWeight: "600" }}>
|
||||
Responsive: cols={sm: 1, md: 2, lg: 3}
|
||||
</h3>
|
||||
<H3>Responsive: cols={sm: 1, md: 2, lg: 3}</H3>
|
||||
<Grid cols={{ sm: 1, md: 2, lg: 3 }} gap={4}>
|
||||
<div style={{ backgroundColor: "#fecaca", padding: "16px", textAlign: "center" }}>Card 1</div>
|
||||
<div style={{ backgroundColor: "#bbf7d0", padding: "16px", textAlign: "center" }}>Card 2</div>
|
||||
|
|
@ -101,9 +101,7 @@ export const Test = () => {
|
|||
|
||||
{/* More responsive examples */}
|
||||
<VStack gap={2}>
|
||||
<h3 style={{ fontSize: "16px", fontWeight: "600" }}>
|
||||
More responsive: cols={sm: 2, lg: 4, xl: 6}
|
||||
</h3>
|
||||
<H3>More responsive: cols={sm: 2, lg: 4, xl: 6}</H3>
|
||||
<Grid cols={{ sm: 2, lg: 4, xl: 6 }} gap={4}>
|
||||
<div style={{ backgroundColor: "#fecaca", padding: "16px", textAlign: "center" }}>Item A</div>
|
||||
<div style={{ backgroundColor: "#bbf7d0", padding: "16px", textAlign: "center" }}>Item B</div>
|
||||
|
|
@ -116,7 +114,7 @@ export const Test = () => {
|
|||
|
||||
{/* Payment method example */}
|
||||
<VStack gap={2}>
|
||||
<h3 style={{ fontSize: "16px", fontWeight: "600" }}>Payment buttons example</h3>
|
||||
<H3>Payment buttons example</H3>
|
||||
<Grid cols={3} gap={4}>
|
||||
<Button variant="outline" style={{ height: "80px", flexDirection: "column" }}>
|
||||
<div style={{ fontSize: "24px" }}>💳</div>
|
||||
|
|
@ -135,9 +133,7 @@ export const Test = () => {
|
|||
|
||||
{/* Alignment examples */}
|
||||
<VStack gap={2}>
|
||||
<h3 style={{ fontSize: "16px", fontWeight: "600" }}>
|
||||
Alignment: v="center" h="center"
|
||||
</h3>
|
||||
<H3>Alignment: v="center" h="center"</H3>
|
||||
<Grid cols={3} gap={4} v="center" h="center" style={{ height: "128px", backgroundColor: "#f3f4f6" }}>
|
||||
<div style={{ backgroundColor: "#fecaca", padding: "8px" }}>Item 1</div>
|
||||
<div style={{ backgroundColor: "#bbf7d0", padding: "8px" }}>Item 2</div>
|
||||
|
|
@ -146,13 +142,13 @@ export const Test = () => {
|
|||
</VStack>
|
||||
|
||||
<VStack gap={2}>
|
||||
<h3 style={{ fontSize: "16px", fontWeight: "600" }}>Alignment: v="start" h="end"</h3>
|
||||
<H3>Alignment: v="start" h="end"</H3>
|
||||
<Grid cols={2} gap={4} v="start" h="end" style={{ height: "96px", backgroundColor: "#f3f4f6" }}>
|
||||
<div style={{ backgroundColor: "#e9d5ff", padding: "8px" }}>Left</div>
|
||||
<div style={{ backgroundColor: "#fed7aa", padding: "8px" }}>Right</div>
|
||||
</Grid>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
94
src/icon.tsx
94
src/icon.tsx
|
|
@ -2,7 +2,9 @@ import "hono/jsx"
|
|||
import type { FC, JSX } from "hono/jsx"
|
||||
import * as icons from "lucide-static"
|
||||
import { Grid } from "./grid"
|
||||
import { VStack, HStack } from "./stack"
|
||||
import { VStack } from "./stack"
|
||||
import { Section } from "./section"
|
||||
import { H2, Text } from "./text"
|
||||
|
||||
export type IconName = keyof typeof icons
|
||||
|
||||
|
|
@ -69,100 +71,100 @@ export const IconLink: FC<IconLinkProps> = (props) => {
|
|||
|
||||
export const Test = () => {
|
||||
return (
|
||||
<div style={{ padding: "24px" }}>
|
||||
<Section>
|
||||
{/* === ICON TESTS === */}
|
||||
|
||||
{/* Size variations */}
|
||||
<div style={{ marginBottom: "32px" }}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold", marginBottom: "16px" }}>Icon Size Variations</h2>
|
||||
<VStack gap={4}>
|
||||
<H2>Icon Size Variations</H2>
|
||||
<div style={{ display: "flex", alignItems: "center", gap: "16px" }}>
|
||||
{([3, 4, 5, 6, 8, 10, 12, 16] as const).map((size) => (
|
||||
<div key={size} style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "8px" }}>
|
||||
<VStack h="center" gap={2} key={size}>
|
||||
<Icon name="Heart" size={size} />
|
||||
<p style={{ fontSize: "14px" }}>{size}</p>
|
||||
</div>
|
||||
<Text>{size}</Text>
|
||||
</VStack>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</VStack>
|
||||
|
||||
{/* Styling with CSS classes */}
|
||||
<div style={{ marginBottom: "32px" }}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold", marginBottom: "16px" }}>Styling with CSS Classes</h2>
|
||||
<VStack gap={4}>
|
||||
<H2>Styling with CSS Classes</H2>
|
||||
<Grid cols={5} gap={6}>
|
||||
<VStack h="center" gap={2}>
|
||||
<Icon name="Star" size={12} />
|
||||
<p style={{ fontSize: "14px" }}>Default</p>
|
||||
<Text>Default</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Icon name="Star" size={12} style={{ color: "#3b82f6" }} />
|
||||
<p style={{ fontSize: "14px" }}>Blue Color</p>
|
||||
<Text>Blue Color</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Icon name="Star" size={12} class="stroke-1" />
|
||||
<p style={{ fontSize: "14px" }}>Thin Stroke</p>
|
||||
<Text>Thin Stroke</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Icon name="Star" size={12} style={{ color: "#fbbf24", fill: "currentColor", stroke: "none" }} />
|
||||
<p style={{ fontSize: "14px" }}>Filled</p>
|
||||
<Text>Filled</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Icon name="Star" size={12} style={{ color: "#a855f7", transition: "color 0.2s" }} />
|
||||
<p style={{ fontSize: "14px" }}>Hover Effect</p>
|
||||
<Text>Hover Effect</Text>
|
||||
</VStack>
|
||||
</Grid>
|
||||
</div>
|
||||
</VStack>
|
||||
|
||||
{/* Advanced styling */}
|
||||
<div style={{ marginBottom: "32px" }}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold", marginBottom: "16px" }}>Advanced Styling</h2>
|
||||
<VStack gap={4}>
|
||||
<H2>Advanced Styling</H2>
|
||||
<Grid cols={4} gap={6}>
|
||||
<VStack h="center" gap={2}>
|
||||
<Icon name="Heart" size={12} style={{ color: "#ef4444", fill: "currentColor", stroke: "none" }} />
|
||||
<p style={{ fontSize: "14px" }}>Filled Heart</p>
|
||||
<Text>Filled Heart</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Icon name="Shield" size={12} style={{ color: "#16a34a", strokeWidth: "2" }} />
|
||||
<p style={{ fontSize: "14px" }}>Thick Stroke</p>
|
||||
<Text>Thick Stroke</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Icon name="Sun" size={12} style={{ color: "#eab308" }} />
|
||||
<p style={{ fontSize: "14px" }}>Sun Icon</p>
|
||||
<Text>Sun Icon</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Icon name="Zap" size={12} style={{ color: "#60a5fa", filter: "drop-shadow(0 4px 6px rgba(0,0,0,0.3))" }} />
|
||||
<p style={{ fontSize: "14px" }}>Drop Shadow</p>
|
||||
<Text>Drop Shadow</Text>
|
||||
</VStack>
|
||||
</Grid>
|
||||
</div>
|
||||
</VStack>
|
||||
|
||||
{/* === ICON LINK TESTS === */}
|
||||
|
||||
{/* Basic icon links */}
|
||||
<div style={{ marginBottom: "32px" }}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold", marginBottom: "16px" }}>Icon Links</h2>
|
||||
<VStack gap={4}>
|
||||
<H2>Icon Links</H2>
|
||||
<div style={{ display: "flex", gap: "24px" }}>
|
||||
<div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "8px" }}>
|
||||
<VStack h="center" gap={2}>
|
||||
<IconLink name="Home" size={8} href="/" />
|
||||
<p style={{ fontSize: "14px" }}>Home Link</p>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "8px" }}>
|
||||
<Text>Home Link</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<IconLink name="ExternalLink" size={8} href="https://example.com" target="_blank" />
|
||||
<p style={{ fontSize: "14px" }}>External Link</p>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "8px" }}>
|
||||
<Text>External Link</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<IconLink name="Mail" size={8} href="mailto:hello@example.com" />
|
||||
<p style={{ fontSize: "14px" }}>Email Link</p>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "8px" }}>
|
||||
<Text>Email Link</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<IconLink name="Phone" size={8} href="tel:+1234567890" />
|
||||
<p style={{ fontSize: "14px" }}>Phone Link</p>
|
||||
</div>
|
||||
<Text>Phone Link</Text>
|
||||
</VStack>
|
||||
</div>
|
||||
</div>
|
||||
</VStack>
|
||||
|
||||
{/* Styled icon links */}
|
||||
<div>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold", marginBottom: "16px" }}>Styled Icon Links</h2>
|
||||
<VStack gap={4}>
|
||||
<H2>Styled Icon Links</H2>
|
||||
<Grid cols={4} gap={6}>
|
||||
<VStack h="center" gap={2}>
|
||||
<IconLink
|
||||
|
|
@ -176,7 +178,7 @@ export const Test = () => {
|
|||
borderRadius: "8px",
|
||||
}}
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>Button Style</p>
|
||||
<Text>Button Style</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<IconLink
|
||||
|
|
@ -189,19 +191,19 @@ export const Test = () => {
|
|||
borderRadius: "9999px",
|
||||
}}
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>Circle Border</p>
|
||||
<Text>Circle Border</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<IconLink name="Heart" size={8} href="#" style={{ color: "#ef4444" }} />
|
||||
<p style={{ fontSize: "14px" }}>Red Heart</p>
|
||||
<Text>Red Heart</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<IconLink name="Star" size={8} href="#" style={{ color: "#fbbf24", fill: "currentColor" }} />
|
||||
<p style={{ fontSize: "14px" }}>Filled Star</p>
|
||||
<Text>Filled Star</Text>
|
||||
</VStack>
|
||||
</Grid>
|
||||
</div>
|
||||
</div>
|
||||
</VStack>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { Section } from "./section"
|
||||
import { H2, H3, H4, H5, Text, SmallText } from "./text"
|
||||
import "hono/jsx"
|
||||
import type { FC, JSX } from "hono/jsx"
|
||||
import { VStack, HStack } from "./stack"
|
||||
|
|
@ -32,38 +34,38 @@ export const Test = () => {
|
|||
]
|
||||
|
||||
return (
|
||||
<VStack gap={8} style={{ padding: "24px" }}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Image Examples</h2>
|
||||
<Section>
|
||||
<H2>Image Examples</H2>
|
||||
|
||||
{/* Size variations */}
|
||||
<VStack gap={4}>
|
||||
<h3 style={{ fontSize: "18px", fontWeight: "600" }}>Size Variations</h3>
|
||||
<H3>Size Variations</H3>
|
||||
<HStack gap={4} wrap>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image src={sampleImages[0]!} width={64} height={64} objectFit="cover" alt="64x64" />
|
||||
<p style={{ fontSize: "14px" }}>64x64</p>
|
||||
<Text>64x64</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image src={sampleImages[0]!} width={96} height={96} objectFit="cover" alt="96x96" />
|
||||
<p style={{ fontSize: "14px" }}>96x96</p>
|
||||
<Text>96x96</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image src={sampleImages[0]!} width={128} height={128} objectFit="cover" alt="128x128" />
|
||||
<p style={{ fontSize: "14px" }}>128x128</p>
|
||||
<Text>128x128</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image src={sampleImages[0]!} width={192} height={128} objectFit="cover" alt="192x128" />
|
||||
<p style={{ fontSize: "14px" }}>192x128</p>
|
||||
<Text>192x128</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</VStack>
|
||||
|
||||
{/* Object fit variations */}
|
||||
<VStack gap={4}>
|
||||
<h3 style={{ fontSize: "18px", fontWeight: "600" }}>Object Fit Variations</h3>
|
||||
<p style={{ fontSize: "14px", color: "#6b7280" }}>
|
||||
<H3>Object Fit Variations</H3>
|
||||
<Text>
|
||||
Same image with different object-fit values
|
||||
</p>
|
||||
</Text>
|
||||
<HStack gap={6} wrap>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image
|
||||
|
|
@ -74,7 +76,7 @@ export const Test = () => {
|
|||
style={{ border: "1px solid black" }}
|
||||
alt="Object cover"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>object-fit: cover</p>
|
||||
<Text>object-fit: cover</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image
|
||||
|
|
@ -85,7 +87,7 @@ export const Test = () => {
|
|||
style={{ border: "1px solid black", backgroundColor: "#f3f4f6" }}
|
||||
alt="Object contain"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>object-fit: contain</p>
|
||||
<Text>object-fit: contain</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image
|
||||
|
|
@ -96,7 +98,7 @@ export const Test = () => {
|
|||
style={{ border: "1px solid black" }}
|
||||
alt="Object fill"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>object-fit: fill</p>
|
||||
<Text>object-fit: fill</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image
|
||||
|
|
@ -107,7 +109,7 @@ export const Test = () => {
|
|||
style={{ border: "1px solid black", backgroundColor: "#f3f4f6" }}
|
||||
alt="Object scale-down"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>object-fit: scale-down</p>
|
||||
<Text>object-fit: scale-down</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image
|
||||
|
|
@ -118,14 +120,14 @@ export const Test = () => {
|
|||
style={{ border: "1px solid black", backgroundColor: "#f3f4f6" }}
|
||||
alt="Object none"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>object-fit: none</p>
|
||||
<Text>object-fit: none</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</VStack>
|
||||
|
||||
{/* Styling examples */}
|
||||
<VStack gap={4}>
|
||||
<h3 style={{ fontSize: "18px", fontWeight: "600" }}>Styling Examples</h3>
|
||||
<H3>Styling Examples</H3>
|
||||
<HStack gap={6} wrap>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image
|
||||
|
|
@ -136,7 +138,7 @@ export const Test = () => {
|
|||
style={{ borderRadius: "8px", border: "4px solid #3b82f6" }}
|
||||
alt="Rounded with border"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>Rounded + Border</p>
|
||||
<Text>Rounded + Border</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image
|
||||
|
|
@ -147,7 +149,7 @@ export const Test = () => {
|
|||
style={{ boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)" }}
|
||||
alt="With shadow"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>With Shadow</p>
|
||||
<Text>With Shadow</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Image
|
||||
|
|
@ -162,18 +164,18 @@ export const Test = () => {
|
|||
}}
|
||||
alt="Circular with effects"
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>Circular + Effects</p>
|
||||
<Text>Circular + Effects</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</VStack>
|
||||
|
||||
{/* Common use cases */}
|
||||
<VStack gap={6}>
|
||||
<h3 style={{ fontSize: "18px", fontWeight: "600" }}>Common Use Cases</h3>
|
||||
<H3>Common Use Cases</H3>
|
||||
|
||||
{/* Avatar */}
|
||||
<VStack gap={2}>
|
||||
<h4 style={{ fontWeight: "500" }}>Avatar</h4>
|
||||
<H4>Avatar</H4>
|
||||
<Image
|
||||
src={sampleImages[0]!}
|
||||
width={48}
|
||||
|
|
@ -186,19 +188,19 @@ export const Test = () => {
|
|||
|
||||
{/* Card image */}
|
||||
<VStack gap={2} style={{ maxWidth: "384px" }}>
|
||||
<h4 style={{ fontWeight: "500" }}>Card Image</h4>
|
||||
<H4>Card Image</H4>
|
||||
<VStack gap={0} style={{ border: "1px solid #d1d5db", borderRadius: "8px", overflow: "hidden" }}>
|
||||
<Image src={sampleImages[1]!} width={384} height={192} objectFit="cover" alt="Card image" />
|
||||
<VStack gap={1} style={{ padding: "16px" }}>
|
||||
<h5 style={{ fontWeight: "500" }}>Card Title</h5>
|
||||
<p style={{ fontSize: "14px", color: "#6b7280" }}>Card description goes here</p>
|
||||
<H5>Card Title</H5>
|
||||
<Text>Card description goes here</Text>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
|
||||
{/* Gallery grid */}
|
||||
<VStack gap={2}>
|
||||
<h4 style={{ fontWeight: "500" }}>Gallery Grid</h4>
|
||||
<H4>Gallery Grid</H4>
|
||||
<Grid cols={3} gap={2}>
|
||||
{sampleImages.map((src, i) => (
|
||||
<Image
|
||||
|
|
@ -214,6 +216,6 @@ export const Test = () => {
|
|||
</Grid>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,4 +25,10 @@ export type { SelectProps, SelectOption } from "./select"
|
|||
export { Placeholder } from "./placeholder"
|
||||
export { default as PlaceholderDefault } from "./placeholder"
|
||||
|
||||
export { H1, H2, H3, H4, H5, Text, SmallText } from "./text"
|
||||
|
||||
export { Box, RedBox, GreenBox, BlueBox, GrayBox } from "./box"
|
||||
|
||||
export { Section } from "./section"
|
||||
|
||||
export type { TailwindSize } from "./types"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { Section } from "./section"
|
||||
import { H2, H3, H4, H5, Text, SmallText } from "./text"
|
||||
import "hono/jsx"
|
||||
import type { JSX, FC } from "hono/jsx"
|
||||
import { VStack, HStack } from "./stack"
|
||||
|
|
@ -18,7 +20,7 @@ export const Input: FC<InputProps> = (props) => {
|
|||
backgroundColor: "white",
|
||||
fontSize: "14px",
|
||||
outline: "none",
|
||||
...style,
|
||||
...(style as JSX.CSSProperties),
|
||||
}
|
||||
|
||||
if (!children) {
|
||||
|
|
@ -69,10 +71,10 @@ export const Input: FC<InputProps> = (props) => {
|
|||
|
||||
export const Test = () => {
|
||||
return (
|
||||
<VStack gap={8} style={{ padding: "24px", maxWidth: "448px" }}>
|
||||
<Section maxWidth="448px">
|
||||
{/* Basic inputs */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Basic Inputs</h2>
|
||||
<H2>Basic Inputs</H2>
|
||||
<VStack gap={4}>
|
||||
<Input placeholder="Enter your name" />
|
||||
<Input type="email" placeholder="Enter your email" />
|
||||
|
|
@ -82,7 +84,7 @@ export const Test = () => {
|
|||
|
||||
{/* Custom styling */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Custom Styling</h2>
|
||||
<H2>Custom Styling</H2>
|
||||
<VStack gap={4}>
|
||||
<Input style={{ height: "32px", fontSize: "12px" }} placeholder="Small input" />
|
||||
<Input placeholder="Default input" />
|
||||
|
|
@ -92,7 +94,7 @@ export const Test = () => {
|
|||
|
||||
{/* With values */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>With Values</h2>
|
||||
<H2>With Values</H2>
|
||||
<VStack gap={4}>
|
||||
<Input value="John Doe" placeholder="Name" />
|
||||
<Input type="email" value="john@example.com" placeholder="Email" />
|
||||
|
|
@ -101,7 +103,7 @@ export const Test = () => {
|
|||
|
||||
{/* Disabled state */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Disabled State</h2>
|
||||
<H2>Disabled State</H2>
|
||||
<VStack gap={4}>
|
||||
<Input disabled placeholder="Disabled input" style={{ opacity: 0.5, cursor: "not-allowed" }} />
|
||||
<Input disabled value="Disabled with value" style={{ opacity: 0.5, cursor: "not-allowed" }} />
|
||||
|
|
@ -110,7 +112,7 @@ export const Test = () => {
|
|||
|
||||
{/* Label above */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Label Above</h2>
|
||||
<H2>Label Above</H2>
|
||||
<VStack gap={4}>
|
||||
<Input placeholder="Enter your name">Name</Input>
|
||||
<Input type="email" placeholder="Enter your email">
|
||||
|
|
@ -124,7 +126,7 @@ export const Test = () => {
|
|||
|
||||
{/* Label to the left */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Label Left</h2>
|
||||
<H2>Label Left</H2>
|
||||
<VStack gap={4}>
|
||||
<Input labelPosition="left" placeholder="Enter your name">
|
||||
Name
|
||||
|
|
@ -140,7 +142,7 @@ export const Test = () => {
|
|||
|
||||
{/* Label to the right */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Label Right</h2>
|
||||
<H2>Label Right</H2>
|
||||
<VStack gap={4}>
|
||||
<Input labelPosition="right" placeholder="Enter your name">
|
||||
Name
|
||||
|
|
@ -156,7 +158,7 @@ export const Test = () => {
|
|||
|
||||
{/* Horizontal layout */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Horizontal Layout</h2>
|
||||
<H2>Horizontal Layout</H2>
|
||||
<HStack gap={4}>
|
||||
<Input placeholder="First name">First</Input>
|
||||
<Input placeholder="Last name">Last</Input>
|
||||
|
|
@ -166,7 +168,7 @@ export const Test = () => {
|
|||
|
||||
{/* Custom styling */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Custom Input Styling</h2>
|
||||
<H2>Custom Input Styling</H2>
|
||||
<VStack gap={4}>
|
||||
<Input style={{ borderColor: "#93c5fd" }} placeholder="Custom styled input">
|
||||
<span style={{ color: "#2563eb", fontWeight: "bold" }}>Custom Label</span>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { Section } from "./section"
|
||||
import { H2, H3, H4, H5, Text, SmallText } from "./text"
|
||||
import "hono/jsx"
|
||||
import { Avatar } from "./avatar"
|
||||
import type { AvatarProps } from "./avatar"
|
||||
|
|
@ -34,19 +36,19 @@ export const Placeholder = {
|
|||
|
||||
export const Test = () => {
|
||||
return (
|
||||
<VStack gap={8} style={{ padding: "24px" }}>
|
||||
<Section>
|
||||
{/* === AVATAR TESTS === */}
|
||||
|
||||
{/* Show all available avatar styles */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>
|
||||
<H2>
|
||||
All Avatar Styles ({allStyles.length} total)
|
||||
</h2>
|
||||
</H2>
|
||||
<Grid cols={10} gap={3}>
|
||||
{allStyles.map((style) => (
|
||||
<VStack h="center" gap={1} key={style}>
|
||||
<Placeholder.Avatar type={style} size={48} />
|
||||
<p style={{ fontSize: "12px", fontWeight: "500" }}>{style}</p>
|
||||
<SmallText style={{ fontWeight: "500" }}>{style}</Text>
|
||||
</VStack>
|
||||
))}
|
||||
</Grid>
|
||||
|
|
@ -54,12 +56,12 @@ export const Test = () => {
|
|||
|
||||
{/* Avatar size variations */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Avatar Size Variations</h2>
|
||||
<H2>Avatar Size Variations</H2>
|
||||
<HStack gap={4}>
|
||||
{[24, 32, 48, 64].map((size) => (
|
||||
<VStack h="center" gap={2} key={size}>
|
||||
<Placeholder.Avatar size={size} />
|
||||
<p style={{ fontSize: "14px" }}>{size}px</p>
|
||||
<Text>{size}px</Text>
|
||||
</VStack>
|
||||
))}
|
||||
</HStack>
|
||||
|
|
@ -67,41 +69,41 @@ export const Test = () => {
|
|||
|
||||
{/* Avatar styling combinations */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Avatar Styling Options</h2>
|
||||
<H2>Avatar Styling Options</H2>
|
||||
<HStack gap={6}>
|
||||
<VStack h="center" gap={2}>
|
||||
<Placeholder.Avatar rounded size={64} />
|
||||
<p style={{ fontSize: "14px" }}>Rounded + Background</p>
|
||||
<Text>Rounded + Background</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<div style={{ backgroundColor: "#e5e7eb", padding: "8px" }}>
|
||||
<Placeholder.Avatar rounded transparent size={64} />
|
||||
</div>
|
||||
<p style={{ fontSize: "14px" }}>Rounded + Transparent</p>
|
||||
<Text>Rounded + Transparent</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Placeholder.Avatar size={64} />
|
||||
<p style={{ fontSize: "14px" }}>Square + Background</p>
|
||||
<Text>Square + Background</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<div style={{ backgroundColor: "#e5e7eb", padding: "8px" }}>
|
||||
<Placeholder.Avatar transparent size={64} />
|
||||
</div>
|
||||
<p style={{ fontSize: "14px" }}>Square + Transparent</p>
|
||||
<Text>Square + Transparent</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</VStack>
|
||||
|
||||
{/* Avatar seed variations */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>
|
||||
<H2>
|
||||
Avatar Seeds (Same Style, Different People)
|
||||
</h2>
|
||||
</H2>
|
||||
<HStack gap={4}>
|
||||
{["alice", "bob", "charlie", "diana"].map((seed) => (
|
||||
<VStack h="center" gap={2} key={seed}>
|
||||
<Placeholder.Avatar seed={seed} size={64} />
|
||||
<p style={{ fontSize: "14px" }}>"{seed}"</p>
|
||||
<Text>"{seed}"</Text>
|
||||
</VStack>
|
||||
))}
|
||||
</HStack>
|
||||
|
|
@ -109,11 +111,11 @@ export const Test = () => {
|
|||
|
||||
{/* === IMAGE TESTS === */}
|
||||
<VStack gap={6}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Placeholder Images</h2>
|
||||
<H2>Placeholder Images</H2>
|
||||
|
||||
{/* Size variations */}
|
||||
<VStack gap={3}>
|
||||
<h3 style={{ fontSize: "18px", fontWeight: "600" }}>Size Variations</h3>
|
||||
<H3>Size Variations</H3>
|
||||
<HStack gap={4}>
|
||||
{[
|
||||
{ width: 100, height: 100 },
|
||||
|
|
@ -123,9 +125,9 @@ export const Test = () => {
|
|||
].map(({ width, height }) => (
|
||||
<VStack h="center" gap={2} key={`${width}x${height}`}>
|
||||
<Placeholder.Image width={width} height={height} seed={1} />
|
||||
<p style={{ fontSize: "14px" }}>
|
||||
<Text>
|
||||
{width}×{height}
|
||||
</p>
|
||||
</Text>
|
||||
</VStack>
|
||||
))}
|
||||
</HStack>
|
||||
|
|
@ -133,14 +135,14 @@ export const Test = () => {
|
|||
|
||||
{/* Different seeds - show variety */}
|
||||
<VStack gap={3}>
|
||||
<h3 style={{ fontSize: "18px", fontWeight: "600" }}>
|
||||
<H3>
|
||||
Different Images (Different Seeds)
|
||||
</h3>
|
||||
</H3>
|
||||
<HStack gap={4}>
|
||||
{[1, 2, 3, 4, 5].map((seed) => (
|
||||
<VStack h="center" gap={2} key={seed}>
|
||||
<Placeholder.Image width={150} height={150} seed={seed} />
|
||||
<p style={{ fontSize: "14px" }}>Seed {seed}</p>
|
||||
<Text>Seed {seed}</Text>
|
||||
</VStack>
|
||||
))}
|
||||
</HStack>
|
||||
|
|
@ -148,7 +150,7 @@ export const Test = () => {
|
|||
|
||||
{/* With custom styles */}
|
||||
<VStack gap={3}>
|
||||
<h3 style={{ fontSize: "18px", fontWeight: "600" }}>With Custom Styles</h3>
|
||||
<H3>With Custom Styles</H3>
|
||||
<HStack gap={6}>
|
||||
<VStack h="center" gap={2}>
|
||||
<Placeholder.Image
|
||||
|
|
@ -158,7 +160,7 @@ export const Test = () => {
|
|||
objectFit="cover"
|
||||
style={{ borderRadius: "8px", border: "4px solid #3b82f6" }}
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>Rounded + Border</p>
|
||||
<Text>Rounded + Border</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Placeholder.Image
|
||||
|
|
@ -168,7 +170,7 @@ export const Test = () => {
|
|||
objectFit="cover"
|
||||
style={{ boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)" }}
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>With Shadow</p>
|
||||
<Text>With Shadow</Text>
|
||||
</VStack>
|
||||
<VStack h="center" gap={2}>
|
||||
<Placeholder.Image
|
||||
|
|
@ -182,7 +184,7 @@ export const Test = () => {
|
|||
boxShadow: "0 10px 15px rgba(0, 0, 0, 0.3)",
|
||||
}}
|
||||
/>
|
||||
<p style={{ fontSize: "14px" }}>Circular + Effects</p>
|
||||
<Text>Circular + Effects</Text>
|
||||
</VStack>
|
||||
</HStack>
|
||||
</VStack>
|
||||
|
|
|
|||
48
src/section.tsx
Normal file
48
src/section.tsx
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import "hono/jsx"
|
||||
import type { FC, PropsWithChildren, JSX } from "hono/jsx"
|
||||
import { VStack } from "./stack"
|
||||
import type { TailwindSize } from "./types"
|
||||
|
||||
type SectionProps = PropsWithChildren & {
|
||||
gap?: TailwindSize
|
||||
maxWidth?: string
|
||||
style?: JSX.CSSProperties
|
||||
}
|
||||
|
||||
export const Section: FC<SectionProps> = ({ children, gap = 8, maxWidth, style }) => {
|
||||
return (
|
||||
<VStack gap={gap} style={{ padding: "24px", maxWidth, ...style }}>
|
||||
{children}
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
|
||||
export const Test = () => {
|
||||
return (
|
||||
<div>
|
||||
<Section>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Default Section</h2>
|
||||
<p>This is a section with default gap (8)</p>
|
||||
<p>It has padding and vertical spacing between children</p>
|
||||
</Section>
|
||||
|
||||
<Section gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Compact Section</h2>
|
||||
<p>This section has a smaller gap (4)</p>
|
||||
<p>Items are closer together</p>
|
||||
</Section>
|
||||
|
||||
<Section gap={12}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Spacious Section</h2>
|
||||
<p>This section has a larger gap (12)</p>
|
||||
<p>Items have more breathing room</p>
|
||||
</Section>
|
||||
|
||||
<Section maxWidth="600px" style={{ backgroundColor: "#f3f4f6" }}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Constrained Width Section</h2>
|
||||
<p>This section has a max width of 600px and a gray background</p>
|
||||
<p>Good for centering content on wide screens</p>
|
||||
</Section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import { Section } from "./section"
|
||||
import { H2, H3, H4, H5, Text, SmallText } from "./text"
|
||||
import "hono/jsx"
|
||||
import type { JSX, FC } from "hono/jsx"
|
||||
import { VStack, HStack } from "./stack"
|
||||
|
|
@ -158,10 +160,10 @@ export const Test = () => {
|
|||
]
|
||||
|
||||
return (
|
||||
<VStack gap={8} style={{ padding: "24px", maxWidth: "448px" }}>
|
||||
<Section maxWidth="448px">
|
||||
{/* Basic selects */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Basic Selects</h2>
|
||||
<H2>Basic Selects</H2>
|
||||
<VStack gap={4}>
|
||||
<Select options={months} placeholder="Select month" />
|
||||
<Select options={years} placeholder="Select year" />
|
||||
|
|
@ -171,7 +173,7 @@ export const Test = () => {
|
|||
|
||||
{/* With values */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>With Values</h2>
|
||||
<H2>With Values</H2>
|
||||
<VStack gap={4}>
|
||||
<Select options={months} value="03" />
|
||||
<Select options={years} value="2025" />
|
||||
|
|
@ -180,7 +182,7 @@ export const Test = () => {
|
|||
|
||||
{/* Disabled state */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Disabled State</h2>
|
||||
<H2>Disabled State</H2>
|
||||
<VStack gap={4}>
|
||||
<Select
|
||||
options={months}
|
||||
|
|
@ -194,7 +196,7 @@ export const Test = () => {
|
|||
|
||||
{/* Custom styling */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Custom Styling</h2>
|
||||
<H2>Custom Styling</H2>
|
||||
<VStack gap={4}>
|
||||
<Select options={countries} style={{ borderColor: "#93c5fd" }} placeholder="Custom styled select" />
|
||||
<Select options={months} style={{ height: "32px", fontSize: "12px" }} placeholder="Small select" />
|
||||
|
|
@ -203,7 +205,7 @@ export const Test = () => {
|
|||
|
||||
{/* Label above */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Label Above</h2>
|
||||
<H2>Label Above</H2>
|
||||
<VStack gap={4}>
|
||||
<Select options={months} placeholder="Select month">
|
||||
Birth Month
|
||||
|
|
@ -219,7 +221,7 @@ export const Test = () => {
|
|||
|
||||
{/* Label to the left */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Label Left</h2>
|
||||
<H2>Label Left</H2>
|
||||
<VStack gap={4}>
|
||||
<Select labelPosition="left" options={months} placeholder="Select month">
|
||||
Month
|
||||
|
|
@ -235,7 +237,7 @@ export const Test = () => {
|
|||
|
||||
{/* Label to the right */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Label Right</h2>
|
||||
<H2>Label Right</H2>
|
||||
<VStack gap={4}>
|
||||
<Select labelPosition="right" options={months} placeholder="Select month">
|
||||
Month
|
||||
|
|
@ -248,7 +250,7 @@ export const Test = () => {
|
|||
|
||||
{/* Horizontal layout (like card form) */}
|
||||
<VStack gap={4}>
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold" }}>Horizontal Layout</h2>
|
||||
<H2>Horizontal Layout</H2>
|
||||
<HStack gap={4}>
|
||||
<Select options={months} placeholder="MM">
|
||||
Expires
|
||||
|
|
@ -258,6 +260,6 @@ export const Test = () => {
|
|||
</Select>
|
||||
</HStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ import type { TailwindSize } from "./types"
|
|||
import "hono/jsx"
|
||||
import type { FC, PropsWithChildren, JSX } from "hono/jsx"
|
||||
import { Grid } from "./grid"
|
||||
import { Section } from "./section"
|
||||
import { H2 } from "./text"
|
||||
import { RedBox, GreenBox, BlueBox } from "./box"
|
||||
|
||||
export const VStack: FC<VStackProps> = (props) => {
|
||||
return (
|
||||
|
|
@ -64,10 +67,10 @@ export const Test = () => {
|
|||
const crossAxisOpts: CrossAxisOpts[] = ["start", "center", "end", "stretch", "baseline"]
|
||||
|
||||
return (
|
||||
<VStack gap={8} style={{ padding: "16px" }}>
|
||||
<Section gap={8} style={{ padding: "16px" }}>
|
||||
{/* HStack layout matrix */}
|
||||
<VStack gap={2}>
|
||||
<h2 style={{ fontSize: "18px", fontWeight: "bold" }}>HStack Layout</h2>
|
||||
<H2>HStack Layout</H2>
|
||||
<div style={{ overflowX: "auto" }}>
|
||||
<Grid cols={7} gap={1} style={{ gridTemplateColumns: "auto repeat(6, 1fr)" }}>
|
||||
{/* Header row: blank + h labels */}
|
||||
|
|
@ -90,9 +93,9 @@ export const Test = () => {
|
|||
v={v}
|
||||
style={{ backgroundColor: "#f3f4f6", padding: "8px", height: "96px", border: "1px solid #9ca3af" }}
|
||||
>
|
||||
<div style={{ textAlign: "center", padding: "4px", backgroundColor: "#ef4444" }}>Aa</div>
|
||||
<div style={{ textAlign: "center", padding: "4px", backgroundColor: "#22c55e" }}>Aa</div>
|
||||
<div style={{ textAlign: "center", padding: "4px", backgroundColor: "#3b82f6" }}>Aa</div>
|
||||
<RedBox>Aa</RedBox>
|
||||
<GreenBox>Aa</GreenBox>
|
||||
<BlueBox>Aa</BlueBox>
|
||||
</HStack>
|
||||
)),
|
||||
])}
|
||||
|
|
@ -102,7 +105,7 @@ export const Test = () => {
|
|||
|
||||
{/* VStack layout matrix */}
|
||||
<VStack gap={2}>
|
||||
<h2 style={{ fontSize: "18px", fontWeight: "bold" }}>VStack Layout</h2>
|
||||
<H2>VStack Layout</H2>
|
||||
<div style={{ overflowX: "auto" }}>
|
||||
<Grid cols={6} gap={1} style={{ gridTemplateColumns: "auto repeat(5, 1fr)" }}>
|
||||
{/* Header row: blank + h labels */}
|
||||
|
|
@ -125,16 +128,16 @@ export const Test = () => {
|
|||
h={h}
|
||||
style={{ backgroundColor: "#f3f4f6", padding: "8px", height: "168px", border: "1px solid #9ca3af" }}
|
||||
>
|
||||
<div style={{ textAlign: "center", padding: "4px", backgroundColor: "#ef4444" }}>Aa</div>
|
||||
<div style={{ textAlign: "center", padding: "4px", backgroundColor: "#22c55e" }}>Aa</div>
|
||||
<div style={{ textAlign: "center", padding: "4px", backgroundColor: "#3b82f6" }}>Aa</div>
|
||||
<RedBox>Aa</RedBox>
|
||||
<GreenBox>Aa</GreenBox>
|
||||
<BlueBox>Aa</BlueBox>
|
||||
</VStack>
|
||||
)),
|
||||
])}
|
||||
</Grid>
|
||||
</div>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
73
src/text.tsx
Normal file
73
src/text.tsx
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import "hono/jsx"
|
||||
import type { FC, PropsWithChildren, JSX } from "hono/jsx"
|
||||
|
||||
type TextProps = PropsWithChildren & {
|
||||
style?: JSX.CSSProperties
|
||||
}
|
||||
|
||||
export const H1: FC<TextProps> = ({ children, style }) => (
|
||||
<h1 style={{ fontSize: "24px", fontWeight: "bold", ...style }}>{children}</h1>
|
||||
)
|
||||
|
||||
export const H2: FC<TextProps> = ({ children, style }) => (
|
||||
<h2 style={{ fontSize: "20px", fontWeight: "bold", ...style }}>{children}</h2>
|
||||
)
|
||||
|
||||
export const H3: FC<TextProps> = ({ children, style }) => (
|
||||
<h3 style={{ fontSize: "18px", fontWeight: "600", ...style }}>{children}</h3>
|
||||
)
|
||||
|
||||
export const H4: FC<TextProps> = ({ children, style }) => (
|
||||
<h4 style={{ fontSize: "16px", fontWeight: "600", ...style }}>{children}</h4>
|
||||
)
|
||||
|
||||
export const H5: FC<TextProps> = ({ children, style }) => (
|
||||
<h5 style={{ fontSize: "14px", fontWeight: "500", ...style }}>{children}</h5>
|
||||
)
|
||||
|
||||
export const Text: FC<TextProps> = ({ children, style }) => (
|
||||
<p style={{ fontSize: "14px", ...style }}>{children}</p>
|
||||
)
|
||||
|
||||
export const SmallText: FC<TextProps> = ({ children, style }) => (
|
||||
<p style={{ fontSize: "12px", ...style }}>{children}</p>
|
||||
)
|
||||
|
||||
export const Test = () => {
|
||||
return (
|
||||
<div style={{ padding: "24px", display: "flex", flexDirection: "column", gap: "32px" }}>
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
|
||||
<H1>Heading 1 (24px, bold)</H1>
|
||||
<H2>Heading 2 (20px, bold)</H2>
|
||||
<H3>Heading 3 (18px, semibold)</H3>
|
||||
<H4>Heading 4 (16px, semibold)</H4>
|
||||
<H5>Heading 5 (14px, medium)</H5>
|
||||
<Text>Regular text (14px)</Text>
|
||||
<SmallText>Small text (12px)</SmallText>
|
||||
</div>
|
||||
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
|
||||
<H2>Custom Styling</H2>
|
||||
<Text style={{ color: "#3b82f6" }}>Blue text with custom color</Text>
|
||||
<Text style={{ fontWeight: "bold", fontStyle: "italic" }}>Bold italic text</Text>
|
||||
<SmallText style={{ color: "#ef4444", textTransform: "uppercase" }}>
|
||||
Red uppercase small text
|
||||
</SmallText>
|
||||
</div>
|
||||
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: "8px", maxWidth: "600px" }}>
|
||||
<H2>Typography Example</H2>
|
||||
<H3>Article Title</H3>
|
||||
<Text>
|
||||
This is a paragraph of regular text. It demonstrates how the Text component can be used for body
|
||||
content in articles, blog posts, or any other long-form content.
|
||||
</Text>
|
||||
<Text>
|
||||
Multiple paragraphs can be stacked together to create readable content with consistent styling
|
||||
throughout your application.
|
||||
</Text>
|
||||
<SmallText style={{ color: "#64748b" }}>Last updated: Today</SmallText>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -25,8 +25,8 @@ app.get('/', c => {
|
|||
})
|
||||
|
||||
function testFiles(): string[] {
|
||||
return readdirSync('./test')
|
||||
.filter(x => x.endsWith('.tsx') && !x.startsWith('server'))
|
||||
return readdirSync('./src')
|
||||
.filter(x => x.endsWith('.tsx') && !x.startsWith('index'))
|
||||
.map(x => x.replace('.tsx', ''))
|
||||
.sort()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user