1+ <script setup lang="ts">
2+
3+ import {onMounted , onUnmounted , ref , watch } from " vue" ;
4+ import {getChanges , getVersionsAfter , getVersionsBefore , keyVersions , nowChanges , nowUpgradeInfo } from " ./upgrade" ;
5+
6+ const fromOptions = ref ([]);
7+ const toOptions = ref ([]);
8+ const nowFrom = ref (nowUpgradeInfo .value .from );
9+ const nowTo = ref (nowUpgradeInfo .value .to );
10+ const isFromDropdownOpen = ref (false );
11+ const isToDropdownOpen = ref (false );
12+
13+ onMounted (() => {
14+ reload ();
15+ window .addEventListener (' hashchange' , reload );
16+ });
17+
18+ onUnmounted (() => {
19+ window .removeEventListener (' hashchange' , reload );
20+ });
21+
22+ watch (nowFrom , () => {
23+ update ();
24+ });
25+
26+ watch (nowTo , () => {
27+ update ();
28+ });
29+
30+ function openFromDropdown() {
31+ isFromDropdownOpen .value = true ;
32+ }
33+
34+ function closeFromDropdown() {
35+ isFromDropdownOpen .value = false ;
36+ }
37+
38+ function selectFrom(version : string ) {
39+ nowFrom .value = version ;
40+ }
41+
42+ function openToDropdown() {
43+ isToDropdownOpen .value = true ;
44+ }
45+
46+ function closeToDropdown() {
47+ isToDropdownOpen .value = false ;
48+ }
49+
50+ function selectTo(version : string ) {
51+ nowTo .value = version ;
52+ }
53+
54+ function update() {
55+ nowUpgradeInfo .value = {
56+ from: nowFrom .value ,
57+ to: nowTo .value
58+ };
59+ window .location .hash = ` #${nowUpgradeInfo .value .from }-${nowUpgradeInfo .value .to } ` ;
60+ fromOptions .value = getVersionsBefore (nowUpgradeInfo .value .to );
61+ toOptions .value = getVersionsAfter (nowUpgradeInfo .value .from );
62+ nowChanges .value = getChanges (nowUpgradeInfo .value );
63+ const changes = nowChanges .value .map (change => ` ${change .from }-to-${change .to } ` );
64+ document .querySelectorAll (' .upgrade-parts-container div' ).forEach (ele => {
65+ if (changes .includes (ele .id )) {
66+ ele .classList .add (' show' );
67+ } else {
68+ ele .classList .remove (' show' );
69+ }
70+ });
71+ }
72+
73+ function reload() {
74+ const anchor = window .location .hash ;
75+ const [from, to] = anchor .slice (1 ).split (' -' );
76+ if (keyVersions .slice (0 , - 1 ).includes (from ) && getVersionsAfter (from ).includes (to )) {
77+ nowFrom .value = from ;
78+ nowTo .value = to ;
79+ }
80+ update ()
81+ }
82+ </script >
83+
84+ <template >
85+ <div class =" card" >
86+ I'm upgrading from
87+ <div class =" dropdown" @mouseover =" openFromDropdown" @mouseleave =" closeFromDropdown" >
88+ <button class =" dropdown-button" >{{ nowFrom }}</button >
89+ <div class =" dropdown-content" :class =" { 'show-content': isFromDropdownOpen }" >
90+ <a v-for =" ver in fromOptions" @click =" selectFrom(ver)" >{{ ver }}</a >
91+ </div >
92+ </div >
93+ to
94+ <div class =" dropdown" @mouseover =" openToDropdown" @mouseleave =" closeToDropdown" >
95+ <button class =" dropdown-button" >{{ nowTo }}</button >
96+ <div class =" dropdown-content" :class =" { 'show-content': isToDropdownOpen }" >
97+ <a v-for =" ver in toOptions" @click =" selectTo(ver)" >{{ ver }}</a >
98+ </div >
99+ </div >
100+ </div >
101+ </template >
102+
103+ <style scoped>
104+ .card {
105+ font-family : ' Helvetica Neue' , sans-serif ;
106+ width : fit-content ;
107+ padding : 16px ;
108+ margin-top : 20px ;
109+ margin-bottom : 8px ;
110+ border-radius : 4px ;
111+ background-color : var (--vt-c-bg-soft );
112+ }
113+
114+ .dropdown {
115+ width : fit-content ;
116+ position : relative ;
117+ display : inline-block ;
118+ }
119+
120+ .dropdown-button {
121+ border : 1px solid var (--vt-c-divider-light );
122+ border-radius : 4px ;
123+ background-color : var (--vt-c-bg );
124+ color : var (--vt-c-text-1 );
125+ padding : 10px ;
126+ font-size : 16px ;
127+ cursor : pointer ;
128+ }
129+
130+ .dropdown-content {
131+ opacity : 0 ;
132+ overflow : hidden ;
133+ display : block ;
134+ position : absolute ;
135+ background-color : var (--vp-c-bg-elv );
136+ border-radius : 4px ;
137+ border : 1px solid var (--vp-c-divider );
138+ box-shadow : 0 8px 16px 0 rgba (0 , 0 , 0 , 0.2 );
139+ z-index : 1 ;
140+ transition : opacity 0.25s ;
141+ }
142+
143+ .dropdown-content a {
144+ font-size : 16px ;
145+ color : var (--vp-c-text-1 );
146+ padding : 10px ;
147+ text-decoration : none ;
148+ display : block ;
149+ }
150+
151+ .dropdown-content a :hover {
152+ transition : color 0.2s ;
153+ color : var (--vp-c-brand-1 );
154+ }
155+
156+ .show-content {
157+ opacity : 1 !important ;
158+ }
159+ </style >
160+
161+ <style >
162+ .show {
163+ display : initial !important ;
164+ }
165+
166+ .default-hide {
167+ display : none ;
168+ }
169+ </style >
0 commit comments