Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/components/aspect-ratio.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {AspectRatio} from 'kinu';

| Name | Description | Rendered HTML |
| --- | --- | --- |
| AspectRatio | Ratio container | `<div k="aspect-ratio">` |
| AspectRatio | Ratio container | |

## Props

Expand Down
2 changes: 1 addition & 1 deletion docs/components/avatar.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {Avatar} from 'kinu';

| Name | Description | Rendered HTML |
| --- | --- | --- |
| Avatar | User profile image | `<img k="avatar">` |
| Avatar | User profile image | |

## Props

Expand Down
2 changes: 1 addition & 1 deletion docs/components/button.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {Button} from 'kinu';

| Name | Description | Rendered HTML |
| --- | --- | --- |
| Button | Interactive action control | `k="button"` |
| Button | Interactive action control | `p="button"` |

## Props

Expand Down
4 changes: 2 additions & 2 deletions docs/components/carousel.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import {Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious}
| Carousel | Image slider | — |
| CarouselContent | Slider content | — |
| CarouselItem | Slide item | `<div k="carousel-item">` |
| CarouselPrevious | Previous button | `<button k="carousel-previous">` |
| CarouselNext | Next button | `<button k="carousel-next">` |
| CarouselPrevious | Previous button | |
| CarouselNext | Next button | |

## Props

Expand Down
4 changes: 2 additions & 2 deletions docs/components/color-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import {ColorPicker} from 'kinu';

| Name | Description | Rendered HTML |
| --- | --- | --- |
| ColorPicker | Color input | `<input k="color-picker">` |
| ColorPicker | Component | `<input k="color-picker">` |

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| value | `string` | — | Current color as a hex string (e.g. `"#ff0000"`). |
| value | `string | number | readonly string[] | undefined` | — | Current color value as a hex string (e.g. "#ff0000"). |
| onChange | `(event: Event) => void` | — | Change handler for the color input. |
| disabled | `boolean` | — | Disable the input. |
| name | `string` | — | Input name used for form submissions. |
Expand Down
2 changes: 1 addition & 1 deletion docs/components/context-menu.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger} fr
| --- | --- | --- |
| ContextMenuTrigger | Menu trigger | — |
| ContextMenu | Right-click menu | — |
| ContextMenuContent | Menu content | `<dialog k="context-menu">` |
| ContextMenuContent | Menu content | |
| ContextMenuItem | Menu item | `<button k="context-menu-item">` |

## Props
Expand Down
2 changes: 1 addition & 1 deletion docs/components/dialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {Dialog, DialogClose, DialogContent, DialogTrigger} from 'kinu';
| --- | --- | --- |
| Dialog | Modal overlay | — |
| DialogTrigger | Dialog trigger | — |
| DialogContent | Dialog content | `<dialog k="dialog-content">` |
| DialogContent | Dialog content | |
| DialogClose | Close button | — |

## Props
Expand Down
4 changes: 2 additions & 2 deletions docs/components/drawer.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import {Drawer, DrawerClose, DrawerContent, DrawerTrigger} from 'kinu';

| Name | Description | Rendered HTML |
| --- | --- | --- |
| Drawer | Slide-out panel | `<div k="drawer">` |
| Drawer | Slide-out panel | |
| DrawerTrigger | Drawer trigger | — |
| DrawerContent | Drawer content | `<dialog k="drawer-content">` |
| DrawerContent | Drawer content | |
| DrawerClose | Close button | — |

## Props
Expand Down
6 changes: 3 additions & 3 deletions docs/components/dropdown-menu.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ import {DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger

| Name | Description | Rendered HTML |
| --- | --- | --- |
| DropdownMenu | Dropdown menu | `<span k="dropdown">` |
| DropdownMenu | Dropdown menu | |
| DropdownMenuTrigger | Menu trigger | — |
| DropdownMenuContent | Menu content | `<dialog k="dropdown-content">` |
| DropdownMenuItem | Menu item | `k="dropdown-menu-item"` |
| DropdownMenuContent | Menu content | |
| DropdownMenuItem | Menu item | `p="dropdown-menu-item"` |

## Props

Expand Down
12 changes: 6 additions & 6 deletions docs/components/file-upload.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@ Native file input with a styled button for selecting local files.
```tsx
import {FileUpload} from 'kinu';

<FileUpload />
<FileUpload accept="image/*" />
```

## Exports

| Name | Description | Rendered HTML |
| --- | --- | --- |
| FileUpload | File input | `<input k="file-upload">` |
| FileUpload | Component | `<input k="file-upload">` |

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| onChange | `(event: Event) => void` | — | Called when the user selects files. Access selected files via `event.target.files`. |
| accept | `string` | — | Allowed file types as MIME types or extensions (e.g. `"image/*"` or `".pdf,.docx"`). |
| onChange | `(event: Event) => void` | — | Change handler called when the user selects files. |
| accept | `string` | — | Allowed file types as MIME types or extensions (e.g. "image/*" or ".pdf"). |
| multiple | `boolean` | — | Allow selecting multiple files. |
| disabled | `boolean` | — | Disable the input. |
| name | `string` | — | Input name used for form submissions. |

## Notes

- Sets type="file" for you and forwards all native input props.
- Use `accept` to restrict selectable file types.
- Use `capture="user"` or `capture="environment"` to invoke the camera on mobile.
- Use the accept prop to restrict selectable file types.
- Use capture="user" or capture="environment" to invoke the camera on mobile.

---

Expand Down
7 changes: 5 additions & 2 deletions docs/components/popover.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import {Popover, PopoverClose, PopoverContent, PopoverTrigger} from 'kinu';

| Name | Description | Rendered HTML |
| --- | --- | --- |
| Popover | Floating content | `<span k="popover">` |
| Popover | Floating content | |
| PopoverTrigger | Popover trigger | — |
| PopoverContent | Popover content | `<dialog k="popover-content">` |
| PopoverContent | Popover content | |
| PopoverClose | Component | — |

## Props
Expand All @@ -36,10 +36,13 @@ import {Popover, PopoverClose, PopoverContent, PopoverTrigger} from 'kinu';
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| id | `string` | — | Override the auto-generated dialog ID. |
| mobile | `"drawer"` | — | When set to `"drawer"`, renders as a bottom-sheet drawer on mobile (≤640px)
while keeping popover behavior on larger screens. |

## Notes

- Control placement with the placement attribute on PopoverContent.
- Set `mobile="drawer"` on PopoverContent to render as a bottom-sheet drawer on small screens (≤640px).
- Stays declarative thanks to the commands polyfill.

---
Expand Down
4 changes: 2 additions & 2 deletions docs/components/sheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import {Sheet, SheetClose, SheetContent, SheetTrigger} from 'kinu';

| Name | Description | Rendered HTML |
| --- | --- | --- |
| Sheet | Overlay panel | `<div k="sheet">` |
| Sheet | Overlay panel | |
| SheetTrigger | Sheet trigger | — |
| SheetContent | Sheet content | `<dialog k="sheet-content">` |
| SheetContent | Sheet content | |
| SheetClose | Close button | — |

## Props
Expand Down
9 changes: 5 additions & 4 deletions docs/components/time-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,23 @@ import {TimePicker} from 'kinu';

| Name | Description | Rendered HTML |
| --- | --- | --- |
| TimePicker | Time input | `<input k="time-picker">` |
| TimePicker | Component | `<input k="time-picker">` |

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| value | `string \| number \| readonly string[] \| undefined` | — | Current time value in HH:MM or HH:MM:SS format. |
| value | `string | number | readonly string[] | undefined` | — | Current time value in HH:MM or HH:MM:SS format. |
| onChange | `(event: Event) => void` | — | Change handler for time input. |
| disabled | `boolean` | — | Disable the input. |
| name | `string` | — | Input name used for form submissions. |
| step | `number` | — | Granularity in seconds. Common values: 60 (1 min), 900 (15 min), 1800 (30 min). |
| step | `number` | 60 | Granularity of the time value in seconds.
Common values: 60 (1 min), 900 (15 min), 1800 (30 min). |

## Notes

- Sets type="time" for you and forwards all native input props.
- Use `step` to constrain selectable intervals, e.g. `step={1800}` for 30-minute increments.
- Use the step prop to constrain selectable intervals, e.g. step={1800} for 30-minute increments.

---

Expand Down
1 change: 1 addition & 0 deletions docs/components/toggle.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {Toggle} from 'kinu';

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| size | `"sm" | "md" | "lg"` | 'md' | Size preset for the toggle. |
| pressed | `boolean` | — | Controls the pressed state and maps to `aria-pressed` on the DOM element. |
| onClick | `(event: MouseEvent) => void` | — | Click handler for toggling state. |
| disabled | `boolean` | — | Disable the toggle. |
Expand Down
78 changes: 65 additions & 13 deletions docs/examples/popover.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,73 @@
import {Button, Popover, PopoverContent, PopoverTrigger} from 'kinu';
import {
Button,
DropdownMenuItem,
Input,
Label,
Popover,
PopoverClose,
PopoverContent,
PopoverTrigger,
Separator,
} from 'kinu';

export function Demo() {
return (
<Popover>
<PopoverTrigger>
<Button variant="outline">Open Popover</Button>
</PopoverTrigger>
<PopoverContent>
<div style={{padding: '1rem'}}>
<h3 style={{margin: '0 0 0.5rem 0'}}>Popover Content</h3>
<p style={{margin: '0'}}>This is content inside a popover.</p>
</div>
</PopoverContent>
</Popover>
<div style={{display: 'flex', gap: '1rem', flexWrap: 'wrap'}}>
<Popover>
<PopoverTrigger>
<Button variant="outline">Dimensions</Button>
</PopoverTrigger>
<PopoverContent>
<div style={{display: 'flex', flexDirection: 'column', gap: '0.75rem', padding: '1rem'}}>
<p style={{margin: 0, fontWeight: 500}}>Set dimensions</p>
<div style={{display: 'grid', gridTemplateColumns: 'auto 1fr', alignItems: 'center', gap: '0.5rem 0.75rem'}}>
<Label htmlFor="pop-w">Width</Label>
<Input id="pop-w" type="number" value="320" size="sm" />
<Label htmlFor="pop-h">Height</Label>
<Input id="pop-h" type="number" value="240" size="sm" />
</div>
</div>
</PopoverContent>
</Popover>

<Popover>
<PopoverTrigger>
<Button variant="outline">Adaptive ↕</Button>
</PopoverTrigger>
<PopoverContent mobile="drawer">
<div style={{padding: '0.5rem'}}>
<p style={{margin: '0.5rem 0.5rem 0.75rem', fontWeight: 500}}>
Pick a color
</p>
<Separator />
{['Red', 'Orange', 'Green', 'Blue', 'Purple'].map((color) => (
<DropdownMenuItem key={color}>{color}</DropdownMenuItem>
))}
<Separator />
<div style={{padding: '0.25rem'}}>
<PopoverClose>
<Button variant="outline" size="sm" style={{width: '100%'}}>
Done
</Button>
</PopoverClose>
</div>
</div>
</PopoverContent>
</Popover>
</div>
);
}

export const code = `<Popover>...</Popover>`;
export const code = `{/* Standard popover */}
<Popover>
<PopoverTrigger><Button>Dimensions</Button></PopoverTrigger>
<PopoverContent>...</PopoverContent>
</Popover>

{/* Adaptive: popover on desktop, drawer on mobile */}
<Popover>
<PopoverTrigger><Button>Pick color</Button></PopoverTrigger>
<PopoverContent mobile="drawer">...</PopoverContent>
</Popover>`;

export default {Demo, code};
36 changes: 18 additions & 18 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,15 @@
"file": "components/context-menu.md",
"description": "Right-click context menu powered by the native dialog element."
},
{
"slug": "color-picker",
"title": "Color Picker",
"section": "Components",
"category": "Data Input",
"order": 7,
"file": "components/color-picker.md",
"description": "Styled color swatch input that opens the native OS color picker."
},
{
"slug": "combobox",
"title": "Combobox",
Expand Down Expand Up @@ -431,24 +440,6 @@
"file": "components/file-upload.md",
"description": "Native file input with a styled button for selecting local files."
},
{
"slug": "time-picker",
"title": "Time Picker",
"section": "Components",
"category": "Data Input",
"order": 9,
"file": "components/time-picker.md",
"description": "Styled time input that shares the same foundation as Date Picker."
},
{
"slug": "color-picker",
"title": "Color Picker",
"section": "Components",
"category": "Data Input",
"order": 7,
"file": "components/color-picker.md",
"description": "Styled color swatch input that opens the native OS color picker."
},
{
"slug": "sheet",
"title": "Sheet",
Expand All @@ -467,6 +458,15 @@
"file": "components/label.md",
"description": "Typography-aligned label component for form controls."
},
{
"slug": "time-picker",
"title": "Time Picker",
"section": "Components",
"category": "Data Input",
"order": 9,
"file": "components/time-picker.md",
"description": "Styled time input that shares the same foundation as Date Picker."
},
{
"slug": "textarea",
"title": "Textarea",
Expand Down
1 change: 1 addition & 0 deletions docs/metadata.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ export default [
usage: `<Popover>\n <PopoverTrigger><Button>Open</Button></PopoverTrigger>\n <PopoverContent>Content</PopoverContent>\n <PopoverClose><Button>Close</Button></PopoverClose>\n</Popover>`,
notes: [
'Control placement with the placement attribute on PopoverContent.',
'Set `mobile="drawer"` on PopoverContent to render as a bottom-sheet drawer on small screens (≤640px).',
'Stays declarative thanks to the commands polyfill.'
]
},
Expand Down
13 changes: 13 additions & 0 deletions src/components/button/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@
text-decoration: none;
}

/* Variant: input */
[k="button"][variant="input"] {
border: 1px solid hsl(var(--k-input));
background-color: hsl(var(--k-background));
color: hsl(var(--k-foreground));
font-weight: 400;
justify-content: flex-start;
}

[k="button"][variant="input"]:hover {
border-color: hsl(var(--k-ring));
}

/* Size: sm */
[k="button"][size="sm"] {
height: 2.25rem;
Expand Down
3 changes: 2 additions & 1 deletion src/components/button/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export type ButtonVariant =
| 'outline'
| 'secondary'
| 'ghost'
| 'link';
| 'link'
| 'input';

/**
* Size presets supported by Button.
Expand Down
Loading
Loading