@yh-ui/yh-ui-skill 1.0.51 β†’ 1.0.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "packageName": "@yh-ui/yh-ui-skill",
3
- "version": "1.0.51"
3
+ "version": "1.0.53"
4
4
  }
@@ -25,9 +25,25 @@ Do not use this skill for:
25
25
 
26
26
  ## Core Rules
27
27
 
28
+ > [!IMPORTANT]
29
+ > **🚫 The Absolute Anti-Hallucination Standard (η¬¬δΈ€ε‡†εˆ™)**
30
+ > **DO NOT invent or guess any properties, events, slots, methods, CSS selectors, theme presets, locale files, sub-components, or package names.**
31
+ > All code generated **MUST align 100%** with the actual source code definitions in this repository (refer to `references/source-truth.md` for extracted AST data) and the official component library documentation (`https://1079161148.github.io/yh-ui/`).
32
+ > If a property, method, or event is not defined in the source code or documented in the official site, you **must not** guess it. Doing so will directly crash compiler or runtime systems and is strictly forbidden.
33
+
28
34
  - **Strict YH-UI Prioritization**: Under no circumstances should you generate custom HTML/CSS controls (e.g. custom buttons, inputs, tables, dialogs, drawers, scrollbars, markdown cards) or manually construct network fetches/stream connections when YH-UI packages support them. You must 100% prioritize utilizing YH-UI components and utilities.
29
- - **Extension & Re-encapsulation Principle**: If a YH-UI component does not fully meet a specific UI requirement, you must first try to extend it using slot customisation, CSS overrides, or component composition. Writing custom elements from scratch is a last resort, and you must justify why YH-UI could not be extended.
30
- - Do not invent components, props, hooks, package paths, or theme APIs. Check `references/source-truth.md` to ensure names are real.
35
+ - **Extension & Re-encapsulation Principle**: If a YH-UI component does not fully meet a specific UI requirement, you must first try to extend it using slot customization, CSS overrides, or component composition. Writing custom elements from scratch is a last resort, and you must justify why YH-UI could not be extended.
36
+ - **On-Demand Loading (ζŒ‰ιœ€εŠ θ½½) by Default**: Unless configuring global imports, prioritize on-demand imports to ensure optimal bundle size (δ½“η§―ζœ€δΌ˜).
37
+ - Import components from `@yh-ui/components` and their styling:
38
+ ```ts
39
+ import { YhButton, YhTable } from '@yh-ui/components'
40
+ import '@yh-ui/components/style.css'
41
+ ```
42
+ - Import icons from `@yh-ui/icons/vue` or `@yh-ui/icons`:
43
+ ```ts
44
+ import { Icon } from '@yh-ui/icons/vue'
45
+ ```
46
+ - **Language Defaults (TypeScript & SCSS/Sass)**: By default, SFC files and code snippets must declare TypeScript (`lang="ts"`) for script blocks and SCSS/Sass (`lang="scss"`) for style blocks.
31
47
  - Use `@yh-ui/yh-ui` for ordinary Vue apps that want the all-in-one entry.
32
48
  - Use `@yh-ui/nuxt` for Nuxt apps and rely on auto-imported components/composables.
33
49
  - Use `@yh-ui/components` when the user asks for component-only usage.
@@ -38,6 +54,46 @@ Do not use this skill for:
38
54
  - Keep model API keys on the server. Never put provider secrets in browser code.
39
55
  - In SSR/Nuxt, wrap browser-heavy flow editors in `<ClientOnly>`.
40
56
 
57
+ ### Component-Level Best Practices & Source Alignment
58
+
59
+ Below are the detailed rules and best practices for core YH-UI components. Refer to `references/source-truth.md` for the complete API surface of all priority components.
60
+
61
+ #### 1. Data Tables: `YhTable` & `YhTableColumn`
62
+
63
+ - **Column Setup**: Bind column configurations via the `columns` property as a stable array (computed or constant). Do not write raw loop markups inside the component unless using column-slot extensions.
64
+ - **Feature Integration**: Use built-in properties like `pagination`, `resizable`, `loading`, `border` directly.
65
+ - **Exposed Methods**: Use typed refs (`InstanceType<typeof YhTable>`) to invoke functions like `exportData`, `importData`, `insertRow`, `removeRow`, `scrollTo`, and `clearSelection`. Do not guess names (e.g., do not write `.getSelectedRows()` if the source exposes `.getSelectionRows()`).
66
+ - **Events**: Handle events like `selection-change`, `page-change`, `row-click`, `sort-change`, `update:data` exactly as defined.
67
+
68
+ #### 2. Forms & Inputs: `YhForm`, `YhFormItem`, `YhFormSchema`
69
+
70
+ - **Form Validation**: Always bind `:model` and `:rules` on `YhForm`. `YhFormItem` must define the matching `prop` string for validation.
71
+ - **Form Schema**: Use `YhFormSchema` with `:schema` and `:formProps` to render dynamic schemas. Schema configurations must utilize real component names (e.g., `input`, `select`, `date-picker`).
72
+ - **Input Components**: Use `v-model` with native properties like `clearable`, `placeholder`, `disabled`, `show-word-limit`.
73
+
74
+ #### 3. AI UI Components: `YhAiChat`, `YhAiBubble`, `YhAiSender`, `YhAiThoughtChain`
75
+
76
+ - **State Binding**: Do not manage messages and loading states manually. Connect them directly to `useAIChat` or `useAIStream` from `@yh-ui/ai-sdk/vue`.
77
+ - **Sender Layout (`YhAiSender`)**: Bind `v-model` for input and listen to `@send`, `@upload`, and `@command` events. Custom action icons should be placed inside `#actions` or `#submit` slots.
78
+ - **Bubble Layout (`YhAiBubble`)**: Use `citations` array to display reference sources, and handle citation click logic. Ensure `role` (`'user'` or `'assistant'`), `streaming`, and `loading` are properly set.
79
+ - **Thought Chain (`YhAiThoughtChain`)**: Feed structured steps into the `items` property. Bind `@node-click` to let users view step details.
80
+
81
+ #### 4. Interactive Flow Canvas: `Flow` (from `@yh-ui/flow`)
82
+
83
+ - **Layout Sizing**: Always wrap the `Flow` component in a container with a defined height (e.g., `height: 600px;` or `h-screen`).
84
+ - **Canvas Extensions**: Place `Minimap`, `Controls`, and `FlowBackground` inside the `Flow` template body.
85
+ - **Gating in SSR**: Wrap the `Flow` component inside `<ClientOnly>` in SSR environments (such as Nuxt) to avoid canvas/ResizeObserver errors during server builds.
86
+
87
+ #### 5. Layout & Utilities: `YhScrollbar`, `YhConfigProvider`
88
+
89
+ - **Custom Scrollbars**: Use `YhScrollbar` with `height` or `max-height` instead of styling custom divs.
90
+ - **Global Provider**: Place `YhConfigProvider` at the root of the app to control global sizes and internationalization (`:locale`).
91
+ - **Locale Files**: Import locale languages using lowercase paths:
92
+ ```ts
93
+ import zhCn from '@yh-ui/locale/lang/zh-cn'
94
+ import en from '@yh-ui/locale/lang/en'
95
+ ```
96
+
41
97
  ## Agent Workflow
42
98
 
43
99
  1. Classify the task: Vue app, Nuxt app, AI UI, request/data, flow/workflow, theme/locale, icon, or review.
@@ -47,159 +103,6 @@ Do not use this skill for:
47
103
  5. Generate code with real package imports and YH-UI components.
48
104
  6. Check the result against `references/codegen-rubric.md` before answering.
49
105
 
50
- ## Quick Package Decision
51
-
52
- | Task | Package |
53
- | ----------------------------------- | ------------------------------------- |
54
- | Full Vue component library | `@yh-ui/yh-ui` |
55
- | Component-only import | `@yh-ui/components` |
56
- | Nuxt integration | `@yh-ui/nuxt` |
57
- | AI chat UI and streams | `@yh-ui/components` + `@yh-ui/ai-sdk` |
58
- | Request hooks and clients | `@yh-ui/request` |
59
- | Flow editor and workflow canvas | `@yh-ui/flow` |
60
- | Iconify runtime and icon components | `@yh-ui/icons` |
61
- | Theme tokens and runtime theme | `@yh-ui/theme` |
62
- | Locale files | `@yh-ui/locale` |
63
-
64
- ## High-Frequency Patterns
65
-
66
- ### Vue Install
67
-
68
- ```ts
69
- import { createApp } from 'vue'
70
- import YhUI from '@yh-ui/yh-ui'
71
- import '@yh-ui/yh-ui/css'
72
- import App from './App.vue'
73
-
74
- createApp(App).use(YhUI).mount('#app')
75
- ```
76
-
77
- ### Global Config & i18n (Root Setup)
78
-
79
- ```vue
80
- <script setup lang="ts">
81
- import { ref } from 'vue'
82
- import { YhConfigProvider } from '@yh-ui/components'
83
- import zhCn from '@yh-ui/locale/lang/zh-cn'
84
- import en from '@yh-ui/locale/lang/en'
85
-
86
- const locale = ref(zhCn)
87
- const currentSize = ref<'default' | 'small' | 'large'>('default')
88
-
89
- function toggleLang() {
90
- locale.value = locale.value.name === 'zh-cn' ? en : zhCn
91
- }
92
- </script>
93
-
94
- <template>
95
- <YhConfigProvider :locale="locale" :size="currentSize">
96
- <button @click="toggleLang">Switch Language</button>
97
- <AppLayout>
98
- <router-view />
99
- </AppLayout>
100
- </YhConfigProvider>
101
- </template>
102
- ```
103
-
104
- ### On-Demand Components
105
-
106
- ```vue
107
- <script setup lang="ts">
108
- import { YhButton, YhInput, YhTable } from '@yh-ui/components'
109
- import '@yh-ui/components/style.css'
110
- </script>
111
-
112
- <template>
113
- <YhInput clearable placeholder="Search" />
114
- <YhButton type="primary">Submit</YhButton>
115
- <YhTable :data="rows" :columns="columns" />
116
- </template>
117
- ```
118
-
119
- ### Nuxt
120
-
121
- ```ts
122
- export default defineNuxtConfig({
123
- modules: ['@yh-ui/nuxt'],
124
- yhUI: {
125
- importStyle: true,
126
- buildTranspile: true,
127
- prefix: 'Yh'
128
- }
129
- })
130
- ```
131
-
132
- ### AI Chat
133
-
134
- ```vue
135
- <script setup lang="ts">
136
- import { YhAiBubble, YhAiSender } from '@yh-ui/components'
137
- import { useAIChat } from '@yh-ui/ai-sdk/vue'
138
-
139
- const { messages, input, isLoading, sendMessage, stop } = useAIChat({
140
- api: '/api/chat'
141
- })
142
- </script>
143
-
144
- <template>
145
- <YhAiBubble
146
- v-for="message in messages"
147
- :key="message.id"
148
- :role="message.role"
149
- :content="message.content"
150
- streaming
151
- />
152
- <YhAiSender v-model="input" :loading="isLoading" @send="sendMessage" @cancel="stop" />
153
- </template>
154
- ```
155
-
156
- ### Flow Editor
157
-
158
- ```vue
159
- <script setup lang="ts">
160
- import { Controls, Flow, FlowBackground, Minimap } from '@yh-ui/flow'
161
- import type { FlowEdge, FlowNode } from '@yh-ui/flow'
162
-
163
- const nodes: FlowNode[] = [
164
- { id: 'start', type: 'input', label: 'Start', position: { x: 80, y: 80 } }
165
- ]
166
- const edges: FlowEdge[] = []
167
- </script>
168
-
169
- <template>
170
- <Flow :nodes="nodes" :edges="edges" fit-view style="height: 560px">
171
- <Minimap />
172
- <Controls />
173
- <FlowBackground />
174
- </Flow>
175
- </template>
176
- ```
177
-
178
- ### Theme
179
-
180
- ```ts
181
- import { ThemePlugin } from '@yh-ui/theme'
182
-
183
- app.use(ThemePlugin, {
184
- preset: 'blue',
185
- dark: false,
186
- persist: true
187
- })
188
- ```
189
-
190
- ### Icons
191
-
192
- ```vue
193
- <script setup lang="ts">
194
- import { Icon } from '@yh-ui/icons/vue'
195
- </script>
196
-
197
- <template>
198
- <Icon icon="mdi:home" :size="20" color="var(--yh-color-primary)" />
199
- <Icon icon="mdi:loading" spin />
200
- </template>
201
- ```
202
-
203
106
  ## Progressive References
204
107
 
205
108
  Read only the file needed for the task:
@@ -1,40 +1,60 @@
1
- # Code Generation Rubric
1
+ # Code Generation Rubric (Evolved Standard)
2
2
 
3
- Use this checklist before returning YH-UI code.
3
+ Use this checklist before returning YH-UI code. It ensures generated code is 100% bug-free, aligned with source code interfaces, and conforms to modern Vue 3.5+ and Anthony Fu (antfu) styling standards.
4
+
5
+ ---
4
6
 
5
7
  ## Must Pass
6
8
 
7
- - **Prioritize YH-UI**: 100% of UI elements and utility actions (like tables, dropdowns, dialogs, scrolls, loading icons, fetch hooks) use YH-UI packages if supported. Writing custom elements when YH-UI supports them **fails** code generation.
8
- - **Strict Extensions**: Any customization or gaps in YH-UI controls are addressed via slot templates, custom style parameters, or composites. Writing raw custom controls is only permitted as a last resort and must be documented.
9
- - **Real Exports Only**: Imports use actual package boundaries and names listed inside `source-truth.md`. Hallucinated names or paths **fail** code generation.
10
- - Vue examples include required component CSS when importing `@yh-ui/components` on-demand.
11
- - Nuxt examples use `@yh-ui/nuxt` and rely on auto-imports (without manually importing YH-UI components in pages).
12
- - Locale imports use `@yh-ui/locale/lang/zh-cn`, `@yh-ui/locale/lang/en`, or other real locale paths.
13
- - Theme customization uses `@yh-ui/theme`, `ThemePlugin`, `useTheme`, or standard CSS design variables.
14
- - Request client instances use `createRequest` and `useRequest` from `@yh-ui/request` (no custom axios or raw fetch queries).
15
- - Flow examples wrap editor canvases inside explicitly dimensioned heights, and use `<ClientOnly>` in SSR.
16
- - AI examples do not expose provider keys in client-side script code.
17
- - Vue SFC files strictly match block sequences, TS variables structure, reactivity parameters, and onUnmounted cleanups detailed in `vue-component-practices.md`.
9
+ - **🚫 Absolute Zero Hallucination (η¬¬δΈ€ε‡†εˆ™)**: Any code that invents or guesses properties, event names, slots, methods, class names, or package paths **fails** code generation. All declarations must align 100% with the source code definitions (`references/source-truth.md`) and the official docs (`https://1079161148.github.io/yh-ui/`).
10
+ - **Prioritize YH-UI Native Features**: 100% of UI elements and utility actions (like tables, dropdowns, dialogs, scrolls, loading icons, fetch hooks) use YH-UI packages if supported. Writing custom elements when YH-UI supports them **fails** code generation.
11
+ - **On-Demand Importing (ζŒ‰ιœ€εŠ θ½½)**: Vue examples must import components directly from `@yh-ui/components` and include the CSS file:
12
+ ```ts
13
+ import { YhButton } from '@yh-ui/components'
14
+ import '@yh-ui/components/style.css'
15
+ ```
16
+ - **Antfu Import Formatting**: Imports must be grouped and sorted correctly:
17
+ 1. Vue core (e.g., `ref`, `computed`).
18
+ 2. Libraries (e.g., `@yh-ui/request`).
19
+ 3. UI / Local (e.g., `@yh-ui/components`).
20
+ 4. Types (`import type { ... }`).
21
+ - **Default Coding Languages**: Vue SFCs must declare TypeScript (`lang="ts"`) for script blocks and SCSS/Sass (`lang="scss"`) for style blocks by default.
22
+ - **Modern Reactivity & Props**:
23
+ - For Vue 3.5+, use reactive props destructuring: `const { size = 'default' } = defineProps<Props>()`.
24
+ - Use `defineModel` for two-way bindings.
25
+ - Prefer `ref()` over `reactive()` for standard state parameters.
26
+ - **TypeScript Strict Standards**:
27
+ - Component template refs must be typed using `InstanceType<typeof Component>` and defined without `null` initialization if bound:
28
+ ```ts
29
+ const tableRef = ref<InstanceType<typeof YhTable>>()
30
+ ```
31
+ - **Performance Allocations**:
32
+ - Heavy objects (Monaco editor, ECharts, Flow canvases) **must** be stored in `shallowRef()` to prevent performance degradation.
33
+ - **Zero SSR API Leaks**:
34
+ - Never read `window`, `document`, or `localStorage`/`sessionStorage` during initial setup initialization. Wrap them in `onMounted`.
35
+ - Never store request-specific reactive state in global singleton variables.
36
+ - **Mandatory Cleanups**:
37
+ - All active timers (`setTimeout`, `setInterval`), observers (`ResizeObserver`), and DOM/window event listeners **must** be cleared or unregistered in `onUnmounted` or `onBeforeUnmount`.
38
+
39
+ ---
18
40
 
19
41
  ## Should Pass
20
42
 
21
- - Pick the smallest YH-UI surface that solves the task.
22
- - Prefer composable AI UI for custom products and `YhAiChat` for complete chat surfaces.
43
+ - Custom composables should accept arguments as `MaybeRefOrGetter<T>` and parse them using `toValue()`.
44
+ - Custom composables should perform side-effect cleanups using `onScopeDispose()`.
45
+ - Use `v-once` for static templates and `v-memo` for complex grid iterations to maximize rendering performance.
23
46
  - Include empty, loading, and error states for data-heavy pages.
24
- - Keep templates TypeScript-friendly: use `import type`, type template refs with `InstanceType<typeof YhComponent>`, and define typed interface objects.
25
- - Avoid unrelated dependencies (like lodash, element-plus, custom hooks) when YH-UI already provides the capability.
26
- - Keep generated UI code readable and production-shaped, not demo-only.
27
- - Use stable `:key` values, computed derived state, and explicit loading/error/empty states where relevant.
47
+ - Pick the smallest YH-UI surface that solves the task.
48
+ - Keep templates clean of complex calculations: move logic into `computed` variables.
49
+
50
+ ---
28
51
 
29
- ## Red Flags
52
+ ## Red Flags (Auto-Fail)
30
53
 
31
54
  - **Hallucinated Controls**: Reinventing standard visual controls (e.g. custom scroll elements, custom select components, custom modal popups) instead of using the corresponding YH-UI components.
32
55
  - **Custom Fetches**: Initiating direct `fetch` / `axios` connections in views instead of utilizing `createRequest` or `useRequest` from `@yh-ui/request`.
33
- - **Untyped Ref Handles**: Declaring component template refs without type-casting them using `InstanceType<typeof ...>` (e.g. `const refVal = ref(null)`).
34
- - Invented `Yh*` components.
35
- - Old APIs such as `createYhTheme` or `createRequestInstance`.
36
- - Nuxt pages manually importing many YH-UI components despite auto-import.
37
- - Hard-coded design tokens where `var(--yh-*)` variables would fit.
38
- - Flow canvas without height.
39
- - Provider secrets in Vite env variables or browser bundles.
40
- - Direct prop mutation, untyped emits, inaccessible icon buttons, or browser-only APIs during SSR.
56
+ - **Guessing Component APIs**: Accessing non-existent component methods or passing non-existent properties (e.g., trying to call `tableRef.value.getSelected()` when only `getSelectionRows()` exists).
57
+ - **Untyped Ref Handles**: Declaring component template refs without type-casting them using `InstanceType<typeof ...>`.
58
+ - **SSR Hydration Failure**: Direct window/document access during the root setup execution scope.
59
+ - **SSR Memory Leak**: Global, shared mutable reactive state that persists across requests.
60
+ - **Missing Cleanup**: Leaving running intervals, observers, or window resize event listeners active after a component is unmounted.
@@ -149,9 +149,7 @@ Expose: `clearFilter`, `clearSelection`, `clearSort`, `doLayout`, `exportData`,
149
149
 
150
150
  Use hooks from these source modules:
151
151
 
152
- `useNamespace`, `useZIndex`, `useSKU`, `useCountdown`, `useLocale`, `useId`, `useYhId`, `useFormItem`, `useVirtualScroll`, `useCache`, `useEventListener`, `useScrollLock`, `useClickOutside`, `useConfig`, AI hooks from `use-ai`, and reactive storage helpers from `storage`.
153
-
154
- > **Note**: `useYhId` is an alias for `useId` exported from `@yh-ui/hooks`. Use `useYhId` when naming conflicts with Vue 3.5+ native `useId` are a concern. In Nuxt, `useYhId` is also available as an auto-import from `@yh-ui/hooks`.
152
+ `useNamespace`, `useZIndex`, `useSKU`, `useCountdown`, `useLocale`, `useId`, `useFormItem`, `useVirtualScroll`, `useCache`, `useEventListener`, `useScrollLock`, `useClickOutside`, `useConfig`, AI hooks from `use-ai`, and reactive storage helpers from `storage`.
155
153
 
156
154
  ## `@yh-ui/flow` Exports
157
155
 
@@ -198,7 +196,7 @@ Use these real capabilities:
198
196
 
199
197
  The Nuxt module registers component names using the configured prefix, default `Yh`. It also auto-imports common hooks and globals from `@yh-ui/hooks` and `@yh-ui/components`.
200
198
 
201
- Important nuance: native `useId` is not overridden. YH-UI's hook is also exported as `useYhId` directly from `@yh-ui/hooks`, and in Nuxt it is auto-imported as `useYhId`.
199
+ Important nuance: native `useId` is not overridden. YH-UI's hook is imported as `useYhId`.
202
200
 
203
201
  ## Known Non-Goals
204
202
 
@@ -1,147 +1,222 @@
1
- # Vue Component Practices
2
-
3
- Use these rules when generating or reviewing YH-UI Vue 3 code. They combine Vue official guidance with component-library patterns that make AI-generated code safer and easier to maintain.
4
-
5
- ## SFC Structure
6
-
7
- - Prefer `<script setup lang="ts">` for all application pages and component definitions.
8
- - Always order SFC blocks as `<script>`, `<template>`, then `<style scoped>`.
9
- - Internal setup block sequence:
10
- 1. Module/library imports (separate external dependencies from local `@yh-ui` packages).
11
- 2. TypeScript types & interfaces.
12
- 3. `defineProps`, `defineEmits`, and `defineModel`.
13
- 4. Reactive state & refs.
14
- 5. Computed properties.
15
- 6. Watchers (`watch` / `watchEffect`).
16
- 7. Lifecycle hooks (`onMounted`, `onUnmounted`, etc.).
17
- 8. Action functions / methods.
18
- - Use `scoped` styles to prevent styling leakages. Never use raw global selector tags inside SFC styles.
19
- - Keep templates clean: move calculations, complex conditions, or array mapping out of the template into computed variables.
20
-
21
- ## Props, Emits, And v-model
22
-
23
- - Always type props with clear TypeScript interfaces. Use type-only imports (`import type { ... }`) for external type models.
24
- - For **Vue 3.5+**, prefer reactive props destructuring:
1
+ # Vue Component Practices (Evolved Standard)
2
+
3
+ Use these rules when generating or reviewing YH-UI Vue 3.5+ code. They combine Vue official core guidance, Anthony Fu (antfu) best practices, and industry-leading component-library standards.
4
+
5
+ ---
6
+
7
+ ## 1. Imports & SFC Code Structure (Antfu Style)
8
+
9
+ - **Strict Import Grouping & Sorting**:
10
+ 1. **Core dependencies**: Vue core APIs (e.g. `ref`, `computed`, `watch`, `onMounted`).
11
+ 2. **Third-party / Tooling libraries**: (e.g. `@yh-ui/request`, `@yh-ui/ai-sdk`).
12
+ 3. **Local components and hooks**: (e.g. `@yh-ui/components`, `@yh-ui/hooks`).
13
+ 4. **Types and Interfaces**: Always separate runtime imports from type-only imports using `import type`.
14
+ ```ts
15
+ import { computed, onMounted, ref } from 'vue'
16
+ import { useRequest } from '@yh-ui/request'
17
+ import { YhTable } from '@yh-ui/components'
18
+ import type { TableColumn } from '@yh-ui/components'
19
+ ```
20
+ - **SFC Block Ordering & Language Defaults**: Always write scripts in TypeScript (`lang="ts"`) and styles in SCSS/Sass (`lang="scss"`) by default. Layout files strictly as:
21
+
22
+ ```html
23
+ <script setup lang="ts">
24
+ // TypeScript Logic
25
+ </script>
26
+
27
+ <template>
28
+ <!-- HTML Structure -->
29
+ </template>
30
+
31
+ <style scoped lang="scss">
32
+ /* SCSS Scoped Styling */
33
+ </style>
34
+ ```
35
+
36
+ - **Scoped Styles Requirement**: Styles must always be `scoped` to prevent selector leaking. Prefer CSS custom properties (Variables) with sensible fallbacks:
37
+ ```css
38
+ .yh-element {
39
+ color: var(--yh-color-primary, #1d4ed8);
40
+ background-color: var(--yh-bg-color, #ffffff);
41
+ }
42
+ ```
43
+
44
+ ---
45
+
46
+ ## 2. Props, Emits, and v-model
47
+
48
+ - **Reactive Props Destructuring (Vue 3.5+)**:
49
+ Always use Vue 3.5 native reactive destructuring for props, supplying defaults directly in the destructure expression. Avoid verbose `withDefaults`.
50
+
25
51
  ```ts
26
- const { size = 'medium', disabled = false, data = () => [] } = defineProps<Props>()
52
+ interface Props {
53
+ size?: 'small' | 'default' | 'large'
54
+ disabled?: boolean
55
+ items?: string[]
56
+ }
57
+
58
+ const { size = 'default', disabled = false, items = () => [] } = defineProps<Props>()
27
59
  ```
28
- This is the official Vue 3.5+ best practice and avoids verbose `withDefaults`.
29
- - For Vue < 3.5 or projects without destructure support, fallback to `withDefaults(defineProps<Props>(), defaults)`.
30
- - Use typed `defineEmits` or `defineModel` for two-way bindings:
31
60
 
61
+ - **Two-way Bindings with `defineModel`**:
62
+ Use the Vue 3.4+ native `defineModel` macro for cleaner two-way data flows:
32
63
  ```ts
33
- // Two-way binding model (Vue 3.4+)
34
64
  const modelValue = defineModel<string>({ default: '' })
35
-
36
- // Typed custom events
65
+ ```
66
+ - **Typed Emits**:
67
+ Always declare emits with strict TypeScript tuple parameters instead of array strings:
68
+ ```ts
37
69
  const emit = defineEmits<{
38
70
  change: [value: string]
39
71
  submit: []
40
72
  }>()
41
73
  ```
42
74
 
43
- - Never mutate props. If props need internal modifications, copy them to a local `ref` or compile them via `computed` getters/setters.
75
+ ---
76
+
77
+ ## 3. Slots & Composition Customization
78
+
79
+ - **Flexible Slot Design (`slots`)**:
80
+ Prefer using Vue `slots` for customizable templates over hard-coded markup. Always declare and use named slots (e.g. `header`, `footer`, `actions`, `empty`) to provide clear extension templates:
81
+ ```html
82
+ <slot name="header">
83
+ <h3>Default Header Title</h3>
84
+ </slot>
85
+ ```
86
+ - **Component Composition**:
87
+ Prefer composing multiple YH-UI library components together (e.g. nesting slots, wrapper components) before deciding to write raw custom controls.
88
+
89
+ ---
90
+
91
+ ## 4. Reactivity and Composable Design (Antfu & Vueuse Standards)
92
+
93
+ - **Prefer `ref()` over `reactive()`**:
94
+ Use `ref()` for all state variables (including objects and arrays) to keep destructuring clean and avoid losing reactivity. Use `reactive()` only when managing deep, nested form states that must be passed as a single object.
95
+ - **MaybeRefOrGetter and toValue (Vue 3.3+)**:
96
+ When writing reusable hooks/composables that accept reactive inputs, declare them as `MaybeRefOrGetter<T>` to accept raw values, Refs, or Getter functions. Use `toValue()` to retrieve their current value reactively:
44
97
 
45
- ## Slots And Composition
98
+ ```ts
99
+ import { toValue } from 'vue'
100
+ import type { MaybeRefOrGetter } from 'vue'
46
101
 
47
- - Prefer slots for customizable content over hard-coded markup when writing reusable components.
48
- - Use named slots for clear extension points such as `header`, `toolbar`, `actions`, `empty`, and `footer`.
49
- - In app pages, compose YH-UI components directly instead of wrapping every component in a thin local abstraction.
50
- - Create composables only when stateful logic is reused or complex enough to deserve a named boundary.
102
+ export function useFeature(enabled: MaybeRefOrGetter<boolean>) {
103
+ const isActive = computed(() => toValue(enabled))
104
+ }
105
+ ```
51
106
 
52
- ## Reactivity & Lifecycle Cleanups
107
+ - **Scope Disposal for Composables**:
108
+ Always clean up active watchers, event listeners, and side-effects inside composables using `onScopeDispose` so they can be clean-run in non-component reactive scopes (like Pinia stores):
53
109
 
54
- - Use `ref` for primitive values, lists/arrays, or objects that will be completely overwritten.
55
- - Use `reactive` only for complex nested states that require deep property mutation.
56
- - Use `computed` for all derived values instead of writing sync watchers or manually maintaining double state variables.
57
- - Use `watch` or `watchEffect` solely for side-effects (e.g. storage sync, async API triggers). Always specify `immediate: true` or `deep: true` only if required.
58
- - Use `shallowRef` for heavy objects, DOM nodes, third-party library instances (ECharts, Monco Editor, Flow canvases), as deep reactivity on these will degrade performance.
59
- - **Critical Lifecycle Cleanups**: Always clean up timeouts, intervals, ResizeObservers, WebSocket event listeners, and custom event listeners in `onUnmounted`:
60
110
  ```ts
61
- const timer = setInterval(tick, 1000)
62
- onUnmounted(() => {
63
- clearInterval(timer)
111
+ import { onScopeDispose, watch } from 'vue'
112
+
113
+ watch(source, (val) => {
114
+ // side effect
115
+ })
116
+
117
+ onScopeDispose(() => {
118
+ // clean up side effect if scope is destroyed
64
119
  })
65
120
  ```
66
121
 
67
- ## Accessibility
122
+ - **Shallow Ref for Performance (`shallowRef`)**:
123
+ Always wrap heavy non-reactive objects, DOM nodes, third-party libraries (e.g. Monaco Editor, ECharts, Flow canvas objects) in `shallowRef()` instead of `ref()` to bypass Vue's deep proxy traversal, saving significant CPU cycles:
124
+ ```ts
125
+ import { shallowRef } from 'vue'
126
+ const editorInstance = shallowRef<any>(null)
127
+ ```
68
128
 
69
- - Prefer semantic HTML around YH-UI components.
70
- - Ensure icon-only buttons have an accessible label.
71
- - Keep form labels visible through `YhFormItem` or explicit `aria-label`.
72
- - Preserve keyboard behavior for dialogs, drawers, dropdowns, popovers, tabs, and menus.
73
- - Do not remove focus outlines unless replacing them with an equally visible focus style.
129
+ ---
74
130
 
75
- ## Performance
131
+ ## 5. Performance & DOM Optimization
76
132
 
77
- - Keep large tables and lists virtualized when YH-UI offers virtual scrolling.
78
- - Use lazy-loaded components for heavy features such as flow editors, charts, code editors, and AI artifact renderers.
79
- - Avoid creating new object/function literals in hot template loops when they can be stable constants.
80
- - Use `v-show` for frequent toggles and `v-if` for expensive conditional branches.
81
- - Use stable `:key` values in `v-for`; never use array index when item identity exists.
82
- - Keep expensive formatting in computed values or memoized helpers.
133
+ - **Template Ref Binding**:
134
+ Type template refs cleanly using Vue's component instance types. Keep the ref initializer empty (without passing `null`) since Vue will automatically assign it on mount:
83
135
 
84
- ## SSR And Hydration
136
+ ```ts
137
+ import { ref } from 'vue'
138
+ import { YhTable } from '@yh-ui/components'
85
139
 
86
- - Do not access `window`, `document`, `localStorage`, `ResizeObserver`, or canvas APIs during SSR.
87
- - Use `onMounted` or Nuxt `<ClientOnly>` for browser-only integrations.
88
- - Give flow editors, charts, virtual lists, and code editors stable container dimensions to avoid hydration/layout shifts.
89
- - Keep server-rendered initial state deterministic.
140
+ const tableRef = ref<InstanceType<typeof YhTable>>()
141
+ // Access: tableRef.value?.exportData()
142
+ ```
90
143
 
91
- ## Forms And Data Pages
144
+ - **v-once and v-memo**:
145
+ - Use `v-once` for complex static text, icons, or banners that never update after initial mount.
146
+ - Use `v-memo` for virtual lists, heavy table columns, or grids to selectively re-trigger patch loops only when specific criteria changes:
147
+ ```html
148
+ <div v-for="item in list" :key="item.id" v-memo="[item.updatedAt, selectedId === item.id]">
149
+ <!-- Deep cell content -->
150
+ </div>
151
+ ```
152
+
153
+ ---
154
+
155
+ ## 6. Accessibility Standards (A11y)
156
+
157
+ - **Accessible Outlines & Semantic HTML**:
158
+ Never strip accessibility focus outlines without supplying custom visible focus states. Rely on semantic HTML structure (`<nav>`, `<main>`, `<article>`, `<header>`) when writing template wrappers.
159
+ - **Labels & Aria attributes**:
160
+ Ensure that icon-only buttons define a descriptive `aria-label` attribute. Keep inputs properly linked with visual labels or explicit `aria-label` placeholders to guarantee full screen-reader accessibility.
161
+ - **Keyboard Navigation**:
162
+ Maintain correct keyboard accessibility tab indexes and focus-trap logic inside overlay views (like dialogs, drawer panels, or search drop-downs).
163
+
164
+ ---
165
+
166
+ ## 7. SSR & Hydration Safeguards (Nuxt Compatibility)
167
+
168
+ - **Zero Browser API Calls during Setup**:
169
+ - Do not access `window`, `document`, `navigator`, or `localStorage`/`sessionStorage` directly in the setup scope.
170
+ - Wrap all browser-specific execution inside `onMounted` or gate it using `import.meta.client` (or `typeof window !== 'undefined'`):
171
+ ```ts
172
+ onMounted(() => {
173
+ const token = localStorage.getItem('auth-token')
174
+ })
175
+ ```
176
+ - **Memory Leak Prevention on Server**:
177
+ Never declare component-level or page-level mutable state in global singleton module-level variables. All reactive state must be wrapped inside `setup()` or Pinia boundaries to prevent cross-request state pollution during SSR.
178
+ - **ClientOnly Wrapping**:
179
+ For charts, code editors, and canvas components (like `@yh-ui/flow`), wrap them inside the `<ClientOnly>` component (in Nuxt) or gate them via dynamic mounting triggers:
180
+ ```html
181
+ <ClientOnly fallback="Loading canvas...">
182
+ <Flow :nodes="nodes" :edges="edges" />
183
+ </ClientOnly>
184
+ ```
92
185
 
93
- - Use `YhForm`, `YhFormItem`, and typed form state for editable data.
94
- - Keep search filters separate from committed query params when a page needs reset/search behavior.
95
- - Include loading, error, empty, and success feedback for request-driven screens.
96
- - Use `YhMessage`, `YhNotification`, `YhPopconfirm`, and `YhMessageBox` for user feedback instead of ad hoc alerts.
97
- - Use `YhTable` columns as stable constants or computed values, not inline arrays in templates.
186
+ ---
98
187
 
99
- ## Component-Library Code Style
188
+ ## 8. CSS BEM Namespace (YH-UI Library Rule)
100
189
 
101
- - Preserve public API compatibility when editing reusable components.
102
- - Do not rename props/events unless the user explicitly asks for a breaking change.
103
- - Keep component props small and orthogonal.
104
- - Prefer CSS variables and existing theme tokens over hard-coded colors.
105
- - Use `useNamespace` for internal BEM-style component classes when editing package components.
106
- - Use `useZIndex`, `useLocale`, `useId`/`useYhId`, and config hooks instead of local one-off implementations.
190
+ When modifying or building library components, use YH-UI's built-in namespace utility `useNamespace` to auto-generate standard classes following the BEM (Block-Element-Modifier) pattern:
107
191
 
108
- ## YH-UI Prioritization & Extension Workflow
192
+ ```ts
193
+ import { useNamespace } from '@yh-ui/hooks'
109
194
 
110
- To ensure we prioritize existing UI framework logic and do not write duplicate custom HTML/CSS controls, follow this decision tree when implementing user interface requests:
195
+ const ns = useNamespace('my-button')
196
+ // ns.b() -> 'yh-my-button'
197
+ // ns.e('icon') -> 'yh-my-button__icon'
198
+ // ns.m('disabled') -> 'yh-my-button--disabled'
199
+ ```
111
200
 
112
- 1. **Verify Availability**: Search `references/source-truth.md` and `references/component-map.md`. If a component exists (e.g., `YhTable`, `YhDialog`, `YhConfigProvider`, `YhScrollbar`), you **must** use it. Do not write raw `<div class="custom-scroll">` or raw `<dialog>`.
113
- 2. **Handle Feature Gaps (Encapsulation/Extension)**: If a component is missing a sub-feature, do not abandon the component. Apply extension patterns in order of priority:
114
- - **Slot Customization**: Use slots (e.g., `#toolbar`, `#empty`, `#default` custom cells) to inject the custom logic.
115
- - **Props & Event Listeners**: Use component event bindings and dynamic property configs to override behavior.
116
- - **CSS Variable Injection**: Inject style variables (e.g. style overrides like `--yh-button-font-weight`) to alter theme aesthetics without altering core element code.
117
- - **Composite Patterns**: Group multiple YH-UI components together (e.g. wrap a `YhTable` and `YhPagination` or nesting slots) before trying to write raw elements.
118
- 3. **Raw Component Last Resort**: Only build a custom element from scratch if the functionality is entirely absent in the UI framework and cannot be composed/wrapped. You must document this reasoning in the code comments.
201
+ ---
119
202
 
120
- ## TypeScript Strict Standards
203
+ ## 9. Lifecycle Cleanups Checklist
121
204
 
122
- To maintain clean typing boundaries and avoid runtime failures, follow these TS conventions:
205
+ To ensure absolute stability, every component **must** clean up all registered side-effects inside `onUnmounted` / `onBeforeUnmount`:
123
206
 
124
- - **Type-only imports**: When importing interfaces, schemas, or types from YH-UI packages, use the `import type` syntax:
125
- ```ts
126
- import type { FormSchema } from '@yh-ui/components'
127
- import type { FlowNode, FlowEdge } from '@yh-ui/flow'
128
- import type { ThemeOptions } from '@yh-ui/theme'
129
- ```
130
- - **Type Template Refs**: Never leave component template refs untyped (`const refVal = ref(null)`). Always use Vue's `InstanceType` utility to extract component exports:
207
+ - Clear all `setTimeout` and `setInterval` handles.
208
+ - Disconnect `ResizeObserver`, `IntersectionObserver`, and `MutationObserver` instances.
209
+ - Remove event listeners bound to `window`, `document`, or custom event emitter nodes:
131
210
 
132
211
  ```ts
133
- import { ref } from 'vue'
134
- import { YhTable } from '@yh-ui/components'
212
+ const onResize = () => {
213
+ /* ... */
214
+ }
215
+ window.addEventListener('resize', onResize)
135
216
 
136
- const tableRef = ref<InstanceType<typeof YhTable> | null>(null)
217
+ onUnmounted(() => {
218
+ window.removeEventListener('resize', onResize)
219
+ })
137
220
  ```
138
221
 
139
- - **Exposed APIs**: Access exposed methods on components strictly through these typed instances (e.g., `tableRef.value?.exportData(...)`, `formRef.value?.validate()`).
140
- - **Data Models**: Strongly type response objects and row lists using `interface` declarations; never pass `any` into data bindings or request helper promises.
141
-
142
- ## Testing Expectations
143
-
144
- - For reusable components, test props, emitted events, slots, keyboard/focus behavior, and important visual states.
145
- - For composables, test state transitions and cleanup.
146
- - For request code, test loading, success, error, retry, and cancellation when present.
147
- - For Nuxt/SSR examples, check that browser-only code is gated.
222
+ - Clean up active audio/video elements, media recorders, or streaming controllers (like LangChain's `AbortController`).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yh-ui/yh-ui-skill",
3
- "version": "1.0.51",
3
+ "version": "1.0.53",
4
4
  "description": "YH-UI skill installer for modern AI coding tools",
5
5
  "type": "module",
6
6
  "bin": {