Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4299b51
fix: resolve dialog trigger, table empty safety, and release workflow…
RhenCloud Oct 4, 2026
93d285e
feat: add experimental command palette
RhenCloud Oct 4, 2026
e0be157
feat: add sheet drawer
RhenCloud Oct 4, 2026
39f3ac9
feat: add date picker components
RhenCloud Oct 4, 2026
ef36708
feat: enhance data table controls
RhenCloud Oct 4, 2026
da38d21
feat: add application shell layout
RhenCloud Oct 4, 2026
6269ae1
feat: add resizable panel
RhenCloud Oct 4, 2026
ac0087b
chore: sort sidebar components alphabetically
RhenCloud Oct 4, 2026
ad9579b
feat: add file upload
RhenCloud Oct 4, 2026
d3e231c
feat: add multi select
RhenCloud Oct 4, 2026
044917a
feat: add tree view
RhenCloud Oct 4, 2026
30b131f
feat: add timeline
RhenCloud Oct 4, 2026
407951c
feat(theme): add configurable design tokens
RhenCloud Oct 4, 2026
b3a472f
fix(code-block): adapt highlighting to theme
RhenCloud Oct 4, 2026
8382379
feat(app-shell): add responsive navigation
RhenCloud Oct 4, 2026
cb1828a
feat(tree-view): add highlight and async loading
RhenCloud Oct 4, 2026
6e23ed0
feat(locale): add i18n locale injection context
RhenCloud Oct 4, 2026
62cf1b5
feat(locale): eliminate hardcoded strings across components
RhenCloud Oct 4, 2026
5fa3aee
feat(playground): add non-production environment banner
RhenCloud Oct 4, 2026
d21e891
fix(playground): refine preview banner style and resolve strict type …
RhenCloud Oct 4, 2026
a9d63bd
feat(docs-suite): add Callout, InlineCode, Steps, AnchorHeading, Toc,…
RhenCloud Oct 4, 2026
10457fd
feat(landing): add Navbar, Footer, and Hero components
RhenCloud Oct 4, 2026
789f512
fix(landing): address review findings for Navbar, Footer, and Hero
RhenCloud Oct 4, 2026
cb1839b
feat(icon): implement universal Icon component and language icon supp…
RhenCloud Oct 5, 2026
ceb4fb2
fix(playground): import icon from @recloudstudio/ui/icons and clean t…
RhenCloud Oct 5, 2026
22cd4ec
fix(playground): point icon demo NavTree links to real routes
RhenCloud Oct 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/bright-tables-expand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Enhance DataTable with controlled sorting, pagination, selection, column visibility, and loading, empty, and error states.
5 changes: 5 additions & 0 deletions .changeset/bright-trees-navigate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Add TreeView for accessible resource, directory, and permission hierarchies with selection, expansion, and cascaded checkbox states.
5 changes: 5 additions & 0 deletions .changeset/calm-docs-suite-arrive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": minor
---

Add documentation and typography component suite: Callout, InlineCode, Steps, AnchorHeading, Toc, PrevNext, NavTree, and CodeGroup with accessibility and locale support.
5 changes: 5 additions & 0 deletions .changeset/calm-icons-arrive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": minor
---

Add universal `Icon` component and multi-library icon resolution registry with `IconSource` integration across TreeView, NavTree, CommandPalette, Tabs, CodeBlock, and menus.
5 changes: 5 additions & 0 deletions .changeset/calm-landing-suite-arrive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": minor
---

Add landing page components: Navbar (SiteHeader), Footer, and Hero with layout variants, responsive mobile drawer, and CTA slots.
5 changes: 5 additions & 0 deletions .changeset/calm-locales-expand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Expand i18n localization coverage across components (Select, Combobox, MultiSelect, DatePicker, DateRangePicker, CodeBlock, Editable, TagInput, AlertDialog, DataTable) and eliminate hardcoded Chinese fallbacks.
5 changes: 5 additions & 0 deletions .changeset/calm-locales-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": minor
---

Add lightweight i18n locale injection context with default zh-CN/en-US messages, adapt Pagination, EmptyState, DataTable, FileUpload, and TreeView to consume contextual translations, and document usage in Playground.
5 changes: 5 additions & 0 deletions .changeset/calm-sheets-deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Add Sheet, a directional drawer for console details and secondary actions.
5 changes: 5 additions & 0 deletions .changeset/calm-trees-highlight.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": minor
---

Add highlight-variant customization, active selection badges, asynchronous child node loading, multi-selection mode, drag-and-drop reordering, and icon/label slots to TreeView.
5 changes: 5 additions & 0 deletions .changeset/fresh-timelines-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Add Timeline for operational logs and change history with status markers, actor metadata, and customization slots.
5 changes: 5 additions & 0 deletions .changeset/green-dates-arrive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Add DatePicker and DateRangePicker with stable local date values and range presets.
5 changes: 5 additions & 0 deletions .changeset/light-code-blocks-adapt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Match code block surfaces and syntax highlighting to the active light or dark theme.
5 changes: 5 additions & 0 deletions .changeset/moody-cases-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Fix Dialog trigger slot handling, DataTable fallback for empty or undefined rows, TagInput IME composition behavior, Nuxt module type prefix, and package externalization.
5 changes: 5 additions & 0 deletions .changeset/quick-cloud-commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Add the experimental CommandPalette for accessible command navigation in developer tools.
5 changes: 5 additions & 0 deletions .changeset/quiet-shells-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Add AppShell and Sidebar primitives for developer console layouts.
5 changes: 5 additions & 0 deletions .changeset/shell-navigation-adapts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": minor
---

Add collapsible desktop sidebars, mobile menu trigger slots, and content width conventions to AppShell. Document responsive Sheet navigation and AppShell, Sidebar, and NavigationMenu responsibilities.
5 changes: 5 additions & 0 deletions .changeset/smooth-files-arrive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Add FileUpload with drag-and-drop, validation, upload progress, cancellation, previews, and retry states.
5 changes: 5 additions & 0 deletions .changeset/soft-themes-adapt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": minor
---

Add a configurable theme system with system color mode, palettes, density, radius, shadows, persistent preferences, and hydration-safe Nuxt initialization. Publish layered primitive and semantic CSS design tokens for consistent component styling.
5 changes: 5 additions & 0 deletions .changeset/tender-selects-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Add MultiSelect with searchable grouped options, removable selection tags, clearing, and form validation support.
5 changes: 5 additions & 0 deletions .changeset/tiny-panels-scale.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@recloudstudio/ui": patch
---

Add ResizablePanel for accessible, keyboard-adjustable console workspaces.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: CI
on:
pull_request:
push:
branches: [main]
branches: [main, dev]

permissions:
contents: read
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: oven-sh/setup-bun@v2
with:
bun-version: "1.4.2"
Expand All @@ -40,6 +42,8 @@ jobs:
url: https://npm.pkg.github.com
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 24
Expand All @@ -48,7 +52,7 @@ jobs:
with:
bun-version: "1.4.2"
- run: bun install --frozen-lockfile
- run: bun run --cwd packages/ui typecheck && bun run --cwd packages/ui build
- run: bun run --cwd packages/ui typecheck && bun run --cwd packages/ui test && bun run --cwd packages/ui build
- run: test "v$(node -p "require('./packages/ui/package.json').version")" = "$GITHUB_REF_NAME"
# 重新推送同一 tag 时,跳过已发布过该版本的注册表,只补发失败的那一个
- id: published
Expand All @@ -64,6 +68,8 @@ jobs:
- if: matrix.registry.name == 'npm' && steps.published.outputs.exists != 'true'
run: npm publish --provenance --access public --registry=${{ matrix.registry.url }}
working-directory: packages/ui
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- if: matrix.registry.name == 'github' && steps.published.outputs.exists != 'true'
run: npm publish --registry=${{ matrix.registry.url }}
working-directory: packages/ui
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ dist/
.turbo/
.nuxt/
.output/
.vitest/
*.log
.DS_Store
.direnv/
Expand Down
58 changes: 58 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,29 @@ Read `docs/README.md` inside that installed package first, then read the relevan
This block is written and re-added by `turbo` before repository-scoped commands when an AI agent is detected. In the Turborepo source repository, its template is defined in `crates/turborepo-cli/src/cli/agent_guidance.rs`. Removing the managed block while updates are enabled means a later qualifying invocation will add it again. Set `"agentGuidance": false` in the root `turbo.json` or `turbo.jsonc` to opt out; this does not remove an existing block. Keep the block committed with your work to avoid an uncommitted change on the next agent invocation.
<!-- END:turborepo-agent-rules -->

## ReCloud UI Agent Guide

## External Engineering Standards

The following standards are mandatory when their subject applies to the task:

- [Git workflow](https://docs.worldexecute.me/development/git/)
- [TypeScript style](https://docs.worldexecute.me/development/ts-style/)
- [Markdown style](https://docs.worldexecute.me/development/markdown/)

Read only the standard required for the current work; do not preload all three to conserve context.

| Work being performed | Required reading |
| --- | --- |
| Creating branches, committing, preparing a PR, merging, tagging, or changing Git history | Git workflow |
| Adding or modifying `.ts`, `.tsx`, `.js`, `.jsx`, or Vue script code | TypeScript style |
| Adding or modifying `.md` / `.mdx` content, including Changesets | Markdown style |

- Read the relevant linked standard before performing the matching work, and apply its rules throughout that task.
- Repository-local instructions, package scripts, and release workflow take precedence where they explicitly conflict with an external standard. In particular, this repository develops on `dev` as described in [Releases](#releases).
- Do not fetch, quote, or duplicate the full external standards in issues, PRs, commits, or repository files. Link to them and retain only task-specific project rules here.
- Do not commit secrets, credentials, tokens, local IDE settings, build output, or temporary files. Keep commits focused and independently verifiable.

## Workspace

- Use Bun 1.4.2. This is a Bun workspace: the publishable Vue 3 library is `packages/ui`; `apps/playground` is the Nuxt 4 documentation and integration app.
Expand All @@ -24,6 +47,41 @@ This block is written and re-added by `turbo` before repository-scoped commands
- The Playground build refuses to run while a Nuxt dev server holds `apps/playground/.nuxt`; stop the dev server first.
- `bun run ci` is the full workspace gate. Biome intentionally excludes `.vue` files, so do not treat a passing root lint as Vue validation.

## Component Delivery

- A published component lives in `packages/ui/src/components/<name>/`. Keep its implementation, public types, and `index.ts` barrel together.
- Export every public component and type from `packages/ui/src/index.ts`. Do not expose implementation-only helpers by accident.
- Every new public component needs a Playground page at `apps/playground/pages/components/<name>.vue` and an entry in `apps/playground/utils/catalog.ts`.
- `catalog.ts` sorts entries inside each category by title; preserve category order and do not manually work around that sort.
- Follow existing Vue 3 patterns: typed props and emits, `cn()` for class composition, keyboard interactions and ARIA semantics for every interactive control, and light/dark mode support.
- Build console-oriented primitives first: dense but readable states, durable empty/loading/error states, controlled data APIs, and explicit async ownership. Do not make network requests or invent backend protocols inside UI components.
- Keep public state controlled where consumers need to own it. If a component also offers an uncontrolled default, document the interaction and preserve predictable update events.

## Theme and Design Tokens

- Treat `packages/ui/src/theme.css` as the token source of truth. Use semantic tokens (`--background`, `--foreground`, `--card`, `--primary`, `--border`, `--ring`, and status tokens) rather than hard-coded palette values in new or modified components.
- Keep the three visual layers distinct: brand gradients are for emphasis and primary moments; surfaces are neutral; semantic colors communicate status. Never use the brand gradient as generic decoration.
- `useTheme()` owns persisted user preferences for color mode, palette, density, radius, and shadow. Keep `light`, `dark`, and `system` behavior hydration-safe; `auto` remains a compatibility alias only.
- Any persisted theme preference must be represented both by `useTheme()` and `createThemeInitScript()` so the pre-hydration document state matches the hydrated app.
- Preserve legacy CSS variable aliases while migrating components; removing or renaming a public token is a breaking change.
- Use the Sans font stack for UI and the Mono stack for code. Apply tabular numbers to data-heavy tables and metrics with `.rc-tabular-nums` or `data-numeric`.

## Changesets

- Every consumer-visible `@recloudstudio/ui` change requires a Changeset in `.changeset/`; docs-only, tests-only, tooling-only, and behavior-neutral refactors do not.
- Read package names from `package.json`; never list private apps or invent package names.
- Choose the smallest valid bump: `patch` for compatible fixes, `minor` for compatible public features/options/exports, and `major` only for consumer-breaking API or behavior changes.
- Write one or two concise English release-note sentences focused on consumer impact. Do not edit package versions, generated changelogs, or `.changeset/config.json` unless explicitly asked.
- Create and validate the Changeset in the same change as the feature. A typical file is:

```md
---
"@recloudstudio/ui": minor
---

Add configurable theme preferences and hydration-safe initialization.
```

## Releases

- Develop on `dev`; merge `dev` into `main` only for a planned release. Do not commit feature work directly to `main`, except an urgent production fix.
Expand Down
1 change: 1 addition & 0 deletions apps/playground/app.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<ToastProvider />
<PreviewBanner />
<div class="min-h-screen flex flex-col bg-slate-50 dark:bg-[#090E17] text-slate-700 dark:text-slate-200 transition-colors">
<!-- 顶部导航栏 -->
<header class="sticky top-0 z-40 border-b border-slate-200/80 dark:border-slate-800/80 bg-white/90 dark:bg-[#090E17]/90 backdrop-blur-md">
Expand Down
110 changes: 110 additions & 0 deletions apps/playground/components/PreviewBanner.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<template>
<div
v-if="showBanner"
class="relative z-50 border-b border-blue-500/15 bg-slate-900/[0.03] backdrop-blur-md px-4 py-2 text-xs text-slate-700 transition-colors dark:border-blue-400/15 dark:bg-slate-950/40 dark:text-slate-300"
role="region"
aria-label="环境预览提示"
>
<div class="mx-auto flex max-w-7xl items-center justify-between gap-4">
<div class="flex min-w-0 items-center gap-2.5">
<span
class="inline-flex shrink-0 items-center gap-1.5 rounded-full px-2 py-0.5 text-[11px] font-semibold tracking-wide ring-1 ring-inset"
:class="isDev
? 'bg-amber-500/10 text-amber-700 ring-amber-500/25 dark:bg-amber-400/10 dark:text-amber-300 dark:ring-amber-400/25'
: 'bg-[#2563EB]/10 text-[#1D4ED8] ring-[#2563EB]/25 dark:bg-[#70ACFE]/10 dark:text-[#70ACFE] dark:ring-[#70ACFE]/25'"
>
<span
class="h-1.5 w-1.5 rounded-full"
:class="isDev ? 'bg-amber-500 animate-pulse' : 'bg-[#2563EB] dark:bg-[#70ACFE] animate-pulse'"
/>
{{ envBadge }}
</span>

<p class="truncate text-xs leading-none">
<span class="font-medium text-slate-900 dark:text-slate-100">{{ envTitle }}</span>
<span v-if="branch" class="ml-1.5 inline-flex items-center gap-1 rounded bg-slate-200/60 px-1.5 py-0.5 font-mono text-[11px] text-slate-800 dark:bg-slate-800 dark:text-slate-200">
<svg class="h-3 w-3 opacity-60" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="6" y1="3" x2="6" y2="15" />
<circle cx="18" cy="6" r="3" />
<circle cx="6" cy="18" r="3" />
<path d="M18 9a9 9 0 0 1-9 9" />
</svg>
{{ branch }}
</span>
<span v-if="shortSha" class="ml-1 font-mono text-[11px] text-slate-500 dark:text-slate-400">@{{ shortSha }}</span>
<span class="mx-2 hidden text-slate-300 sm:inline dark:text-slate-700">·</span>
<span class="hidden text-slate-500 sm:inline dark:text-slate-400">此环境包含未发布的组件与实验性功能。</span>
</p>
</div>

<div class="flex shrink-0 items-center gap-2">
<a
v-if="commitUrl"
:href="commitUrl"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center gap-1 rounded-md px-2 py-1 text-[11px] font-medium text-slate-600 transition-colors hover:bg-slate-200/60 hover:text-slate-900 dark:text-slate-400 dark:hover:bg-slate-800 dark:hover:text-slate-200"
>
<span>提交记录</span>
<svg class="h-3 w-3 opacity-70" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M7 17L17 7M17 7H7M17 7V17" />
</svg>
</a>

<button
type="button"
class="inline-flex h-6 w-6 items-center justify-center rounded-md text-slate-400 transition-colors hover:bg-slate-200/60 hover:text-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#2563EB] dark:text-slate-500 dark:hover:bg-slate-800 dark:hover:text-slate-200"
aria-label="关闭提示"
@click="dismissed = true"
>
<svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" d="M18 6 6 18M6 6l12 12" />
</svg>
</button>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import { useRuntimeConfig } from '#app'

const config = useRuntimeConfig()
const dismissed = ref(false)

const cfPages = computed(() => Boolean(config.public.cfPages))
const branch = computed(() => String(config.public.cfPagesBranch || ''))
const commitSha = computed(() => String(config.public.cfPagesCommitSha || ''))
const shortSha = computed(() => commitSha.value ? commitSha.value.slice(0, 7) : '')

const isDev = process.dev || process.env.NODE_ENV !== 'production'
const isPreviewBranch = computed(() => {
if (!branch.value) return false
return branch.value !== 'main' && branch.value !== 'master'
})

const showBanner = computed(() => {
if (dismissed.value) return false
if (isDev) return true
if (cfPages.value && isPreviewBranch.value) return true
return false
})

const envBadge = computed(() => {
if (isDev) return 'Local Dev'
if (cfPages.value) return 'Preview'
return 'Preview'
})

const envTitle = computed(() => {
if (isDev) return '本地开发环境'
if (cfPages.value) return 'Cloudflare Pages 预览环境'
return '预览环境'
})

const commitUrl = computed(() => {
if (!commitSha.value) return ''
return `https://github.com/ReCloudStudio/UI/commit/${commitSha.value}`
})
</script>
13 changes: 11 additions & 2 deletions apps/playground/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { defineNuxtConfig } from 'nuxt/config'
import tailwindcss from '@tailwindcss/vite'
import { createThemeInitScript } from '../../packages/ui/src/utils/themeScript'

export default defineNuxtConfig({
// 固定 buildDir:Nuxt 4 生产构建会在 .nuxt 已存在时自动切到 node_modules/.cache,
Expand All @@ -12,8 +13,8 @@ export default defineNuxtConfig({
title: 'ReCloud UI · ReCloud Studio 设计系统',
script: [
{
// 首屏主题引导:在渲染前应用已保存主题,避免深浅色闪烁
innerHTML: `(function(){try{var m=localStorage.getItem('recloud-theme')||'auto';var d=m==='dark'||(m==='auto'&&matchMedia('(prefers-color-scheme: dark)').matches);var e=document.documentElement;e.classList.toggle('dark',d);e.dataset.theme=d?'dark':'light';}catch(e){}})();`
// 首屏应用完整的主题偏好,避免 Vue hydration 前的颜色、密度与圆角闪烁。
innerHTML: createThemeInitScript()
}
],
link: [
Expand All @@ -33,5 +34,13 @@ export default defineNuxtConfig({
plugins: [tailwindcss()]
},
devtools: { enabled: true },
runtimeConfig: {
public: {
cfPages: process.env.CF_PAGES || '',
cfPagesBranch: process.env.CF_PAGES_BRANCH || '',
cfPagesCommitSha: process.env.CF_PAGES_COMMIT_SHA || '',
cfPagesUrl: process.env.CF_PAGES_URL || ''
}
},
compatibilityDate: '2026-10-02'
})
Loading
Loading