@yh-ui/yh-ui-skill 1.0.38 → 1.0.42
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.
- package/assets/llms-full.txt +2 -0
- package/assets/llms.txt +2 -0
- package/assets/metadata.json +1 -1
- package/assets/skills/yh-ui/README.md +35 -32
- package/assets/skills/yh-ui/README.zh-CN.md +55 -0
- package/assets/skills/yh-ui/SKILL.md +57 -2
- package/assets/skills/yh-ui/references/codegen-rubric.md +16 -12
- package/assets/skills/yh-ui/references/nuxt.md +49 -3
- package/assets/skills/yh-ui/references/recipes-ai.md +129 -37
- package/assets/skills/yh-ui/references/recipes-flow.md +143 -37
- package/assets/skills/yh-ui/references/recipes-form-schema.md +147 -42
- package/assets/skills/yh-ui/references/recipes-icons.md +126 -0
- package/assets/skills/yh-ui/references/recipes-table.md +98 -47
- package/assets/skills/yh-ui/references/recipes-theme.md +141 -0
- package/assets/skills/yh-ui/references/request.md +98 -19
- package/assets/skills/yh-ui/references/vue-component-practices.md +82 -19
- package/package.json +1 -1
|
@@ -1,56 +1,162 @@
|
|
|
1
|
-
# Deep Recipe: Flow
|
|
1
|
+
# Deep Recipe: Flow Editor
|
|
2
2
|
|
|
3
|
-
Use this recipe
|
|
3
|
+
Use this recipe when building visual workflow editors, node graph layouts, BPMN diagram canvases, AI agent workflow charts, or visual automation tools.
|
|
4
4
|
|
|
5
5
|
## Default Choice
|
|
6
6
|
|
|
7
|
-
Use `@yh-ui/flow` with `Flow
|
|
7
|
+
Use `@yh-ui/flow` with the core `Flow` canvas, complemented by helper components like `Controls`, `Minimap`, and `FlowBackground`.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Custom Node & Edge Types
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- **BPMN Nodes**: Call `registerBpmnNodes()` to enable elements like `BpmnStartEvent`, `BpmnEndEvent`, `BpmnTask`, `BpmnServiceTask`, `BpmnUserTask`, `BpmnExclusiveGateway`, and gateway routes.
|
|
12
|
+
- **AI Workflow Nodes**: Call `registerAiWorkflowNodes()` to enable AI building blocks like `AiLlmNode`, `AiPromptNode`, `AiAgentNode`, `AiToolNode`, `AiConditionNode`, `AiStartNode`, and `AiMemoryNode`.
|
|
13
|
+
- **Custom Editor Helpers**: Use `NodeResizer` (for interactive sizing anchors), `NodeToolbar` (message actions above nodes), and `NodeEditPanel` for sidebar updates.
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
- Events: `update:modelValue`, `update:nodes`, `update:edges`, `nodeClick`, `nodeDragStart`, `nodeDrag`, `nodeDragEnd`, `edgeClick`, `edgeConnect`, `selectionChange`, `historyChange`, `viewportChange`.
|
|
15
|
-
- Slots: `node`, `edge`.
|
|
16
|
-
- Use AI workflow nodes: `AiLlmNode`, `AiPromptNode`, `AiAgentNode`, `AiToolNode`, `AiConditionNode`, `AiStartNode`, `AiEndNode`, `AiMemoryNode`.
|
|
17
|
-
- Use BPMN nodes: `BpmnStartEvent`, `BpmnEndEvent`, `BpmnTask`, `BpmnServiceTask`, `BpmnUserTask`, `BpmnExclusiveGateway`, `BpmnParallelGateway`, `BpmnInclusiveGateway`.
|
|
15
|
+
## Pattern: Interactive AI Agent Flow Editor
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
This example showcases a full-featured flow editor with auto-alignment guides, grid snap, interactive node resizing, history management (undo/redo), and AI workflow preset registration:
|
|
20
18
|
|
|
21
19
|
```vue
|
|
22
20
|
<script setup lang="ts">
|
|
23
|
-
import {
|
|
24
|
-
import
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
import { ref } from 'vue'
|
|
22
|
+
import {
|
|
23
|
+
Flow,
|
|
24
|
+
Controls,
|
|
25
|
+
Minimap,
|
|
26
|
+
FlowBackground,
|
|
27
|
+
registerAiWorkflowNodes,
|
|
28
|
+
NodeResizer,
|
|
29
|
+
NodeToolbar,
|
|
30
|
+
type FlowNode,
|
|
31
|
+
type FlowEdge
|
|
32
|
+
} from '@yh-ui/flow'
|
|
33
|
+
import { YhButton, YhMessage } from '@yh-ui/components'
|
|
34
|
+
|
|
35
|
+
// 1. Register AI Workflow node presets on the engine
|
|
36
|
+
registerAiWorkflowNodes()
|
|
37
|
+
|
|
38
|
+
// 2. Setup nodes state
|
|
39
|
+
const nodes = ref<FlowNode[]>([
|
|
40
|
+
{
|
|
41
|
+
id: 'node-start',
|
|
42
|
+
type: 'ai-start',
|
|
43
|
+
label: 'Trigger Prompt',
|
|
44
|
+
position: { x: 100, y: 150 }
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'node-llm',
|
|
48
|
+
type: 'ai-llm',
|
|
49
|
+
label: 'Process text (DeepSeek)',
|
|
50
|
+
position: { x: 350, y: 150 },
|
|
51
|
+
// Custom data parameters
|
|
52
|
+
data: { model: 'deepseek-chat', temperature: 0.7 }
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 'node-end',
|
|
56
|
+
type: 'ai-end',
|
|
57
|
+
label: 'Output Result',
|
|
58
|
+
position: { x: 600, y: 150 }
|
|
59
|
+
}
|
|
60
|
+
])
|
|
61
|
+
|
|
62
|
+
// 3. Setup edges state
|
|
63
|
+
const edges = ref<FlowEdge[]>([
|
|
64
|
+
{ id: 'e-start-llm', source: 'node-start', target: 'node-llm', type: 'smooth' },
|
|
65
|
+
{ id: 'e-llm-end', source: 'node-llm', target: 'node-end', type: 'bezier' }
|
|
66
|
+
])
|
|
67
|
+
|
|
68
|
+
const flowRef = ref<any>(null)
|
|
69
|
+
|
|
70
|
+
// History management helpers
|
|
71
|
+
function triggerUndo() {
|
|
72
|
+
if (flowRef.value?.history) {
|
|
73
|
+
flowRef.value.history.undo()
|
|
74
|
+
YhMessage.info('Action undone')
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function triggerRedo() {
|
|
79
|
+
if (flowRef.value?.history) {
|
|
80
|
+
flowRef.value.history.redo()
|
|
81
|
+
YhMessage.info('Action redone')
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function handleNodeClick(node: FlowNode) {
|
|
86
|
+
console.log('Clicked node config:', node.data)
|
|
87
|
+
}
|
|
36
88
|
</script>
|
|
37
89
|
|
|
38
90
|
<template>
|
|
39
|
-
<
|
|
40
|
-
<
|
|
41
|
-
<
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
91
|
+
<div class="editor-layout">
|
|
92
|
+
<div class="editor-header">
|
|
93
|
+
<YhButton size="small" icon="mdi:undo" @click="triggerUndo">Undo</YhButton>
|
|
94
|
+
<YhButton size="small" icon="mdi:redo" @click="triggerRedo">Redo</YhButton>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<!-- Explicit container dimensions are mandatory for Flow to compute sizes -->
|
|
98
|
+
<div class="canvas-container" style="height: 600px; border: 1px solid var(--yh-border-color)">
|
|
99
|
+
<Flow
|
|
100
|
+
ref="flowRef"
|
|
101
|
+
v-model:nodes="nodes"
|
|
102
|
+
v-model:edges="edges"
|
|
103
|
+
snap-to-grid
|
|
104
|
+
show-alignment-guides
|
|
105
|
+
:min-zoom="0.2"
|
|
106
|
+
:max-zoom="4"
|
|
107
|
+
:history="true"
|
|
108
|
+
@nodeClick="handleNodeClick"
|
|
109
|
+
>
|
|
110
|
+
<Minimap />
|
|
111
|
+
<Controls />
|
|
112
|
+
<FlowBackground color="#ccc" :grid-size="15" />
|
|
113
|
+
|
|
114
|
+
<!-- Custom slot overriding for customized node presentation -->
|
|
115
|
+
<template #node="{ node }">
|
|
116
|
+
<div class="custom-node-body">
|
|
117
|
+
<!-- NodeToolbar renders edit controls above the active node -->
|
|
118
|
+
<NodeToolbar :visible="node.selected" position="top">
|
|
119
|
+
<button class="node-action-btn">Configure</button>
|
|
120
|
+
</NodeToolbar>
|
|
121
|
+
|
|
122
|
+
<!-- NodeResizer renders adjustment handles around the box -->
|
|
123
|
+
<NodeResizer :min-width="100" :min-height="40" />
|
|
124
|
+
|
|
125
|
+
<div class="node-label">{{ node.label }}</div>
|
|
126
|
+
</div>
|
|
127
|
+
</template>
|
|
128
|
+
</Flow>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
46
131
|
</template>
|
|
132
|
+
|
|
133
|
+
<style scoped>
|
|
134
|
+
.canvas-container {
|
|
135
|
+
background-color: var(--yh-bg-color-page);
|
|
136
|
+
}
|
|
137
|
+
.custom-node-body {
|
|
138
|
+
padding: 10px;
|
|
139
|
+
border-radius: var(--yh-border-radius-base);
|
|
140
|
+
border: 1px solid var(--yh-border-color);
|
|
141
|
+
background: var(--yh-bg-color);
|
|
142
|
+
box-shadow: var(--yh-box-shadow-light);
|
|
143
|
+
min-width: 150px;
|
|
144
|
+
}
|
|
145
|
+
.node-action-btn {
|
|
146
|
+
background: var(--yh-color-primary);
|
|
147
|
+
color: #fff;
|
|
148
|
+
border: none;
|
|
149
|
+
font-size: 11px;
|
|
150
|
+
border-radius: 4px;
|
|
151
|
+
cursor: pointer;
|
|
152
|
+
padding: 2px 6px;
|
|
153
|
+
}
|
|
154
|
+
</style>
|
|
47
155
|
```
|
|
48
156
|
|
|
49
157
|
## Agent Rules
|
|
50
158
|
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
- Use slots for custom node/edge rendering.
|
|
56
|
-
- Do not render Flow in a zero-height container.
|
|
159
|
+
- **Explicit Height**: Always wrap the `Flow` canvas inside a container element with an explicit CSS height (e.g. `style="height: 600px"`). Flow cannot render inside collapsed grid elements.
|
|
160
|
+
- **ClientOnly in Nuxt**: Because flow editors heavily access browser SVG methods, always wrap `Flow` in `<ClientOnly>` when building Nuxt SSR applications.
|
|
161
|
+
- **Controlled Models**: Bind canvas state using Vue 3 two-way models `v-model:nodes` and `v-model:edges` to guarantee changes propagate between component nodes and state.
|
|
162
|
+
- **Durable data properties**: Save custom node parameter fields (like database queries, API targets) inside the serializable `node.data` object.
|
|
@@ -1,82 +1,187 @@
|
|
|
1
1
|
# Deep Recipe: YhFormSchema
|
|
2
2
|
|
|
3
|
-
Use this recipe
|
|
3
|
+
Use this recipe when building complex forms generated dynamically from schemas, including repeating item lists, custom field renderers, layout grids, or conditional field visibility/dependencies.
|
|
4
4
|
|
|
5
5
|
## Default Choice
|
|
6
6
|
|
|
7
|
-
Use `YhFormSchema` when
|
|
7
|
+
Use `YhFormSchema` when forms are configuration-driven, require repeating group elements, or need layout grid scaling. Use `YhForm` + `YhFormItem` only for simple static fields.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Schema Item Configurations
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Each field schema object supports:
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
13
|
+
- `field`: The key name in the model object.
|
|
14
|
+
- `label`: Form label description.
|
|
15
|
+
- `component`: Native component identifier (e.g. `'input'`, `'select'`, `'switch'`, `'date-picker'`).
|
|
16
|
+
- `props`: Target component props passed dynamically.
|
|
17
|
+
- `formItemProps`: Props passed directly to the containing `YhFormItem` (e.g. `labelWidth`).
|
|
18
|
+
- `required` / `rules`: Form validation constraints.
|
|
19
|
+
- `hidden`: A boolean or function `(model) => boolean` determining field visibility.
|
|
20
|
+
- `disabled`: A boolean or function `(model) => boolean` determining disabled state.
|
|
21
|
+
- `span` / `col`: Control grid widths (e.g. `12` for half column, `24` for full width).
|
|
22
|
+
- `asyncOptions`: Fetch options dynamically from APIs.
|
|
23
|
+
- `render`: A custom function `(h, { model, field }) => VNode` for custom render logic.
|
|
24
|
+
- `type`: Set to `'list'` for repeatable sub-form fields.
|
|
18
25
|
|
|
19
|
-
## Pattern: Dynamic Form
|
|
26
|
+
## Pattern: Advanced Dynamic Form
|
|
20
27
|
|
|
21
28
|
```vue
|
|
22
29
|
<script setup lang="ts">
|
|
23
|
-
import { ref } from 'vue'
|
|
24
|
-
import {
|
|
30
|
+
import { ref, h } from 'vue'
|
|
31
|
+
import { YhFormSchema, YhButton, YhMessage, YhInput } from '@yh-ui/components'
|
|
25
32
|
import type { FormSchema } from '@yh-ui/components'
|
|
26
33
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
// Define typed form state
|
|
35
|
+
const formModel = ref({
|
|
36
|
+
projectName: '',
|
|
37
|
+
deploymentType: 'cloud',
|
|
38
|
+
cloudProvider: '',
|
|
39
|
+
scaleNodes: 3,
|
|
40
|
+
environments: [{ name: 'staging', domain: 'staging.company.com' }]
|
|
31
41
|
})
|
|
32
42
|
|
|
43
|
+
// Define schema configuration
|
|
33
44
|
const schema: FormSchema = [
|
|
34
45
|
{
|
|
35
|
-
field: '
|
|
36
|
-
label: 'Name',
|
|
46
|
+
field: 'projectName',
|
|
47
|
+
label: 'Project Name',
|
|
37
48
|
component: 'input',
|
|
38
49
|
required: true,
|
|
39
|
-
|
|
50
|
+
span: 24, // Full width row
|
|
51
|
+
props: {
|
|
52
|
+
placeholder: 'Enter project name',
|
|
53
|
+
clearable: true
|
|
54
|
+
}
|
|
40
55
|
},
|
|
41
56
|
{
|
|
42
|
-
field: '
|
|
43
|
-
label: '
|
|
57
|
+
field: 'deploymentType',
|
|
58
|
+
label: 'Deployment Type',
|
|
44
59
|
component: 'select',
|
|
45
60
|
required: true,
|
|
61
|
+
span: 12,
|
|
62
|
+
props: {
|
|
63
|
+
options: [
|
|
64
|
+
{ label: 'Cloud Hosted', value: 'cloud' },
|
|
65
|
+
{ label: 'On-Premises', value: 'on-premise' }
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
field: 'cloudProvider',
|
|
71
|
+
label: 'Cloud Provider',
|
|
72
|
+
component: 'select',
|
|
73
|
+
span: 12,
|
|
74
|
+
// Conditional visibility: only show if deploymentType is cloud
|
|
75
|
+
hidden: (model) => model.deploymentType !== 'cloud',
|
|
76
|
+
required: (model) => model.deploymentType === 'cloud',
|
|
46
77
|
asyncOptions: async () => [
|
|
47
|
-
{ label: '
|
|
48
|
-
{ label: '
|
|
78
|
+
{ label: 'AWS', value: 'aws' },
|
|
79
|
+
{ label: 'Google Cloud Platform', value: 'gcp' },
|
|
80
|
+
{ label: 'Microsoft Azure', value: 'azure' }
|
|
49
81
|
]
|
|
50
82
|
},
|
|
51
83
|
{
|
|
52
|
-
field: '
|
|
53
|
-
label: '
|
|
54
|
-
component: '
|
|
55
|
-
|
|
84
|
+
field: 'scaleNodes',
|
|
85
|
+
label: 'Scale Nodes Count',
|
|
86
|
+
component: 'input-number',
|
|
87
|
+
span: 12,
|
|
88
|
+
props: {
|
|
89
|
+
min: 1,
|
|
90
|
+
max: 100
|
|
91
|
+
},
|
|
92
|
+
// Conditional disabled state: lock count if cloudProvider is not GCP
|
|
93
|
+
disabled: (model) => model.cloudProvider !== 'gcp'
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
field: 'customRenderer',
|
|
97
|
+
label: 'Custom Field',
|
|
98
|
+
span: 12,
|
|
99
|
+
// Custom render method returning standard VNode
|
|
100
|
+
render: (h, { model, field }) => {
|
|
101
|
+
return h(YhInput, {
|
|
102
|
+
modelValue: model[field],
|
|
103
|
+
'onUpdate:modelValue': (val: string) => {
|
|
104
|
+
model[field] = val
|
|
105
|
+
},
|
|
106
|
+
placeholder: 'Generated via render()'
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
field: 'divider1',
|
|
112
|
+
type: 'divider',
|
|
113
|
+
span: 24
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
field: 'environments',
|
|
117
|
+
label: 'Target Environments',
|
|
118
|
+
type: 'list', // Repeating sub-form group
|
|
119
|
+
span: 24,
|
|
120
|
+
props: {
|
|
121
|
+
// Define schemas for elements inside list array rows
|
|
122
|
+
schema: [
|
|
123
|
+
{
|
|
124
|
+
field: 'name',
|
|
125
|
+
label: 'Env Name',
|
|
126
|
+
component: 'input',
|
|
127
|
+
required: true,
|
|
128
|
+
span: 8
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
field: 'domain',
|
|
132
|
+
label: 'Access Domain',
|
|
133
|
+
component: 'input',
|
|
134
|
+
required: true,
|
|
135
|
+
span: 16
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
56
139
|
}
|
|
57
140
|
]
|
|
58
141
|
|
|
59
|
-
|
|
60
|
-
|
|
142
|
+
const formRef = ref<InstanceType<typeof YhFormSchema> | null>(null)
|
|
143
|
+
|
|
144
|
+
async function handleSave() {
|
|
145
|
+
if (!formRef.value) return
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const valid = await formRef.value.validate()
|
|
149
|
+
if (valid) {
|
|
150
|
+
YhMessage.success('Form configurations validated successfully!')
|
|
151
|
+
console.log('Final Model:', formModel.value)
|
|
152
|
+
}
|
|
153
|
+
} catch (err: any) {
|
|
154
|
+
YhMessage.error(`Validation failed: ${err.message || err}`)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function handleReset() {
|
|
159
|
+
formRef.value?.resetFields()
|
|
61
160
|
}
|
|
62
161
|
</script>
|
|
63
162
|
|
|
64
163
|
<template>
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
164
|
+
<div class="form-container">
|
|
165
|
+
<!-- gutter specifies spacing between form grid components -->
|
|
166
|
+
<YhFormSchema
|
|
167
|
+
ref="formRef"
|
|
168
|
+
v-model="formModel"
|
|
169
|
+
:schema="schema"
|
|
170
|
+
:gutter="20"
|
|
171
|
+
:form-props="{ labelPosition: 'top' }"
|
|
172
|
+
/>
|
|
173
|
+
|
|
174
|
+
<div class="form-buttons">
|
|
175
|
+
<YhButton type="primary" @click="handleSave">Submit Configuration</YhButton>
|
|
176
|
+
<YhButton @click="handleReset">Reset Fields</YhButton>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
72
179
|
</template>
|
|
73
180
|
```
|
|
74
181
|
|
|
75
182
|
## Agent Rules
|
|
76
183
|
|
|
77
|
-
- Use `v-model`
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
- Use `type: 'list'` for repeatable field groups.
|
|
82
|
-
- Do not use `YhFormSchema` for a tiny static form unless schema generation is useful.
|
|
184
|
+
- **Use Model Value**: Always bind data using `v-model` (equivalent to `v-model:modelValue`).
|
|
185
|
+
- **Define Render Returns**: Custom field `render` methods must accept `h` function parameters and return a valid VNode using actual components imported from `@yh-ui/components`.
|
|
186
|
+
- **List Sub-schema**: When using `type: 'list'`, nested schema arrays must be defined inside `props.schema`.
|
|
187
|
+
- **Gutter Config**: Set layout spacings using the `:gutter` prop on the wrapper `YhFormSchema`.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Deep Recipe: YH-UI Icons
|
|
2
|
+
|
|
3
|
+
Use this recipe when integrating and rendering icons across YH-UI components. YH-UI uses a high-performance icon system based on Iconify, supporting thousands of icons with zero runtime overhead.
|
|
4
|
+
|
|
5
|
+
## Default Choice
|
|
6
|
+
|
|
7
|
+
Use the `Icon` component (aliased as `YhIcon`) from `@yh-ui/icons/vue` or `@yh-ui/icons`.
|
|
8
|
+
|
|
9
|
+
## Usage Patterns
|
|
10
|
+
|
|
11
|
+
### 1. Iconify String Name (Recommended)
|
|
12
|
+
|
|
13
|
+
You can reference any icon using the standard `collection:icon` syntax. The package loads the icon asynchronously.
|
|
14
|
+
|
|
15
|
+
```vue
|
|
16
|
+
<script setup lang="ts">
|
|
17
|
+
import { Icon } from '@yh-ui/icons/vue'
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<!-- Material Design Icons collection -->
|
|
22
|
+
<Icon icon="mdi:home" />
|
|
23
|
+
|
|
24
|
+
<!-- Element Plus Icons collection -->
|
|
25
|
+
<Icon icon="ep:search" />
|
|
26
|
+
|
|
27
|
+
<!-- Lucide Icons collection -->
|
|
28
|
+
<Icon icon="lucide:settings" />
|
|
29
|
+
</template>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. Pre-registered Aliases
|
|
33
|
+
|
|
34
|
+
You can use simplified short names for common UI actions (which resolve to pre-configured presets under the hood):
|
|
35
|
+
|
|
36
|
+
```vue
|
|
37
|
+
<template>
|
|
38
|
+
<Icon name="home" />
|
|
39
|
+
<!-- Resolves to mdi:home -->
|
|
40
|
+
<Icon name="search" />
|
|
41
|
+
<!-- Resolves to mdi:magnify -->
|
|
42
|
+
<Icon name="loading" />
|
|
43
|
+
<!-- Resolves to mdi:loading -->
|
|
44
|
+
</template>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. SVG Strings
|
|
48
|
+
|
|
49
|
+
If you need to render raw SVG data dynamically without loading it from an external collection:
|
|
50
|
+
|
|
51
|
+
```vue
|
|
52
|
+
<script setup lang="ts">
|
|
53
|
+
import { Icon } from '@yh-ui/icons/vue'
|
|
54
|
+
|
|
55
|
+
const customSvg = '<path d="M12 2L2 22h20L12 2z" fill="currentColor"/>'
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<template>
|
|
59
|
+
<Icon :svg="customSvg" />
|
|
60
|
+
</template>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 4. Custom Icon Components
|
|
64
|
+
|
|
65
|
+
If you've imported raw Vue component icons from a local folder or another icon package:
|
|
66
|
+
|
|
67
|
+
```vue
|
|
68
|
+
<script setup lang="ts">
|
|
69
|
+
import { Icon } from '@yh-ui/icons/vue'
|
|
70
|
+
import CustomStarComponent from './CustomStar.vue'
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<template>
|
|
74
|
+
<Icon :component="CustomStarComponent" />
|
|
75
|
+
</template>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Styling & Animations
|
|
79
|
+
|
|
80
|
+
### Size and Color
|
|
81
|
+
|
|
82
|
+
Adjust sizing (takes either numbers for pixel dimensions or CSS string values) and fill colors:
|
|
83
|
+
|
|
84
|
+
```vue
|
|
85
|
+
<template>
|
|
86
|
+
<Icon icon="mdi:heart" :size="24" color="var(--yh-color-danger)" />
|
|
87
|
+
<Icon icon="mdi:heart" size="2rem" color="#ff4d4f" />
|
|
88
|
+
</template>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Rotating & Spin Animations
|
|
92
|
+
|
|
93
|
+
Apply static rotations or infinite spinning animations (highly useful for loading states):
|
|
94
|
+
|
|
95
|
+
```vue
|
|
96
|
+
<template>
|
|
97
|
+
<!-- Rotated 90 degrees -->
|
|
98
|
+
<Icon icon="mdi:chevron-right" :rotate="90" />
|
|
99
|
+
|
|
100
|
+
<!-- Infinite spin animation (1s full rotation) -->
|
|
101
|
+
<Icon icon="mdi:loading" spin />
|
|
102
|
+
</template>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Integration with YH-UI Components
|
|
106
|
+
|
|
107
|
+
Many YH-UI components support passing an icon name directly or via slots:
|
|
108
|
+
|
|
109
|
+
```vue
|
|
110
|
+
<script setup lang="ts">
|
|
111
|
+
import { YhButton, YhInput } from '@yh-ui/components'
|
|
112
|
+
import { Icon } from '@yh-ui/icons/vue'
|
|
113
|
+
</script>
|
|
114
|
+
|
|
115
|
+
<template>
|
|
116
|
+
<!-- Passing icon prop -->
|
|
117
|
+
<YhButton type="primary" icon="mdi:plus">Add User</YhButton>
|
|
118
|
+
|
|
119
|
+
<!-- Custom slot rendering -->
|
|
120
|
+
<YhInput placeholder="Enter username">
|
|
121
|
+
<template #prefix>
|
|
122
|
+
<Icon icon="mdi:account" :size="16" />
|
|
123
|
+
</template>
|
|
124
|
+
</YhInput>
|
|
125
|
+
</template>
|
|
126
|
+
```
|