diff --git a/.changeset/CHANGELOG.md b/.changeset/CHANGELOG.md new file mode 100644 index 0000000..f149d3f --- /dev/null +++ b/.changeset/CHANGELOG.md @@ -0,0 +1,48 @@ +# @arkitect-ui/react & @arkitect-ui/solid Changelog + +All notable changes to this project will be documented in this file. + +## [0.2.0] - 2026-02-28 + +### Added + +#### React Components + +- **Alert Dialog** - Modal dialog for alerts and confirmations +- **Avatar** - User avatar with fallback support +- **Badge** - Status badges and labels +- **Button** - Multi-variant button component +- **Card** - Container card component +- **Center** - Centering layout utility +- **Chart** - Recharts-based chart component +- **Checkbox** - Custom checkbox input +- **Collapsible** - Expandable/collapsible content +- **Combobox** - Autocomplete/combobox dropdown +- **Copy Id Button** - Copy element ID to clipboard +- **Data Table** - TanStack table implementation +- **Data Table Filters** - Table filtering utilities +- **Dialog** - Modal dialog component +- **Dropdown Menu** - Dropdown menu component +- **Empty** - Empty state placeholder +- **Float** - Floating element positioning +- **Grid** - CSS Grid layout component +- **Grid Pattern** - Grid background pattern +- **Input** - Text input component +- **Input Group** - Input with added controls/buttons +- **Label** - Form label component +- **Marquee** - Scrolling text marquee +- **Pagination** - Pagination controls +- **Select** - Custom select dropdown +- **Separator** - Visual divider +- **Sheet** - Slide-out panel +- **Sidebar** - Collapsible sidebar navigation +- **Skeleton** - Loading placeholder +- **Stack** - Flexbox layout utility +- **Table** - Data table component +- **Textarea** - Multi-line text input +- **Toast** - Toast notification system +- **Tooltip** - Hover tooltip component + +#### Solid.js Components + +All React components listed above are also available for Solid.js with the same API. diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..e5b6d8d --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..ad6f18a --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.changeset/great-deer-relate.md b/.changeset/great-deer-relate.md new file mode 100644 index 0000000..0079044 --- /dev/null +++ b/.changeset/great-deer-relate.md @@ -0,0 +1,44 @@ +--- +"@arkitect-ui/react": minor +"@arkitect-ui/solid": minor +"@arkitect-ui/shared": patch +--- + +# Initial Component Release + +## React Components + +- **Alert Dialog** - Modal dialog for alerts and confirmations +- **Avatar** - User avatar with fallback support +- **Badge** - Status badges and labels +- **Button** - Multi-variant button component +- **Card** - Container card component +- **Center** - Centering layout utility +- **Chart** - Recharts-based chart component +- **Checkbox** - Custom checkbox input +- **Collapsible** - Expandable/collapsible content +- **Combobox** - Autocomplete/combobox dropdown +- **Copy Id Button** - Copy element ID to clipboard +- **Data Table** - TanStack table implementation +- **Data Table Filters** - Table filtering utilities +- **Dialog** - Modal dialog component +- **Dropdown Menu** - Dropdown menu component +- **Empty** - Empty state placeholder +- **Float** - Floating element positioning +- **Grid** - CSS Grid layout component +- **Grid Pattern** - Grid background pattern +- **Input** - Text input component +- **Input Group** - Input with added controls/buttons +- **Label** - Form label component +- **Marquee** - Scrolling text marquee +- **Pagination** - Pagination controls +- **Select** - Custom select dropdown +- **Separator** - Visual divider +- **Sheet** - Slide-out panel +- **Sidebar** - Collapsible sidebar navigation +- **Skeleton** - Loading placeholder +- **Stack** - Flexbox layout utility +- **Table** - Data table component +- **Textarea** - Multi-line text input +- **Toast** - Toast notification system +- **Tooltip** - Hover tooltip component diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 0000000..a33195f --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,7 @@ +// Folder-specific settings +// +// For a full list of overridable settings, and general information on folder-specific settings, +// see the documentation: https://zed.dev/docs/configuring-zed#settings-files +{ + "hidden_files": ["node_modules"] +} diff --git a/apps/docs/astro.config.ts b/apps/docs/astro.config.ts index 83fb07c..167f5ff 100644 --- a/apps/docs/astro.config.ts +++ b/apps/docs/astro.config.ts @@ -60,11 +60,40 @@ export default defineConfig({ { label: "Components", items: [ + "react/components/alert-dialog", + "react/components/avatar", + "react/components/badge", "react/components/button", + "react/components/card", + "react/components/center", + "react/components/chart", + "react/components/checkbox", + "react/components/collapsible", + "react/components/combobox", + "react/components/copy-id-button", + "react/components/data-table", + "react/components/data-table-filters", "react/components/dialog", "react/components/dropdown-menu", + "react/components/empty", + "react/components/float", + "react/components/grid", + "react/components/grid-pattern", "react/components/input", + "react/components/input-group", + "react/components/marquee", "react/components/label", + "react/components/pagination", + "react/components/select", + "react/components/separator", + "react/components/sheet", + "react/components/sidebar", + "react/components/skeleton", + "react/components/stack", + "react/components/table", + "react/components/textarea", + "react/components/toast", + "react/components/tooltip", ], }, ], @@ -82,11 +111,40 @@ export default defineConfig({ { label: "Components", items: [ + "solid/components/alert-dialog", + "solid/components/avatar", + "solid/components/badge", "solid/components/button", + "solid/components/card", + "solid/components/center", + "solid/components/chart", + "solid/components/checkbox", + "solid/components/collapsible", + "solid/components/combobox", + "solid/components/copy-id-button", + "solid/components/data-table", + "solid/components/data-table-filters", "solid/components/dialog", "solid/components/dropdown-menu", + "solid/components/empty", + "solid/components/float", + "solid/components/grid", + "solid/components/grid-pattern", "solid/components/input", + "solid/components/input-group", + "solid/components/marquee", "solid/components/label", + "solid/components/pagination", + "solid/components/select", + "solid/components/separator", + "solid/components/sheet", + "solid/components/sidebar", + "solid/components/skeleton", + "solid/components/stack", + "solid/components/table", + "solid/components/textarea", + "solid/components/toast", + "solid/components/tooltip", ], }, ], diff --git a/apps/docs/package.json b/apps/docs/package.json index 2bd7585..da852ad 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -31,6 +31,7 @@ "react-dom": "catalog:", "sharp": "catalog:", "solid-js": "catalog:", + "starlight-changelogs": "catalog:", "starlight-sidebar-topics": "catalog:", "starlight-sidebar-topics-dropdown": "catalog:", "starlight-theme-nova": "catalog:", diff --git a/apps/docs/src/content/docs/react/components/alert-dialog.mdx b/apps/docs/src/content/docs/react/components/alert-dialog.mdx new file mode 100644 index 0000000..0761408 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/alert-dialog.mdx @@ -0,0 +1,80 @@ +--- +title: Alert Dialog +description: A modal dialog that interrupts the user with important content and expects a response. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import alertDialogCode from "../../../../../../../packages/react/src/components/ui/alert-dialog.tsx?raw"; + +## Component + + + + + + + + Are you absolutely sure? + + This action cannot be undone. This will permanently delete your account + and remove your data from our servers. + + + + Cancel + Continue + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/alert-dialog.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/alert-dialog.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/alert-dialog.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/avatar.mdx b/apps/docs/src/content/docs/react/components/avatar.mdx new file mode 100644 index 0000000..a28255b --- /dev/null +++ b/apps/docs/src/content/docs/react/components/avatar.mdx @@ -0,0 +1,54 @@ +--- +title: Avatar +description: An image element with a fallback for loading and error states. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import avatarCode from "../../../../../../../packages/react/src/components/ui/avatar.tsx?raw"; + +## Component + + + + CN + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/avatar.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/avatar.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/avatar.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/react/components/badge.mdx b/apps/docs/src/content/docs/react/components/badge.mdx new file mode 100644 index 0000000..c2aefce --- /dev/null +++ b/apps/docs/src/content/docs/react/components/badge.mdx @@ -0,0 +1,56 @@ +--- +title: Badge +description: Displays a badge or a component that looks like a badge. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import badgeCode from "../../../../../../../packages/react/src/components/ui/badge.tsx?raw"; + +## Component + + + Default + Secondary + Destructive + Outline + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/badge.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/badge.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/badge.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/react/components/card.mdx b/apps/docs/src/content/docs/react/components/card.mdx new file mode 100644 index 0000000..1c3f610 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/card.mdx @@ -0,0 +1,62 @@ +--- +title: Card +description: Displays a card with header, content, and footer. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import cardCode from "../../../../../../../packages/react/src/components/ui/card.tsx?raw"; + +## Component + + + + Card Title + Card description goes here. + + +

Card content goes here.

+
+ +

Card footer

+
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/card.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/card.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/card.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/react/components/center.mdx b/apps/docs/src/content/docs/react/components/center.mdx new file mode 100644 index 0000000..a2e45d1 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/center.mdx @@ -0,0 +1,53 @@ +--- +title: Center +description: A layout component that centers its content. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import centerCode from "../../../../../../../packages/react/src/components/ui/center.tsx?raw"; + +## Component + + + Centered Content + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/center.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/center.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/center.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/react/components/chart.mdx b/apps/docs/src/content/docs/react/components/chart.mdx new file mode 100644 index 0000000..79dc943 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/chart.mdx @@ -0,0 +1,63 @@ +--- +title: Chart +description: A component that displays data in charts using Recharts. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import chartCode from "../../../../../../../packages/react/src/components/ui/chart.tsx?raw"; + +## Component + + + + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/chart.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/chart.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/chart.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/checkbox.mdx b/apps/docs/src/content/docs/react/components/checkbox.mdx new file mode 100644 index 0000000..22a2dc4 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/checkbox.mdx @@ -0,0 +1,56 @@ +--- +title: Checkbox +description: A control that allows the user to toggle between checked and not checked. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import checkboxCode from "../../../../../../../packages/react/src/components/ui/checkbox.tsx?raw"; + +## Component + + + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/checkbox.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/checkbox.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/checkbox.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/react/components/collapsible.mdx b/apps/docs/src/content/docs/react/components/collapsible.mdx new file mode 100644 index 0000000..085fe4a --- /dev/null +++ b/apps/docs/src/content/docs/react/components/collapsible.mdx @@ -0,0 +1,65 @@ +--- +title: Collapsible +description: An expandable content container that shows and hides content on click. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import collapsibleCode from "../../../../../../../packages/react/src/components/ui/collapsible.tsx?raw"; + +## Component + + + + Can I use this in my project? + + Yes. You can use this component in your projects. + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/collapsible.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/collapsible.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/collapsible.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/combobox.mdx b/apps/docs/src/content/docs/react/components/combobox.mdx new file mode 100644 index 0000000..df84ced --- /dev/null +++ b/apps/docs/src/content/docs/react/components/combobox.mdx @@ -0,0 +1,100 @@ +--- +title: Combobox +description: A dropdown component with search functionality and keyboard navigation. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import comboboxCode from "../../../../../../../packages/react/src/components/ui/combobox.tsx?raw"; + +## Component + +([]) + + return ( + + + + + + + + + + + + + {frameworks.items[0].label} + + + + + + {frameworks.items[1].label} + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/combobox.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/combobox.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/combobox.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/copy-id-button.mdx b/apps/docs/src/content/docs/react/components/copy-id-button.mdx new file mode 100644 index 0000000..00e4e84 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/copy-id-button.mdx @@ -0,0 +1,54 @@ +--- +title: Copy ID Button +description: A button component that copies an ID to the clipboard. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import copyIdButtonCode from "../../../../../../../packages/react/src/components/ui/copy-id-button.tsx?raw"; + +## Component + + + user_123456789 + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/copy-id-button.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/copy-id-button.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/copy-id-button.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/data-table-filters.mdx b/apps/docs/src/content/docs/react/components/data-table-filters.mdx new file mode 100644 index 0000000..a082155 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/data-table-filters.mdx @@ -0,0 +1,81 @@ +--- +title: DataTableFilters +description: Filter controls for data tables with text, select, and date inputs. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components" +import ComponentPreview from "@/components/ComponentPreview.astro" +import dataTableFiltersCode from "../../../../../../../packages/react/src/components/ui/data-table-filters.tsx?raw" + +## Component + + console.log("Filter values:", values)} + /> + ) +}`} + /> + +## Installation + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/data-table-filters.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/data-table-filters.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/data-table-filters.json + ``` + + + + + + + + +## API Reference + +### FilterConfigType + +```ts +type FilterConfig = { + id: string + type: "text" | "select" | "date" + label: string + placeholder?: string + options?: { label: string; value: string }[] +} +``` + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `filters` | `FilterConfig[]` | `[]` | Array of filter configurations | +| `values` | `Record` | `{}` | Current filter values | +| `onFilterChange` | `(values: Record) => void` | - | Callback when filter values change | diff --git a/apps/docs/src/content/docs/react/components/data-table.mdx b/apps/docs/src/content/docs/react/components/data-table.mdx new file mode 100644 index 0000000..633461e --- /dev/null +++ b/apps/docs/src/content/docs/react/components/data-table.mdx @@ -0,0 +1,77 @@ +--- +title: DataTable +description: A table component with column definitions and data rendering. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components" +import ComponentPreview from "@/components/ComponentPreview.astro" +import dataTableCode from "../../../../../../../packages/react/src/components/ui/data-table.tsx?raw" + +## Component + + + ) +}`} +/> + + +## Installation + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/data-table.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/data-table.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/data-table.json + ``` + + + + + + + + + +## API Reference + +### `Column` + +```ts +interface Column { + accessorKey?: keyof T + header?: string | React.ReactNode + cell?: (row: T) => React.ReactNode + accessorFn?: (row: T) => unknown +} +``` + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `columns` | `Column[]` | - | Array of column definitions | +| `data` | `T[]` | - | Array of data to display | +| `caption` | `string` | - | Table caption | +| `emptyMessage` | `string` | `"No data available"` | Message to show when no data | \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/empty.mdx b/apps/docs/src/content/docs/react/components/empty.mdx new file mode 100644 index 0000000..aadc760 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/empty.mdx @@ -0,0 +1,60 @@ +--- +title: Empty +description: A component for displaying empty states with optional image, title, and description. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import emptyCode from "../../../../../../../packages/react/src/components/ui/empty.tsx?raw"; + +## Component + + + + + + No files found + + Try adjusting your search or filter to find what you're looking for. + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/empty.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/empty.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/empty.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/react/components/float.mdx b/apps/docs/src/content/docs/react/components/float.mdx new file mode 100644 index 0000000..18b241b --- /dev/null +++ b/apps/docs/src/content/docs/react/components/float.mdx @@ -0,0 +1,68 @@ +--- +title: Float +description: A simple positioning component for floating content relative to a trigger. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import floatCode from "../../../../../../../packages/react/src/components/ui/float.tsx?raw"; + +## Component + + +
+ + {isOpen && ( + +
+

Floating content here

+
+
+ )} +
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/float.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/float.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/float.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/grid-pattern.mdx b/apps/docs/src/content/docs/react/components/grid-pattern.mdx new file mode 100644 index 0000000..6e783c4 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/grid-pattern.mdx @@ -0,0 +1,56 @@ +--- +title: Grid Pattern +description: A component that displays a grid pattern background. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import gridPatternCode from "../../../../../../../packages/react/src/components/ui/grid-pattern.tsx?raw"; + +## Component + + + +
+ Grid Pattern Background +
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/grid-pattern.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/grid-pattern.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/grid-pattern.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/react/components/grid.mdx b/apps/docs/src/content/docs/react/components/grid.mdx new file mode 100644 index 0000000..97a4462 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/grid.mdx @@ -0,0 +1,58 @@ +--- +title: Grid +description: A layout component that displays items in a grid. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import gridCode from "../../../../../../../packages/react/src/components/ui/grid.tsx?raw"; + +## Component + + +
Item 1
+
Item 2
+
Item 3
+
Item 4
+
Item 5
+
Item 6
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/grid.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/grid.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/grid.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/input-group.mdx b/apps/docs/src/content/docs/react/components/input-group.mdx new file mode 100644 index 0000000..f86a872 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/input-group.mdx @@ -0,0 +1,58 @@ +--- +title: Input Group +description: A component that groups an input with an add-on. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import inputGroupCode from "../../../../../../../packages/react/src/components/ui/input-group.tsx?raw"; + +## Component + + + https:// + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/input-group.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/input-group.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/input-group.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/marquee.mdx b/apps/docs/src/content/docs/react/components/marquee.mdx new file mode 100644 index 0000000..0fd128b --- /dev/null +++ b/apps/docs/src/content/docs/react/components/marquee.mdx @@ -0,0 +1,57 @@ +--- +title: Marquee +description: A slider component that scrolls infinitely. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import marqueeCode from "../../../../../../../packages/react/src/components/ui/marquee.tsx?raw"; + +## Component + + +
Slide 1
+
Slide 2
+
Slide 3
+
Slide 4
+
Slide 5
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/marquee.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/marquee.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/marquee.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/pagination.mdx b/apps/docs/src/content/docs/react/components/pagination.mdx new file mode 100644 index 0000000..363ebda --- /dev/null +++ b/apps/docs/src/content/docs/react/components/pagination.mdx @@ -0,0 +1,72 @@ +--- +title: Pagination +description: A pagination component for navigating through pages of data. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import paginationCode from "../../../../../../../packages/react/src/components/ui/pagination.tsx?raw"; + +## Component + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/pagination.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/pagination.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/pagination.json + ``` + + + + + + + + +## API Reference + +### Pagination + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `page` | `number` | - | Current page number | +| `totalPages` | `number` | - | Total number of pages | +| `pageSize` | `number` | 10 | Number of items per page | +| `pageSizeOptions` | `number[]` | [10, 25, 50, 100] | Available page size options | +| `onPageChange` | `(page: number) => void` | - | Callback when page changes | +| `onPageSizeChange` | `(pageSize: number) => void` | - | Callback when page size changes | +| `className` | `string` | - | Additional CSS classes | \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/select.mdx b/apps/docs/src/content/docs/react/components/select.mdx new file mode 100644 index 0000000..916a96e --- /dev/null +++ b/apps/docs/src/content/docs/react/components/select.mdx @@ -0,0 +1,61 @@ +--- +title: Select +description: Displays a select component with options. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import selectCode from "../../../../../../../packages/react/src/components/ui/select.tsx?raw"; + +## Component + + + + + + + Apple + Banana + Orange + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/select.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/select.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/select.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/react/components/separator.mdx b/apps/docs/src/content/docs/react/components/separator.mdx new file mode 100644 index 0000000..0c9c64b --- /dev/null +++ b/apps/docs/src/content/docs/react/components/separator.mdx @@ -0,0 +1,59 @@ +--- +title: Separator +description: Displays a separator between content. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import separatorCode from "../../../../../../../packages/react/src/components/ui/separator.tsx?raw"; + +## Component + + +
+ Content above separator +
+ +
+ Content below separator +
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/separator.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/separator.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/separator.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/react/components/sheet.mdx b/apps/docs/src/content/docs/react/components/sheet.mdx new file mode 100644 index 0000000..2c570e8 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/sheet.mdx @@ -0,0 +1,77 @@ +--- +title: Sheet +description: A panel that slides in from the edge of the screen. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import sheetCode from "../../../../../../../packages/react/src/components/ui/sheet.tsx?raw"; + +## Component + + + + + + + + Edit profile + + Make changes to your profile here. Click save when you're done. + + +
+
+

Name

+ +
+
+
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/sheet.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/sheet.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/sheet.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/sidebar.mdx b/apps/docs/src/content/docs/react/components/sidebar.mdx new file mode 100644 index 0000000..a76abe7 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/sidebar.mdx @@ -0,0 +1,95 @@ +--- +title: Sidebar +description: A vertical navigation component that can collapse and expand. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import sidebarCode from "../../../../../../../packages/react/src/components/ui/sidebar.tsx?raw"; + +## Component + + + + + setCollapsed(!collapsed)} + /> + + + + Navigation + + + + Home + + + + Users + + + + + + + + Settings + + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/sidebar.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/sidebar.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/sidebar.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/skeleton.mdx b/apps/docs/src/content/docs/react/components/skeleton.mdx new file mode 100644 index 0000000..fd00dca --- /dev/null +++ b/apps/docs/src/content/docs/react/components/skeleton.mdx @@ -0,0 +1,57 @@ +--- +title: Skeleton +description: A placeholder preview while content is loading. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import skeletonCode from "../../../../../../../packages/react/src/components/ui/skeleton.tsx?raw"; + +## Component + + + +
+ + +
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/skeleton.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/skeleton.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/skeleton.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/react/components/stack.mdx b/apps/docs/src/content/docs/react/components/stack.mdx new file mode 100644 index 0000000..6ab8100 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/stack.mdx @@ -0,0 +1,55 @@ +--- +title: Stack +description: A layout component that stacks its children vertically or horizontally. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import stackCode from "../../../../../../../packages/react/src/components/ui/stack.tsx?raw"; + +## Component + + +
Item 1
+
Item 2
+
Item 3
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/stack.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/stack.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/stack.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/table.mdx b/apps/docs/src/content/docs/react/components/table.mdx new file mode 100644 index 0000000..a21a166 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/table.mdx @@ -0,0 +1,162 @@ +--- +title: Table +description: A table component for displaying data in rows and columns. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import tableCode from "../../../../../../../packages/react/src/components/ui/table.tsx?raw"; + +## Component + + + A list of your recent invoices. + + + Invoice + Status + Method + Amount + + + + + INV001 + Paid + Credit Card + $250.00 + + + INV002 + Pending + PayPal + $150.00 + + + INV003 + Paid + Bank Transfer + $350.00 + + + + + Total + $750.00 + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/table.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/table.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/table.json + ``` + + + + + + + + +## API Reference + +### Table + +The main table container component. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `className` | `string` | - | Additional CSS classes | + +### TableHeader + +The table header container. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `className` | `string` | - | Additional CSS classes | + +### TableBody + +The table body container. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `className` | `string` | - | Additional CSS classes | + +### TableFooter + +The table footer container. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `className` | `string` | - | Additional CSS classes | + +### TableRow + +A table row component. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `className` | `string` | - | Additional CSS classes | + +### TableHead + +A table header cell component. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `className` | `string` | - | Additional CSS classes | + +### TableCell + +A table cell component. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `className` | `string` | - | Additional CSS classes | + +### TableCaption + +A table caption component. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `className` | `string` | - | Additional CSS classes | \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/textarea.mdx b/apps/docs/src/content/docs/react/components/textarea.mdx new file mode 100644 index 0000000..c8a8c44 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/textarea.mdx @@ -0,0 +1,54 @@ +--- +title: Textarea +description: A component for entering multi-line text. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import textareaCode from "../../../../../../../packages/react/src/components/ui/textarea.tsx?raw"; + +## Component + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/textarea.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/textarea.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/textarea.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/react/components/toast.mdx b/apps/docs/src/content/docs/react/components/toast.mdx new file mode 100644 index 0000000..e728aa6 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/toast.mdx @@ -0,0 +1,125 @@ +--- +title: Toast +description: A toast component for displaying notifications using Ark UI. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import toastCode from "../../../../../../../packages/react/src/components/ui/toast.tsx?raw"; + +## Component + + + + + + + + ) +}`} +/> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/toast.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/toast.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/toast.json + ``` + + + + + + + + +## Usage + +The Toast component uses Ark UI's toast primitive. You need to render the `Toaster` component in your app root and use the `toast` function to display notifications. + +```tsx +import { Toaster, toast } from "@/components/ui/toast" + +function App() { + return ( + <> + + + + ) +} +``` + +### toast function + +The `toast` function accepts either a string or an object: + +```tsx +// Simple usage +toast("Event created") + +// With options +toast({ + title: "Event created", + description: "Your event has been saved successfully", + type: "success", // "info" | "success" | "error" | "warning" + duration: 5000, +}) +``` + +### Convenience methods + +```tsx +toast.success("Operation successful") +toast.error("Something went wrong") +toast.warning("Please review your input") +toast.info("New update available") +toast.dismiss() // Dismiss all toasts +toast.dismiss(id) // Dismiss specific toast +``` diff --git a/apps/docs/src/content/docs/react/components/tooltip.mdx b/apps/docs/src/content/docs/react/components/tooltip.mdx new file mode 100644 index 0000000..6106ac5 --- /dev/null +++ b/apps/docs/src/content/docs/react/components/tooltip.mdx @@ -0,0 +1,60 @@ +--- +title: Tooltip +description: A component that displays a tooltip on hover or focus. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import tooltipCode from "../../../../../../../packages/react/src/components/ui/tooltip.tsx?raw"; + +## Component + + + + + Hover me + + + This is a tooltip + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/tooltip.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/tooltip.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/tooltip.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/alert-dialog.mdx b/apps/docs/src/content/docs/solid/components/alert-dialog.mdx new file mode 100644 index 0000000..2afe46a --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/alert-dialog.mdx @@ -0,0 +1,80 @@ +--- +title: Alert Dialog +description: A modal dialog that interrupts the user with important content and expects a response. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import alertDialogCode from "../../../../../../../packages/solid/src/components/ui/alert-dialog.tsx?raw"; + +## Component + + + + + + + + Are you absolutely sure? + + This action cannot be undone. This will permanently delete your account + and remove your data from our servers. + + + + Cancel + Continue + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/alert_dialog.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/alert_dialog.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/alert_dialog.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/avatar.mdx b/apps/docs/src/content/docs/solid/components/avatar.mdx new file mode 100644 index 0000000..c1598f8 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/avatar.mdx @@ -0,0 +1,54 @@ +--- +title: Avatar +description: An image element with a fallback for loading and error states. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import avatarCode from "../../../../../../../packages/solid/src/components/ui/avatar.tsx?raw"; + +## Component + + + + CN + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/avatar.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/avatar.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/avatar.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/solid/components/badge.mdx b/apps/docs/src/content/docs/solid/components/badge.mdx new file mode 100644 index 0000000..a92f727 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/badge.mdx @@ -0,0 +1,56 @@ +--- +title: Badge +description: Displays a badge or a component that looks like a badge. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import badgeCode from "../../../../../../../packages/solid/src/components/ui/badge.tsx?raw"; + +## Component + + + Default + Secondary + Destructive + Outline + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/badge.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/badge.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/badge.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/solid/components/card.mdx b/apps/docs/src/content/docs/solid/components/card.mdx new file mode 100644 index 0000000..c84c353 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/card.mdx @@ -0,0 +1,62 @@ +--- +title: Card +description: Displays a card with header, content, and footer. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import cardCode from "../../../../../../../packages/solid/src/components/ui/card.tsx?raw"; + +## Component + + + + Card Title + Card description goes here. + + +

Card content goes here.

+
+ +

Card footer

+
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/card.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/card.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/card.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/solid/components/center.mdx b/apps/docs/src/content/docs/solid/components/center.mdx new file mode 100644 index 0000000..b8c44f4 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/center.mdx @@ -0,0 +1,53 @@ +--- +title: Center +description: A layout component that centers its content. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import centerCode from "../../../../../../../packages/solid/src/components/ui/center.tsx?raw"; + +## Component + + + Centered Content + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/center.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/center.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/center.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/chart.mdx b/apps/docs/src/content/docs/solid/components/chart.mdx new file mode 100644 index 0000000..6ae575a --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/chart.mdx @@ -0,0 +1,63 @@ +--- +title: Chart +description: A component that displays data in charts using Recharts. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import chartCode from "../../../../../../../packages/solid/src/components/ui/chart.tsx?raw"; + +## Component + + + + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/chart.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/chart.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/chart.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/checkbox.mdx b/apps/docs/src/content/docs/solid/components/checkbox.mdx new file mode 100644 index 0000000..d628b9a --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/checkbox.mdx @@ -0,0 +1,56 @@ +--- +title: Checkbox +description: A control that allows the user to toggle between checked and not checked. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import checkboxCode from "../../../../../../../packages/solid/src/components/ui/checkbox.tsx?raw"; + +## Component + + + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/checkbox.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/checkbox.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/checkbox.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/solid/components/collapsible.mdx b/apps/docs/src/content/docs/solid/components/collapsible.mdx new file mode 100644 index 0000000..a0666b6 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/collapsible.mdx @@ -0,0 +1,65 @@ +--- +title: Collapsible +description: An expandable content container that shows and hides content on click. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import collapsibleCode from "../../../../../../../packages/solid/src/components/ui/collapsible.tsx?raw"; + +## Component + + + + Can I use this in my project? + + Yes. You can use this component in your projects. + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/collapsible.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/collapsible.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/collapsible.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/combobox.mdx b/apps/docs/src/content/docs/solid/components/combobox.mdx new file mode 100644 index 0000000..3becfcb --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/combobox.mdx @@ -0,0 +1,100 @@ +--- +title: Combobox +description: A dropdown component with search functionality and keyboard navigation. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import comboboxCode from "../../../../../../../packages/solid/src/components/ui/combobox.tsx?raw"; + +## Component + +([]) + + return ( + + + + + + + + + + + + + {frameworks.items[0].label} + + + + + + {frameworks.items[1].label} + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/combobox.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/combobox.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/combobox.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/copy-id-button.mdx b/apps/docs/src/content/docs/solid/components/copy-id-button.mdx new file mode 100644 index 0000000..a7ce8b3 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/copy-id-button.mdx @@ -0,0 +1,54 @@ +--- +title: Copy ID Button +description: A button component that copies an ID to the clipboard. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import copyIdButtonCode from "../../../../../../../packages/solid/src/components/ui/copy-id-button.tsx?raw"; + +## Component + + + user_123456789 + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/copy-id-button.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/copy-id-button.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/copy-id-button.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/data-table-filters.mdx b/apps/docs/src/content/docs/solid/components/data-table-filters.mdx new file mode 100644 index 0000000..6ac61ce --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/data-table-filters.mdx @@ -0,0 +1,104 @@ +--- +title: DataTableFilters +description: Filter controls for data tables with text, select, and date inputs. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components" +import ComponentPreview from "@/components/ComponentPreview.astro" +import dataTableFiltersCode from "../../../../../../../packages/solid/src/components/ui/data-table-filters.tsx?raw" + +## Component + + console.log("Filter values:", values)} + /> + ) +}`} + /> + +## Installation + +```bash +npx arkitect-ui@latest add data-table-filters +``` + +## Usage + +```tsx +import { DataTableFilters } from "@arkitect-ui/solid" +``` + +## Examples + +### Default + + + +## Installation + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/data-table-filters.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/data-table-filters.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/data-table-filters.json + ``` + + + + + + + + +## API Reference + +### FilterConfigType + +```ts +type FilterConfig = { + id: string + type: "text" | "select" | "date" + label: string + placeholder?: string + options?: { label: string; value: string }[] +} +``` + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `filters` | `FilterConfig[]` | `[]` | Array of filter configurations | +| `values` | `Record` | `{}` | Current filter values | +| `onFilterChange` | `(values: Record) => void` | - | Callback when filter values change | diff --git a/apps/docs/src/content/docs/solid/components/data-table.mdx b/apps/docs/src/content/docs/solid/components/data-table.mdx new file mode 100644 index 0000000..8f7ccb6 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/data-table.mdx @@ -0,0 +1,89 @@ +--- +title: DataTable +description: A table component with column definitions and data rendering. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components" +import ComponentPreview from "@/components/ComponentPreview.astro" +import dataTableCode from "../../../../../../../packages/solid/src/components/ui/data-table.tsx?raw" + +## Component + + row.status === "active" ? "Active" : "Inactive", + }, +] + +const data = [ + { id: 1, name: "John Doe", email: "john@example.com", status: "active" }, + { id: 2, name: "Jane Smith", email: "jane@example.com", status: "inactive" }, + { id: 3, name: "Bob Johnson", email: "bob@example.com", status: "active" }, +] + +export function DataTableDemo() { + return +}`} +/> + + +## Installation + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/data-table.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/data-table.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/data-table.json + ``` + + + + + + + + + +## API Reference + +### `Column` + +```ts +interface Column { + accessorKey?: keyof T + header?: string + cell?: (row: T) => unknown + accessorFn?: (row: T) => unknown +} +``` + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `columns` | `Column[]` | - | Array of column definitions | +| `data` | `T[]` | - | Array of data to display | +| `caption` | `string` | - | Table caption | +| `emptyMessage` | `string` | `"No data available"` | Message to show when no data | diff --git a/apps/docs/src/content/docs/solid/components/empty.mdx b/apps/docs/src/content/docs/solid/components/empty.mdx new file mode 100644 index 0000000..b4c3729 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/empty.mdx @@ -0,0 +1,60 @@ +--- +title: Empty +description: A component for displaying empty states with optional image, title, and description. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import emptyCode from "../../../../../../../packages/solid/src/components/ui/empty.tsx?raw"; + +## Component + + + + + + No files found + + Try adjusting your search or filter to find what you're looking for. + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/empty.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/empty.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/empty.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/solid/components/float.mdx b/apps/docs/src/content/docs/solid/components/float.mdx new file mode 100644 index 0000000..cc75c30 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/float.mdx @@ -0,0 +1,68 @@ +--- +title: Float +description: A simple positioning component for floating content relative to a trigger. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import floatCode from "../../../../../../../packages/solid/src/components/ui/float.tsx?raw"; + +## Component + + +
+ + + +
+

Floating content here

+
+
+
+
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/float.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/float.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/float.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/grid-pattern.mdx b/apps/docs/src/content/docs/solid/components/grid-pattern.mdx new file mode 100644 index 0000000..1b7a0e3 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/grid-pattern.mdx @@ -0,0 +1,56 @@ +--- +title: Grid Pattern +description: A component that displays a grid pattern background. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import gridPatternCode from "../../../../../../../packages/solid/src/components/ui/grid-pattern.tsx?raw"; + +## Component + + + +
+ Grid Pattern Background +
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/grid-pattern.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/grid-pattern.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/grid-pattern.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/grid.mdx b/apps/docs/src/content/docs/solid/components/grid.mdx new file mode 100644 index 0000000..4720061 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/grid.mdx @@ -0,0 +1,58 @@ +--- +title: Grid +description: A layout component that displays items in a grid. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import gridCode from "../../../../../../../packages/solid/src/components/ui/grid.tsx?raw"; + +## Component + + +
Item 1
+
Item 2
+
Item 3
+
Item 4
+
Item 5
+
Item 6
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/grid.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/grid.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/grid.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/input-group.mdx b/apps/docs/src/content/docs/solid/components/input-group.mdx new file mode 100644 index 0000000..208c053 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/input-group.mdx @@ -0,0 +1,58 @@ +--- +title: Input Group +description: A component that groups an input with an add-on. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import inputGroupCode from "../../../../../../../packages/solid/src/components/ui/input-group.tsx?raw"; + +## Component + + + https:// + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/input-group.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/input-group.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/input-group.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/marquee.mdx b/apps/docs/src/content/docs/solid/components/marquee.mdx new file mode 100644 index 0000000..4429100 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/marquee.mdx @@ -0,0 +1,57 @@ +--- +title: Marquee +description: A slider component that scrolls infinitely. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import marqueeCode from "../../../../../../../packages/solid/src/components/ui/marquee.tsx?raw"; + +## Component + + +
Slide 1
+
Slide 2
+
Slide 3
+
Slide 4
+
Slide 5
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/marquee.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/marquee.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/marquee.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/pagination.mdx b/apps/docs/src/content/docs/solid/components/pagination.mdx new file mode 100644 index 0000000..c695753 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/pagination.mdx @@ -0,0 +1,72 @@ +--- +title: Pagination +description: A pagination component for navigating through pages of data. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import paginationCode from "../../../../../../../packages/solid/src/components/ui/pagination.tsx?raw"; + +## Component + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/pagination.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/pagination.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/pagination.json + ``` + + + + + + + + +## API Reference + +### Pagination + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `page` | `number` | - | Current page number | +| `totalPages` | `number` | - | Total number of pages | +| `pageSize` | `number` | 10 | Number of items per page | +| `pageSizeOptions` | `number[]` | [10, 25, 50, 100] | Available page size options | +| `onPageChange` | `(page: number) => void` | - | Callback when page changes | +| `onPageSizeChange` | `(pageSize: number) => void` | - | Callback when page size changes | +| `class` | `string` | - | Additional CSS classes | \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/select.mdx b/apps/docs/src/content/docs/solid/components/select.mdx new file mode 100644 index 0000000..e5b7c05 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/select.mdx @@ -0,0 +1,60 @@ +--- +title: Select +description: Displays a select component with options. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import selectCode from "../../../../../../../packages/solid/src/components/ui/select.tsx?raw"; + +## Component + + + + + + + Apple + Banana + Orange + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/select.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/select.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/select.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/solid/components/separator.mdx b/apps/docs/src/content/docs/solid/components/separator.mdx new file mode 100644 index 0000000..936de65 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/separator.mdx @@ -0,0 +1,59 @@ +--- +title: Separator +description: Displays a separator between content. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import separatorCode from "../../../../../../../packages/solid/src/components/ui/separator.tsx?raw"; + +## Component + + +
+ Content above separator +
+ +
+ Content below separator +
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/separator.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/separator.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/separator.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/solid/components/sheet.mdx b/apps/docs/src/content/docs/solid/components/sheet.mdx new file mode 100644 index 0000000..f627386 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/sheet.mdx @@ -0,0 +1,77 @@ +--- +title: Sheet +description: A panel that slides in from the edge of the screen. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import sheetCode from "../../../../../../../packages/solid/src/components/ui/sheet.tsx?raw"; + +## Component + + + + + + + + Edit profile + + Make changes to your profile here. Click save when you're done. + + +
+
+

Name

+ +
+
+
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/sheet.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/sheet.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/sheet.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/sidebar.mdx b/apps/docs/src/content/docs/solid/components/sidebar.mdx new file mode 100644 index 0000000..78a77fd --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/sidebar.mdx @@ -0,0 +1,95 @@ +--- +title: Sidebar +description: A vertical navigation component that can collapse and expand. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import sidebarCode from "../../../../../../../packages/solid/src/components/ui/sidebar.tsx?raw"; + +## Component + + + + + setCollapsed(!collapsed())} + /> + + + + Navigation + + + + Home + + + + Users + + + + + + + + Settings + + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/sidebar.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/sidebar.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/sidebar.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/skeleton.mdx b/apps/docs/src/content/docs/solid/components/skeleton.mdx new file mode 100644 index 0000000..fdcf2db --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/skeleton.mdx @@ -0,0 +1,57 @@ +--- +title: Skeleton +description: A placeholder preview while content is loading. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import skeletonCode from "../../../../../../../packages/solid/src/components/ui/skeleton.tsx?raw"; + +## Component + + + +
+ + +
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/skeleton.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/skeleton.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/skeleton.json + ``` + + + + + + + diff --git a/apps/docs/src/content/docs/solid/components/stack.mdx b/apps/docs/src/content/docs/solid/components/stack.mdx new file mode 100644 index 0000000..2846c80 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/stack.mdx @@ -0,0 +1,55 @@ +--- +title: Stack +description: A layout component that stacks its children vertically or horizontally. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import stackCode from "../../../../../../../packages/solid/src/components/ui/stack.tsx?raw"; + +## Component + + +
Item 1
+
Item 2
+
Item 3
+ + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/stack.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/stack.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/stack.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/table.mdx b/apps/docs/src/content/docs/solid/components/table.mdx new file mode 100644 index 0000000..fd110b6 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/table.mdx @@ -0,0 +1,162 @@ +--- +title: Table +description: A table component for displaying data in rows and columns. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import tableCode from "../../../../../../../packages/solid/src/components/ui/table.tsx?raw"; + +## Component + + + A list of your recent invoices. + + + Invoice + Status + Method + Amount + + + + + INV001 + Paid + Credit Card + $250.00 + + + INV002 + Pending + PayPal + $150.00 + + + INV003 + Paid + Bank Transfer + $350.00 + + + + + Total + $750.00 + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/table.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/table.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/table.json + ``` + + + + + + + + +## API Reference + +### Table + +The main table container component. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `class` | `string` | - | Additional CSS classes | + +### TableHeader + +The table header container. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `class` | `string` | - | Additional CSS classes | + +### TableBody + +The table body container. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `class` | `string` | - | Additional CSS classes | + +### TableFooter + +The table footer container. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `class` | `string` | - | Additional CSS classes | + +### TableRow + +A table row component. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `class` | `string` | - | Additional CSS classes | + +### TableHead + +A table header cell component. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `class` | `string` | - | Additional CSS classes | + +### TableCell + +A table cell component. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `class` | `string` | - | Additional CSS classes | + +### TableCaption + +A table caption component. + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `class` | `string` | - | Additional CSS classes | \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/textarea.mdx b/apps/docs/src/content/docs/solid/components/textarea.mdx new file mode 100644 index 0000000..53186e7 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/textarea.mdx @@ -0,0 +1,54 @@ +--- +title: Textarea +description: A component for entering multi-line text. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import textareaCode from "../../../../../../../packages/solid/src/components/ui/textarea.tsx?raw"; + +## Component + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/textarea.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/textarea.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/textarea.json + ``` + + + + + + + \ No newline at end of file diff --git a/apps/docs/src/content/docs/solid/components/toast.mdx b/apps/docs/src/content/docs/solid/components/toast.mdx new file mode 100644 index 0000000..33ef540 --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/toast.mdx @@ -0,0 +1,125 @@ +--- +title: Toast +description: A toast component for displaying notifications using Ark UI. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import toastCode from "../../../../../../../packages/solid/src/components/ui/toast.tsx?raw"; + +## Component + + + + + + + + ) +}`} +/> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/toast.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/toast.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/toast.json + ``` + + + + + + + + +## Usage + +The Toast component uses Ark UI's toast primitive. You need to render the `Toaster` component in your app root and use the `toast` function to display notifications. + +```tsx +import { Toaster, toast } from "@/components/ui/toast" + +function App() { + return ( + <> + + + + ) +} +``` + +### toast function + +The `toast` function accepts either a string or an object: + +```tsx +// Simple usage +toast("Event created") + +// With options +toast({ + title: "Event created", + description: "Your event has been saved successfully", + type: "success", // "info" | "success" | "error" | "warning" + duration: 5000, +}) +``` + +### Convenience methods + +```tsx +toast.success("Operation successful") +toast.error("Something went wrong") +toast.warning("Please review your input") +toast.info("New update available") +toast.dismiss() // Dismiss all toasts +toast.dismiss(id) // Dismiss specific toast +``` diff --git a/apps/docs/src/content/docs/solid/components/tooltip.mdx b/apps/docs/src/content/docs/solid/components/tooltip.mdx new file mode 100644 index 0000000..f2860fe --- /dev/null +++ b/apps/docs/src/content/docs/solid/components/tooltip.mdx @@ -0,0 +1,60 @@ +--- +title: Tooltip +description: A component that displays a tooltip on hover or focus. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import tooltipCode from "../../../../../../../packages/solid/src/components/ui/tooltip.tsx?raw"; + +## Component + + + + + Hover me + + + This is a tooltip + + + + ) +}`} + /> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/tooltip.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/tooltip.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/s/tooltip.json + ``` + + + + + + + \ No newline at end of file diff --git a/docs/.md b/docs/componet-creation-guide.md similarity index 88% rename from docs/.md rename to docs/componet-creation-guide.md index 02cfa8a..2b105b5 100644 --- a/docs/.md +++ b/docs/componet-creation-guide.md @@ -366,65 +366,65 @@ Add to `registry.json`: } ``` - ### 8. Create Documentation +### 8. Create Documentation Create `apps/docs/src/content/docs/react/components/your-component.mdx`: - ````mdx - --- - title: Your Component - description: Description of your component. - --- - - import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; - import ComponentPreview from "@/components/ComponentPreview.astro"; - import yourComponentCode from "../../../../../../../packages/react/src/components/ui/your-component.tsx?raw"; - - ## Component - - - {/* Example usage */} - - ) - }`} - /> +````mdx +--- +title: Your Component +description: Description of your component. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; +import ComponentPreview from "@/components/ComponentPreview.astro"; +import yourComponentCode from "../../../../../../../packages/react/src/components/ui/your-component.tsx?raw"; + +## Component - ## Installation - - - - - - ```bash - npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/your-component.json - ``` - - - ```bash - pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/your-component.json - ``` - - - ```bash - bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/your-component.json - ``` - - - - - - - - ```` + + {/* Example usage */} + + ) +}`} +/> + +## Installation + + + + + + ```bash + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/your-component.json + ``` + + + ```bash + pnpm dlx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/your-component.json + ``` + + + ```bash + bunx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/your-component.json + ``` + + + + + + + +```` ### 9. Update Astro Config diff --git a/docs/prd-component-library.md b/docs/prd-component-library.md new file mode 100644 index 0000000..7171d7d --- /dev/null +++ b/docs/prd-component-library.md @@ -0,0 +1,475 @@ +# PRD: Arkitect UI - Biblioteca de Componentes UI + +## Resumen Ejecutivo + +Arkitect UI es una biblioteca de componentes UI que ofrece compatibilidad API externa con Shadcn UI mientras utiliza Ark UI internamente como primitive. El proyecto soporta tanto React como Solid.js con la misma API pública, permitiendo a los desarrolladores migrar fácilmente desde Shadcn o usar la biblioteca con cualquier framework soportado. + +## Estado Actual del Proyecto + +### Componentes Existentes + +| Componente | React | Solid | Stories | +| ------------- | ----- | ----- | ------- | +| button | ✅ | ✅ | ✅ | +| input | ✅ | ✅ | ✅ | +| label | ✅ | ✅ | ✅ | +| dialog | ✅ | ✅ | ✅ | +| dropdown-menu | ✅ | ✅ | ✅ | + +### Estructura del Proyecto + +``` +packages/ +├── react/ # Componentes React +│ └── src/ +│ ├── components/ui/ +│ └── index.ts +├── solid/ # Componentes Solid.js +│ └── src/ +│ ├── components/ui/ +│ └── index.tsx +└── shared/ # Utilidades compartidas +apps/ +├── docs/ # Documentación (Astro Starlight) +└── ... +``` + +## Requisitos del Proyecto + +### Alcance + +Implementar 30 componentes UI para ambos paquetes (React + Solid) manteniendo compatibilidad API con Shadcn UI: + +**Lote 1 (10 componentes)** + +- button (existente) +- input (existente) +- label (existente) +- dialog (existente) +- dropdown-menu (existente) +- badge (NUEVO) +- card (NUEVO) +- checkbox (NUEVO) +- select (NUEVO) +- separator (NUEVO) + +**Lote 2 (10 componentes)** + +- alert-dialog +- avatar +- collapsible +- combobox +- empty +- float +- sheet +- sidebar +- skeleton +- sonner + +**Lote 3 (10 componentes)** + +- center +- chart +- copy-id-button +- data-table +- data-table-filters +- grid-pattern +- grid +- infinite-slider +- input-group +- textarea +- tooltip + +### Compatibilidad API con Shadcn + +Todos los componentes deben mantener compatibilidad API con Shadcn UI: + +#### Exportación de Componentes + +```typescript +// shadcn +import { Button, buttonVariants } from "@/components/ui/button" + +// arkitect (misma API) +import { Button, buttonVariants } from "@arkitect-ui/react" +``` + +#### Props y Tipos + +- Mantener mismos nombres de props que Shadcn +- Soportar todas las variantes de Shadcn +- Mantener tipos de TypeScript compatibles +- Usar forwardRef para compatibilidad de refs + +#### Estilos CSS + +- Usar clases Tailwind CSS idénticas a Shadcn +- Mantener data attributes para estados (data-[state=open], etc.) +- Soportar tokens de diseño de Shadcn + +### Requisitos Técnicos + +#### Stack Tecnológico + +- **Framework UI**: React 19, Solid.js 1.9 +- **Primitives**: Ark UI (@ark-ui/react, @ark-ui/solid) +- **Estilos**: Tailwind CSS v4 +- **Variantes**: class-variance-authority (CVA) +- **Iconos**: Tabler Icons (@tabler/icons-react, @tabler/icons-solidjs) +- **Testing**: Vitest +- **Documentación**: Storybook, Astro Starlight + +#### Patrones de Implementación + +**React:** + +```typescript +import { Component } from "@ark-ui/react" +import { cva, type VariantProps } from "class-variance-authority" +import { type ComponentProps, forwardRef } from "react" +import { cn } from "@/lib/utils" + +const componentVariants = cva("base-classes", { + variants: { + variant: { + default: "variant-classes", + }, + size: { + default: "size-classes", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, +}) + +export interface ComponentProps extends ComponentProps<"element">, VariantProps { + asChild?: boolean +} + +const Component = forwardRef( + ({ className, variant, size, ...props }, ref) => { + return ( + + ) + }, +) +Component.displayName = "Component" + +export { Component, componentVariants } +``` + +**Solid:** + +```typescript +import { Component } from "@ark-ui/solid" +import { cva, type VariantProps } from "class-variance-authority" +import { type ComponentProps, splitProps } from "solid-js" +import { cn } from "@/lib/utils" + +const componentVariants = cva("base-classes", {/* ... */}) + +export interface ComponentProps extends ComponentProps<"element">, VariantProps {} + +export const Component = (props: ComponentProps) => { + const [local, rest] = splitProps(props, ["class", "variant", "size"]) + + return ( + + ) +} +``` + +#### Diferencias Clave Ark UI vs Radix + +| Radix (Shadcn) | Ark UI | +| --------------- | --------------------------------- | +| Menu.Root | Menu.Root | +| Menu.Trigger | Menu.Trigger | +| Menu.Content | Menu.Content + Positioner | +| Menu.Item | Menu.Item (requiere prop `value`) | +| Menu.RadioGroup | Menu.RadioItemGroup | +| Portal | Positioner | + +## Requisitos de Testing + +### Tests Unitarios (Vitest) + +Cada componente debe incluir: + +- Tests para variantes +- Tests para sizes +- Tests para estados (disabled, focus, etc.) +- Tests para props personalizadas +- Tests de accesibilidad básica + +```typescript +// Ejemplo estructura test +import { describe, expect, it } from "vitest" +import { render, screen } from "@testing-library/react" +import { Component } from "./component" + +describe("Component", () => { + it("renders with default variant", () => { + render(Content) + expect(screen.getByText("Content")).toBeDefined() + }) + + it("renders with custom variant", () => { + render(Content) + expect(screen.getByText("Content")).toBeDefined() + }) + + it("handles disabled state", () => { + render(Content) + expect(screen.getByText("Content")).toBeDisabled() + }) +}) +``` + +### Stories (Storybook) + +Cada componente debe incluir stories para: + +- Default/state básico +- Todas las variantes +- Todos los sizes +- Estados interactivos (hover, focus, disabled) +- Casos de uso comunes + +```typescript +// Ejemplo estructura story +import type { Meta, StoryObj } from "@storybook/react-vite" +import { Component } from "./component" + +const meta: Meta = { + title: "React/UI/Component", + component: Component, +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => Content, +} + +export const VariantSecondary: Story = { + render: () => Content, +} +``` + +## Requisitos de Documentación + +### Documentación MDX + +Cada componente debe tener documentación en `apps/docs/src/content/docs/react/components/` y `apps/docs/src/content/docs/solid/components/`: + +````mdx +--- +title: Component Name +description: Description of the component. +--- + +import { Tabs, TabItem, Code } from "@astrojs/starlight/components" +import ComponentPreview from "@/components/ComponentPreview.astro" + +## Component + + + +## Installation + + + + npx shadcn@latest add https://devx-op.github.io/arkitect-ui/r/r/component.json + + + + + + +## Usage + +```tsx +import { Component } from "@arkitect-ui/react" +```` + +## Props + +| Prop | Type | Default | Description | +| ------- | ------------------------ | --------- | --------------------- | +| variant | "default" \| "secondary" | "default" | Visual style | +| size | "sm" \| "md" \| "lg" | "md" | Size of the component | + +```` +### Actualización de Archivos + +#### exports (index.ts / index.tsx) + +```typescript +export * from "./components/ui/new-component" +```` + +#### registry.json + +```json +{ + "name": "r/new-component", + "type": "registry:ui", + "title": "React New Component", + "description": "New component for react", + "author": "Arkitect-UI (http://devx-ops https://devx-op.github.io/arkitect-ui/)", + "dependencies": ["@ark-ui/react", "@tabler/icons-react"], + "files": [{ + "path": "packages/react/src/components/ui/new-component.tsx", + "type": "registry:ui" + }] +}, + +{ + "name": "s/new-component", + "type": "registry:ui", + "title": "Solid New Component", + "description": "New Component for solid", + "author": "Arkitect-UI (http://devx-ops https://devx-op.github.io/arkitect-ui/)", + "dependencies": [ + "@ark-ui/solid", "@tabler/icons-solid" + ], + "files": [ + { + "path": "packages/solid/src/components/ui/new-component.tsx", + "type": "registry:ui"; + } + ] +}, +``` + +#### Sidebar Navigation (astro.config.ts) + +```typescript +{ + label: "Components", + items: [ + "react/components/button", + "react/components/new-component", + ], +} +``` + +## Skill de Creación de Componentes + +### Ubicación + +Extender el documento existente en `docs/componet-creation-guide.md` con instrucciones específicas para esta iniciativa. + +### Contenido de la Skill + +1. **Análisis de Referencia**: Cómo obtener código de Shadcn +2. **Mapeo Radix → Ark UI**: Tabla de conversiones +3. **Templates**: Código base para React y Solid +4. **Checklist**: Lista de verificación de implementación +5. **Patrones Comunes**: Soluciones a problemas frecuentes +6. **Errores Comunes**: Troubleshooting guide + +## Proceso de QA + +### Verificación Local + +```bash +# Build de componentes +nx run react:build +nx run solid:build + +# Typecheck +nx run react:typecheck +nx run solid:typecheck + +# Lint +nx run react:lint +nx run solid:lint + +# Tests +nx run react:test +nx run solid:test +``` + +### Storybook + +- Ejecutar `nx run docs:storybook` +- Verificar todos los stories +- Verificar controls para props +- Verificar documentación inline + +### Checklist de Componente + +- [ ] Componente React implementado +- [ ] Componente Solid implementado +- [ ] Stories React creadas +- [ ] Stories Solid creadas +- [ ] Tests unitarios creados +- [ ] Exports actualizados en index.ts +- [ ] Exports actualizados en index.tsx +- [ ] Registry actualizado +- [ ] Documentación MDX creada +- [ ] Sidebar actualizado +- [ ] Build pasa +- [ ] Typecheck pasa +- [ ] Tests pasan +- [ ] Manual review en Storybook + +## Timeline + +### Lote 1 (10 componentes) + +- **Duración estimada**: 2-3 semanas +- **Entregables**: 5 componentes nuevos + tests + docs + +### Lote 2 (10 componentes) + +- **Duración estimada**: 3-4 semanas +- **Entregables**: 10 componentes nuevos + tests + docs + +### Lote 3 (10 componentes) + +- **Duración estimada**: 3-4 semanas +- **Entregables**: 10 componentes nuevos + tests + docs + +**Total estimado**: 8-11 semanas + +## Risks y Mitigations + +| Risk | Impact | Mitigation | +| ---------------------------------- | ------ | ---------------------------------------- | +| Complejidad de Ark UI | Alto | Documentar patrones en skill | +| Incompatibilidades de API | Medio | Tests exhaustivos, comparison con Shadcn | +| Mantenimiento dual (React + Solid) | Medio | Templates reutilizables, código paralelo | +| Performance | Bajo | Monitoreo en CI, benchmarks | + +## Métricas de Éxito + +- 30 componentes funcionando para React y Solid +- 100% compatibilidad API con Shadcn +- Tests coverage > 80% +- Documentación completa para cada componente +- Build y tests pasando en CI + +## Recursos + +- [Shadcn UI](https://ui.shadcn.com) +- [Ark UI React](https://ark-ui.com/react) +- [Ark UI Solid](https://ark-ui.com/solid) +- [Tabler Icons](https://tabler.io/icons) +- [Tailwind CSS](https://tailwindcss.com) diff --git a/openspec/changes/changelog-setup/proposal.md b/openspec/changes/changelog-setup/proposal.md new file mode 100644 index 0000000..5ad3e8d --- /dev/null +++ b/openspec/changes/changelog-setup/proposal.md @@ -0,0 +1,122 @@ +# Proposal: Changelog Setup + +## Intent + +Set up automated changesets versioning and starlight-changelogs documentation integration to track and display component additions. This will provide: + +1. Automated version management for component releases +2. Changelog pages visible in documentation sidebar +3. Fixed Storybook ID format to avoid conflicts with hyphenated component names in MDX + +## Scope + +### In Scope + +1. **Changeset Initialization** + - Initialize changesets in the repository + - Create initial changeset describing 30+ new components + - Configure versioning (likely patch for new components) + - Set up the commit message generation workflow + +2. **Starlight Changelogs Configuration** + - Update `src/content.config.ts` to add changelogs collection + - Configure starlight-changelogs plugin in `astro.config.ts` + - Set up sidebar entry for changelog page + - Configure provider to track changesets + +3. **Storybook SKILL.md Fix** + - Update `.storybook/preview.ts` SKILL.md to include fixed ID format + - Add `id: "react-ui-component-name"` to Meta for each story + - This allows MDX to use hyphenated component names + +### Out of Scope + +- Publishing workflow automation (CI/CD for releases) +- GitHub release creation automation +- Migration of existing components to new format + +## Approach + +### Step 1: Initialize Changesets + +Run `npx changesets init` to set up changesets configuration. + +### Step 2: Create First Changeset + +Create a changeset using `npx changeset` to describe all new components: + +- Version: patch (0.0.1 since no breaking changes) +- Components: 30+ new UI components added + +### Step 3: Configure Starlight Changelogs + +1. Update `apps/docs/src/content.config.ts`: + - Import `changelogsLoader` from starlight-changelogs + - Add new `changelogs` collection with changeset provider + - Point to the CHANGELOG.md that changesets generates + +2. Update `apps/docs/astro.config.ts`: + - Add starlight-changelogs plugin to plugins array + - Configure sidebar with changelog link + +### Step 4: Fix Storybook SKILL.md + +Update `.storybook/preview.ts` SKILL.md pattern to use fixed IDs: + +```typescript +const meta: Meta = { + title: "React/UI/ComponentName", + component: Component, + id: "react-ui-component-name", // Fixed ID for Storybook +} +``` + +### Decision: Local vs Deploy + +**Recommendation: Run locally first** + +- First changeset should be created and committed locally +- Verify changelog generation and docs integration work correctly +- Then push to trigger CI and deployment +- This allows fixing any issues before triggering deploy + +## Affected Areas + +| Area | Impact | Description | +| --------------------------------- | -------- | ------------------------------- | +| `package.json` | Modified | Add @changesets/cli dependency | +| `.changeset/` | New | Changesets configuration | +| `packages/react/CHANGELOG.md` | New | Generated changelog | +| `packages/solid/CHANGELOG.md` | New | Generated changelog | +| `apps/docs/src/content.config.ts` | Modified | Add changelogs collection | +| `apps/docs/astro.config.ts` | Modified | Add starlight-changelogs plugin | +| `.storybook/preview.ts` | Modified | Fix ID format in SKILL.md | + +## Risks + +| Risk | Likelihood | Mitigation | +| ----------------------------------- | ---------- | ------------------------------------- | +| Changeset version conflicts | Low | Use patch version for initial release | +| Changelog plugin integration issues | Medium | Test locally before deploying | +| Storybook ID conflicts | Medium | Use fixed ID format consistently | + +## Rollback Plan + +1. Remove `@changesets/cli` from package.json +2. Remove `.changeset/` directory +3. Revert `content.config.ts` and `astro.config.ts` changes +4. Revert Storybook preview.ts changes + +## Dependencies + +- `@changesets/cli` package +- `starlight-changelogs` (already installed) +- Changesets generates CHANGELOG.md in package directories + +## Success Criteria + +- [ ] Changesets initialized and first changeset created +- [ ] Changelog page appears in docs sidebar +- [ ] Components listed in changelog +- [ ] Storybook stories use fixed ID format +- [ ] Local dev server shows changelog correctly diff --git a/openspec/changes/lote-1/design.md b/openspec/changes/lote-1/design.md new file mode 100644 index 0000000..cd2f4b2 --- /dev/null +++ b/openspec/changes/lote-1/design.md @@ -0,0 +1,497 @@ +# Design: Lote 1 - First Batch UI Components + +## Technical Approach + +Implement 5 UI components (badge, card, checkbox, select, separator) following the established Arkitect UI pattern: Shadcn UI API externally, Ark UI primitives internally where needed. + +**Implementation Order** (by complexity): + +1. **Separator** - Simplest, pure CSS, no Ark UI +2. **Badge** - Simple CVA styling, no Ark UI +3. **Card** - Composition of semantic HTML wrappers +4. **Checkbox** - Uses `@ark-ui/react/checkbox` +5. **Select** - Most complex, uses `@ark-ui/react/select` with `createListCollection` + +--- + +## Architecture Decisions + +### Decision: Checkbox Indeterminate State Handling + +**Choice**: Use Ark UI's native `indeterminate` prop on `Checkbox.Control`, not a separate checked state value. + +**Alternatives considered**: + +- Using `checked="indeterminate"` as a string value (Shadcn pattern) +- Creating custom indeterminate icon logic + +**Rationale**: Ark UI checkbox has built-in `indeterminate` boolean prop that handles the mixed state visually. The Shadcn API accepts `checked="indeterminate"` which we will normalize to the Ark UI pattern by detecting the string value and passing it as a boolean to the Indicator component. + +### Decision: Select API Pattern + +**Choice**: Support both simple children pattern AND `createListCollection` pattern. + +**Alternatives considered**: + +- Only support `createListCollection` (strict Ark UI) +- Only support simple children (Shadcn-style) + +**Rationale**: + +- Shadcn users expect simple `Label` pattern +- Ark UI recommends `createListCollection` for better type safety and performance +- Solution: Accept children but also support collection prop for advanced use cases + +### Decision: Card Composition Structure + +**Choice**: Export all 5 Card parts as separate components (CardHeader, CardTitle, CardDescription, CardContent, CardFooter). + +**Alternatives considered**: + +- Single Card component with render props +- Object-based API (Card.Header, Card.Title, etc.) + +**Rationale**: Follows Shadcn UI pattern exactly - users expect composable components. Uses simple semantic HTML wrappers without Ark UI primitives (no complex state needed). + +### Decision: Testing Approach + +**Choice**: Story-based testing via Storybook, no additional unit test files. + +**Alternatives considered**: + +- Vitest unit tests alongside stories +- Only manual testing in Storybook + +**Rationale**: + +- Existing project uses Storybook stories as primary test coverage +- Stories demonstrate all variants and states +- CVA and simple components don't need extensive unit testing + +--- + +## Data Flow + +### Component Hierarchy + +``` +packages/react/src/components/ui/ +├── badge.tsx # CVA-only, no children composition +├── badge.stories.tsx # Variant stories +├── card.tsx # Composition: Card > CardHeader > CardTitle/Description > CardContent > CardFooter +├── card.stories.tsx # Composition stories +├── checkbox.tsx # Ark UI: Checkbox.Root > Checkbox.HiddenInput > Checkbox.Control > Checkbox.Indicator +├── checkbox.stories.tsx +├── select.tsx # Ark UI: Select.Root > Select.Trigger > Select.ValueText | Select.Content > Select.Item +├── select.stories.tsx +├── separator.tsx # CVA-only, semantic
+└── separator.stories.tsx +``` + +--- + +## File Changes + +### React Components + +| File | Action | Description | +| -------------------------------------------------------- | ------ | ----------------------------------------------- | +| `packages/react/src/components/ui/badge.tsx` | Create | Badge component with CVA (4 variants × 3 sizes) | +| `packages/react/src/components/ui/badge.stories.tsx` | Create | Storybook stories | +| `packages/react/src/components/ui/card.tsx` | Create | Card + 5 sub-components | +| `packages/react/src/components/ui/card.stories.tsx` | Create | Storybook stories | +| `packages/react/src/components/ui/checkbox.tsx` | Create | Ark UI Checkbox with indeterminate | +| `packages/react/src/components/ui/checkbox.stories.tsx` | Create | Storybook stories | +| `packages/react/src/components/ui/select.tsx` | Create | Ark UI Select with createListCollection | +| `packages/react/src/components/ui/select.stories.tsx` | Create | Storybook stories | +| `packages/react/src/components/ui/separator.tsx` | Create | Separator with orientation variants | +| `packages/react/src/components/ui/separator.stories.tsx` | Create | Storybook stories | +| `packages/react/src/index.ts` | Modify | Add 5 exports | + +### Solid Components + +| File | Action | Description | +| -------------------------------------------------------- | ------ | ---------------------- | +| `packages/solid/src/components/ui/badge.tsx` | Create | Solid badge with CVA | +| `packages/solid/src/components/ui/badge.stories.tsx` | Create | Storybook stories | +| `packages/solid/src/components/ui/card.tsx` | Create | Solid card composition | +| `packages/solid/src/components/ui/card.stories.tsx` | Create | Storybook stories | +| `packages/solid/src/components/ui/checkbox.tsx` | Create | Solid Ark UI checkbox | +| `packages/solid/src/components/ui/checkbox.stories.tsx` | Create | Storybook stories | +| `packages/solid/src/components/ui/select.tsx` | Create | Solid Ark UI select | +| `packages/solid/src/components/ui/select.stories.tsx` | Create | Storybook stories | +| `packages/solid/src/components/ui/separator.tsx` | Create | Solid separator | +| `packages/solid/src/components/ui/separator.stories.tsx` | Create | Storybook stories | +| `packages/solid/src/index.tsx` | Modify | Add 5 exports | + +### Registry & Config + +| File | Action | Description | +| ----------------------------------------------------------- | ------ | ----------------------------------- | +| `registry.json` | Modify | Add 10 entries (5 React + 5 Solid) | +| `apps/docs/astro.config.ts` | Modify | Add sidebar items for 10 components | +| `apps/docs/src/content/docs/react/components/badge.mdx` | Create | Documentation | +| `apps/docs/src/content/docs/react/components/card.mdx` | Create | Documentation | +| `apps/docs/src/content/docs/react/components/checkbox.mdx` | Create | Documentation | +| `apps/docs/src/content/docs/react/components/select.mdx` | Create | Documentation | +| `apps/docs/src/content/docs/react/components/separator.mdx` | Create | Documentation | +| `apps/docs/src/content/docs/solid/components/badge.mdx` | Create | Documentation | +| `apps/docs/src/content/docs/solid/components/card.mdx` | Create | Documentation | +| `apps/docs/src/content/docs/solid/components/checkbox.mdx` | Create | Documentation | +| `apps/docs/src/content/docs/solid/components/select.mdx` | Create | Documentation | +| `apps/docs/src/content/docs/solid/components/separator.mdx` | Create | Documentation | + +--- + +## Component Details + +### 1. Badge Component + +**Technical Approach**: Pure CVA component, no Ark UI primitive. + +**CVA Variants**: + +```typescript +const badgeVariants = cva("badge-base", { + variants: { + variant: { + default: "bg-primary text-primary-foreground", + secondary: "bg-secondary text-secondary-foreground", + destructive: "bg-destructive text-destructive-foreground", + outline: "border border-input text-foreground", + }, + size: { + default: "h-5 px-2.5 text-xs", + sm: "h-4 px-2 text-[0.65rem]", + lg: "h-6 px-3 text-sm", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, +}) +``` + +**Icons Needed**: None + +**Ark UI Mapping**: None (pure CVA) + +**File Structure**: + +``` +badge.tsx # Badge + badgeVariants +badge.stories.tsx # Default, Secondary, Destructive, Outline × default/sm/lg +``` + +--- + +### 2. Card Component + +**Technical Approach**: Semantic HTML composition, no Ark UI primitive. + +**Exports**: + +- `Card` - Main container (div) +- `CardHeader` - Header wrapper (div) +- `CardTitle` - Title element (h3) +- `CardDescription` - Description element (p) +- `CardContent` - Content wrapper (div) +- `CardFooter` - Footer wrapper (div) + +**Icons Needed**: None + +**Ark UI Mapping**: None (semantic HTML) + +**File Structure**: + +``` +card.tsx # All 6 components +card.stories.tsx # Full card, Header only, Content only, etc. +``` + +--- + +### 3. Checkbox Component + +**Technical Approach**: Ark UI Checkbox with custom styling to match Shadcn. + +**Ark UI Mapping**: + +| Shadcn | Ark UI | +| -------------- | ---------------------- | +| `` | `Checkbox.Root` | +| (hidden input) | `Checkbox.HiddenInput` | +| (box) | `Checkbox.Control` | +| (checkmark) | `Checkbox.Indicator` | + +**CVA Variants**: + +```typescript +const checkboxVariants = cva( + "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50", + { + variants: {}, + }, +) +``` + +**Icons Needed**: + +- `IconCheck` from `@tabler/icons-react` - for checked state + +**Indeterminate Handling**: + +```typescript +// Shadcn API: checked="indeterminate" +// Convert to Ark UI: + + + {indeterminate ? : } + + +``` + +**File Structure**: + +``` +checkbox.tsx # Checkbox + checkboxVariants +checkbox.stories.tsx # Unchecked, Checked, Indeterminate, Disabled +``` + +--- + +### 4. Select Component + +**Technical Approach**: Ark UI Select with `createListCollection` for items. + +**Ark UI Mapping**: + +| Shadcn | Ark UI | +| ------------------- | -------------------------------------- | +| `)[filter.id] || ""} + onChange={(e) => handleValueChange(filter.id, e.target.value)} + className="w-[200px]" + /> + )} + {filter.type === "select" && ( + + )} + + ))} + {filters.length > 0 && Object.keys(values).length > 0 && ( + + )} + + ) + }, +) +DataTableFilters.displayName = "DataTableFilters" + +export { DataTableFilters } +export type { FilterConfig as FilterConfigType } diff --git a/packages/react/src/components/ui/data-table.stories.tsx b/packages/react/src/components/ui/data-table.stories.tsx new file mode 100644 index 0000000..970352b --- /dev/null +++ b/packages/react/src/components/ui/data-table.stories.tsx @@ -0,0 +1,71 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { DataTable } from "./data-table" + +type User = { + id: number + name: string + email: string + status: "active" | "inactive" +} + +const columns = [ + { + accessorKey: "id", + header: "ID", + }, + { + accessorKey: "name", + header: "Name", + }, + { + accessorKey: "email", + header: "Email", + }, + { + accessorKey: "status", + header: "Status", + cell: (row: User) => ( + + {row.status} + + ), + }, +] as const + +const data: User[] = [ + { id: 1, name: "John Doe", email: "john@example.com", status: "active" }, + { id: 2, name: "Jane Smith", email: "jane@example.com", status: "inactive" }, + { id: 3, name: "Bob Johnson", email: "bob@example.com", status: "active" }, +] + +const meta = { + title: "React/UI/DataTable", + component: DataTable, + tags: ["autodocs"], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = { + args: { + columns: [...columns] as never[], + data, + }, +} + +export const Empty: Story = { + args: { + columns: [...columns] as never[], + data: [], + emptyMessage: "No users found", + }, +} + +export const WithCaption: Story = { + args: { + columns: [...columns] as never[], + data, + caption: "User List", + }, +} diff --git a/packages/react/src/components/ui/data-table.tsx b/packages/react/src/components/ui/data-table.tsx new file mode 100644 index 0000000..c02972d --- /dev/null +++ b/packages/react/src/components/ui/data-table.tsx @@ -0,0 +1,358 @@ +import { forwardRef, type HTMLAttributes, useEffect, useState } from "react" +import { + flexRender, + getCoreRowModel, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + type RowSelectionState, + type SortingState, + useReactTable, +} from "@tanstack/react-table" +import { cn } from "@/lib/utils" +import { IconChevronDown, IconChevronUp, IconSelector } from "@tabler/icons-react" +import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "./table" + +export interface DataTableColumn { + id?: string + accessorKey?: keyof T + header?: string | React.ReactNode + cell?: (info: { row: T; getValue: () => unknown }) => React.ReactNode + accessorFn?: (row: T) => unknown + enableSorting?: boolean +} + +export interface DataTableProps extends HTMLAttributes { + columns: DataTableColumn[] + data: T[] + caption?: string + emptyMessage?: string + enableSelection?: boolean + pageSize?: number + initialSorting?: SortingState + onRowSelectionChange?: (selection: RowSelectionState) => void + getRowId?: (row: T) => string +} + +// SSR guard hook - returns false on server, true on client +function useHydrated() { + const [hydrated, setHydrated] = useState(false) + + useEffect(() => { + setHydrated(true) + }, []) + + return hydrated +} + +// Main DataTable component with SSR support +const DataTable = forwardRef(function DataTable( + { + className, + columns, + data, + caption, + emptyMessage = "No data available", + enableSelection = false, + pageSize = 10, + initialSorting = [], + onRowSelectionChange, + getRowId, + ...props + }: DataTableProps, + ref: React.ForwardedRef, +) { + const isHydrated = useHydrated() + + // SSR: Show loading state until hydrated + if (!isHydrated) { + return ( +
+
+ + + + Loading... + + + + + + Loading table... + + + +
+
+
+ ) + } + + const [sorting, setSorting] = useState(initialSorting) + const [rowSelection, setRowSelection] = useState({}) + + const handleSort = (getToggleSortingHandler: () => () => void) => { + const handler = getToggleSortingHandler() + if (handler) handler() + } + + const columnDefs = columns.map((col, index) => { + const colId = col.id ?? (col.accessorKey ? String(col.accessorKey) : `col_${index}`) + + return { + ...col, + id: colId, + header: ( + { column }: { + column: { + getCanSort: () => boolean + getIsSorted: () => "asc" | "desc" | false + getToggleSortingHandler: () => () => void + } + }, + ) => { + const canSort = col.enableSorting !== false && column.getCanSort() + const isSorted = column.getIsSorted() + return ( + + ) + }, + cell: col.cell + ? ({ getValue, row }: { getValue: () => unknown; row: { original: T } }) => + col.cell!({ + row: row.original as T, + getValue, + }) + : undefined, + } + }) + + const tableOptions = { + data, + columns: columnDefs as any, + state: { + sorting, + rowSelection, + }, + enableRowSelection: enableSelection, + onRowSelectionChange: (updater: any) => { + const newSelection = typeof updater === "function" ? updater(rowSelection) : updater + setRowSelection(newSelection) + onRowSelectionChange?.(newSelection) + }, + onSortingChange: (updater: any) => { + const newSorting = typeof updater === "function" ? updater(sorting) : updater + setSorting(newSorting) + }, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getPaginationRowModel: getPaginationRowModel(), + initialState: { + pagination: { + pageSize, + }, + }, + } + + if (getRowId) { + ;(tableOptions as any).getRowId = (row: T, index: number, parent?: any) => getRowId(row) + } + + const table = useReactTable(tableOptions as any) + + const selectedRows = Object.keys(rowSelection).length + const totalColumns = columns.length + (enableSelection ? 1 : 0) + + return ( +
+
+ + {caption && {caption}} + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + if (header.id === "select") { + return ( + + + + ) + } + return ( + + {header.isPlaceholder + ? null + : flexRender(header.column.columnDef.header, header.getContext())} + + ) + })} + + ))} + + + {table.getRowModel().rows?.length === 0 ? + ( + + + {emptyMessage} + + + ) : + ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => { + const colDef = cell.column.columnDef as any + if (colDef.id === "select") { + return ( + + + + ) + } + return ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ) + })} + + )) + )} + +
+
+ +
+
+ {enableSelection && selectedRows > 0 && ( + + {selectedRows} of {table.getFilteredRowModel().rows.length} row(s) selected + + )} + Showing{" "} + + {table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1} + {" "} + to{" "} + + {Math.min( + (table.getState().pagination.pageIndex + 1) * table.getState().pagination.pageSize, + table.getFilteredRowModel().rows.length, + )} + {" "} + of {table.getFilteredRowModel().rows.length} results +
+ +
+ + + + Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()} + + + +
+
+
+ ) +}) as ( + props: DataTableProps & React.RefAttributes, +) => React.ReactElement | null + +export { DataTable } diff --git a/packages/react/src/components/ui/empty.stories.tsx b/packages/react/src/components/ui/empty.stories.tsx new file mode 100644 index 0000000..77cec22 --- /dev/null +++ b/packages/react/src/components/ui/empty.stories.tsx @@ -0,0 +1,25 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Empty, EmptyDescription, EmptyImage, EmptyTitle, IconFolderOff } from "./empty" + +const meta = { + title: "React/UI/Empty", + component: Empty, + tags: ["autodocs"], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + + + No results found + + Try adjusting your search or filter to find what you are looking for. + + + ), +} diff --git a/packages/react/src/components/ui/empty.tsx b/packages/react/src/components/ui/empty.tsx new file mode 100644 index 0000000..f3ccdd9 --- /dev/null +++ b/packages/react/src/components/ui/empty.tsx @@ -0,0 +1,31 @@ +import { type ComponentProps, forwardRef } from "react" +import { cn } from "@/lib/utils" +import { IconFolderOff } from "@tabler/icons-react" + +const Empty = forwardRef>(({ className, ...props }, ref) => { + return ( +
+ ) +}) +Empty.displayName = "Empty" + +const EmptyImage = forwardRef>(({ className, ...props }, ref) => { + return
+}) +EmptyImage.displayName = "EmptyImage" + +const EmptyTitle = forwardRef>(({ className, ...props }, ref) => { + return

+}) +EmptyTitle.displayName = "EmptyTitle" + +const EmptyDescription = forwardRef>(({ className, ...props }, ref) => { + return

+}) +EmptyDescription.displayName = "EmptyDescription" + +export { Empty, EmptyDescription, EmptyImage, EmptyTitle, IconFolderOff } diff --git a/packages/react/src/components/ui/float.stories.tsx b/packages/react/src/components/ui/float.stories.tsx new file mode 100644 index 0000000..5d80e7e --- /dev/null +++ b/packages/react/src/components/ui/float.stories.tsx @@ -0,0 +1,63 @@ +import type { Meta, StoryObj } from "@storybook/react-vite" +import { Float } from "./float" +import { Button } from "./button" + +const meta: Meta = { + title: "React/UI/Float", + component: Float, +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( +

+ Reference element + +
+ Floating content +
+
+
+ ), +} + +export const Top: Story = { + render: () => ( +
+ Reference element + +
+ Floats above +
+
+
+ ), +} + +export const Right: Story = { + render: () => ( +
+ Reference element + +
+ Floats right +
+
+
+ ), +} + +export const WithOffset: Story = { + render: () => ( +
+ Reference element + +
+ With 8px offset +
+
+
+ ), +} diff --git a/packages/react/src/components/ui/float.tsx b/packages/react/src/components/ui/float.tsx new file mode 100644 index 0000000..ed87346 --- /dev/null +++ b/packages/react/src/components/ui/float.tsx @@ -0,0 +1,62 @@ +import { type ComponentProps, forwardRef } from "react" +import { cn } from "@/lib/utils" + +type Placement = + | "top-start" + | "top" + | "top-end" + | "bottom-start" + | "bottom" + | "bottom-end" + | "left-start" + | "left" + | "left-end" + | "right-start" + | "right" + | "right-end" + +interface FloatProps extends ComponentProps<"div"> { + placement: Placement + offset?: string | number + offsetX?: string | number + offsetY?: string | number +} + +const positionClasses: Record = { + "top-start": "bottom-full left-0 mb-2", + top: "bottom-full left-1/2 -translate-x-1/2 mb-2", + "top-end": "bottom-full right-0 mb-2", + "bottom-start": "top-full left-0 mt-2", + bottom: "top-full left-1/2 -translate-x-1/2 mt-2", + "bottom-end": "top-full right-0 mt-2", + "left-start": "right-full top-0 mr-2", + left: "right-full top-1/2 -translate-y-1/2 mr-2", + "left-end": "right-full bottom-0 mr-2", + "right-start": "left-full top-0 ml-2", + right: "left-full top-1/2 -translate-y-1/2 ml-2", + "right-end": "left-full bottom-0 ml-2", +} + +const Float = forwardRef( + ({ className, placement, offset, offsetX, offsetY, children, ...props }, ref) => { + return ( +
+ {children} +
+ ) + }, +) +Float.displayName = "Float" + +export { Float, type FloatProps } diff --git a/packages/react/src/components/ui/grid-pattern.stories.tsx b/packages/react/src/components/ui/grid-pattern.stories.tsx new file mode 100644 index 0000000..bb131bd --- /dev/null +++ b/packages/react/src/components/ui/grid-pattern.stories.tsx @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from "@storybook/react-vite" +import { GridPattern } from "./grid-pattern" + +const meta: Meta = { + title: "React/UI/GridPattern", + component: GridPattern, +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( +
+ +
+ ), +} + +export const CustomColor: Story = { + render: () => ( +
+ +
+ ), +} + +export const CustomSize: Story = { + render: () => ( +
+ +
+ ), +} diff --git a/packages/react/src/components/ui/grid-pattern.tsx b/packages/react/src/components/ui/grid-pattern.tsx new file mode 100644 index 0000000..f4efdd2 --- /dev/null +++ b/packages/react/src/components/ui/grid-pattern.tsx @@ -0,0 +1,49 @@ +import { type ComponentProps } from "react" +import { cn } from "@/lib/utils" + +export interface GridPatternProps extends ComponentProps<"svg"> { + width?: number + height?: number + x?: number + y?: number + color?: string +} + +export function GridPattern({ + className, + width = 40, + height = 40, + x = 0, + y = 0, + color = "currentColor", + ...props +}: GridPatternProps) { + const patternId = `grid-pattern-${Math.random().toString(36).slice(2, 9)}` + + return ( + + + + + + + + + ) +} diff --git a/packages/react/src/components/ui/grid.stories.tsx b/packages/react/src/components/ui/grid.stories.tsx new file mode 100644 index 0000000..fd443ec --- /dev/null +++ b/packages/react/src/components/ui/grid.stories.tsx @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from "@storybook/react-vite" +import { Grid } from "./grid" + +const meta: Meta = { + title: "React/UI/Grid", + component: Grid, +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + +
1
+
2
+
3
+
4
+
5
+
6
+
+ ), +} + +export const WithGap: Story = { + render: () => ( + +
1
+
2
+
3
+
4
+
+ ), +} diff --git a/packages/react/src/components/ui/grid.tsx b/packages/react/src/components/ui/grid.tsx new file mode 100644 index 0000000..c54d593 --- /dev/null +++ b/packages/react/src/components/ui/grid.tsx @@ -0,0 +1,22 @@ +import { type ComponentProps, type CSSProperties } from "react" +import { cn } from "@/lib/utils" + +export interface GridProps extends ComponentProps<"div"> { + columns?: number + gap?: number | string +} + +export function Grid({ className, columns = 1, gap, style, children, ...props }: GridProps) { + const gridStyle: CSSProperties = { + display: "grid", + gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`, + gap: typeof gap === "number" ? `${gap * 0.25}rem` : gap, + ...style, + } + + return ( +
+ {children} +
+ ) +} diff --git a/packages/react/src/components/ui/input-group.stories.tsx b/packages/react/src/components/ui/input-group.stories.tsx new file mode 100644 index 0000000..67cbe64 --- /dev/null +++ b/packages/react/src/components/ui/input-group.stories.tsx @@ -0,0 +1,28 @@ +import type { Meta, StoryObj } from "@storybook/react-vite" +import { InputGroup } from "./input-group" +import { Input } from "./input" + +const meta: Meta = { + title: "React/UI/InputGroup", + component: InputGroup, +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + + + ), +} + +export const WithLabel: Story = { + render: () => ( + + + + ), +} diff --git a/packages/react/src/components/ui/input-group.tsx b/packages/react/src/components/ui/input-group.tsx new file mode 100644 index 0000000..223d313 --- /dev/null +++ b/packages/react/src/components/ui/input-group.tsx @@ -0,0 +1,15 @@ +import { type ComponentProps } from "react" +import { cn } from "@/lib/utils" + +export interface InputGroupProps extends ComponentProps<"div"> { + label?: string +} + +export function InputGroup({ className, label, children, ...props }: InputGroupProps) { + return ( +
+ {label && } +
{children}
+
+ ) +} diff --git a/packages/react/src/components/ui/marquee.stories.tsx b/packages/react/src/components/ui/marquee.stories.tsx new file mode 100644 index 0000000..ec1aee8 --- /dev/null +++ b/packages/react/src/components/ui/marquee.stories.tsx @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from "@storybook/react-vite" +import { Marquee } from "./marquee" + +const meta: Meta = { + title: "React/UI/Marquee", + component: Marquee, +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + {[1, 2, 3, 4, 5].map((i) => ( +
+ Item {i} +
+ ))} +
+ ), +} diff --git a/packages/react/src/components/ui/marquee.tsx b/packages/react/src/components/ui/marquee.tsx new file mode 100644 index 0000000..8b083ef --- /dev/null +++ b/packages/react/src/components/ui/marquee.tsx @@ -0,0 +1,41 @@ +import { type ComponentProps, type CSSProperties } from "react" +import { cn } from "@/lib/utils" + +export interface MarqueeProps extends ComponentProps<"div"> { + speed?: number + direction?: "left" | "right" +} + +export function Marquee({ + className, + speed = 50, + direction = "left", + children, + ...props +}: MarqueeProps) { + const style: CSSProperties = { + animation: `scroll ${10000 / speed}ms linear infinite`, + animationDirection: direction === "right" ? "reverse" : "normal", + } + + return ( +
+
+ {children} + {children} +
+
+ ) +} + +// SSR guard - only run on client +if (typeof document !== "undefined") { + const style = document.createElement("style") + style.textContent = ` +@keyframes scroll { + from { transform: translateX(0); } + to { transform: translateX(-50%); } +} +` + document.head.appendChild(style) +} diff --git a/packages/react/src/components/ui/pagination.stories.tsx b/packages/react/src/components/ui/pagination.stories.tsx new file mode 100644 index 0000000..1b78f71 --- /dev/null +++ b/packages/react/src/components/ui/pagination.stories.tsx @@ -0,0 +1,49 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Pagination } from "./pagination" + +const meta = { + title: "React/UI/Pagination", + component: Pagination, + tags: ["autodocs"], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = { + args: { + page: 1, + totalPages: 10, + pageSize: 10, + onPageChange: (page: number) => console.log("Page changed to:", page), + }, +} + +export const WithPageSize: Story = { + args: { + page: 1, + totalPages: 10, + pageSize: 25, + pageSizeOptions: [10, 25, 50, 100], + onPageChange: (page: number) => console.log("Page changed to:", page), + onPageSizeChange: (size: number) => console.log("Page size changed to:", size), + }, +} + +export const MiddlePage: Story = { + args: { + page: 5, + totalPages: 10, + pageSize: 10, + onPageChange: (page: number) => console.log("Page changed to:", page), + }, +} + +export const LastPage: Story = { + args: { + page: 10, + totalPages: 10, + pageSize: 10, + onPageChange: (page: number) => console.log("Page changed to:", page), + }, +} diff --git a/packages/react/src/components/ui/pagination.tsx b/packages/react/src/components/ui/pagination.tsx new file mode 100644 index 0000000..0c9516d --- /dev/null +++ b/packages/react/src/components/ui/pagination.tsx @@ -0,0 +1,117 @@ +import { Pagination as PaginationPrimitive } from "@ark-ui/react/pagination" +import { forwardRef, type HTMLAttributes } from "react" +import { cn } from "@/lib/utils" +import { IconChevronLeft, IconChevronRight } from "@tabler/icons-react" + +export interface PaginationProps extends Omit, "onPageChange"> { + page: number + totalPages: number + pageSize?: number + pageSizeOptions?: number[] + onPageChange: (page: number) => void + onPageSizeChange?: (pageSize: number) => void +} + +const Pagination = forwardRef( + ( + { + className, + page, + totalPages, + pageSize = 10, + pageSizeOptions = [10, 25, 50, 100], + onPageChange, + onPageSizeChange, + ...props + }, + ref, + ) => { + const count = totalPages + + return ( +
+ {onPageSizeChange && ( +
+ Rows per page: + +
+ )} + onPageChange(details.page)} + className="flex items-center gap-1" + > + + + Previous page + + + + {(pagination) => + pagination.pages.map((pageItem, index) => + pageItem.type === "page" ? + ( + + {pageItem.value} + + ) : + ( + + ... + + ) + )} + + + + + Next page + + + + + Page {page} of {totalPages} + +
+ ) + }, +) + +Pagination.displayName = "Pagination" + +export { Pagination } diff --git a/packages/react/src/components/ui/select.stories.tsx b/packages/react/src/components/ui/select.stories.tsx new file mode 100644 index 0000000..ec4bffe --- /dev/null +++ b/packages/react/src/components/ui/select.stories.tsx @@ -0,0 +1,170 @@ +import type { Meta, StoryObj } from "@storybook/react-vite" +import { useState } from "react" +import { createListCollection } from "@ark-ui/react" +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectSeparator, + SelectTrigger, + SelectValue, +} from "./select" + +const meta: Meta = { + title: "React/UI/Select", + component: Select, + parameters: { + layout: "padded", + }, +} + +export default meta +type Story = StoryObj + +const frameworks = createListCollection({ + items: [ + { label: "React", value: "react" }, + { label: "Solid", value: "solid" }, + { label: "Vue", value: "vue" }, + { label: "Svelte", value: "svelte" }, + ], +}) + +export const Default: Story = { + render: () => { + const [value, setValue] = useState("") + + return ( + + ) + }, +} + +export const WithGroups: Story = { + render: () => { + const [value, setValue] = useState("") + + const groupedCollection = createListCollection({ + items: [ + { label: "JavaScript", value: "javascript", group: "JavaScript" }, + { label: "TypeScript", value: "typescript", group: "JavaScript" }, + { label: "Python", value: "python", group: "Python" }, + { label: "Django", value: "django", group: "Python" }, + { label: "Go", value: "go", group: "Go" }, + { label: "Rust", value: "rust", group: "Go" }, + ], + itemToString: (item) => item.label, + itemToValue: (item) => item.value, + }) + + return ( + + ) + }, +} + +export const WithSeparator: Story = { + render: () => { + const [value, setValue] = useState("") + + return ( + + ) + }, +} + +export const Disabled: Story = { + render: () => { + const [value, setValue] = useState("") + + const disabledCollection = createListCollection({ + items: [ + { label: "React", value: "react" }, + { label: "Solid", value: "solid" }, + { label: "Vue", value: "vue" }, + { label: "Svelte", value: "svelte", disabled: true }, + ], + itemToString: (item) => item.label, + itemToValue: (item) => item.value, + isItemDisabled: (item) => item.disabled ?? false, + }) + + return ( + + ) + }, +} diff --git a/packages/react/src/components/ui/select.tsx b/packages/react/src/components/ui/select.tsx new file mode 100644 index 0000000..e402157 --- /dev/null +++ b/packages/react/src/components/ui/select.tsx @@ -0,0 +1,101 @@ +import { Select as SelectPrimitives } from "@ark-ui/react" +import type { CollectionItem } from "@ark-ui/react/collection" +import { IconCheck, IconChevronDown } from "@tabler/icons-react" +import { type ComponentProps, type ComponentRef, forwardRef } from "react" +import { cn } from "@/lib/utils" + +// Generic root component that accepts a collection +const Select = (props: SelectPrimitives.RootProps) => ( + +) + +const SelectTrigger = forwardRef< + ComponentRef, + ComponentProps +>(({ className, children, ...props }, ref) => ( + span]:line-clamp-1", + className, + )} + {...props} + > + {children} + + + + +)) +SelectTrigger.displayName = "SelectTrigger" + +const SelectValue = (props: SelectPrimitives.ValueTextProps) => ( + +) + +const SelectContent = forwardRef< + ComponentRef, + ComponentProps +>(({ className, children, ...props }, ref) => ( + + + {children} + + +)) +SelectContent.displayName = "SelectContent" + +const SelectItem = forwardRef< + ComponentRef, + ComponentProps +>(({ className, children, ...props }, ref) => ( + + + + + {children} + +)) +SelectItem.displayName = "SelectItem" + +const SelectGroup = (props: SelectPrimitives.ItemGroupProps) => + +const SelectLabel = forwardRef< + ComponentRef, + ComponentProps +>(({ className, ...props }, ref) => ( + +)) +SelectLabel.displayName = "SelectLabel" + +const SelectSeparator = forwardRef< + ComponentRef<"hr">, + ComponentProps<"hr"> +>(({ className, ...props }, ref) => ( +
+)) +SelectSeparator.displayName = "SelectSeparator" + +export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue } diff --git a/packages/react/src/components/ui/separator.stories.tsx b/packages/react/src/components/ui/separator.stories.tsx new file mode 100644 index 0000000..234a002 --- /dev/null +++ b/packages/react/src/components/ui/separator.stories.tsx @@ -0,0 +1,53 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Separator } from "./separator" + +const meta = { + title: "React/UI/Separator", + component: Separator, + tags: ["autodocs"], + argTypes: { + orientation: { + control: "select", + options: ["horizontal", "vertical"], + }, + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( +
+
Separator between items
+ +
Item 1
+ +
Item 2
+ +
Item 3
+
+ ), +} + +export const Horizontal: Story = { + args: { + orientation: "horizontal", + }, + render: () => , +} + +export const Vertical: Story = { + args: { + orientation: "vertical", + }, + render: () => ( +
+ Item 1 + + Item 2 + + Item 3 +
+ ), +} diff --git a/packages/react/src/components/ui/separator.tsx b/packages/react/src/components/ui/separator.tsx new file mode 100644 index 0000000..1a2720e --- /dev/null +++ b/packages/react/src/components/ui/separator.tsx @@ -0,0 +1,39 @@ +import { cva, type VariantProps } from "class-variance-authority" +import { forwardRef } from "react" +import { cn } from "@/lib/utils" + +const separatorVariants = cva("shrink-0 bg-border", { + variants: { + orientation: { + horizontal: "h-px w-full", + vertical: "h-full w-px", + }, + }, + defaultVariants: { + orientation: "horizontal", + }, +}) + +export type SeparatorOrientation = "horizontal" | "vertical" + +export interface SeparatorProps extends VariantProps { + className?: string + decorative?: boolean + children?: never +} + +const Separator = forwardRef( + ({ className, orientation = "horizontal", decorative = true }, ref) => { + return ( +
+ ) + }, +) +Separator.displayName = "Separator" + +export { Separator, separatorVariants } diff --git a/packages/react/src/components/ui/sheet.stories.tsx b/packages/react/src/components/ui/sheet.stories.tsx new file mode 100644 index 0000000..35a88fd --- /dev/null +++ b/packages/react/src/components/ui/sheet.stories.tsx @@ -0,0 +1,47 @@ +import type { Meta, StoryObj } from "@storybook/react-vite" +import { + Sheet, + SheetClose, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "./sheet" +import { Button } from "./button" + +const meta: Meta = { + title: "React/UI/Sheet", + component: Sheet, +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + + + + + + Edit profile + Make changes to your profile here. Click save when you're done. + +
+

Sheet content goes here

+
+ + + + + + + + +
+
+ ), +} diff --git a/packages/react/src/components/ui/sheet.tsx b/packages/react/src/components/ui/sheet.tsx new file mode 100644 index 0000000..fcaaee3 --- /dev/null +++ b/packages/react/src/components/ui/sheet.tsx @@ -0,0 +1,122 @@ +import { Dialog as DialogPrimitives } from "@ark-ui/react" +import { IconX } from "@tabler/icons-react" +import { cva, type VariantProps } from "class-variance-authority" +import { type ComponentProps, type ComponentPropsWithoutRef, type ComponentRef, forwardRef } from "react" +import { cn } from "@/lib/utils" +import { Button, type ButtonProps } from "./button" + +const Sheet = (props: DialogPrimitives.RootProps) => + +const SheetTrigger = (props: DialogPrimitives.TriggerProps) => ( + +) + +const SheetClose = forwardRef( + ({ children, ...props }, ref) => ( + + + + ), +) + +SheetClose.displayName = "SheetClose" + +const SheetHeader = ({ + className, + ...props +}: ComponentProps<"div">) => ( +
+) + +SheetHeader.displayName = "SheetHeader" + +const SheetFooter = ({ + className, + ...props +}: ComponentProps<"div">) => ( +
+) + +SheetFooter.displayName = "SheetFooter" + +const SheetTitle = forwardRef< + ComponentRef, + ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +SheetTitle.displayName = "SheetTitle" + +const SheetDescription = forwardRef< + ComponentRef, + ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +SheetDescription.displayName = "SheetDescription" + +const sheetContentStyle = cva( + "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500", + { + variants: { + side: { + top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", + bottom: + "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", + left: + "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", + right: + "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", + }, + }, + defaultVariants: { + side: "right", + }, + }, +) + +interface SheetContentProps extends VariantProps {} + +const SheetContent = forwardRef< + ComponentRef, + ComponentPropsWithoutRef & SheetContentProps +>(({ className, side, ...props }, ref) => ( + <> + + + + + +)) + +SheetContent.displayName = "SheetContent" + +export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } diff --git a/packages/react/src/components/ui/sidebar.stories.tsx b/packages/react/src/components/ui/sidebar.stories.tsx new file mode 100644 index 0000000..401feea --- /dev/null +++ b/packages/react/src/components/ui/sidebar.stories.tsx @@ -0,0 +1,62 @@ +import type { Meta, StoryObj } from "@storybook/react-vite" +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarGroup, + SidebarGroupContent, + SidebarGroupTitle, + SidebarHeader, + SidebarItem, + SidebarToggle, +} from "./sidebar" + +const meta: Meta = { + title: "React/UI/Sidebar", + component: Sidebar, +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( +
+ + + + + + + Navigation + + Dashboard + Analytics + Settings + + + + + Logout + + +
+ ), +} + +export const Collapsed: Story = { + render: () => ( +
+ + + + + + 📊 + 📈 + ⚙️ + + +
+ ), +} diff --git a/packages/react/src/components/ui/sidebar.tsx b/packages/react/src/components/ui/sidebar.tsx new file mode 100644 index 0000000..b7be7c9 --- /dev/null +++ b/packages/react/src/components/ui/sidebar.tsx @@ -0,0 +1,135 @@ +import { type ComponentProps, forwardRef, useState } from "react" +import { IconMenu2, IconX } from "@tabler/icons-react" +import { cn } from "@/lib/utils" +import { Button, type ButtonProps } from "./button" + +// Sidebar - main container +const Sidebar = forwardRef & { collapsed?: boolean }>( + ({ className, collapsed, ...props }, ref) => ( +
+ ), +) +Sidebar.displayName = "Sidebar" + +// SidebarHeader +const SidebarHeader = forwardRef>( + ({ className, ...props }, ref) => ( +
+ ), +) +SidebarHeader.displayName = "SidebarHeader" + +// SidebarContent +const SidebarContent = forwardRef>( + ({ className, ...props }, ref) => ( +
+ ), +) +SidebarContent.displayName = "SidebarContent" + +// SidebarGroup +const SidebarGroup = forwardRef>( + ({ className, ...props }, ref) =>
, +) +SidebarGroup.displayName = "SidebarGroup" + +// SidebarGroupTitle +const SidebarGroupTitle = forwardRef>( + ({ className, ...props }, ref) => ( +
+ ), +) +SidebarGroupTitle.displayName = "SidebarGroupTitle" + +// SidebarGroupContent +const SidebarGroupContent = forwardRef>( + ({ className, ...props }, ref) =>
, +) +SidebarGroupContent.displayName = "SidebarGroupContent" + +// SidebarItem +const SidebarItem = forwardRef & { active?: boolean }>( + ({ className, active, ...props }, ref) => ( +
+ ), +) +SidebarItem.displayName = "SidebarItem" + +// SidebarLink +const SidebarLink = forwardRef & { active?: boolean }>( + ({ className, active, ...props }, ref) => ( + + ), +) +SidebarLink.displayName = "SidebarLink" + +// SidebarFooter +const SidebarFooter = forwardRef>( + ({ className, ...props }, ref) =>
, +) +SidebarFooter.displayName = "SidebarFooter" + +// SidebarToggle - para colapsar/expandir +interface SidebarToggleProps extends ButtonProps { + collapsed?: boolean +} + +const SidebarToggle = forwardRef( + ({ className, collapsed, ...props }, ref) => ( + + ), +) +SidebarToggle.displayName = "SidebarToggle" + +export { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarGroup, + SidebarGroupContent, + SidebarGroupTitle, + SidebarHeader, + SidebarItem, + SidebarLink, + SidebarToggle, +} diff --git a/packages/react/src/components/ui/skeleton.stories.tsx b/packages/react/src/components/ui/skeleton.stories.tsx new file mode 100644 index 0000000..d13ea40 --- /dev/null +++ b/packages/react/src/components/ui/skeleton.stories.tsx @@ -0,0 +1,30 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Skeleton } from "./skeleton" + +const meta = { + title: "React/UI/Skeleton", + component: Skeleton, + tags: ["autodocs"], + argTypes: { + variant: { + control: "select", + options: ["default", "circular"], + }, + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = { + args: { + className: "h-4 w-full", + }, +} + +export const Circular: Story = { + args: { + variant: "circular", + className: "h-12 w-12", + }, +} diff --git a/packages/react/src/components/ui/skeleton.tsx b/packages/react/src/components/ui/skeleton.tsx new file mode 100644 index 0000000..30688e4 --- /dev/null +++ b/packages/react/src/components/ui/skeleton.tsx @@ -0,0 +1,26 @@ +import { cva, type VariantProps } from "class-variance-authority" +import { type ComponentProps, forwardRef } from "react" +import { cn } from "@/lib/utils" + +const skeletonVariants = cva("animate-pulse rounded-md bg-muted", { + variants: { + variant: { + default: "", + circular: "rounded-full", + }, + }, + defaultVariants: { + variant: "default", + }, +}) + +export interface SkeletonProps extends ComponentProps<"div">, VariantProps {} + +const Skeleton = forwardRef( + ({ className, variant, ...props }, ref) => { + return
+ }, +) +Skeleton.displayName = "Skeleton" + +export { Skeleton, skeletonVariants } diff --git a/packages/react/src/components/ui/stack.stories.tsx b/packages/react/src/components/ui/stack.stories.tsx new file mode 100644 index 0000000..75337eb --- /dev/null +++ b/packages/react/src/components/ui/stack.stories.tsx @@ -0,0 +1,49 @@ +import type { Meta, StoryObj } from "@storybook/react-vite" +import { HStack, Stack, VStack } from "./stack" + +const meta: Meta = { + title: "React/UI/Stack", + component: Stack, +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + +
Item 1
+
Item 2
+
Item 3
+
+ ), +} + +export const Horizontal: Story = { + render: () => ( + +
Item 1
+
Item 2
+
Item 3
+
+ ), +} + +export const Vertical: Story = { + render: () => ( + +
Item 1
+
Item 2
+
Item 3
+
+ ), +} + +export const Centered: Story = { + render: () => ( + +
Item 1
+
Item 2
+
+ ), +} diff --git a/packages/react/src/components/ui/stack.tsx b/packages/react/src/components/ui/stack.tsx new file mode 100644 index 0000000..055d2b2 --- /dev/null +++ b/packages/react/src/components/ui/stack.tsx @@ -0,0 +1,66 @@ +import { type ComponentProps } from "react" +import { cn } from "@/lib/utils" + +export interface StackProps extends ComponentProps<"div"> { + gap?: number | string + align?: "start" | "center" | "end" | "stretch" + justify?: "start" | "center" | "end" | "between" | "around" + vertical?: boolean +} + +export function Stack({ + className, + gap = 0, + align, + justify, + vertical = false, + children, + ...props +}: StackProps) { + const alignClasses: Record = { + start: "items-start", + center: "items-center", + end: "items-end", + stretch: "items-stretch", + } + + const justifyClasses: Record = { + start: "justify-start", + center: "justify-center", + end: "justify-end", + between: "justify-between", + around: "justify-around", + } + + return ( +
+ {children} +
+ ) +} + +export interface HStackProps extends StackProps { + vertical?: false +} + +export function HStack(props: HStackProps) { + return +} + +export interface VStackProps extends StackProps { + vertical?: true +} + +export function VStack(props: VStackProps) { + return +} diff --git a/packages/react/src/components/ui/table.stories.tsx b/packages/react/src/components/ui/table.stories.tsx new file mode 100644 index 0000000..358cdf6 --- /dev/null +++ b/packages/react/src/components/ui/table.stories.tsx @@ -0,0 +1,53 @@ +import type { Meta, StoryObj } from "@storybook/react" +import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "./table" + +const meta = { + title: "React/UI/Table", + component: Table, + tags: ["autodocs"], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + A list of your recent invoices. + + + Invoice + Status + Method + Amount + + + + + INV001 + Paid + Credit Card + $250.00 + + + INV002 + Pending + PayPal + $150.00 + + + INV003 + Paid + Bank Transfer + $350.00 + + + + + Total + $750.00 + + +
+ ), +} diff --git a/packages/react/src/components/ui/table.tsx b/packages/react/src/components/ui/table.tsx new file mode 100644 index 0000000..86da373 --- /dev/null +++ b/packages/react/src/components/ui/table.tsx @@ -0,0 +1,97 @@ +import { forwardRef, type HTMLAttributes, type TdHTMLAttributes, type ThHTMLAttributes } from "react" +import { cn } from "@/lib/utils" + +const Table = forwardRef>( + ({ className, ...props }, ref) => ( +
+ + + ), +) +Table.displayName = "Table" + +const TableHeader = forwardRef>( + ({ className, ...props }, ref) => , +) +TableHeader.displayName = "TableHeader" + +const TableBody = forwardRef>( + ({ className, ...props }, ref) => ( + + ), +) +TableBody.displayName = "TableBody" + +const TableFooter = forwardRef>( + ({ className, ...props }, ref) => ( + tr]:last:border-b-0", className)} + {...props} + /> + ), +) +TableFooter.displayName = "TableFooter" + +const TableRow = forwardRef>( + ({ className, ...props }, ref) => ( + + ), +) +TableRow.displayName = "TableRow" + +const TableHead = forwardRef>( + ({ className, ...props }, ref) => ( +
[role=checkbox]]:translate-y-[2px]", + className, + )} + {...props} + /> + ), +) +TableHead.displayName = "TableHead" + +const TableCell = forwardRef>( + ({ className, ...props }, ref) => ( + [role=checkbox]]:translate-y-[2px]", + className, + )} + {...props} + /> + ), +) +TableCell.displayName = "TableCell" + +const TableCaption = forwardRef>( + ({ className, ...props }, ref) => ( +
+ ), +) +TableCaption.displayName = "TableCaption" + +export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } diff --git a/packages/react/src/components/ui/textarea.stories.tsx b/packages/react/src/components/ui/textarea.stories.tsx new file mode 100644 index 0000000..9a65e8b --- /dev/null +++ b/packages/react/src/components/ui/textarea.stories.tsx @@ -0,0 +1,26 @@ +import type { Meta, StoryObj } from "@storybook/react-vite" +import { Textarea } from "./textarea" + +const meta: Meta = { + title: "React/UI/Textarea", + component: Textarea, +} + +export default meta +type Story = StoryObj + +export const Default: Story = { + render: () => + ), +} + +export const Disabled: Story = { + render: () => + ), +} diff --git a/packages/solid/src/components/ui/textarea.tsx b/packages/solid/src/components/ui/textarea.tsx new file mode 100644 index 0000000..92e3bf4 --- /dev/null +++ b/packages/solid/src/components/ui/textarea.tsx @@ -0,0 +1,29 @@ +import { cva } from "class-variance-authority" +import { type ComponentProps, splitProps } from "solid-js" +import { cn } from "@/lib/utils" + +const textareaStyle = cva( + "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", + { + variants: { + variant: { + outline: "border-base-400 border bg-transparent", + soft: "bg-base-100", + plain: "bg-transparent border-none", + }, + }, + defaultVariants: { + variant: "outline", + }, + }, +) + +export interface TextareaProps extends ComponentProps<"textarea"> { + variant?: "outline" | "soft" | "plain" +} + +export function Textarea(props: TextareaProps) { + const [local, rest] = splitProps(props, ["class", "variant"]) + + return