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