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
1 change: 1 addition & 0 deletions apps/preskok/content/docs/forms/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"list-box",
"choice-box",
"multi-select",
"token-field",
"tag-field",
"tag-group",
"calendar",
Expand Down
76 changes: 76 additions & 0 deletions apps/preskok/content/docs/forms/token-field.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: Token Field
description: Enter free text with selectable inline tokens.
status: new
---

import { CodeTabs } from "@/components/code-tabs"
import { ComponentPreview } from "@/components/component-preview"
import { ComponentSource } from "@/components/component-source"

<ComponentPreview
name="token-field-preskok-demo"
description="A vehicle note that tokenizes statuses and mentions inline."
/>

## Installation

<CodeTabs>

<TabsList>
<TabsTrigger id="cli">CLI</TabsTrigger>
<TabsTrigger id="manual">Manual</TabsTrigger>
</TabsList>
<TabsContent id="cli">

```bash
npx preskok-ui@latest add token-field
```

</TabsContent>

<TabsContent id="manual">

<Steps>

<Step>

Copy and paste the following code into your project.

<ComponentSource
name="token-field"
title="registry/preskok/ui/preskok-ui/token-field.tsx"
/>

</Step>
<Step>Update the import paths to match your project setup.</Step>

</Steps>

</TabsContent>

</CodeTabs>

## Usage

```tsx
import { TokenFieldValue } from "react-aria-components/TokenField"

import { Token, TokenField } from "@/components/ui/preskok-ui/token-field"

const value = new TokenFieldValue([
{ type: "text", text: "Find " },
{ type: "token", text: "status:available" },
])

export function TokenFieldDemo() {
return (
<TokenField defaultValue={value} label="Inventory query">
{(segment) => <Token>{segment.text}</Token>}
</TokenField>
)
}
```

`TokenField` uses a `TokenFieldValue` to represent its sequence of text and token
segments. Extend that value class when the field needs custom tokenization rules.
12 changes: 12 additions & 0 deletions apps/preskok/content/docs/layout/table.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ import { ComponentSource } from "@/components/component-source"
description="Table with drag and drop functionality."
/>

## Interactive cells

<ComponentPreview
name="table-interactive-cells-preskok-demo"
description="Tab between text fields inside selectable table rows."
/>

Set `keyboardNavigationBehavior="tab"` when cells contain interactive controls.
This keeps arrow keys and text input inside the control while

<kbd>Tab</kbd> moves through each focusable cell.

## Installation

<CodeTabs>
Expand Down
7 changes: 7 additions & 0 deletions apps/preskok/content/docs/popups/menu.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ export function MenuDemo() {

## Examples

### Context Menu

<ComponentPreview
name="menu-context-menu-preskok-demo"
description="Open the menu from a right click, keyboard command, or long press."
/>

### Submenu

<ComponentPreview
Expand Down
1 change: 1 addition & 0 deletions apps/preskok/content/docs/popups/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"modal",
"drawer",
"popover",
"preview-trigger",
"sheet",
"tooltip",
"context-menu",
Expand Down
78 changes: 78 additions & 0 deletions apps/preskok/content/docs/popups/preview-trigger.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: Preview Trigger
description: Display an interactive popover on hover, focus, or long press.
status: new
---

import { CodeTabs } from "@/components/code-tabs"
import { ComponentPreview } from "@/components/component-preview"
import { ComponentSource } from "@/components/component-source"

<ComponentPreview
name="preview-trigger-preskok-demo"
description="An interactive vehicle preview available across pointer, keyboard, and touch input."
/>

## Installation

<CodeTabs>

<TabsList>
<TabsTrigger id="cli">CLI</TabsTrigger>
<TabsTrigger id="manual">Manual</TabsTrigger>
</TabsList>
<TabsContent id="cli">

```bash
npx preskok-ui@latest add preview-trigger
```

</TabsContent>

<TabsContent id="manual">

<Steps>

<Step>

Copy and paste the following code into your project.

<ComponentSource
name="preview-trigger"
title="registry/preskok/ui/preskok-ui/preview-trigger.tsx"
/>

</Step>
<Step>Update the import paths to match your project setup.</Step>

</Steps>

</TabsContent>

</CodeTabs>

## Usage

```tsx
import { Link } from "@/components/ui/preskok-ui/link"
import {
PreviewContent,
PreviewTrigger,
} from "@/components/ui/preskok-ui/preview-trigger"

export function PreviewTriggerDemo() {
return (
<PreviewTrigger>
<Link href="/vehicles/volvo-ex30">Volvo EX30</Link>
<PreviewContent className="p-4">
Interactive preview content
</PreviewContent>
</PreviewTrigger>
)
}
```

Preview content opens after a warmup delay on hover or focus and on long press
for touch input. While it is open, <kbd>Tab</kbd> moves focus into the popover and

<kbd>Escape</kbd> closes it and restores focus.
11 changes: 11 additions & 0 deletions apps/preskok/content/docs/text/keyboard.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ import { ComponentSource } from "@/components/component-source"
description="Common shortcut badges."
/>

## Shortcuts

<ComponentPreview
name="keyboard-shortcuts-preskok-demo"
description="Handle platform-aware shortcuts with useKeyboard."
/>

`useKeyboard` accepts shortcut strings such as `Mod+s`, where `Mod` resolves to
Command on macOS and Control on other platforms. A shortcut handler prevents the
browser default and stops propagation unless it returns a different policy.

## Installation

```bash
Expand Down
16 changes: 16 additions & 0 deletions apps/preskok/lib/source.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
import { createElement } from "react"
import { loader } from "fumadocs-core/source"
import { statusBadgesPlugin } from "fumadocs-core/source/status-badges"
import { docs } from "fumadocs-mdx:collections/server"

export const docsRoute = ""
export const docsImageRoute = "/og/docs"

export const source = loader({
baseUrl: docsRoute,
plugins: [
statusBadgesPlugin({
renderBadge: (status) =>
createElement(
"small",
{
className:
"bg-primary/10 text-primary dark:bg-primary/15 shrink-0 rounded-full px-1.5 py-0.5 font-medium",
"data-status": status,
},
status.charAt(0).toUpperCase() + status.slice(1)
),
}),
],
source: docs.toFumadocsSource(),
})

Expand Down
9 changes: 4 additions & 5 deletions apps/preskok/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
"postinstall": "fumadocs-mdx"
},
"dependencies": {
"@internationalized/date": "^3.12.2",
"@react-aria/i18n": "^3.13.1",
"@react-stately/color": "^3.10.1",
"@internationalized/date": "^3.12.3",
"@tabler/icons-react": "^3.44.0",
"@tailwindcss/postcss": "^4.3.1",
"@tanstack/react-table": "^8.21.3",
Expand Down Expand Up @@ -49,11 +47,12 @@
"ntcjs": "^1.1.3",
"postcss": "^8.5.15",
"react": "19.2.7",
"react-aria-components": "^1.19.0",
"react-aria": "^3.51.0",
"react-aria-components": "^1.20.0",
"react-dom": "19.2.7",
"react-number-format": "^5.4.5",
"react-resizable-panels": "^4.11.2",
"react-stately": "^3.48.0",
"react-stately": "^3.49.0",
"recharts": "3.9.0",
"rimraf": "^6.1.3",
"shadcn": "^4.11.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/preskok/public/r/badge.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"files": [
{
"path": "registry/preskok/ui/preskok-ui/badge.tsx",
"content": "\"use client\"\n\nimport type { ComponentProps } from \"react\"\nimport React from \"react\"\nimport { tv, type VariantProps } from \"tailwind-variants\"\n\nconst badgeIntents = {\n primary: [\n \"[--badge-primary:color-mix(in_oklab,var(--color-primary)_10%,white_90%)] [--badge-primary-foreground:color-mix(in_oklab,var(--color-primary)_60%,white_40%)] bg-(--badge-primary)\",\n \"dark:bg-primary/15 text-primary dark:text-(--badge-primary-foreground) dark:group-hover:bg-primary/25\",\n \"group-hover:bg-[color-mix(in_oklab,var(--color-primary)_15%,white_85%)] dark:group-hover:bg-primary/20\",\n ],\n secondary: [\n \"bg-secondary group-hover:bg-border text-secondary-foreground\",\n ],\n success: [\n \"bg-emerald-500/15 text-emerald-700 group-hover:bg-emerald-500/25 dark:bg-emerald-500/10 dark:text-emerald-400 dark:group-hover:bg-emerald-500/20\",\n ],\n info: \"bg-sky-500/15 text-sky-700 group-hover:bg-sky-500/25 dark:bg-sky-500/10 dark:text-sky-300 dark:group-hover:bg-sky-500/20\",\n warning:\n \"bg-amber-400/20 text-amber-700 group-hover:bg-amber-400/30 dark:bg-amber-400/10 dark:text-amber-400 dark:group-hover:bg-amber-400/15\",\n danger:\n \"bg-red-500/15 text-red-700 group-hover:bg-red-500/25 dark:bg-red-500/10 dark:text-red-400 dark:group-hover:bg-red-500/20\",\n outline:\n \"inset-ring-border bg-transparent text-foreground group-hover:bg-secondary\",\n}\nconst badgeStyles = tv({\n base: \"inset-ring inset-ring-transparent inline-flex items-center gap-x-1.5 py-0.5 font-medium text-xs/5 **:data-[slot=icon]:size-3 forced-colors:outline\",\n variants: {\n intent: { ...badgeIntents },\n isCircle: {\n true: \"rounded-full px-2\",\n false: \"rounded-sm px-1.5\",\n },\n },\n defaultVariants: {\n intent: \"primary\",\n isCircle: true,\n },\n})\n\ninterface BadgeProps\n extends ComponentProps<\"span\">, VariantProps<typeof badgeStyles> {\n className?: string\n children: React.ReactNode\n}\n\nconst Badge = ({\n children,\n intent,\n isCircle = true,\n className,\n ...props\n}: BadgeProps) => {\n return (\n <span {...props} className={badgeStyles({ intent, isCircle, className })}>\n {children}\n </span>\n )\n}\nexport { Badge, badgeIntents, badgeStyles }\nexport type { BadgeProps }\n",
"content": "\"use client\"\n\nimport type { ComponentProps } from \"react\"\nimport React from \"react\"\nimport { tv, type VariantProps } from \"tailwind-variants\"\n\nconst badgeIntents = {\n primary: [\n \"[--badge-primary:color-mix(in_oklab,var(--color-primary)_10%,white_90%)] [--badge-primary-foreground:color-mix(in_oklab,var(--color-primary)_60%,white_40%)] bg-(--badge-primary)\",\n \"dark:bg-primary/15 text-primary dark:text-(--badge-primary-foreground) dark:group-hover:bg-primary/25\",\n \"group-hover:bg-[color-mix(in_oklab,var(--color-primary)_15%,white_85%)] dark:group-hover:bg-primary/20\",\n ],\n secondary: [\"bg-secondary group-hover:bg-border text-secondary-foreground\"],\n success: [\n \"bg-emerald-500/15 text-emerald-700 group-hover:bg-emerald-500/25 dark:bg-emerald-500/10 dark:text-emerald-400 dark:group-hover:bg-emerald-500/20\",\n ],\n info: \"bg-sky-500/15 text-sky-700 group-hover:bg-sky-500/25 dark:bg-sky-500/10 dark:text-sky-300 dark:group-hover:bg-sky-500/20\",\n warning:\n \"bg-amber-400/20 text-amber-700 group-hover:bg-amber-400/30 dark:bg-amber-400/10 dark:text-amber-400 dark:group-hover:bg-amber-400/15\",\n danger:\n \"bg-red-500/15 text-red-700 group-hover:bg-red-500/25 dark:bg-red-500/10 dark:text-red-400 dark:group-hover:bg-red-500/20\",\n outline:\n \"inset-ring-border bg-transparent text-foreground group-hover:bg-secondary\",\n}\nconst badgeStyles = tv({\n base: \"inset-ring inset-ring-transparent inline-flex items-center gap-x-1.5 py-0.5 font-medium text-xs/5 **:data-[slot=icon]:size-3 forced-colors:outline\",\n variants: {\n intent: { ...badgeIntents },\n isCircle: {\n true: \"rounded-full px-2\",\n false: \"rounded-sm px-1.5\",\n },\n },\n defaultVariants: {\n intent: \"primary\",\n isCircle: true,\n },\n})\n\ninterface BadgeProps\n extends ComponentProps<\"span\">, VariantProps<typeof badgeStyles> {\n className?: string\n children: React.ReactNode\n}\n\nconst Badge = ({\n children,\n intent,\n isCircle = true,\n className,\n ...props\n}: BadgeProps) => {\n return (\n <span {...props} className={badgeStyles({ intent, isCircle, className })}>\n {children}\n </span>\n )\n}\nexport { Badge, badgeIntents, badgeStyles }\nexport type { BadgeProps }\n",
"type": "registry:ui"
}
],
Expand Down
Loading
Loading