@pythoughts/vue-skills-mcp 0.1.0

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.
Files changed (208) hide show
  1. package/README.md +63 -0
  2. package/index.mjs +139 -0
  3. package/package.json +34 -0
  4. package/skills/create-adaptable-composable/SKILL.md +76 -0
  5. package/skills/vue-best-practices/SKILL.md +154 -0
  6. package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
  7. package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
  8. package/skills/vue-best-practices/references/component-async.md +97 -0
  9. package/skills/vue-best-practices/references/component-data-flow.md +350 -0
  10. package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
  11. package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
  12. package/skills/vue-best-practices/references/component-slots.md +216 -0
  13. package/skills/vue-best-practices/references/component-suspense.md +228 -0
  14. package/skills/vue-best-practices/references/component-teleport.md +108 -0
  15. package/skills/vue-best-practices/references/component-transition-group.md +128 -0
  16. package/skills/vue-best-practices/references/component-transition.md +125 -0
  17. package/skills/vue-best-practices/references/composables.md +290 -0
  18. package/skills/vue-best-practices/references/directives.md +162 -0
  19. package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
  20. package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
  21. package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
  22. package/skills/vue-best-practices/references/plugins.md +166 -0
  23. package/skills/vue-best-practices/references/reactivity.md +346 -0
  24. package/skills/vue-best-practices/references/render-functions.md +201 -0
  25. package/skills/vue-best-practices/references/sfc.md +310 -0
  26. package/skills/vue-best-practices/references/state-management.md +135 -0
  27. package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
  28. package/skills/vue-debug-guides/SKILL.md +205 -0
  29. package/skills/vue-debug-guides/reference/animation-key-for-rerender.md +160 -0
  30. package/skills/vue-debug-guides/reference/animation-transitiongroup-performance.md +241 -0
  31. package/skills/vue-debug-guides/reference/async-component-error-handling.md +115 -0
  32. package/skills/vue-debug-guides/reference/async-component-keepalive-ref-issue.md +112 -0
  33. package/skills/vue-debug-guides/reference/async-component-suspense-control.md +84 -0
  34. package/skills/vue-debug-guides/reference/async-component-vue-router.md +109 -0
  35. package/skills/vue-debug-guides/reference/attrs-event-listener-merging.md +205 -0
  36. package/skills/vue-debug-guides/reference/checkbox-true-false-value-form-submission.md +118 -0
  37. package/skills/vue-debug-guides/reference/cleanup-side-effects.md +172 -0
  38. package/skills/vue-debug-guides/reference/click-events-on-components.md +180 -0
  39. package/skills/vue-debug-guides/reference/component-naming-conflicts.md +159 -0
  40. package/skills/vue-debug-guides/reference/component-ref-requires-defineexpose.md +176 -0
  41. package/skills/vue-debug-guides/reference/composable-avoid-hidden-side-effects.md +208 -0
  42. package/skills/vue-debug-guides/reference/composable-call-location-restrictions.md +141 -0
  43. package/skills/vue-debug-guides/reference/composable-naming-return-pattern.md +139 -0
  44. package/skills/vue-debug-guides/reference/composable-tovalue-inside-watcheffect.md +182 -0
  45. package/skills/vue-debug-guides/reference/composition-api-not-functional-programming.md +120 -0
  46. package/skills/vue-debug-guides/reference/composition-api-script-setup-async-context.md +203 -0
  47. package/skills/vue-debug-guides/reference/composition-api-vs-react-hooks-differences.md +156 -0
  48. package/skills/vue-debug-guides/reference/computed-array-mutation.md +148 -0
  49. package/skills/vue-debug-guides/reference/computed-conditional-dependencies.md +147 -0
  50. package/skills/vue-debug-guides/reference/computed-no-parameters.md +159 -0
  51. package/skills/vue-debug-guides/reference/computed-no-side-effects.md +107 -0
  52. package/skills/vue-debug-guides/reference/computed-return-value-readonly.md +160 -0
  53. package/skills/vue-debug-guides/reference/configure-app-before-mount.md +89 -0
  54. package/skills/vue-debug-guides/reference/declare-emits-for-documentation.md +212 -0
  55. package/skills/vue-debug-guides/reference/define-expose-before-await.md +192 -0
  56. package/skills/vue-debug-guides/reference/define-model-default-value-sync.md +139 -0
  57. package/skills/vue-debug-guides/reference/defineEmits-must-be-top-level.md +164 -0
  58. package/skills/vue-debug-guides/reference/defineEmits-no-runtime-and-type-mixed.md +170 -0
  59. package/skills/vue-debug-guides/reference/definemodel-object-mutation-no-emit.md +148 -0
  60. package/skills/vue-debug-guides/reference/dom-update-timing-nexttick.md +90 -0
  61. package/skills/vue-debug-guides/reference/dynamic-argument-constraints.md +146 -0
  62. package/skills/vue-debug-guides/reference/dynamic-component-registration-vite.md +147 -0
  63. package/skills/vue-debug-guides/reference/event-modifier-order-matters.md +101 -0
  64. package/skills/vue-debug-guides/reference/exact-modifier-for-precise-shortcuts.md +155 -0
  65. package/skills/vue-debug-guides/reference/fallthrough-attrs-overwrite-vue3.md +159 -0
  66. package/skills/vue-debug-guides/reference/in-dom-template-parsing-caveats.md +149 -0
  67. package/skills/vue-debug-guides/reference/inheritattrs-false-for-wrapper-components.md +230 -0
  68. package/skills/vue-debug-guides/reference/keepalive-router-nested-double-mount.md +222 -0
  69. package/skills/vue-debug-guides/reference/keepalive-transition-memory-leak.md +144 -0
  70. package/skills/vue-debug-guides/reference/keyup-modifier-timing.md +137 -0
  71. package/skills/vue-debug-guides/reference/lifecycle-dom-access-timing.md +216 -0
  72. package/skills/vue-debug-guides/reference/lifecycle-hooks-synchronous-registration.md +156 -0
  73. package/skills/vue-debug-guides/reference/lifecycle-ssr-awareness.md +184 -0
  74. package/skills/vue-debug-guides/reference/local-components-not-in-descendants.md +151 -0
  75. package/skills/vue-debug-guides/reference/mount-return-value.md +88 -0
  76. package/skills/vue-debug-guides/reference/multi-root-component-class-attrs.md +93 -0
  77. package/skills/vue-debug-guides/reference/native-event-collision-with-emits.md +162 -0
  78. package/skills/vue-debug-guides/reference/no-passive-with-prevent.md +141 -0
  79. package/skills/vue-debug-guides/reference/no-v-if-with-v-for.md +136 -0
  80. package/skills/vue-debug-guides/reference/perf-computed-object-stability.md +157 -0
  81. package/skills/vue-debug-guides/reference/perf-props-stability-update-optimization.md +140 -0
  82. package/skills/vue-debug-guides/reference/plugin-global-properties-sparingly.md +109 -0
  83. package/skills/vue-debug-guides/reference/plugin-install-before-mount.md +124 -0
  84. package/skills/vue-debug-guides/reference/plugin-prefer-provide-inject-over-global-properties.md +120 -0
  85. package/skills/vue-debug-guides/reference/plugin-typescript-type-augmentation.md +157 -0
  86. package/skills/vue-debug-guides/reference/prop-defineprops-scope-limitation.md +161 -0
  87. package/skills/vue-debug-guides/reference/provide-inject-debugging-challenges.md +203 -0
  88. package/skills/vue-debug-guides/reference/provide-inject-default-value-factory.md +244 -0
  89. package/skills/vue-debug-guides/reference/provide-inject-reactivity-not-automatic.md +226 -0
  90. package/skills/vue-debug-guides/reference/provide-inject-synchronous-setup.md +235 -0
  91. package/skills/vue-debug-guides/reference/reactive-destructuring.md +89 -0
  92. package/skills/vue-debug-guides/reference/reactivity-debugging-hooks.md +132 -0
  93. package/skills/vue-debug-guides/reference/reactivity-markraw-for-non-reactive.md +149 -0
  94. package/skills/vue-debug-guides/reference/reactivity-proxy-identity-hazard.md +96 -0
  95. package/skills/vue-debug-guides/reference/reactivity-same-tick-batching.md +166 -0
  96. package/skills/vue-debug-guides/reference/ref-value-access.md +61 -0
  97. package/skills/vue-debug-guides/reference/refs-in-collections-need-value.md +81 -0
  98. package/skills/vue-debug-guides/reference/render-function-avoid-internal-vnode-properties.md +151 -0
  99. package/skills/vue-debug-guides/reference/render-function-vnodes-must-be-unique.md +133 -0
  100. package/skills/vue-debug-guides/reference/rendering-render-function-h-import-vue3.md +148 -0
  101. package/skills/vue-debug-guides/reference/rendering-render-function-return-from-setup.md +148 -0
  102. package/skills/vue-debug-guides/reference/rendering-render-function-slots-as-functions.md +168 -0
  103. package/skills/vue-debug-guides/reference/rendering-resolve-component-for-string-names.md +231 -0
  104. package/skills/vue-debug-guides/reference/select-initial-value-ios-bug.md +91 -0
  105. package/skills/vue-debug-guides/reference/self-referencing-component-name.md +157 -0
  106. package/skills/vue-debug-guides/reference/sfc-named-exports-forbidden.md +184 -0
  107. package/skills/vue-debug-guides/reference/sfc-scoped-css-child-component-styling.md +156 -0
  108. package/skills/vue-debug-guides/reference/sfc-scoped-css-dynamic-content.md +193 -0
  109. package/skills/vue-debug-guides/reference/sfc-scoped-css-slot-content.md +242 -0
  110. package/skills/vue-debug-guides/reference/sfc-script-setup-reactivity.md +195 -0
  111. package/skills/vue-debug-guides/reference/slot-forwarding-to-child-components.md +143 -0
  112. package/skills/vue-debug-guides/reference/slot-implicit-default-content.md +155 -0
  113. package/skills/vue-debug-guides/reference/slot-name-reserved-prop.md +109 -0
  114. package/skills/vue-debug-guides/reference/slot-named-scoped-explicit-default.md +95 -0
  115. package/skills/vue-debug-guides/reference/slot-render-scope-parent-only.md +135 -0
  116. package/skills/vue-debug-guides/reference/slot-v-slot-on-components-or-templates-only.md +122 -0
  117. package/skills/vue-debug-guides/reference/ssr-hydration-mismatch-causes.md +280 -0
  118. package/skills/vue-debug-guides/reference/ssr-platform-specific-apis.md +256 -0
  119. package/skills/vue-debug-guides/reference/state-ssr-cross-request-pollution.md +276 -0
  120. package/skills/vue-debug-guides/reference/suspense-no-builtin-error-handling.md +127 -0
  121. package/skills/vue-debug-guides/reference/suspense-ssr-hydration-issues.md +159 -0
  122. package/skills/vue-debug-guides/reference/tailwind-dynamic-class-generation.md +144 -0
  123. package/skills/vue-debug-guides/reference/teleport-scoped-styles-limitation.md +191 -0
  124. package/skills/vue-debug-guides/reference/teleport-ssr-hydration.md +152 -0
  125. package/skills/vue-debug-guides/reference/teleport-target-must-exist.md +113 -0
  126. package/skills/vue-debug-guides/reference/template-expressions-restrictions.md +114 -0
  127. package/skills/vue-debug-guides/reference/template-functions-no-side-effects.md +187 -0
  128. package/skills/vue-debug-guides/reference/template-ref-null-with-v-if.md +123 -0
  129. package/skills/vue-debug-guides/reference/template-ref-unwrapping-top-level.md +104 -0
  130. package/skills/vue-debug-guides/reference/template-ref-v-for-order.md +172 -0
  131. package/skills/vue-debug-guides/reference/textarea-no-interpolation.md +72 -0
  132. package/skills/vue-debug-guides/reference/transition-group-flip-inline-elements.md +152 -0
  133. package/skills/vue-debug-guides/reference/transition-group-move-animation-position-absolute.md +130 -0
  134. package/skills/vue-debug-guides/reference/transition-group-no-default-wrapper-vue3.md +152 -0
  135. package/skills/vue-debug-guides/reference/transition-js-hooks-done-callback.md +251 -0
  136. package/skills/vue-debug-guides/reference/transition-nested-duration.md +182 -0
  137. package/skills/vue-debug-guides/reference/transition-reusable-scoped-style.md +245 -0
  138. package/skills/vue-debug-guides/reference/transition-router-view-appear.md +193 -0
  139. package/skills/vue-debug-guides/reference/transition-type-when-mixed.md +172 -0
  140. package/skills/vue-debug-guides/reference/transition-unmount-hook-timing.md +149 -0
  141. package/skills/vue-debug-guides/reference/ts-defineprops-boolean-default-false.md +225 -0
  142. package/skills/vue-debug-guides/reference/ts-defineprops-imported-types-limitations.md +281 -0
  143. package/skills/vue-debug-guides/reference/ts-event-handler-explicit-typing.md +213 -0
  144. package/skills/vue-debug-guides/reference/ts-reactive-no-generic-argument.md +196 -0
  145. package/skills/vue-debug-guides/reference/ts-shallowref-for-dynamic-components.md +218 -0
  146. package/skills/vue-debug-guides/reference/ts-template-ref-null-handling.md +249 -0
  147. package/skills/vue-debug-guides/reference/ts-template-type-casting.md +214 -0
  148. package/skills/vue-debug-guides/reference/ts-withdefaults-mutable-factory-function.md +171 -0
  149. package/skills/vue-debug-guides/reference/undeclared-emits-double-firing.md +195 -0
  150. package/skills/vue-debug-guides/reference/use-template-ref-vue35.md +158 -0
  151. package/skills/vue-debug-guides/reference/v-else-must-follow-v-if.md +136 -0
  152. package/skills/vue-debug-guides/reference/v-for-component-props.md +95 -0
  153. package/skills/vue-debug-guides/reference/v-for-computed-reverse-sort.md +86 -0
  154. package/skills/vue-debug-guides/reference/v-for-key-attribute.md +90 -0
  155. package/skills/vue-debug-guides/reference/v-for-range-starts-at-one.md +66 -0
  156. package/skills/vue-debug-guides/reference/v-if-null-check-order.md +171 -0
  157. package/skills/vue-debug-guides/reference/v-model-ignores-html-attributes.md +83 -0
  158. package/skills/vue-debug-guides/reference/v-model-ime-composition.md +83 -0
  159. package/skills/vue-debug-guides/reference/v-model-number-modifier-behavior.md +124 -0
  160. package/skills/vue-debug-guides/reference/v-show-template-limitation.md +124 -0
  161. package/skills/vue-debug-guides/reference/watch-async-cleanup.md +180 -0
  162. package/skills/vue-debug-guides/reference/watch-async-creation-memory-leak.md +176 -0
  163. package/skills/vue-debug-guides/reference/watch-deep-same-object-reference.md +165 -0
  164. package/skills/vue-debug-guides/reference/watch-flush-timing.md +189 -0
  165. package/skills/vue-debug-guides/reference/watch-reactive-property-getter.md +108 -0
  166. package/skills/vue-debug-guides/reference/watcheffect-async-dependency-tracking.md +173 -0
  167. package/skills/vue-debug-guides/reference/watcheffect-flush-post-for-refs.md +176 -0
  168. package/skills/vue-jsx-best-practices/SKILL.md +12 -0
  169. package/skills/vue-jsx-best-practices/reference/render-function-jsx-vue-vs-react.md +141 -0
  170. package/skills/vue-options-api-best-practices/SKILL.md +23 -0
  171. package/skills/vue-options-api-best-practices/reference/no-arrow-functions-in-lifecycle-hooks.md +95 -0
  172. package/skills/vue-options-api-best-practices/reference/no-arrow-functions-in-methods.md +68 -0
  173. package/skills/vue-options-api-best-practices/reference/stateful-methods-lifecycle.md +61 -0
  174. package/skills/vue-options-api-best-practices/reference/ts-options-api-arrow-functions-validators.md +141 -0
  175. package/skills/vue-options-api-best-practices/reference/ts-options-api-computed-return-types.md +192 -0
  176. package/skills/vue-options-api-best-practices/reference/ts-options-api-proptype-complex-types.md +212 -0
  177. package/skills/vue-options-api-best-practices/reference/ts-options-api-provide-inject-limitations.md +135 -0
  178. package/skills/vue-options-api-best-practices/reference/ts-options-api-type-event-handlers.md +202 -0
  179. package/skills/vue-options-api-best-practices/reference/ts-options-api-use-definecomponent.md +172 -0
  180. package/skills/vue-options-api-best-practices/reference/ts-strict-mode-options-api.md +197 -0
  181. package/skills/vue-pinia-best-practices/SKILL.md +21 -0
  182. package/skills/vue-pinia-best-practices/reference/pinia-no-active-pinia-error.md +248 -0
  183. package/skills/vue-pinia-best-practices/reference/pinia-setup-store-return-all-state.md +227 -0
  184. package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md +193 -0
  185. package/skills/vue-pinia-best-practices/reference/state-url-for-ephemeral-filters.md +238 -0
  186. package/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md +262 -0
  187. package/skills/vue-pinia-best-practices/reference/store-method-binding-parentheses.md +191 -0
  188. package/skills/vue-router-best-practices/SKILL.md +23 -0
  189. package/skills/vue-router-best-practices/reference/router-beforeenter-no-param-trigger.md +167 -0
  190. package/skills/vue-router-best-practices/reference/router-beforerouteenter-no-this.md +176 -0
  191. package/skills/vue-router-best-practices/reference/router-guard-async-await-pattern.md +227 -0
  192. package/skills/vue-router-best-practices/reference/router-navigation-guard-infinite-loop.md +187 -0
  193. package/skills/vue-router-best-practices/reference/router-navigation-guard-next-deprecated.md +150 -0
  194. package/skills/vue-router-best-practices/reference/router-param-change-no-lifecycle.md +181 -0
  195. package/skills/vue-router-best-practices/reference/router-simple-routing-cleanup.md +209 -0
  196. package/skills/vue-router-best-practices/reference/router-use-vue-router-for-production.md +183 -0
  197. package/skills/vue-testing-best-practices/SKILL.md +29 -0
  198. package/skills/vue-testing-best-practices/reference/async-component-testing.md +163 -0
  199. package/skills/vue-testing-best-practices/reference/teleport-testing-complexity.md +158 -0
  200. package/skills/vue-testing-best-practices/reference/testing-async-await-flushpromises.md +175 -0
  201. package/skills/vue-testing-best-practices/reference/testing-browser-vs-node-runners.md +208 -0
  202. package/skills/vue-testing-best-practices/reference/testing-component-blackbox-approach.md +144 -0
  203. package/skills/vue-testing-best-practices/reference/testing-composables-helper-wrapper.md +238 -0
  204. package/skills/vue-testing-best-practices/reference/testing-e2e-playwright-recommended.md +242 -0
  205. package/skills/vue-testing-best-practices/reference/testing-no-snapshot-only.md +197 -0
  206. package/skills/vue-testing-best-practices/reference/testing-pinia-store-setup.md +228 -0
  207. package/skills/vue-testing-best-practices/reference/testing-suspense-async-components.md +229 -0
  208. package/skills/vue-testing-best-practices/reference/testing-vitest-recommended-for-vue.md +204 -0
@@ -0,0 +1,152 @@
1
+ ---
2
+ title: TransitionGroup FLIP Animations Do Not Work With Inline Elements
3
+ impact: MEDIUM
4
+ impactDescription: Move animations silently fail on inline elements, causing items to jump
5
+ type: gotcha
6
+ tags: [vue3, transition-group, animation, flip, css, display, inline-block]
7
+ ---
8
+
9
+ # TransitionGroup FLIP Animations Do Not Work With Inline Elements
10
+
11
+ **Impact: MEDIUM** - The FLIP (First, Last, Invert, Play) animation technique that Vue uses for `<TransitionGroup>` move transitions does not work with elements that have `display: inline`. The move animation will silently fail, and items will jump to their new positions instead of smoothly transitioning.
12
+
13
+ This is a CSS limitation, not a Vue bug. CSS transforms (which FLIP uses internally) do not apply to inline elements per the CSS specification.
14
+
15
+ ## Task Checklist
16
+
17
+ - [ ] Ensure list items are not `display: inline` elements
18
+ - [ ] Use `display: inline-block` or `display: block` for list items
19
+ - [ ] Use flexbox or grid containers which make children block-level
20
+ - [ ] Check if inherited styles are setting `display: inline`
21
+
22
+ **Incorrect - Inline elements break move animations:**
23
+ ```vue
24
+ <template>
25
+ <!-- BROKEN: span elements are inline by default -->
26
+ <TransitionGroup name="tag" tag="div" class="tag-container">
27
+ <span v-for="tag in tags" :key="tag.id" class="tag">
28
+ {{ tag.name }}
29
+ </span>
30
+ </TransitionGroup>
31
+ </template>
32
+
33
+ <style>
34
+ .tag-move {
35
+ transition: transform 0.3s ease;
36
+ /* This won't work because spans are inline! */
37
+ }
38
+ </style>
39
+ ```
40
+
41
+ **Correct - Use inline-block:**
42
+ ```vue
43
+ <template>
44
+ <TransitionGroup name="tag" tag="div" class="tag-container">
45
+ <span v-for="tag in tags" :key="tag.id" class="tag">
46
+ {{ tag.name }}
47
+ </span>
48
+ </TransitionGroup>
49
+ </template>
50
+
51
+ <style>
52
+ .tag {
53
+ display: inline-block; /* REQUIRED for FLIP animations */
54
+ }
55
+
56
+ .tag-move {
57
+ transition: transform 0.3s ease;
58
+ }
59
+ </style>
60
+ ```
61
+
62
+ **Correct - Use flexbox container:**
63
+ ```vue
64
+ <template>
65
+ <TransitionGroup name="tag" tag="div" class="tag-container">
66
+ <span v-for="tag in tags" :key="tag.id" class="tag">
67
+ {{ tag.name }}
68
+ </span>
69
+ </TransitionGroup>
70
+ </template>
71
+
72
+ <style>
73
+ .tag-container {
74
+ display: flex;
75
+ flex-wrap: wrap;
76
+ gap: 8px;
77
+ }
78
+
79
+ /* Flex children are block-level, FLIP works automatically */
80
+ .tag-move {
81
+ transition: transform 0.3s ease;
82
+ }
83
+ </style>
84
+ ```
85
+
86
+ **Correct - Use block elements:**
87
+ ```vue
88
+ <template>
89
+ <!-- div elements are block by default -->
90
+ <TransitionGroup name="item" tag="div">
91
+ <div v-for="item in items" :key="item.id" class="item">
92
+ {{ item.name }}
93
+ </div>
94
+ </TransitionGroup>
95
+ </template>
96
+
97
+ <style>
98
+ .item-move {
99
+ transition: transform 0.3s ease;
100
+ }
101
+ </style>
102
+ ```
103
+
104
+ ## Why Inline Elements Don't Work
105
+
106
+ Per CSS specifications, the `transform` property does not apply to inline boxes. Since FLIP animations use CSS transforms to animate element positions:
107
+
108
+ ```css
109
+ /* Vue internally applies something like this during move */
110
+ .item {
111
+ transform: translateX(-50px) translateY(-20px);
112
+ /* Then transitions to transform: none */
113
+ }
114
+ ```
115
+
116
+ This transform is ignored on inline elements, so no animation occurs.
117
+
118
+ ## Elements That Are Inline by Default
119
+
120
+ Be aware of these common inline elements that need `display: inline-block`:
121
+
122
+ - `<span>`
123
+ - `<a>`
124
+ - `<em>`, `<strong>`, `<i>`, `<b>`
125
+ - `<code>`, `<kbd>`
126
+ - `<label>`
127
+ - `<button>` (inline-block by default, but verify)
128
+
129
+ ## Move Animations Also Require Transform Transition
130
+
131
+ The `.move` class must have `transform` in its `transition` property:
132
+
133
+ ```css
134
+ /* CORRECT */
135
+ .list-move {
136
+ transition: transform 0.3s ease;
137
+ }
138
+
139
+ /* ALSO CORRECT */
140
+ .list-move {
141
+ transition: all 0.3s ease; /* 'all' includes transform */
142
+ }
143
+
144
+ /* WRONG - transform not included */
145
+ .list-move {
146
+ transition: opacity 0.3s ease; /* Move won't animate! */
147
+ }
148
+ ```
149
+
150
+ ## Reference
151
+ - [Vue.js TransitionGroup Move Transitions](https://vuejs.org/guide/built-ins/transition-group.html#move-transitions)
152
+ - [MDN CSS Transform - Formal Definition](https://developer.mozilla.org/en-US/docs/Web/CSS/transform#formal_definition)
@@ -0,0 +1,130 @@
1
+ ---
2
+ title: TransitionGroup Move Animation Requires Position Absolute on Leaving Items
3
+ impact: HIGH
4
+ impactDescription: Without position absolute, surrounding items jump instead of smoothly animating
5
+ type: gotcha
6
+ tags: [vue3, transition-group, animation, move-transition, css, list-animation]
7
+ ---
8
+
9
+ # TransitionGroup Move Animation Requires Position Absolute on Leaving Items
10
+
11
+ **Impact: HIGH** - When items are added or removed from a list with `<TransitionGroup>`, surrounding items will instantly "jump" to their new positions instead of smoothly animating. This creates a jarring user experience and is one of the most common mistakes with list animations.
12
+
13
+ The fix is to set `position: absolute` on the `leave-active` class so leaving items are taken out of the layout flow, allowing other items to smoothly animate into their new positions.
14
+
15
+ ## Task Checklist
16
+
17
+ - [ ] Add `.list-move` class (or `.[name]-move`) for smooth repositioning
18
+ - [ ] Set `position: absolute` on `.list-leave-active` class
19
+ - [ ] Ensure the parent container has `position: relative` if needed
20
+ - [ ] Test with rapid add/remove operations to verify smooth animations
21
+
22
+ **Incorrect - Items jump instead of moving:**
23
+ ```vue
24
+ <template>
25
+ <TransitionGroup name="list" tag="ul">
26
+ <li v-for="item in items" :key="item.id">
27
+ {{ item.name }}
28
+ </li>
29
+ </TransitionGroup>
30
+ </template>
31
+
32
+ <style>
33
+ /* INCOMPLETE: Missing move class and position absolute */
34
+ .list-enter-active,
35
+ .list-leave-active {
36
+ transition: all 0.5s ease;
37
+ }
38
+
39
+ .list-enter-from,
40
+ .list-leave-to {
41
+ opacity: 0;
42
+ transform: translateX(30px);
43
+ }
44
+ </style>
45
+ ```
46
+
47
+ **Correct - Smooth move transitions:**
48
+ ```vue
49
+ <template>
50
+ <TransitionGroup name="list" tag="ul">
51
+ <li v-for="item in items" :key="item.id">
52
+ {{ item.name }}
53
+ </li>
54
+ </TransitionGroup>
55
+ </template>
56
+
57
+ <style>
58
+ /* CORRECT: Full set of classes for smooth animations */
59
+
60
+ /* Apply transition to moving elements */
61
+ .list-move,
62
+ .list-enter-active,
63
+ .list-leave-active {
64
+ transition: all 0.5s ease;
65
+ }
66
+
67
+ .list-enter-from,
68
+ .list-leave-to {
69
+ opacity: 0;
70
+ transform: translateX(30px);
71
+ }
72
+
73
+ /* CRITICAL: Take leaving items out of layout flow */
74
+ .list-leave-active {
75
+ position: absolute;
76
+ }
77
+ </style>
78
+ ```
79
+
80
+ ## Why This Works
81
+
82
+ The FLIP animation technique Vue uses internally needs to calculate element positions. When an item leaves:
83
+
84
+ 1. Without `position: absolute`: The leaving item still occupies space in the DOM
85
+ 2. Other items can't move until the leaving item is fully removed
86
+ 3. Result: Items snap to new positions after leave animation completes
87
+
88
+ With `position: absolute`:
89
+
90
+ 1. Leaving item is removed from normal layout flow immediately
91
+ 2. Other items can begin moving into the vacated space
92
+ 3. Result: Leaving animation and move animation happen simultaneously
93
+
94
+ ## Visual Diagram
95
+
96
+ ```
97
+ Without position: absolute:
98
+ [A] [B] [C] [D] <- Remove B
99
+ [A] [C] [D] <- B fading out, C/D waiting
100
+ [A] [C] [D] <- B gone, C/D jump instantly
101
+
102
+ With position: absolute:
103
+ [A] [B] [C] [D] <- Remove B
104
+ [A][B][C] [D] <- B fading (absolute), C/D sliding left
105
+ [A] [C] [D] <- Smooth completion
106
+ ```
107
+
108
+ ## Additional Considerations
109
+
110
+ **Container Width:** When using `position: absolute`, items may need explicit widths:
111
+
112
+ ```css
113
+ .list-leave-active {
114
+ position: absolute;
115
+ width: 100%; /* Or specific width to maintain layout during leave */
116
+ }
117
+ ```
118
+
119
+ **Stacking Context:** Leaving items with `position: absolute` may stack above other elements:
120
+
121
+ ```css
122
+ .list-leave-active {
123
+ position: absolute;
124
+ z-index: -1; /* Optional: put behind other items */
125
+ }
126
+ ```
127
+
128
+ ## Reference
129
+ - [Vue.js TransitionGroup Move Transitions](https://vuejs.org/guide/built-ins/transition-group.html#move-transitions)
130
+ - [FLIP Animation Technique](https://aerotwist.com/blog/flip-your-animations/)
@@ -0,0 +1,152 @@
1
+ ---
2
+ title: TransitionGroup No Longer Renders Default Wrapper Element in Vue 3
3
+ impact: MEDIUM
4
+ impactDescription: Vue 2 to Vue 3 migration may break layouts relying on the default span wrapper
5
+ type: gotcha
6
+ tags: [vue3, transition-group, migration, vue2, breaking-change, wrapper-element]
7
+ ---
8
+
9
+ # TransitionGroup No Longer Renders Default Wrapper Element in Vue 3
10
+
11
+ **Impact: MEDIUM** - In Vue 2, `<transition-group>` always rendered a wrapper element (default `<span>`), but in Vue 3, it renders no wrapper element by default thanks to fragment support. This breaking change can cause layout issues and broken styles when migrating from Vue 2.
12
+
13
+ If your code relies on the wrapper element for styling or layout, you must explicitly specify the `tag` prop in Vue 3.
14
+
15
+ ## Task Checklist
16
+
17
+ - [ ] When migrating from Vue 2, add explicit `tag` prop to all `<TransitionGroup>` components
18
+ - [ ] Review CSS selectors that targeted the wrapper element
19
+ - [ ] Update parent component styles that expected a wrapper element
20
+ - [ ] Consider if the wrapper element is actually needed in Vue 3
21
+
22
+ **Vue 2 Behavior (wrapper element by default):**
23
+ ```vue
24
+ <template>
25
+ <transition-group name="list">
26
+ <div v-for="item in items" :key="item.id">{{ item }}</div>
27
+ </transition-group>
28
+ </template>
29
+
30
+ <!-- Renders as: -->
31
+ <span> <!-- Default wrapper in Vue 2 -->
32
+ <div>Item 1</div>
33
+ <div>Item 2</div>
34
+ </span>
35
+ ```
36
+
37
+ **Vue 3 Behavior (no wrapper by default):**
38
+ ```vue
39
+ <template>
40
+ <TransitionGroup name="list">
41
+ <div v-for="item in items" :key="item.id">{{ item }}</div>
42
+ </TransitionGroup>
43
+ </template>
44
+
45
+ <!-- Renders as (fragment): -->
46
+ <div>Item 1</div>
47
+ <div>Item 2</div>
48
+ <!-- No wrapper element! -->
49
+ ```
50
+
51
+ **Vue 3 - Explicitly specify wrapper:**
52
+ ```vue
53
+ <template>
54
+ <!-- Use tag prop to specify wrapper element -->
55
+ <TransitionGroup name="list" tag="ul">
56
+ <li v-for="item in items" :key="item.id">{{ item }}</li>
57
+ </TransitionGroup>
58
+ </template>
59
+
60
+ <!-- Renders as: -->
61
+ <ul>
62
+ <li>Item 1</li>
63
+ <li>Item 2</li>
64
+ </ul>
65
+ ```
66
+
67
+ ## Migration Scenarios
68
+
69
+ ### Layout Depending on Wrapper
70
+
71
+ **Vue 2 code that breaks in Vue 3:**
72
+ ```vue
73
+ <template>
74
+ <transition-group class="grid-container" name="list">
75
+ <div v-for="item in items" :key="item.id">{{ item }}</div>
76
+ </transition-group>
77
+ </template>
78
+
79
+ <style>
80
+ .grid-container {
81
+ display: grid;
82
+ grid-template-columns: repeat(3, 1fr);
83
+ }
84
+ </style>
85
+ ```
86
+
87
+ In Vue 3, the class is not applied to anything because there's no wrapper element.
88
+
89
+ **Fixed for Vue 3:**
90
+ ```vue
91
+ <template>
92
+ <TransitionGroup class="grid-container" name="list" tag="div">
93
+ <div v-for="item in items" :key="item.id">{{ item }}</div>
94
+ </TransitionGroup>
95
+ </template>
96
+ ```
97
+
98
+ ### Semantic HTML Lists
99
+
100
+ **Vue 2:**
101
+ ```vue
102
+ <transition-group tag="ul" name="list">
103
+ <li v-for="item in items" :key="item.id">{{ item }}</li>
104
+ </transition-group>
105
+ ```
106
+
107
+ **Vue 3 (same syntax, but now tag is more important):**
108
+ ```vue
109
+ <TransitionGroup tag="ul" name="list">
110
+ <li v-for="item in items" :key="item.id">{{ item }}</li>
111
+ </TransitionGroup>
112
+ ```
113
+
114
+ ### When You Don't Need a Wrapper
115
+
116
+ Vue 3's fragment support means you might not need a wrapper at all:
117
+
118
+ ```vue
119
+ <template>
120
+ <div class="parent-with-styles">
121
+ <!-- No tag needed if parent handles layout -->
122
+ <TransitionGroup name="fade">
123
+ <span v-for="item in items" :key="item.id">{{ item }}</span>
124
+ </TransitionGroup>
125
+ </div>
126
+ </template>
127
+
128
+ <style>
129
+ .parent-with-styles {
130
+ display: flex;
131
+ gap: 8px;
132
+ }
133
+ </style>
134
+ ```
135
+
136
+ ## In-DOM Template Syntax
137
+
138
+ When using in-DOM templates (not SFCs), remember to use kebab-case:
139
+
140
+ ```html
141
+ <!-- In-DOM template -->
142
+ <transition-group tag="ul" name="list">
143
+ <li v-for="item in items" :key="item.id">{{ item }}</li>
144
+ </transition-group>
145
+
146
+ <!-- NOT -->
147
+ <TransitionGroup tag="ul" name="list"> <!-- Won't work in DOM templates -->
148
+ ```
149
+
150
+ ## Reference
151
+ - [Vue 3 Migration Guide - TransitionGroup Root Element](https://v3-migration.vuejs.org/breaking-changes/transition-group.html)
152
+ - [Vue.js TransitionGroup](https://vuejs.org/guide/built-ins/transition-group.html)
@@ -0,0 +1,251 @@
1
+ ---
2
+ title: JavaScript Transition Hooks Require done() Callback with css="false"
3
+ impact: HIGH
4
+ impactDescription: Without calling done(), JavaScript-only transitions complete immediately, skipping the animation entirely
5
+ type: gotcha
6
+ tags: [vue3, transition, javascript, animation, hooks, gsap, done-callback]
7
+ ---
8
+
9
+ # JavaScript Transition Hooks Require done() Callback with css="false"
10
+
11
+ **Impact: HIGH** - When using JavaScript-only transitions (with `:css="false"`), the `@enter` and `@leave` hooks **must** call the `done()` callback to signal when the animation completes. Without calling `done()`, Vue considers the transition finished immediately, causing elements to appear/disappear without animation.
12
+
13
+ This is especially important when using animation libraries like GSAP, Anime.js, or the Web Animations API.
14
+
15
+ ## Task Checklist
16
+
17
+ - [ ] When using `:css="false"`, always call `done()` in `@enter` and `@leave` hooks
18
+ - [ ] Call `done()` when your JavaScript animation completes (in the `onComplete` callback)
19
+ - [ ] Remember: `done()` is optional when CSS handles the transition, but **required** with `:css="false"`
20
+ - [ ] Use `:css="false"` to prevent CSS rules from interfering with JS animations
21
+
22
+ **Problematic Code:**
23
+ ```vue
24
+ <template>
25
+ <!-- BAD: No done() callback - animation is skipped! -->
26
+ <Transition :css="false" @enter="onEnter" @leave="onLeave">
27
+ <div v-if="show" class="box">Content</div>
28
+ </Transition>
29
+ </template>
30
+
31
+ <script setup>
32
+ import gsap from 'gsap'
33
+
34
+ function onEnter(el) {
35
+ // Animation starts but Vue doesn't wait for it!
36
+ gsap.from(el, {
37
+ opacity: 0,
38
+ y: 50,
39
+ duration: 0.5
40
+ })
41
+ // Missing done() call - element appears with no animation
42
+ }
43
+
44
+ function onLeave(el) {
45
+ gsap.to(el, {
46
+ opacity: 0,
47
+ y: -50,
48
+ duration: 0.5
49
+ })
50
+ // Missing done() call - element removed immediately!
51
+ }
52
+ </script>
53
+ ```
54
+
55
+ **Correct Code:**
56
+ ```vue
57
+ <template>
58
+ <!-- GOOD: done() callback signals animation completion -->
59
+ <Transition :css="false" @enter="onEnter" @leave="onLeave">
60
+ <div v-if="show" class="box">Content</div>
61
+ </Transition>
62
+ </template>
63
+
64
+ <script setup>
65
+ import gsap from 'gsap'
66
+
67
+ function onEnter(el, done) {
68
+ gsap.from(el, {
69
+ opacity: 0,
70
+ y: 50,
71
+ duration: 0.5,
72
+ onComplete: done // Tell Vue animation is complete
73
+ })
74
+ }
75
+
76
+ function onLeave(el, done) {
77
+ gsap.to(el, {
78
+ opacity: 0,
79
+ y: -50,
80
+ duration: 0.5,
81
+ onComplete: done // Element removed after animation
82
+ })
83
+ }
84
+ </script>
85
+ ```
86
+
87
+ ## Why Use `:css="false"`?
88
+
89
+ 1. **Prevents CSS interference**: Vue won't add transition classes that might conflict
90
+ 2. **Slight performance benefit**: Skips CSS transition detection
91
+ 3. **Clearer intent**: Makes it explicit that JS controls the animation
92
+
93
+ ```vue
94
+ <template>
95
+ <!-- Without :css="false", Vue adds v-enter-active etc. classes -->
96
+ <!-- These can interfere with your JS animation timing -->
97
+ <Transition @enter="onEnter" @leave="onLeave">
98
+ <div v-if="show">May have CSS conflicts</div>
99
+ </Transition>
100
+
101
+ <!-- With :css="false", no classes added - full JS control -->
102
+ <Transition :css="false" @enter="onEnter" @leave="onLeave">
103
+ <div v-if="show">Pure JS animation</div>
104
+ </Transition>
105
+ </template>
106
+ ```
107
+
108
+ ## Complete JavaScript Transition Example
109
+
110
+ ```vue
111
+ <template>
112
+ <Transition
113
+ :css="false"
114
+ @before-enter="onBeforeEnter"
115
+ @enter="onEnter"
116
+ @after-enter="onAfterEnter"
117
+ @enter-cancelled="onEnterCancelled"
118
+ @before-leave="onBeforeLeave"
119
+ @leave="onLeave"
120
+ @after-leave="onAfterLeave"
121
+ @leave-cancelled="onLeaveCancelled"
122
+ >
123
+ <div v-if="show" class="animated-box">Content</div>
124
+ </Transition>
125
+ </template>
126
+
127
+ <script setup>
128
+ import gsap from 'gsap'
129
+ import { ref } from 'vue'
130
+
131
+ const show = ref(false)
132
+ let enterAnimation = null
133
+ let leaveAnimation = null
134
+
135
+ function onBeforeEnter(el) {
136
+ // Set initial state before animation
137
+ el.style.opacity = 0
138
+ el.style.transform = 'translateY(50px)'
139
+ }
140
+
141
+ function onEnter(el, done) {
142
+ // Store animation reference for potential cancellation
143
+ enterAnimation = gsap.to(el, {
144
+ opacity: 1,
145
+ y: 0,
146
+ duration: 0.5,
147
+ ease: 'power2.out',
148
+ onComplete: done // REQUIRED with :css="false"
149
+ })
150
+ }
151
+
152
+ function onAfterEnter(el) {
153
+ // Cleanup after enter completes
154
+ enterAnimation = null
155
+ }
156
+
157
+ function onEnterCancelled() {
158
+ // Handle interruption (e.g., user toggles quickly)
159
+ if (enterAnimation) {
160
+ enterAnimation.kill()
161
+ enterAnimation = null
162
+ }
163
+ }
164
+
165
+ function onBeforeLeave(el) {
166
+ // Set state before leaving
167
+ }
168
+
169
+ function onLeave(el, done) {
170
+ leaveAnimation = gsap.to(el, {
171
+ opacity: 0,
172
+ y: -50,
173
+ duration: 0.5,
174
+ ease: 'power2.in',
175
+ onComplete: done // REQUIRED with :css="false"
176
+ })
177
+ }
178
+
179
+ function onAfterLeave(el) {
180
+ leaveAnimation = null
181
+ }
182
+
183
+ function onLeaveCancelled() {
184
+ if (leaveAnimation) {
185
+ leaveAnimation.kill()
186
+ leaveAnimation = null
187
+ }
188
+ }
189
+ </script>
190
+ ```
191
+
192
+ ## Using Web Animations API
193
+
194
+ ```vue
195
+ <script setup>
196
+ function onEnter(el, done) {
197
+ const animation = el.animate([
198
+ { opacity: 0, transform: 'scale(0.9)' },
199
+ { opacity: 1, transform: 'scale(1)' }
200
+ ], {
201
+ duration: 300,
202
+ easing: 'ease-out'
203
+ })
204
+
205
+ animation.onfinish = done // Call done when animation ends
206
+ }
207
+
208
+ function onLeave(el, done) {
209
+ const animation = el.animate([
210
+ { opacity: 1, transform: 'scale(1)' },
211
+ { opacity: 0, transform: 'scale(0.9)' }
212
+ ], {
213
+ duration: 300,
214
+ easing: 'ease-in'
215
+ })
216
+
217
+ animation.onfinish = done
218
+ }
219
+ </script>
220
+ ```
221
+
222
+ ## Common Mistakes
223
+
224
+ ```javascript
225
+ // WRONG: Calling done() immediately instead of after animation
226
+ function onEnter(el, done) {
227
+ gsap.from(el, { opacity: 0, duration: 0.5 })
228
+ done() // Called immediately - animation skipped!
229
+ }
230
+
231
+ // WRONG: Forgetting done() parameter
232
+ function onEnter(el) { // No 'done' parameter
233
+ gsap.from(el, {
234
+ opacity: 0,
235
+ onComplete: done // Error: done is not defined!
236
+ })
237
+ }
238
+
239
+ // CORRECT: Pass done to animation callback
240
+ function onEnter(el, done) {
241
+ gsap.from(el, {
242
+ opacity: 0,
243
+ duration: 0.5,
244
+ onComplete: done // Called after 0.5s
245
+ })
246
+ }
247
+ ```
248
+
249
+ ## Reference
250
+ - [Vue.js Transition - JavaScript Hooks](https://vuejs.org/guide/built-ins/transition.html#javascript-hooks)
251
+ - [GSAP with Vue](https://gsap.com/resources/vue/)