فهرست منبع

引入uni-vant之前

zhangyujun 3 سال پیش
والد
کامیت
ddb3248014
100فایلهای تغییر یافته به همراه4998 افزوده شده و 15 حذف شده
  1. 7 0
      src/api/modules/user.js
  2. 7 1
      src/api/request.js
  3. 15 1
      src/manifest.json
  4. 21 3
      src/otherPages/classifyChoose/index.vue
  5. 16 10
      src/store/modules/user.js
  6. 2 0
      src/ttcomponents/out/$polyfill/api/relations.js
  7. 505 0
      src/ttcomponents/out/$polyfill/api/utils.js
  8. 5 0
      src/ttcomponents/out/$polyfill/component/classSubdirectory/app.js
  9. 281 0
      src/ttcomponents/out/$polyfill/component/classSubdirectory/component.js
  10. 98 0
      src/ttcomponents/out/$polyfill/component/classSubdirectory/page.js
  11. 39 0
      src/ttcomponents/out/$polyfill/component/classSubdirectory/processRelation.js
  12. 40 0
      src/ttcomponents/out/$polyfill/component/classSubdirectory/promise.js
  13. 127 0
      src/ttcomponents/out/$polyfill/component/classSubdirectory/relation.js
  14. 81 0
      src/ttcomponents/out/$polyfill/component/classSubdirectory/selectComponent.js
  15. 27 0
      src/ttcomponents/out/$polyfill/component/classSubdirectory/utils.js
  16. 31 0
      src/ttcomponents/out/$polyfill/component/componentClass.js
  17. 1 0
      src/ttcomponents/out/action-sheet/index.d.ts
  18. 62 0
      src/ttcomponents/out/action-sheet/index.js
  19. 8 0
      src/ttcomponents/out/action-sheet/index.json
  20. 101 0
      src/ttcomponents/out/action-sheet/index.vue
  21. 69 0
      src/ttcomponents/out/action-sheet/index.wxml
  22. 0 0
      src/ttcomponents/out/action-sheet/index.wxss
  23. 1 0
      src/ttcomponents/out/area/index.d.ts
  24. 234 0
      src/ttcomponents/out/area/index.js
  25. 6 0
      src/ttcomponents/out/area/index.json
  26. 246 0
      src/ttcomponents/out/area/index.vue
  27. 20 0
      src/ttcomponents/out/area/index.wxml
  28. 8 0
      src/ttcomponents/out/area/index.wxs
  29. 1 0
      src/ttcomponents/out/area/index.wxss
  30. 1 0
      src/ttcomponents/out/button/index.d.ts
  31. 58 0
      src/ttcomponents/out/button/index.js
  32. 7 0
      src/ttcomponents/out/button/index.json
  33. 84 0
      src/ttcomponents/out/button/index.vue
  34. 53 0
      src/ttcomponents/out/button/index.wxml
  35. 39 0
      src/ttcomponents/out/button/index.wxs
  36. 0 0
      src/ttcomponents/out/button/index.wxss
  37. 37 0
      src/ttcomponents/out/calendar/calendar.vue
  38. 65 0
      src/ttcomponents/out/calendar/calendar.wxml
  39. 1 0
      src/ttcomponents/out/calendar/components/header/index.d.ts
  40. 16 0
      src/ttcomponents/out/calendar/components/header/index.js
  41. 3 0
      src/ttcomponents/out/calendar/components/header/index.json
  42. 43 0
      src/ttcomponents/out/calendar/components/header/index.vue
  43. 16 0
      src/ttcomponents/out/calendar/components/header/index.wxml
  44. 1 0
      src/ttcomponents/out/calendar/components/header/index.wxss
  45. 1 0
      src/ttcomponents/out/calendar/components/month/index.d.ts
  46. 157 0
      src/ttcomponents/out/calendar/components/month/index.js
  47. 3 0
      src/ttcomponents/out/calendar/components/month/index.json
  48. 195 0
      src/ttcomponents/out/calendar/components/month/index.vue
  49. 39 0
      src/ttcomponents/out/calendar/components/month/index.wxml
  50. 67 0
      src/ttcomponents/out/calendar/components/month/index.wxs
  51. 0 0
      src/ttcomponents/out/calendar/components/month/index.wxss
  52. 1 0
      src/ttcomponents/out/calendar/index.d.ts
  53. 303 0
      src/ttcomponents/out/calendar/index.js
  54. 10 0
      src/ttcomponents/out/calendar/index.json
  55. 325 0
      src/ttcomponents/out/calendar/index.vue
  56. 25 0
      src/ttcomponents/out/calendar/index.wxml
  57. 37 0
      src/ttcomponents/out/calendar/index.wxs
  58. 1 0
      src/ttcomponents/out/calendar/index.wxss
  59. 17 0
      src/ttcomponents/out/calendar/utils.d.ts
  60. 78 0
      src/ttcomponents/out/calendar/utils.js
  61. 25 0
      src/ttcomponents/out/calendar/utils.wxs
  62. 1 0
      src/ttcomponents/out/card/index.d.ts
  63. 49 0
      src/ttcomponents/out/card/index.js
  64. 6 0
      src/ttcomponents/out/card/index.json
  65. 103 0
      src/ttcomponents/out/card/index.vue
  66. 56 0
      src/ttcomponents/out/card/index.wxml
  67. 0 0
      src/ttcomponents/out/card/index.wxss
  68. 1 0
      src/ttcomponents/out/cell-group/index.d.ts
  69. 10 0
      src/ttcomponents/out/cell-group/index.js
  70. 3 0
      src/ttcomponents/out/cell-group/index.json
  71. 27 0
      src/ttcomponents/out/cell-group/index.vue
  72. 9 0
      src/ttcomponents/out/cell-group/index.wxml
  73. 1 0
      src/ttcomponents/out/cell-group/index.wxss
  74. 1 0
      src/ttcomponents/out/cell/index.d.ts
  75. 38 0
      src/ttcomponents/out/cell/index.js
  76. 6 0
      src/ttcomponents/out/cell/index.json
  77. 73 0
      src/ttcomponents/out/cell/index.vue
  78. 46 0
      src/ttcomponents/out/cell/index.wxml
  79. 17 0
      src/ttcomponents/out/cell/index.wxs
  80. 0 0
      src/ttcomponents/out/cell/index.wxss
  81. 1 0
      src/ttcomponents/out/checkbox-group/index.d.ts
  82. 31 0
      src/ttcomponents/out/checkbox-group/index.js
  83. 3 0
      src/ttcomponents/out/checkbox-group/index.json
  84. 43 0
      src/ttcomponents/out/checkbox-group/index.vue
  85. 1 0
      src/ttcomponents/out/checkbox-group/index.wxml
  86. 1 0
      src/ttcomponents/out/checkbox-group/index.wxss
  87. 1 0
      src/ttcomponents/out/checkbox/index.d.ts
  88. 79 0
      src/ttcomponents/out/checkbox/index.js
  89. 6 0
      src/ttcomponents/out/checkbox/index.json
  90. 99 0
      src/ttcomponents/out/checkbox/index.vue
  91. 31 0
      src/ttcomponents/out/checkbox/index.wxml
  92. 20 0
      src/ttcomponents/out/checkbox/index.wxs
  93. 1 0
      src/ttcomponents/out/checkbox/index.wxss
  94. 6 0
      src/ttcomponents/out/circle/canvas.d.ts
  95. 43 0
      src/ttcomponents/out/circle/canvas.js
  96. 1 0
      src/ttcomponents/out/circle/index.d.ts
  97. 201 0
      src/ttcomponents/out/circle/index.js
  98. 3 0
      src/ttcomponents/out/circle/index.json
  99. 204 0
      src/ttcomponents/out/circle/index.vue
  100. 9 0
      src/ttcomponents/out/circle/index.wxml

+ 7 - 0
src/api/modules/user.js

@@ -6,7 +6,14 @@ const user = {
 	 * 用户登录获取token
 	 */
 	async login() {
+		//#ifdef MP-TOUTIAO
 		let res = await wx.login()
+		res  = res[1]
+		//#endif
+		//#ifdef MP-WEIXIN
+		let res = await wx.login()
+		//#endif
+		
 		console.log(res)
 		return request({
 			url: `${process.env.NODE_ENV==='development'?'https://jpcj-admin1.zzxcx.net/twzd-admin':'https://jpcj-admin.zzxcx.net/twzd-admin'}/login/jscode`,

+ 7 - 1
src/api/request.js

@@ -23,7 +23,13 @@ service.interceptors.request.use(
 			if (config.headers.isLogin) {
 				return config
 			}
-			config.headers['Authorization'] = 'Bearer ' + await store.dispatch("getToken") // 让每个请求携带自定义token 请根据实际情况自行修改
+			if(await store.dispatch("getToken")){
+				config.headers['Authorization'] = 'Bearer ' + await store.dispatch("getToken") // 让每个请求携带自定义token 请根据实际情况自行修改
+			}
+			else{
+				
+			}
+			
 			return config
 		},
 		error => {

+ 15 - 1
src/manifest.json

@@ -19,7 +19,21 @@
       }
     }
   },
+  "mp-toutiao": {
+    "appid": "tta896de2b37a8562901",
+    "setting": {
+      "urlCheck": false,
+      "es6": true,
+      "minified": true
+    },
+    "usingComponents": true,
+    "permission": {
+      "scope.userLocation": {
+        "desc": "电影院位置定位请求"
+      }
+    }
+  },
   "uniStatistics": {
     "enable": false
   }
-}
+}

+ 21 - 3
src/otherPages/classifyChoose/index.vue

@@ -1,6 +1,9 @@
 <template>
   <div class="cell-container">
-    <div class="cell-box" style="padding-right: 0px">
+    <div class="cell-box" :class="{
+      'is-row':isRow
+
+    }" >
       <van-cell
         class="cell"
         :title="
@@ -90,15 +93,19 @@ import utils from "@/utils/index";
 export default {
   data() {
     return {
+      isRow:false,
       classifyTip:['软件题库已同步更新至车管所最新,左边的红色必学题,每套题必须学完.',
       '模拟考试能连续5次以上达到96分左右,即可参加考试','如果模拟考试达不到要求,请把右边的选学题也学习一遍'],
       classDataRight: [],
       classDataLeft: [],
-      query: {},
+      query: {
+        vehicle:""
+      },
     };
   },
   onLoad(query) {
     this.query = query;
+    this.isRow = this.query.vehicle ==='摩托车'
     this.getClassData();
   },
   methods: {
@@ -189,17 +196,23 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+
 .cell-container {
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
+    padding: 5px 15px;
+    justify-content: space-between;
 }
 .cell-box {
   display: flex;
-  padding: 5px 15px;
+  align-content: flex-start;
+  align-items: flex-start;
   flex-wrap: wrap;
   flex-direction: column;
 
+  box-sizing: border-box;
+
   .cell {
     width: 167px;
     margin-top: 10px;
@@ -234,4 +247,9 @@ export default {
     margin-right: 5px;
   }
 }
+.is-row{
+  flex-direction: row;
+  width: 100%;
+    justify-content: space-between;
+}
 </style>

+ 16 - 10
src/store/modules/user.js

@@ -31,7 +31,7 @@ const user = {
 			state.tokenObj = tokenObj
 		},
 		//jpcjUserInfo
-		SET_JPCJUSERINFO(state,jpcjUserInfo ) {
+		SET_JPCJUSERINFO(state, jpcjUserInfo) {
 			state.jpcjUserInfo = jpcjUserInfo
 		},
 		REFRESH_TOKEN(state) {
@@ -67,10 +67,13 @@ const user = {
 				title: '登陆中...',
 			})
 			let res = await userApi.login()
-			store.commit('SET_TOKENOBJ', {
-				token: res.data.token,
-				date: new Date().getTime()
-			})
+			if (res.data) {
+				store.commit('SET_TOKENOBJ', {
+					token: res.data.token,
+					date: new Date().getTime()
+				})
+			}
+
 			// store.commit('SET_JPCJUSERINFO',res.data.jpcjUserInfo)
 			wx.hideLoading()
 			return res
@@ -81,11 +84,14 @@ const user = {
 				return tokenObj.token
 			} else {
 				let res = await store.dispatch("Login")
-				store.commit('SET_TOKENOBJ', {
-					token: res.data.token,
-					date: new Date().getTime()
-				})
-				return res.data.token
+				if (res.data) {
+					store.commit('SET_TOKENOBJ', {
+						token: res.data.token,
+						date: new Date().getTime()
+					})
+				}
+
+				return res.data&&res.data.token
 			}
 		},
 		/**

+ 2 - 0
src/ttcomponents/out/$polyfill/api/relations.js

@@ -0,0 +1,2 @@
+module.exports = {
+}

+ 505 - 0
src/ttcomponents/out/$polyfill/api/utils.js

@@ -0,0 +1,505 @@
+
+module.exports = {
+  fnAppClass,
+  browserPath,
+}
+
+function fnAppClass() {
+  const fn = {
+    $data: {},
+    add(key, cb = () => {}) {
+      fn.$data[key] = fn.$data[key] || []
+      fn.$data[key].push(cb)
+      return fn
+    },
+    insert(key, cb = () => {}) {
+      fn.$data[key] = fn.$data[key] || []
+      fn.$data[key].unshift(cb)
+    },
+    getFn(key) {
+      return fn.$data[key]
+    },
+    bind(key, ctx = {}) {
+      fn.$data[key] = fn.$data[key] || []
+      fn.add(key, ctx[key])
+      ctx[key] = function(...params) {
+        const self = this
+        fn.getFn(key)
+          .forEach((cb) => {
+            cb.apply(self, params)
+          })
+      }
+    },
+  }
+  return fn
+}
+
+
+function assertPath(path) {
+  if (typeof path !== 'string') {
+    throw new TypeError(`Path must be a string. Received ${JSON.stringify(path)}`)
+  }
+}
+
+// Resolves . and .. elements in a path with directory names
+function normalizeStringPosix(path, allowAboveRoot) {
+  let res = ''
+  let lastSegmentLength = 0
+  let lastSlash = -1
+  let dots = 0
+  let code
+  for (let i = 0; i <= path.length; ++i) {
+    if (i < path.length) { code = path.charCodeAt(i) } else if (code === 47 /* /*/) { break } else { code = 47 /* /*/ }
+    if (code === 47 /* /*/) {
+      if (lastSlash === i - 1 || dots === 1) {
+        // NOOP
+      } else if (lastSlash !== i - 1 && dots === 2) {
+        if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /* .*/ || res.charCodeAt(res.length - 2) !== 46 /* .*/) {
+          if (res.length > 2) {
+            const lastSlashIndex = res.lastIndexOf('/')
+            if (lastSlashIndex !== res.length - 1) {
+              if (lastSlashIndex === -1) {
+                res = ''
+                lastSegmentLength = 0
+              } else {
+                res = res.slice(0, lastSlashIndex)
+                lastSegmentLength = res.length - 1 - res.lastIndexOf('/')
+              }
+              lastSlash = i
+              dots = 0
+              continue
+            }
+          } else if (res.length === 2 || res.length === 1) {
+            res = ''
+            lastSegmentLength = 0
+            lastSlash = i
+            dots = 0
+            continue
+          }
+        }
+        if (allowAboveRoot) {
+          if (res.length > 0) { res += '/..' } else { res = '..' }
+          lastSegmentLength = 2
+        }
+      } else {
+        if (res.length > 0) { res += `/${path.slice(lastSlash + 1, i)}` } else { res = path.slice(lastSlash + 1, i) }
+        lastSegmentLength = i - lastSlash - 1
+      }
+      lastSlash = i
+      dots = 0
+    } else if (code === 46 /* .*/ && dots !== -1) {
+      ++dots
+    } else {
+      dots = -1
+    }
+  }
+  return res
+}
+
+function _format(sep, pathObject) {
+  const dir = pathObject.dir || pathObject.root
+  const base = pathObject.base || (pathObject.name || '') + (pathObject.ext || '')
+  if (!dir) {
+    return base
+  }
+  if (dir === pathObject.root) {
+    return dir + base
+  }
+  return dir + sep + base
+}
+
+var posix = {
+  // path.resolve([from ...], to)
+  resolve: function resolve() {
+    let resolvedPath = ''
+    let resolvedAbsolute = false
+    let cwd
+
+    for (let i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+      var path
+      if (i >= 0) { path = arguments[i] } else {
+        if (cwd === undefined) { cwd = process.cwd() }
+        path = cwd
+      }
+
+      assertPath(path)
+
+      // Skip empty entries
+      if (path.length === 0) {
+        continue
+      }
+
+      resolvedPath = `${path}/${resolvedPath}`
+      resolvedAbsolute = path.charCodeAt(0) === 47 /* /*/
+    }
+
+    // At this point the path should be resolved to a full absolute path, but
+    // handle relative paths to be safe (might happen when process.cwd() fails)
+
+    // Normalize the path
+    resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute)
+
+    if (resolvedAbsolute) {
+      if (resolvedPath.length > 0) { return `/${resolvedPath}` }
+      return '/'
+    } else if (resolvedPath.length > 0) {
+      return resolvedPath
+    }
+    return '.'
+  },
+
+  normalize: function normalize(path) {
+    assertPath(path)
+
+    if (path.length === 0) { return '.' }
+
+    const isAbsolute = path.charCodeAt(0) === 47 /* /*/
+    const trailingSeparator = path.charCodeAt(path.length - 1) === 47 /* /*/
+
+    // Normalize the path
+    path = normalizeStringPosix(path, !isAbsolute)
+
+    if (path.length === 0 && !isAbsolute) { path = '.' }
+    if (path.length > 0 && trailingSeparator) { path += '/' }
+
+    if (isAbsolute) { return `/${path}` }
+    return path
+  },
+
+  isAbsolute: function isAbsolute(path) {
+    assertPath(path)
+    return path.length > 0 && path.charCodeAt(0) === 47 /* /*/
+  },
+
+  join: function join(...p) {
+    if (p.length === 0) { return '.' }
+    let joined
+    for (let i = 0; i < p.length; ++i) {
+      const arg = p[i]
+      assertPath(arg)
+      if (arg.length > 0) {
+        if (joined === undefined) { joined = arg } else { joined += `/${arg}` }
+      }
+    }
+    if (joined === undefined) { return '.' }
+    return posix.normalize(joined)
+  },
+
+  relative: function relative(from, to) {
+    assertPath(from)
+    assertPath(to)
+
+    if (from === to) { return '' }
+
+    from = posix.resolve(from)
+    to = posix.resolve(to)
+
+    if (from === to) { return '' }
+
+    // Trim any leading backslashes
+    let fromStart = 1
+    for (; fromStart < from.length; ++fromStart) {
+      if (from.charCodeAt(fromStart) !== 47 /* /*/) { break }
+    }
+    const fromEnd = from.length
+    const fromLen = fromEnd - fromStart
+
+    // Trim any leading backslashes
+    let toStart = 1
+    for (; toStart < to.length; ++toStart) {
+      if (to.charCodeAt(toStart) !== 47 /* /*/) { break }
+    }
+    const toEnd = to.length
+    const toLen = toEnd - toStart
+
+    // Compare paths to find the longest common path from root
+    const length = fromLen < toLen ? fromLen : toLen
+    let lastCommonSep = -1
+    let i = 0
+    for (; i <= length; ++i) {
+      if (i === length) {
+        if (toLen > length) {
+          if (to.charCodeAt(toStart + i) === 47 /* /*/) {
+            // We get here if `from` is the exact base path for `to`.
+            // For example: from='/foo/bar'; to='/foo/bar/baz'
+            return to.slice(toStart + i + 1)
+          } else if (i === 0) {
+            // We get here if `from` is the root
+            // For example: from='/'; to='/foo'
+            return to.slice(toStart + i)
+          }
+        } else if (fromLen > length) {
+          if (from.charCodeAt(fromStart + i) === 47 /* /*/) {
+            // We get here if `to` is the exact base path for `from`.
+            // For example: from='/foo/bar/baz'; to='/foo/bar'
+            lastCommonSep = i
+          } else if (i === 0) {
+            // We get here if `to` is the root.
+            // For example: from='/foo'; to='/'
+            lastCommonSep = 0
+          }
+        }
+        break
+      }
+      const fromCode = from.charCodeAt(fromStart + i)
+      const toCode = to.charCodeAt(toStart + i)
+      if (fromCode !== toCode) { break } else if (fromCode === 47 /* /*/) { lastCommonSep = i }
+    }
+
+    let out = ''
+    // Generate the relative path based on the path difference between `to`
+    // and `from`
+    for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
+      if (i === fromEnd || from.charCodeAt(i) === 47 /* /*/) {
+        if (out.length === 0) { out += '..' } else { out += '/..' }
+      }
+    }
+
+    // Lastly, append the rest of the destination (`to`) path that comes after
+    // the common path parts
+    if (out.length > 0) { return out + to.slice(toStart + lastCommonSep) }
+    
+    toStart += lastCommonSep
+    if (to.charCodeAt(toStart) === 47 /* /*/) { ++toStart }
+    return to.slice(toStart)
+  },
+
+  _makeLong: function _makeLong(path) {
+    return path
+  },
+
+  dirname: function dirname(path) {
+    assertPath(path)
+    if (path.length === 0) { return '.' }
+    let code = path.charCodeAt(0)
+    const hasRoot = code === 47 /* /*/
+    let end = -1
+    let matchedSlash = true
+    for (let i = path.length - 1; i >= 1; --i) {
+      code = path.charCodeAt(i)
+      if (code === 47 /* /*/) {
+        if (!matchedSlash) {
+          end = i
+          break
+        }
+      } else {
+        // We saw the first non-path separator
+        matchedSlash = false
+      }
+    }
+
+    if (end === -1) { return hasRoot ? '/' : '.' }
+    if (hasRoot && end === 1) { return '//' }
+    return path.slice(0, end)
+  },
+
+  basename: function basename(path, ext) {
+    if (ext !== undefined && typeof ext !== 'string') { throw new TypeError('"ext" argument must be a string') }
+    assertPath(path)
+
+    let start = 0
+    let end = -1
+    let matchedSlash = true
+    let i
+
+    if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
+      if (ext.length === path.length && ext === path) { return '' }
+      let extIdx = ext.length - 1
+      let firstNonSlashEnd = -1
+      for (i = path.length - 1; i >= 0; --i) {
+        const code = path.charCodeAt(i)
+        if (code === 47 /* /*/) {
+          // If we reached a path separator that was not part of a set of path
+          // separators at the end of the string, stop now
+          if (!matchedSlash) {
+            start = i + 1
+            break
+          }
+        } else {
+          if (firstNonSlashEnd === -1) {
+            // We saw the first non-path separator, remember this index in case
+            // we need it if the extension ends up not matching
+            matchedSlash = false
+            firstNonSlashEnd = i + 1
+          }
+          if (extIdx >= 0) {
+            // Try to match the explicit extension
+            if (code === ext.charCodeAt(extIdx)) {
+              if (--extIdx === -1) {
+                // We matched the extension, so mark this as the end of our path
+                // component
+                end = i
+              }
+            } else {
+              // Extension does not match, so our result is the entire path
+              // component
+              extIdx = -1
+              end = firstNonSlashEnd
+            }
+          }
+        }
+      }
+
+      if (start === end) { end = firstNonSlashEnd } else if (end === -1) { end = path.length }
+      return path.slice(start, end)
+    }
+    for (i = path.length - 1; i >= 0; --i) {
+      if (path.charCodeAt(i) === 47 /* /*/) {
+        // If we reached a path separator that was not part of a set of path
+        // separators at the end of the string, stop now
+        if (!matchedSlash) {
+          start = i + 1
+          break
+        }
+      } else if (end === -1) {
+        // We saw the first non-path separator, mark this as the end of our
+        // path component
+        matchedSlash = false
+        end = i + 1
+      }
+    }
+
+    if (end === -1) { return '' }
+    return path.slice(start, end)
+  },
+
+  extname: function extname(path) {
+    assertPath(path)
+    let startDot = -1
+    let startPart = 0
+    let end = -1
+    let matchedSlash = true
+    // Track the state of characters (if any) we see before our first dot and
+    // after any path separator we find
+    let preDotState = 0
+    for (let i = path.length - 1; i >= 0; --i) {
+      const code = path.charCodeAt(i)
+      if (code === 47 /* /*/) {
+        // If we reached a path separator that was not part of a set of path
+        // separators at the end of the string, stop now
+        if (!matchedSlash) {
+          startPart = i + 1
+          break
+        }
+        continue
+      }
+      if (end === -1) {
+        // We saw the first non-path separator, mark this as the end of our
+        // extension
+        matchedSlash = false
+        end = i + 1
+      }
+      if (code === 46 /* .*/) {
+        // If this is our first dot, mark it as the start of our extension
+        if (startDot === -1) { startDot = i } else if (preDotState !== 1) { preDotState = 1 }
+      } else if (startDot !== -1) {
+        // We saw a non-dot and non-path separator before our dot, so we should
+        // have a good chance at having a non-empty extension
+        preDotState = -1
+      }
+    }
+
+    if (startDot === -1 || end === -1
+        // We saw a non-dot character immediately before the dot
+        || preDotState === 0
+        // The (right-most) trimmed path component is exactly '..'
+        || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
+      return ''
+    }
+    return path.slice(startDot, end)
+  },
+
+  format: function format(pathObject) {
+    if (pathObject === null || typeof pathObject !== 'object') {
+      throw new TypeError(`The "pathObject" argument must be of type Object. Received type ${typeof pathObject}`)
+    }
+    return _format('/', pathObject)
+  },
+
+  parse: function parse(path) {
+    assertPath(path)
+
+    const ret = { root: '', dir: '', base: '', ext: '', name: '' }
+    if (path.length === 0) { return ret }
+    let code = path.charCodeAt(0)
+    const isAbsolute = code === 47 /* /*/
+    let start
+    if (isAbsolute) {
+      ret.root = '/'
+      start = 1
+    } else {
+      start = 0
+    }
+    let startDot = -1
+    let startPart = 0
+    let end = -1
+    let matchedSlash = true
+    let i = path.length - 1
+
+    // Track the state of characters (if any) we see before our first dot and
+    // after any path separator we find
+    let preDotState = 0
+
+    // Get non-dir info
+    for (; i >= start; --i) {
+      code = path.charCodeAt(i)
+      if (code === 47 /* /*/) {
+        // If we reached a path separator that was not part of a set of path
+        // separators at the end of the string, stop now
+        if (!matchedSlash) {
+          startPart = i + 1
+          break
+        }
+        continue
+      }
+      if (end === -1) {
+        // We saw the first non-path separator, mark this as the end of our
+        // extension
+        matchedSlash = false
+        end = i + 1
+      }
+      if (code === 46 /* .*/) {
+        // If this is our first dot, mark it as the start of our extension
+        if (startDot === -1) { startDot = i } else if (preDotState !== 1) { preDotState = 1 }
+      } else if (startDot !== -1) {
+        // We saw a non-dot and non-path separator before our dot, so we should
+        // have a good chance at having a non-empty extension
+        preDotState = -1
+      }
+    }
+
+    if (startDot === -1 || end === -1
+    // We saw a non-dot character immediately before the dot
+    || preDotState === 0
+    // The (right-most) trimmed path component is exactly '..'
+    || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
+      if (end !== -1) {
+        if (startPart === 0 && isAbsolute) { ret.base = ret.name = path.slice(1, end) } else { ret.base = ret.name = path.slice(startPart, end) }
+      }
+    } else {
+      if (startPart === 0 && isAbsolute) {
+        ret.name = path.slice(1, startDot)
+        ret.base = path.slice(1, end)
+      } else {
+        ret.name = path.slice(startPart, startDot)
+        ret.base = path.slice(startPart, end)
+      }
+      ret.ext = path.slice(startDot, end)
+    }
+
+    if (startPart > 0) { ret.dir = path.slice(0, startPart - 1) } else if (isAbsolute) { ret.dir = '/' }
+
+    return ret
+  },
+
+  sep: '/',
+  delimiter: ':',
+  win32: null,
+  posix: null,
+}
+
+posix.posix = posix
+
+function browserPath() {
+  return posix
+}

+ 5 - 0
src/ttcomponents/out/$polyfill/component/classSubdirectory/app.js

@@ -0,0 +1,5 @@
+module.exports = {
+  processTransformationApp(_opts, options) {
+    _opts = Object.assign(_opts, options)
+  },
+}

+ 281 - 0
src/ttcomponents/out/$polyfill/component/classSubdirectory/component.js

@@ -0,0 +1,281 @@
+const utils = require('../../api/utils')
+
+const { fnAppClass, browserPath } = utils
+const createNode = require('./relation')
+const processRelationHandle = require('./processRelation')
+
+const posix = browserPath()
+const Relations = require('../../api/relations')
+const SelectComponent = require('./selectComponent')
+
+function getInfo(key, obj) {
+  let val = {}
+  Object.keys(obj)
+    .forEach((item) => {
+      if (key === item) {
+        val = obj[item]
+      } else if (key.indexOf(item) !== -1) {
+        val = obj[item]
+      }
+    })
+  return val
+}
+function processRelations(ctx, relationInfo = {}) {
+  let route = ctx.is
+  route = route.replace(/\/node_modules\/[a-z-]+\/[a-z-]+/, '')
+    
+  if (route[0] === '/') {
+    route = route.substring(1)
+  }
+  const info = getInfo(route, relationInfo)
+  if (info) {
+    processRelationHandle(info, (node) => {
+      if (node.$id === 'saveChildRef0') {
+        ctx[node.$id] = function() {}
+        node.$index = 0
+        node.$route = route
+        createNode.call(ctx, ctx, null, node)
+        return false
+      }
+      ctx[node.$id] = function(ref) {
+        ctx.$antmove = ctx.$antmove || {}
+        if (ctx.$antmove[node.$id] === undefined) {
+          ctx.$antmove[node.$id] = 0
+        } else {
+          ctx.$antmove[node.$id] += 1
+        }
+        this.selectComponentApp.preProcesscomponents(ref)
+        node.$index = ctx.$antmove[node.$id]
+        node.$route = route
+        createNode.call(ctx, ref, null, node)
+      }
+    })
+  } else {
+    console.warn('Missing nodes relation of ', route)
+  }
+}
+
+function processRelationPath(self, relation) {
+  const from = self.is; let
+    to = relation
+  if (to[0] === '.') {
+    to = `../${to}`
+  }
+  const _p = posix.join(from, to)
+  return _p
+}
+function handleRelations() {
+  if (this.props.theRelations) {
+    Object.keys(this.props.theRelations)
+      .forEach((relation) => {
+        const _p = processRelationPath(this, relation)
+        const relationInfo = this.props.theRelations[relation]
+        let nodes = null
+
+        if (relationInfo.type === 'child' || relationInfo.type === 'descendant') {
+          return false
+        }
+        nodes = findRelationNode(this.$node, _p, relationInfo.type, true)
+        if (!nodes || nodes[0] === undefined) {
+          return false
+        }
+
+        nodes.forEach((n) => {
+          if (!n) {
+            // console.error('wrong relation reference of ', relationInfo);
+            // console.error('from: ', this.$node.$self.is, 'to: ', _p);
+            return false
+          }
+          _relationNode.call(this, n, {
+            relationInfo,
+            _p,
+            relation,
+          })
+        })
+      })
+  }
+}
+
+// process node relation callback
+function _relationNode(node, info) {
+  const { relationInfo, relation, _p } = info
+
+  // 触发父级组件的 relations
+  const type = relationInfo.type
+  let parentType = ''
+  if (type === 'parent') {
+    parentType = 'child'
+  } else if (type === 'ancestor') {
+    parentType = 'descendant'
+  }
+
+  const parentCtx = node.$self
+  const childCtx = this
+  if (typeof parentCtx.props.theRelations === 'object') {
+    Object.keys(parentCtx.props.theRelations)
+      .forEach((relation) => {
+        const relationInfo = parentCtx.props.theRelations[relation]
+        if (relationInfo.type === parentType) {
+          _relationNode.call(parentCtx, childCtx.$node, {
+            relationInfo,
+            relation,
+            _p: processRelationPath(parentCtx, relation),
+          })
+
+          return true
+        }
+      })
+  }
+  
+
+  node = node.$self
+  
+  this._storeRelationNodes = this._storeRelationNodes || {}
+  if (this._storeRelationNodes[_p]) {
+    this._storeRelationNodes[_p].push(node)
+  } else {
+    this._storeRelationNodes[_p] = [node]
+  }
+                    
+  if (this._storeRelationNodes[relation]) {
+    this._storeRelationNodes[relation].push(node)
+  } else {
+    this._storeRelationNodes[relation] = [node]
+  }
+  const ctx = this || {}
+  this.getRelationNodes = function(_p) {
+    this._storeRelationNodes = this._storeRelationNodes || {}
+    return this._storeRelationNodes[_p] || []
+  }
+
+  
+  if (typeof relationInfo.linked === 'function') {
+    relationInfo.linked.call(ctx, node)
+  }
+  
+  if (typeof relationInfo.linkChanged === 'function') {
+    const self = this
+    ctx._lifes = ctx._lifes || {}
+    ctx._lifes.didUpdate = ctx._lifes.didUpdate || []
+    ctx._lifes.didUpdate.push(() => {
+      relationInfo.linkChanged.call(self, node)
+    })
+  }
+  if (typeof relationInfo.unlinked === 'function') {
+    const self = this
+    ctx._lifes = ctx._lifes || {}
+    ctx._lifes.didUnmount = ctx._lifes.didUnmount || []
+    ctx._lifes.didUnmount.push(() => {
+      relationInfo.unlinked.call(self, node)
+    })
+  }
+}
+  
+function findRelationNode(node, p, type, isArray = false) {
+  // parent child ancestor descendant
+  const nodes = []
+  const _prcess = {
+    parent(node) {
+      if (!node || !node.$parent) { return }
+      const _p = node.$parent.$self.is || node.$parent.$self.route
+      if (_p === p) {
+        return node.$parent
+      }
+    },
+    child(node) {
+      let _child = null
+      node.$children
+        .forEach((child) => {
+          const _p = child.$self.is
+
+          if (_p === p) {
+            _child = child
+  
+            if (!isArray) {
+              return _child
+            }
+            nodes.push(_child)
+          }
+        })
+      return _child
+    },
+    ancestor(node) {
+      if (!node) { return }
+      let _node = null
+  
+      _node = _prcess.parent(node)
+      if (!_node) {
+        _node = _prcess.ancestor(node.$parent)
+      }
+      return _node
+    },
+    descendant(node) {
+      let _node = null
+      _node = _prcess.child(node)
+  
+      if (!_node) {
+        node.$children
+          .forEach((c) => {
+            _node = _prcess.child(c)
+  
+            if (!_node) {
+              _node = _prcess.descendant(c)
+            }
+          })
+      }
+  
+      return _node
+    },
+  }
+  
+  const ret = _prcess[type](node)
+  
+  if (isArray) {
+    if (type === 'parent' || type === 'ancestor') { return [ret] }
+    return nodes
+  }
+  return ret
+}
+
+module.exports = {
+  processTransformationComponent(_opts, options) {
+    const fnApp = fnAppClass()
+    _opts = Object.assign(_opts, options)
+    const didMount = function() {
+      // process relations, get relation ast
+      const relationAst = createNode.call(this, null, null, null, null, true).mountedHandles
+      relationAst.push(() => {
+        handleRelations.call(this)
+      })
+    }
+    fnApp.add('onInit', function() {
+      this.onPageReady = function(p) {
+        _opts.onPageReady && _opts.onPageReady.call(this, p)
+      }
+    })
+        
+    fnApp.add('didMount', didMount)
+    fnApp.insert('onInit', function() {
+      this.getRelationNodes = function() {
+        return []
+      }
+      this.selectComponentApp = new SelectComponent(this)
+
+      processRelations(this, Relations)
+      this.selectComponentApp.connect()
+    })
+    fnApp.bind('onInit', _opts)
+        
+
+    fnApp.bind('didMount', _opts)
+    fnApp.add('didUnmount', function() {
+      if (this.$node) {
+        this.$node.parent.removeChild(this.$node)
+        const refId = this.$node.$relationNode.$id
+        this.$antmove[refId]--
+      }
+    })
+    fnApp.bind('didUnmount', options.didUnmount)
+  },
+}
+

+ 98 - 0
src/ttcomponents/out/$polyfill/component/classSubdirectory/page.js

@@ -0,0 +1,98 @@
+const Relations = require('../../api/relations')
+const createNode = require('./relation')
+const processRelationHandle = require('./processRelation')
+const { connectNodes } = require('./utils')
+const selectComponent = require('./selectComponent')
+
+
+module.exports = {
+  processTransformationPage(_opts, options) {
+    _opts = Object.assign(_opts, options)
+
+    _opts.onLoad = function(res) {
+      this.selectComponentApp = new selectComponent(this)
+      this.selectComponentApp.connect()
+      // 初始化节点树
+      createNode.call(this, null, null, null, true)
+      processRelations(this, Relations)
+      if (typeof options.data === 'function') {
+        options.data = options.data()
+      }
+
+      if (options.onLoad) {
+        options.onLoad.call(this, res)
+      }
+    }
+
+    _opts.onReady = function(param) {
+      const ast = this.$node.getRootNode()
+      processRelationNodes(ast)
+
+      if (options.onReady) {
+        options.onReady.call(this, param)
+      }
+      ast.isPageReady = true
+    }
+  },
+}
+
+
+function processRelationNodes(ast = {}) {
+  const $nodes = ast.$nodes
+  
+  /**
+     * componentNodes onPageReady
+     */
+  Object.keys($nodes)
+    .forEach((item) => {
+      const node = $nodes[item]
+      connectNodes(node, ast)
+        
+      if (node.$self && typeof node.$self.onPageReady === 'function') {
+        node.$self.onPageReady()
+      }
+    })
+
+  ast.mountedHandles
+    .forEach((fn) => {
+      fn()
+    })
+  ast.mountedHandles = []
+}
+
+
+function processRelations(ctx, relationInfo = {}) {
+  let route = ctx.route
+  route = route.replace(/\/node_modules\/[a-z-]+\/[a-z-]+/, '')
+
+  if (route[0] !== '/') { route = `/${route}` }
+    
+  const info = relationInfo[route] || relationInfo[route.substring(1)]
+  if (info) {
+    processRelationHandle(info, (node) => {
+      const id = node.$id
+      if (id === 'saveChildRef0') {
+        ctx[id] = function() {}
+        node.$index = 0
+        node.$route = route
+        createNode.call(ctx, ctx, null, node)
+        return false
+      }
+      ctx[id] = function(ref) {
+        if (!ref) { return false }
+        ctx.$antmove = ctx.$antmove || {}
+        if (ctx.$antmove[id] === undefined) {
+          ctx.$antmove[id] = 0
+        } else {
+          ctx.$antmove[id] += 1
+        }
+        ctx.selectComponentApp.preProcesscomponents(ref)
+        node.$index = ctx.$antmove[id]
+        node.$route = route
+        createNode.call(ctx, ref, null, node)
+      }
+    })
+  } else {
+    console.warn('Missing nodes relation of ', route)
+  }
+}

+ 39 - 0
src/ttcomponents/out/$polyfill/component/classSubdirectory/processRelation.js

@@ -0,0 +1,39 @@
+class Node {
+  constructor(opts = {}) {
+    this.$id = opts.id
+    this.$opts = opts
+    this.$children = []
+    this.$parent = null
+
+    this.$render = function() {}
+  }
+
+  appendChild(child) {
+    this.$children.push(child)
+    child.$parent = this
+  }
+
+  removeChild(child) {
+    this.$children = this.$children.filter((c) => {
+      return c.$id !== child.$id
+    })
+  }
+}
+
+module.exports = function link(opts = {}, cb) {
+  const node = new Node({
+    id: opts.id,
+  })
+
+  if (typeof cb === 'function') {
+    cb(node)
+  }
+
+  if (Array.isArray(opts.children)) {
+    opts.children.forEach((child) => {
+      node.appendChild(link(child, cb))
+    })
+  }
+
+  return node
+}

+ 40 - 0
src/ttcomponents/out/$polyfill/component/classSubdirectory/promise.js

@@ -0,0 +1,40 @@
+const isArray = Array.isArray
+Promise.all = function(arr) {
+  return new Promise(((resolve, reject) => {
+    if (!isArray(arr)) {
+      return reject(new TypeError('Promise.all accepts an array'))
+    }
+
+    const args = Array.prototype.slice.call(arr)
+    if (args.length === 0) { return resolve([]) }
+    let remaining = args.length
+
+    function res(i, val) {
+      try {
+        if (val && (typeof val === 'object' || typeof val === 'function')) {
+          const then = val.then
+          if (typeof then === 'function') {
+            then.call(
+              val,
+              (val) => {
+                res(i, val)
+              },
+              reject,
+            )
+            return
+          }
+        }
+        args[i] = val
+        if (--remaining === 0) {
+          resolve(args)
+        }
+      } catch (ex) {
+        reject(ex)
+      }
+    }
+
+    for (let i = 0; i < args.length; i++) {
+      res(i, args[i])
+    }
+  }))
+}

+ 127 - 0
src/ttcomponents/out/$polyfill/component/classSubdirectory/relation.js

@@ -0,0 +1,127 @@
+let id = 0
+const { connectNodes } = require('./utils')
+
+let astCache = {}
+function createAstData() {
+  const RelationAst = {
+    $refNodes: {},
+    $nodes: {},
+    $page: null,
+    current: null,
+    createArray: [],
+    destoryArray: [],
+    mountedHandles: [],
+    componentNodes: {},
+  }
+
+  return RelationAst
+}
+function createNode(ctx) {
+  this.$self = ctx
+  ctx.$node = this
+  this.$id = id++
+  this.$children = []
+}
+
+createNode.prototype = {
+  getRootNode() {
+    const ctx = this.$self
+    const cacheId = ctx.$page ? ctx.$page.$id : ctx.$id
+
+    return astCache[cacheId]
+  },
+  setParent(parent) {
+    this.$parent = parent
+    parent.appendChild(this)
+  },
+  appendChildren() {
+    this.$children
+      .forEach((child) => {
+        this.appendChild(child)
+      })
+  },
+  destory() {
+    const index = this.$relationNode.$index
+    this.$parent.$children.splice(index, 1)
+  },
+  appendChild(child) {
+    this.$children.push(child)
+    child.$parent = this
+  },
+  removeChld(child) {
+    this.$children = this.$children
+      .filter((el) => {
+        return el.$id !== child.$id
+      })
+  },
+}
+
+
+module.exports = function(node, cb = () => {}, relationNode, bool = false, _bool = false) {
+  let RelationAst = {}
+  const cacheId = this.$page ? this.$page.$id : this.$id
+  if (_bool) {
+    return astCache[cacheId]
+  }
+    
+  if (bool || !astCache[cacheId]) {
+    astCache[cacheId] = createAstData()
+    return astCache[cacheId]
+  }
+  let _relationData = {}
+  function initData(isComponent = false) {
+    let _ctx = this
+    _relationData = createAstData()
+    if (isComponent) {
+      _ctx = this.$page
+    }
+    _ctx.$antmove = _ctx.$antmove || {}
+    _ctx.$antmove.relationData = _relationData
+    _ctx.$antmove.astCache = astCache
+  }
+  if (!this.$page) {
+    initData.call(this)
+  } else {
+    if (!this.$page.$antmove
+            || !this.$page.$antmove.relationData) {
+      initData.call(this, true)
+    }
+    _relationData = this.$page.$antmove.relationData
+    astCache = this.$page.$antmove.astCache
+  }
+
+  RelationAst = astCache[cacheId]
+  const wrapNode = new createNode(node)
+  const route = relationNode.$route
+
+  RelationAst.$page = wrapNode
+
+  /**
+       * component
+       */
+  wrapNode.$relationNode = relationNode
+  RelationAst.$nodes[node.$id] = wrapNode
+  RelationAst.$refNodes[route] = RelationAst.$refNodes[route] || {}
+  const componentNodes = RelationAst.$refNodes[route]
+  RelationAst.$refNodes[route][relationNode.$id] = RelationAst.$refNodes[route][relationNode.$id] || []
+  componentNodes[relationNode.$id].push(wrapNode)
+
+  if (RelationAst.isPageReady) {
+    setTimeout(() => {
+      connectNodes(wrapNode, RelationAst)
+      RelationAst.mountedHandles
+        .forEach((fn, i) => {
+          if (wrapNode.$parent) {
+            fn()
+          } else {
+            setTimeout(() => {
+              fn()
+            }, 0)
+          }
+        })
+      RelationAst.mountedHandles = []
+    }, 0)
+  }
+  cb && cb(RelationAst)
+  return RelationAst
+}

+ 81 - 0
src/ttcomponents/out/$polyfill/component/classSubdirectory/selectComponent.js

@@ -0,0 +1,81 @@
+function selectComponent(ctx) {
+  this.$ctx = ctx
+  this.$nodes = {}
+  this.$cacheNodes = {}
+}
+
+selectComponent.prototype = {
+  _addComponentNode(className, ctx) {
+    className = `.${className}`
+    const componentNodes = this.$nodes
+    if (componentNodes[className]) {
+      componentNodes[className].push(ctx)
+    } else {
+      componentNodes[className] = [ctx]
+    }
+    this.$cacheNodes[ctx.$id] = { className }
+  },
+  addComponentNodeId(id, ctx) {
+    id = `#${id}`
+    const componentNodes = this.$nodes
+    if (componentNodes[id]) {
+      componentNodes[id].push(ctx)
+    } else {
+      componentNodes[id] = [ctx]
+    }
+    this.$cacheNodes[ctx.$id] = { id }
+  },
+  addComponentNode(className = '', ctx) {
+    const classNameArray = className.split(/\s+/g)
+    classNameArray.forEach((classNameStr) => {
+      this._addComponentNode(classNameStr, ctx)
+    })
+  },
+  selectComponent(className) {
+    const componentNodes = this.$nodes
+    return componentNodes[className] && componentNodes[className][0]
+  },
+  selectComponents(className) {
+    const componentNodes = this.$nodes
+    return componentNodes[className]
+  },
+  preProcesscomponents,
+  connect() {
+    const ctx = this.$ctx
+    const self = this
+    ctx.selectComponent = function(...p) {
+      if (self.selectComponent(...p) && self.selectComponent(...p)._this !== undefined) {
+        return self.selectComponent(...p)._this
+      }
+      return self.selectComponent(...p)
+    }
+    ctx.selectAllComponents = function(...p) {
+      const componentsArr = self.selectComponents(...p)
+      const newArr = []
+      componentsArr.forEach((item) => {
+        if (item._this !== undefined) {
+          newArr.push(item._this)
+        } else {
+          newArr.push(item)
+        }
+      })
+      return newArr
+    }
+  },
+}
+
+function preProcesscomponents(ctx) {
+  const selectorObj = this.$cacheNodes[ctx.$id]
+  selectorObj && Object.keys(selectorObj)
+    .forEach((item) => {
+      this.$nodes[item] = []
+    })
+  if (ctx.props.id) {
+    this.addComponentNodeId(ctx.props.id, ctx)
+  }
+  if (ctx.props.className) {
+    this.addComponentNode(ctx.props.className, ctx)
+  }
+}
+
+module.exports = selectComponent

+ 27 - 0
src/ttcomponents/out/$polyfill/component/classSubdirectory/utils.js

@@ -0,0 +1,27 @@
+module.exports = {
+  connectNodes: function connectNodes(node, ast) {
+    if (!node.$relationNode.$parent) { return false }
+    const parentNodeId = node.$relationNode.$parent.$id
+    const parentNodeRoute = node.$relationNode.$parent.$route
+    const index = node.$relationNode.$parent.$index
+    
+    const refNumbers = (node.$self.props.refNumbers && node.$self.props.refNumbers.length) || 1
+    
+    const parentArray = ast.$refNodes[parentNodeRoute][parentNodeId]
+    let parent = null
+    if (refNumbers > 1) {
+      parentArray.forEach((_parent) => {
+        if (_parent.$children.length !== refNumbers && !parent) {
+          parent = _parent
+          return true
+        }
+      })
+    } else {
+      parent = parentArray[0]
+    }
+    if (parent) {
+      node.setParent(parent)
+    }
+  },
+}
+

+ 31 - 0
src/ttcomponents/out/$polyfill/component/componentClass.js

@@ -0,0 +1,31 @@
+/**
+ * type:0 missing
+ * type:1 diff
+ * 
+ */
+const appTransformation = require('./classSubdirectory/app')
+const pageTransformation = require('./classSubdirectory/page')
+const componentTransformation = require('./classSubdirectory/component')
+
+module.exports = function processComponent(type = 'Component') {
+  const core = {
+    App(options = {}) {
+      const _opts = {}
+      appTransformation.processTransformationApp(_opts, options)
+      App(_opts)
+    },
+    Page(options = {}) {
+      const _opts = {}
+      pageTransformation.processTransformationPage(_opts, options)
+      Page(_opts)
+    },
+    Component(options = {}) {
+      const _opts = {}
+      componentTransformation.processTransformationComponent(_opts, options)
+            
+      Component(_opts)
+    },
+  }
+
+  return core[type]
+}

+ 1 - 0
src/ttcomponents/out/action-sheet/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 62 - 0
src/ttcomponents/out/action-sheet/index.js

@@ -0,0 +1,62 @@
+import { VantComponent } from "../common/component";
+import { button } from "../mixins/button";
+import { openType } from "../mixins/open-type";
+VantComponent({
+    mixins: [button, openType],
+    props: {
+        show: Boolean,
+        title: String,
+        cancelText: String,
+        description: String,
+        round: {
+            type: Boolean,
+            value: true
+        },
+        zIndex: {
+            type: Number,
+            value: 100
+        },
+        actions: {
+            type: Array,
+            value: []
+        },
+        overlay: {
+            type: Boolean,
+            value: true
+        },
+        closeOnClickOverlay: {
+            type: Boolean,
+            value: true
+        },
+        closeOnClickAction: {
+            type: Boolean,
+            value: true
+        },
+        safeAreaInsetBottom: {
+            type: Boolean,
+            value: true
+        }
+    },
+    methods: {
+        onSelect(event) {
+            const { index } = event.currentTarget.dataset;
+            const item = this.data.actions[index];
+            if (item && !item.disabled && !item.loading) {
+                this.$emit("select", item);
+                if (this.data.closeOnClickAction) {
+                    this.onClose();
+                }
+            }
+        },
+        onCancel() {
+            this.$emit("cancel");
+        },
+        onClose() {
+            this.$emit("close");
+        },
+        onClickOverlay() {
+            this.$emit("click-overlay");
+            this.onClose();
+        }
+    }
+});

+ 8 - 0
src/ttcomponents/out/action-sheet/index.json

@@ -0,0 +1,8 @@
+{
+	"component": true,
+	"usingComponents": {
+		"van-icon": "../icon/index",
+		"van-popup": "../popup/index",
+		"van-loading": "../loading/index"
+	}
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 101 - 0
src/ttcomponents/out/action-sheet/index.vue


+ 69 - 0
src/ttcomponents/out/action-sheet/index.wxml

@@ -0,0 +1,69 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<van-popup
+  show="{{ show }}"
+  position="bottom"
+  round="{{ round }}"
+  z-index="{{ zIndex }}"
+  overlay="{{ overlay }}"
+  custom-class="van-action-sheet"
+  safe-area-inset-bottom="{{ safeAreaInsetBottom }}"
+  close-on-click-overlay="{{ closeOnClickOverlay }}"
+  bind:close="onClickOverlay"
+>
+  <view wx:if="{{ title }}" class="van-action-sheet__header">
+    {{ title }}
+    <van-icon
+      name="cross"
+      custom-class="van-action-sheet__close"
+      bind:click="onClose"
+    />
+  </view>
+  <view wx:if="{{ description }}" class="van-action-sheet__description van-hairline--bottom">
+    {{ description }}
+  </view>
+  <view wx:if="{{ actions && actions.length }}">
+    <!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 -->
+    <button
+      wx:for="{{ actions }}"
+      wx:key="index"
+      open-type="{{ item.openType }}"
+      style="{{ item.color ? 'color: ' + item.color : '' }}"
+      class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} {{ item.className || '' }}"
+      hover-class="van-action-sheet__item--hover"
+      data-index="{{ index }}"
+      bind:tap="onSelect"
+      bindgetuserinfo="bindGetUserInfo"
+      bindcontact="bindContact"
+      bindgetphonenumber="bindGetPhoneNumber"
+      binderror="bindError"
+      bindlaunchapp="bindLaunchApp"
+      bindopensetting="bindOpenSetting"
+      lang="{{ lang }}"
+      session-from="{{ sessionFrom }}"
+      send-message-title="{{ sendMessageTitle }}"
+      send-message-path="{{ sendMessagePath }}"
+      send-message-img="{{ sendMessageImg }}"
+      show-message-card="{{ showMessageCard }}"
+      app-parameter="{{ appParameter }}"
+    >
+      <block wx:if="{{ !item.loading }}">
+        {{ item.name }}
+        <view wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</view>
+      </block>
+      <van-loading wx:else custom-class="van-action-sheet__loading" size="22px" />
+    </button>
+  </view>
+  <slot />
+  <block wx:if="{{ cancelText }}">
+    <view class="van-action-sheet__gap" />
+    <view
+      class="van-action-sheet__cancel"
+      hover-class="van-action-sheet__cancel--hover"
+      hover-stay-time="70"
+      bind:tap="onCancel"
+    >
+      {{ cancelText }}
+    </view>
+  </block>
+</van-popup>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
src/ttcomponents/out/action-sheet/index.wxss


+ 1 - 0
src/ttcomponents/out/area/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 234 - 0
src/ttcomponents/out/area/index.js

@@ -0,0 +1,234 @@
+import { VantComponent } from "../common/component";
+import { pickerProps } from "../picker/shared";
+import { requestAnimationFrame } from "../common/utils";
+const EMPTY_CODE = "000000";
+VantComponent({
+    classes: ["active-class", "toolbar-class", "column-class"],
+    props: Object.assign(Object.assign({}, pickerProps), {
+        value: {
+            type: String,
+            observer(value) {
+                this.code = value;
+                this.setValues();
+            }
+        },
+        areaList: {
+            type: Object,
+            value: {},
+            observer: "setValues"
+        },
+        columnsNum: {
+            type: null,
+            value: 3
+        },
+        columnsPlaceholder: {
+            type: Array,
+            observer(val) {
+                this.setData({
+                    typeToColumnsPlaceholder: {
+                        province: val[0] || "",
+                        city: val[1] || "",
+                        county: val[2] || ""
+                    }
+                });
+            }
+        }
+    }),
+    data: {
+        columns: [{ values: [] }, { values: [] }, { values: [] }],
+        typeToColumnsPlaceholder: {}
+    },
+    mounted() {
+        requestAnimationFrame(() => {
+            this.setValues();
+        });
+    },
+    methods: {
+        getPicker() {
+            if (this.picker == null) {
+                this.picker = this.selectComponent(".van-area__picker");
+            }
+            return this.picker;
+        },
+        onCancel(event) {
+            this.emit("cancel", event.detail);
+        },
+        onConfirm(event) {
+            const { index } = event.detail;
+            let { value } = event.detail;
+            value = this.parseValues(value);
+            this.emit("confirm", { value, index });
+        },
+        emit(type, detail) {
+            detail.values = detail.value;
+            delete detail.value;
+            this.$emit(type, detail);
+        },
+        parseValues(values) {
+            const { columnsPlaceholder } = this.data;
+            return values.map((value, index) => {
+                if (
+                    value &&
+                    (!value.code || value.name === columnsPlaceholder[index])
+                ) {
+                    return Object.assign(Object.assign({}, value), {
+                        code: "",
+                        name: ""
+                    });
+                }
+                return value;
+            });
+        },
+        onChange(event) {
+            const { index, picker, value } = event.detail;
+            this.code = value[index].code;
+            this.setValues().then(() => {
+                this.$emit("change", {
+                    picker,
+                    values: this.parseValues(picker.getValues()),
+                    index
+                });
+            });
+        },
+        getConfig(type) {
+            const { areaList } = this.data;
+            return (areaList && areaList[`${type}_list`]) || {};
+        },
+        getList(type, code) {
+            if (type !== "province" && !code) {
+                return [];
+            }
+            const { typeToColumnsPlaceholder } = this.data;
+            const list = this.getConfig(type);
+            let result = Object.keys(list).map(code => ({
+                code,
+                name: list[code]
+            }));
+            if (code != null) {
+                // oversea code
+                if (code[0] === "9" && type === "city") {
+                    code = "9";
+                }
+                result = result.filter(item => item.code.indexOf(code) === 0);
+            }
+            if (typeToColumnsPlaceholder[type] && result.length) {
+                // set columns placeholder
+                const codeFill =
+                    type === "province"
+                        ? ""
+                        : type === "city"
+                        ? EMPTY_CODE.slice(2, 4)
+                        : EMPTY_CODE.slice(4, 6);
+                result.unshift({
+                    code: `${code}${codeFill}`,
+                    name: typeToColumnsPlaceholder[type]
+                });
+            }
+            return result;
+        },
+        getIndex(type, code) {
+            let compareNum = type === "province" ? 2 : type === "city" ? 4 : 6;
+            const list = this.getList(type, code.slice(0, compareNum - 2));
+            // oversea code
+            if (code[0] === "9" && type === "province") {
+                compareNum = 1;
+            }
+            code = code.slice(0, compareNum);
+            for (let i = 0; i < list.length; i++) {
+                if (list[i].code.slice(0, compareNum) === code) {
+                    return i;
+                }
+            }
+            return 0;
+        },
+        setValues() {
+            const picker = this.getPicker();
+            if (!picker) {
+                return;
+            }
+            let code = this.code || this.getDefaultCode();
+            const provinceList = this.getList("province");
+            const cityList = this.getList("city", code.slice(0, 2));
+            const stack = [];
+            const indexes = [];
+            const { columnsNum } = this.data;
+            if (columnsNum >= 1) {
+                stack.push(picker.setColumnValues(0, provinceList, false));
+                indexes.push(this.getIndex("province", code));
+            }
+            if (columnsNum >= 2) {
+                stack.push(picker.setColumnValues(1, cityList, false));
+                indexes.push(this.getIndex("city", code));
+                if (cityList.length && code.slice(2, 4) === "00") {
+                    [{ code }] = cityList;
+                }
+            }
+            if (columnsNum === 3) {
+                stack.push(
+                    picker.setColumnValues(
+                        2,
+                        this.getList("county", code.slice(0, 4)),
+                        false
+                    )
+                );
+                indexes.push(this.getIndex("county", code));
+            }
+            return Promise.all(stack)
+                .catch(() => {})
+                .then(() => picker.setIndexes(indexes))
+                .catch(() => {});
+        },
+        getDefaultCode() {
+            const { columnsPlaceholder } = this.data;
+            if (columnsPlaceholder.length) {
+                return EMPTY_CODE;
+            }
+            const countyCodes = Object.keys(this.getConfig("county"));
+            if (countyCodes[0]) {
+                return countyCodes[0];
+            }
+            const cityCodes = Object.keys(this.getConfig("city"));
+            if (cityCodes[0]) {
+                return cityCodes[0];
+            }
+            return "";
+        },
+        getValues() {
+            const picker = this.getPicker();
+            if (!picker) {
+                return [];
+            }
+            return this.parseValues(
+                picker.getValues().filter(value => !!value)
+            );
+        },
+        getDetail() {
+            const values = this.getValues();
+            const area = {
+                code: "",
+                country: "",
+                province: "",
+                city: "",
+                county: ""
+            };
+            if (!values.length) {
+                return area;
+            }
+            const names = values.map(item => item.name);
+            area.code = values[values.length - 1].code;
+            if (area.code[0] === "9") {
+                area.country = names[1] || "";
+                area.province = names[2] || "";
+            } else {
+                area.province = names[0] || "";
+                area.city = names[1] || "";
+                area.county = names[2] || "";
+            }
+            return area;
+        },
+        reset(code) {
+            this.code = code || "";
+            return this.setValues();
+        }
+    }
+});

+ 6 - 0
src/ttcomponents/out/area/index.json

@@ -0,0 +1,6 @@
+{
+	"component": true,
+	"usingComponents": {
+		"van-picker": "../picker/index"
+	}
+}

+ 246 - 0
src/ttcomponents/out/area/index.vue

@@ -0,0 +1,246 @@
+<template>
+<uni-shadow-root class="vant-area-index"><van-picker class="van-area__picker" active-class="active-class" toolbar-class="toolbar-class" column-class="column-class" show-toolbar value-key="name" :title="title" :loading="loading" :columns="computed.displayColumns(columns, columnsNum)" :item-height="itemHeight" :visible-item-count="visibleItemCount" :cancel-button-text="cancelButtonText" :confirm-button-text="confirmButtonText" @change="onChange" @confirm="onConfirm" @cancel="onCancel"></van-picker></uni-shadow-root>
+</template>
+<wxs src="./index.wxs" module="computed"></wxs>
+<script>
+import VanPicker from '../picker/index.vue'
+global['__wxVueOptions'] = {components:{'van-picker': VanPicker}}
+
+global['__wxRoute'] = 'vant/area/index'
+import { VantComponent } from '../common/component';
+import { pickerProps } from '../picker/shared';
+import { requestAnimationFrame } from '../common/utils';
+const EMPTY_CODE = '000000';
+VantComponent({
+  classes: ['active-class', 'toolbar-class', 'column-class'],
+  props: Object.assign(Object.assign({}, pickerProps), {
+    value: {
+      type: String,
+      observer(value) {
+        this.code = value;
+        this.setValues();
+      },
+    },
+    areaList: {
+      type: Object,
+      value: {},
+      observer: 'setValues',
+    },
+    columnsNum: {
+      type: null,
+      value: 3,
+    },
+    columnsPlaceholder: {
+      type: Array,
+      observer(val) {
+        this.setData({
+          typeToColumnsPlaceholder: {
+            province: val[0] || '',
+            city: val[1] || '',
+            county: val[2] || '',
+          },
+        });
+      },
+    },
+  }),
+  data: {
+    columns: [{ values: [] }, { values: [] }, { values: [] }],
+    typeToColumnsPlaceholder: {},
+  },
+  mounted() {
+    requestAnimationFrame(() => {
+      this.setValues();
+    });
+  },
+  methods: {
+    getPicker() {
+      if (this.picker == null) {
+        this.picker = this.selectComponent('.van-area__picker');
+      }
+      return this.picker;
+    },
+    onCancel(event) {
+      this.emit('cancel', event.detail);
+    },
+    onConfirm(event) {
+      const { index } = event.detail;
+      let { value } = event.detail;
+      value = this.parseValues(value);
+      this.emit('confirm', { value, index });
+    },
+    emit(type, detail) {
+      detail.values = detail.value;
+      delete detail.value;
+      this.$emit(type, detail);
+    },
+    parseValues(values) {
+      const { columnsPlaceholder } = this.data;
+      return values.map((value, index) => {
+        if (
+          value &&
+          (!value.code || value.name === columnsPlaceholder[index])
+        ) {
+          return Object.assign(Object.assign({}, value), {
+            code: '',
+            name: '',
+          });
+        }
+        return value;
+      });
+    },
+    onChange(event) {
+      const { index, picker, value } = event.detail;
+      this.code = value[index].code;
+      this.setValues().then(() => {
+        this.$emit('change', {
+          picker,
+          values: this.parseValues(picker.getValues()),
+          index,
+        });
+      });
+    },
+    getConfig(type) {
+      const { areaList } = this.data;
+      return (areaList && areaList[`${type}_list`]) || {};
+    },
+    getList(type, code) {
+      if (type !== 'province' && !code) {
+        return [];
+      }
+      const { typeToColumnsPlaceholder } = this.data;
+      const list = this.getConfig(type);
+      let result = Object.keys(list).map((code) => ({
+        code,
+        name: list[code],
+      }));
+      if (code != null) {
+        // oversea code
+        if (code[0] === '9' && type === 'city') {
+          code = '9';
+        }
+        result = result.filter((item) => item.code.indexOf(code) === 0);
+      }
+      if (typeToColumnsPlaceholder[type] && result.length) {
+        // set columns placeholder
+        const codeFill =
+          type === 'province'
+            ? ''
+            : type === 'city'
+            ? EMPTY_CODE.slice(2, 4)
+            : EMPTY_CODE.slice(4, 6);
+        result.unshift({
+          code: `${code}${codeFill}`,
+          name: typeToColumnsPlaceholder[type],
+        });
+      }
+      return result;
+    },
+    getIndex(type, code) {
+      let compareNum = type === 'province' ? 2 : type === 'city' ? 4 : 6;
+      const list = this.getList(type, code.slice(0, compareNum - 2));
+      // oversea code
+      if (code[0] === '9' && type === 'province') {
+        compareNum = 1;
+      }
+      code = code.slice(0, compareNum);
+      for (let i = 0; i < list.length; i++) {
+        if (list[i].code.slice(0, compareNum) === code) {
+          return i;
+        }
+      }
+      return 0;
+    },
+    setValues() {
+      const picker = this.getPicker();
+      if (!picker) {
+        return;
+      }
+      let code = this.code || this.getDefaultCode();
+      const provinceList = this.getList('province');
+      const cityList = this.getList('city', code.slice(0, 2));
+      const stack = [];
+      const indexes = [];
+      const { columnsNum } = this.data;
+      if (columnsNum >= 1) {
+        stack.push(picker.setColumnValues(0, provinceList, false));
+        indexes.push(this.getIndex('province', code));
+      }
+      if (columnsNum >= 2) {
+        stack.push(picker.setColumnValues(1, cityList, false));
+        indexes.push(this.getIndex('city', code));
+        if (cityList.length && code.slice(2, 4) === '00') {
+          [{ code }] = cityList;
+        }
+      }
+      if (columnsNum === 3) {
+        stack.push(
+          picker.setColumnValues(
+            2,
+            this.getList('county', code.slice(0, 4)),
+            false
+          )
+        );
+        indexes.push(this.getIndex('county', code));
+      }
+      return Promise.all(stack)
+        .catch(() => {})
+        .then(() => picker.setIndexes(indexes))
+        .catch(() => {});
+    },
+    getDefaultCode() {
+      const { columnsPlaceholder } = this.data;
+      if (columnsPlaceholder.length) {
+        return EMPTY_CODE;
+      }
+      const countyCodes = Object.keys(this.getConfig('county'));
+      if (countyCodes[0]) {
+        return countyCodes[0];
+      }
+      const cityCodes = Object.keys(this.getConfig('city'));
+      if (cityCodes[0]) {
+        return cityCodes[0];
+      }
+      return '';
+    },
+    getValues() {
+      const picker = this.getPicker();
+      if (!picker) {
+        return [];
+      }
+      return this.parseValues(picker.getValues().filter((value) => !!value));
+    },
+    getDetail() {
+      const values = this.getValues();
+      const area = {
+        code: '',
+        country: '',
+        province: '',
+        city: '',
+        county: '',
+      };
+      if (!values.length) {
+        return area;
+      }
+      const names = values.map((item) => item.name);
+      area.code = values[values.length - 1].code;
+      if (area.code[0] === '9') {
+        area.country = names[1] || '';
+        area.province = names[2] || '';
+      } else {
+        area.province = names[0] || '';
+        area.city = names[1] || '';
+        area.county = names[2] || '';
+      }
+      return area;
+    },
+    reset(code) {
+      this.code = code || '';
+      return this.setValues();
+    },
+  },
+});
+export default global['__wxComponents']['vant/area/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';
+</style>

+ 20 - 0
src/ttcomponents/out/area/index.wxml

@@ -0,0 +1,20 @@
+<wxs src="./index.wxs" module="computed" />
+
+<van-picker
+  class="van-area__picker"
+  active-class="active-class"
+  toolbar-class="toolbar-class"
+  column-class="column-class"
+  show-toolbar
+  value-key="name"
+  title="{{ title }}"
+  loading="{{ loading }}"
+  columns="{{ computed.displayColumns(columns, columnsNum) }}"
+  item-height="{{ itemHeight }}"
+  visible-item-count="{{ visibleItemCount }}"
+  cancel-button-text="{{ cancelButtonText }}"
+  confirm-button-text="{{ confirmButtonText }}"
+  bind:change="onChange"
+  bind:confirm="onConfirm"
+  bind:cancel="onCancel"
+/>

+ 8 - 0
src/ttcomponents/out/area/index.wxs

@@ -0,0 +1,8 @@
+/* eslint-disable */
+function displayColumns(columns, columnsNum) {
+  return columns.slice(0, +columnsNum);
+}
+
+module.exports = {
+  displayColumns: displayColumns,
+};

+ 1 - 0
src/ttcomponents/out/area/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';

+ 1 - 0
src/ttcomponents/out/button/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 58 - 0
src/ttcomponents/out/button/index.js

@@ -0,0 +1,58 @@
+import { VantComponent } from "../common/component";
+import { button } from "../mixins/button";
+import { openType } from "../mixins/open-type";
+import { canIUseFormFieldButton } from "../common/version";
+const mixins = [button, openType];
+if (canIUseFormFieldButton()) {
+    mixins.push("wx://form-field-button");
+}
+VantComponent({
+    mixins,
+    classes: ["hover-class", "loading-class"],
+    data: {
+        baseStyle: ""
+    },
+    props: {
+        formType: String,
+        icon: String,
+        classPrefix: {
+            type: String,
+            value: "van-icon"
+        },
+        plain: Boolean,
+        block: Boolean,
+        round: Boolean,
+        square: Boolean,
+        loading: Boolean,
+        hairline: Boolean,
+        disabled: Boolean,
+        loadingText: String,
+        customStyle: String,
+        loadingType: {
+            type: String,
+            value: "circular"
+        },
+        type: {
+            type: String,
+            value: "default"
+        },
+        dataset: null,
+        size: {
+            type: String,
+            value: "normal"
+        },
+        loadingSize: {
+            type: String,
+            value: "20px"
+        },
+        color: String
+    },
+    methods: {
+        onClick() {
+            if (!this.data.loading) {
+                this.$emit("click");
+            }
+        },
+        noop() {}
+    }
+});

+ 7 - 0
src/ttcomponents/out/button/index.json

@@ -0,0 +1,7 @@
+{
+	"component": true,
+	"usingComponents": {
+		"van-icon": "../icon/index",
+		"van-loading": "../loading/index"
+	}
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 84 - 0
src/ttcomponents/out/button/index.vue


+ 53 - 0
src/ttcomponents/out/button/index.wxml

@@ -0,0 +1,53 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+<wxs src="./index.wxs" module="computed" />
+
+<button
+  id="{{ id }}"
+  data-detail="{{ dataset }}"
+  class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}"
+  hover-class="van-button--active hover-class"
+  lang="{{ lang }}"
+  form-type="{{ formType }}"
+  style="{{ computed.rootStyle({ plain, color, customStyle }) }}"
+  open-type="{{ disabled ? '' : openType }}"
+  business-id="{{ businessId }}"
+  session-from="{{ sessionFrom }}"
+  send-message-title="{{ sendMessageTitle }}"
+  send-message-path="{{ sendMessagePath }}"
+  send-message-img="{{ sendMessageImg }}"
+  show-message-card="{{ showMessageCard }}"
+  app-parameter="{{ appParameter }}"
+  aria-label="{{ ariaLabel }}"
+  bindtap="{{ !disabled ? 'onClick' : 'noop' }}"
+  bindgetuserinfo="bindGetUserInfo"
+  bindcontact="bindContact"
+  bindgetphonenumber="bindGetPhoneNumber"
+  binderror="bindError"
+  bindlaunchapp="bindLaunchApp"
+  bindopensetting="bindOpenSetting"
+>
+  <block wx:if="{{ loading }}">
+    <van-loading
+      custom-class="loading-class"
+      size="{{ loadingSize }}"
+      type="{{ loadingType }}"
+      color="{{ computed.loadingColor({ type, color, plain }) }}"
+    />
+    <view wx:if="{{ loadingText }}" class="van-button__loading-text">
+      {{ loadingText }}
+    </view>
+  </block>
+  <block wx:else>
+    <van-icon
+      wx:if="{{ icon }}"
+      size="1.2em"
+      name="{{ icon }}"
+      class-prefix="{{ classPrefix }}"
+      class="van-button__icon"
+      custom-style="line-height: inherit;"
+    />
+    <view class="van-button__text">
+      <slot />
+    </view>
+  </block>
+</button>

+ 39 - 0
src/ttcomponents/out/button/index.wxs

@@ -0,0 +1,39 @@
+/* eslint-disable */
+var style = require('../wxs/style.wxs');
+
+function rootStyle(data) {
+  if (!data.color) {
+    return data.customStyle;
+  }
+
+  var properties = {
+    color: data.plain ? data.color : '#fff',
+    background: data.plain ? null : data.color,
+  };
+
+  // hide border when color is linear-gradient
+  if (data.color.indexOf('gradient') !== -1) {
+    properties.border = 0;
+  } else {
+    properties['border-color'] = data.color;
+  }
+
+  return style([properties, data.customStyle]);
+}
+
+function loadingColor(data) {
+  if (data.plain) {
+    return data.color ? data.color : '#c9c9c9';
+  }
+
+  if (data.type === 'default') {
+    return '#c9c9c9';
+  }
+
+  return '#fff';
+}
+
+module.exports = {
+  rootStyle: rootStyle,
+  loadingColor: loadingColor,
+};

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
src/ttcomponents/out/button/index.wxss


+ 37 - 0
src/ttcomponents/out/calendar/calendar.vue

@@ -0,0 +1,37 @@
+<template>
+<uni-shadow-root class="vant-calendar-calendar"><view class="van-calendar">
+  <header :title="title" :showTitle="showTitle" :subtitle="subtitle" :showSubtitle="showSubtitle">
+    <slot name="title" slot="title"></slot>
+  </header>
+
+  <scroll-view class="van-calendar__body" scroll-y :scroll-into-view="scrollIntoView">
+    <month v-for="(item,index) in (computed.getMonths(minDate, maxDate))" :key="item.index" :id="'month'+(index)" class="month" :data-date="item" :date="item" :type="type" :color="color" :minDate="minDate" :maxDate="maxDate" :showMark="showMark" :formatter="formatter" :rowHeight="rowHeight" :currentDate="currentDate" :showSubtitle="showSubtitle" :allowSameDay="allowSameDay" :showMonthTitle="index !== 0 || !showSubtitle" @click="onClickDay"></month>
+  </scroll-view>
+
+  <view :class="utils.bem('calendar__footer', { safeAreaInsetBottom })">
+    <slot name="footer"></slot>
+  </view>
+
+  <view :class="utils.bem('calendar__footer', { safeAreaInsetBottom })">
+    <van-button v-if="showConfirm" round block type="danger" :color="color" custom-class="van-calendar__confirm" :disabled="computed.getButtonDisabled(type, currentDate)" nativeType="text" @click="onConfirm">
+      {{
+        computed.getButtonDisabled(type, currentDate)
+          ? confirmDisabledText
+          : confirmText
+      }}
+    </van-button>
+  </view>
+</view></uni-shadow-root>
+</template>
+
+<script>
+
+global['__wxRoute'] = 'vant/calendar/calendar'
+
+Component({})
+
+export default global['__wxComponents']['vant/calendar/calendar']
+</script>
+<style platform="mp-weixin">
+
+</style>

+ 65 - 0
src/ttcomponents/out/calendar/calendar.wxml

@@ -0,0 +1,65 @@
+<view class="van-calendar">
+  <header
+    title="{{ title }}"
+    showTitle="{{ showTitle }}"
+    subtitle="{{ subtitle }}"
+    showSubtitle="{{ showSubtitle }}"
+  >
+    <slot name="title" slot="title"></slot>
+  </header>
+
+  <scroll-view
+    class="van-calendar__body"
+    scroll-y
+    scroll-into-view="{{ scrollIntoView }}"
+  >
+    <month
+      wx:for="{{ computed.getMonths(minDate, maxDate) }}"
+      wx:key="index"
+      id="month{{ index }}"
+      class="month"
+      data-date="{{ item }}"
+      date="{{ item }}"
+      type="{{ type }}"
+      color="{{ color }}"
+      minDate="{{ minDate }}"
+      maxDate="{{ maxDate }}"
+      showMark="{{ showMark }}"
+      formatter="{{ formatter }}"
+      rowHeight="{{ rowHeight }}"
+      currentDate="{{ currentDate }}"
+      showSubtitle="{{ showSubtitle }}"
+      allowSameDay="{{ allowSameDay }}"
+      showMonthTitle="{{ index !== 0 || !showSubtitle }}"
+      bind:click="onClickDay"
+    />
+  </scroll-view>
+
+  <view
+    class="{{ utils.bem('calendar__footer', { safeAreaInsetBottom }) }}"
+  >
+    <slot name="footer"></slot>
+  </view>
+
+  <view
+    class="{{ utils.bem('calendar__footer', { safeAreaInsetBottom }) }}"
+  >
+    <van-button
+      wx:if="{{ showConfirm }}"
+      round
+      block
+      type="danger"
+      color="{{ color }}"
+      custom-class="van-calendar__confirm"
+      disabled="{{ computed.getButtonDisabled(type, currentDate) }}"
+      nativeType="text"
+      bind:click="onConfirm"
+    >
+      {{
+        computed.getButtonDisabled(type, currentDate)
+          ? confirmDisabledText
+          : confirmText
+      }}
+    </van-button>
+  </view>
+</view>

+ 1 - 0
src/ttcomponents/out/calendar/components/header/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 16 - 0
src/ttcomponents/out/calendar/components/header/index.js

@@ -0,0 +1,16 @@
+import { VantComponent } from "../../../common/component";
+VantComponent({
+    props: {
+        title: {
+            type: String,
+            value: "日期选择"
+        },
+        subtitle: String,
+        showTitle: Boolean,
+        showSubtitle: Boolean
+    },
+    data: {
+        weekdays: ["日", "一", "二", "三", "四", "五", "六"]
+    },
+    methods: {}
+});

+ 3 - 0
src/ttcomponents/out/calendar/components/header/index.json

@@ -0,0 +1,3 @@
+{
+	"component": true
+}

+ 43 - 0
src/ttcomponents/out/calendar/components/header/index.vue

@@ -0,0 +1,43 @@
+<template>
+<uni-shadow-root class="vant-calendar-components-header-index"><view class="van-calendar__header">
+  <block v-if="showTitle">
+    <view class="van-calendar__header-title"><slot name="title"></slot></view>
+    <view class="van-calendar__header-title">{{ title }}</view>
+  </block>
+
+  <view v-if="showSubtitle" class="van-calendar__header-subtitle">
+    {{ subtitle }}
+  </view>
+
+  <view class="van-calendar__weekdays">
+    <view v-for="(item,index) in (weekdays)" :key="item.index" class="van-calendar__weekday">
+      {{ item }}
+    </view>
+  </view>
+</view></uni-shadow-root>
+</template>
+
+<script>
+
+global['__wxRoute'] = 'vant/calendar/components/header/index'
+import { VantComponent } from '../../../common/component';
+VantComponent({
+  props: {
+    title: {
+      type: String,
+      value: '日期选择',
+    },
+    subtitle: String,
+    showTitle: Boolean,
+    showSubtitle: Boolean,
+  },
+  data: {
+    weekdays: ['日', '一', '二', '三', '四', '五', '六'],
+  },
+  methods: {},
+});
+export default global['__wxComponents']['vant/calendar/components/header/index']
+</script>
+<style platform="mp-weixin">
+@import '../../../common/index.css';.van-calendar__header{-webkit-flex-shrink:0;flex-shrink:0;box-shadow:0 2px 10px rgba(125,126,128,.16);box-shadow:var(--calendar-header-box-shadow,0 2px 10px rgba(125,126,128,.16))}.van-calendar__header-subtitle,.van-calendar__header-title{text-align:center;height:44px;height:var(--calendar-header-title-height,44px);font-weight:500;font-weight:var(--font-weight-bold,500);line-height:44px;line-height:var(--calendar-header-title-height,44px)}.van-calendar__header-title+.van-calendar__header-title,.van-calendar__header-title:empty{display:none}.van-calendar__header-title:empty+.van-calendar__header-title{display:block!important}.van-calendar__weekdays{display:-webkit-flex;display:flex}.van-calendar__weekday{-webkit-flex:1;flex:1;text-align:center;font-size:12px;font-size:var(--calendar-weekdays-font-size,12px);line-height:30px;line-height:var(--calendar-weekdays-height,30px)}
+</style>

+ 16 - 0
src/ttcomponents/out/calendar/components/header/index.wxml

@@ -0,0 +1,16 @@
+<view class="van-calendar__header">
+  <block wx:if="{{ showTitle }}">
+    <view class="van-calendar__header-title"><slot name="title"></slot></view>
+    <view class="van-calendar__header-title">{{ title }}</view>
+  </block>
+
+  <view wx:if="{{ showSubtitle }}" class="van-calendar__header-subtitle">
+    {{ subtitle }}
+  </view>
+
+  <view class="van-calendar__weekdays">
+    <view wx:for="{{ weekdays }}" wx:key="index" class="van-calendar__weekday">
+      {{ item }}
+    </view>
+  </view>
+</view>

+ 1 - 0
src/ttcomponents/out/calendar/components/header/index.wxss

@@ -0,0 +1 @@
+@import '../../../common/index.wxss';.van-calendar__header{-webkit-flex-shrink:0;flex-shrink:0;box-shadow:0 2px 10px rgba(125,126,128,.16);box-shadow:var(--calendar-header-box-shadow,0 2px 10px rgba(125,126,128,.16))}.van-calendar__header-subtitle,.van-calendar__header-title{text-align:center;height:44px;height:var(--calendar-header-title-height,44px);font-weight:500;font-weight:var(--font-weight-bold,500);line-height:44px;line-height:var(--calendar-header-title-height,44px)}.van-calendar__header-title+.van-calendar__header-title,.van-calendar__header-title:empty{display:none}.van-calendar__header-title:empty+.van-calendar__header-title{display:block!important}.van-calendar__weekdays{display:-webkit-flex;display:flex}.van-calendar__weekday{-webkit-flex:1;flex:1;text-align:center;font-size:12px;font-size:var(--calendar-weekdays-font-size,12px);line-height:30px;line-height:var(--calendar-weekdays-height,30px)}

+ 1 - 0
src/ttcomponents/out/calendar/components/month/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 157 - 0
src/ttcomponents/out/calendar/components/month/index.js

@@ -0,0 +1,157 @@
+import { VantComponent } from "../../../common/component";
+import {
+    getMonthEndDay,
+    compareDay,
+    getPrevDay,
+    getNextDay
+} from "../../utils";
+VantComponent({
+    props: {
+        date: {
+            type: null,
+            observer: "setDays"
+        },
+        type: {
+            type: String,
+            observer: "setDays"
+        },
+        color: String,
+        minDate: {
+            type: null,
+            observer: "setDays"
+        },
+        maxDate: {
+            type: null,
+            observer: "setDays"
+        },
+        showMark: Boolean,
+        rowHeight: null,
+        formatter: {
+            type: null,
+            observer: "setDays"
+        },
+        currentDate: {
+            type: null,
+            observer: "setDays"
+        },
+        allowSameDay: Boolean,
+        showSubtitle: Boolean,
+        showMonthTitle: Boolean
+    },
+    data: {
+        visible: true,
+        days: []
+    },
+    methods: {
+        onClick(event) {
+            const { index } = event.currentTarget.dataset;
+            const item = this.data.days[index];
+            if (item.type !== "disabled") {
+                this.$emit("click", item);
+            }
+        },
+        setDays() {
+            const days = [];
+            const startDate = new Date(this.data.date);
+            const year = startDate.getFullYear();
+            const month = startDate.getMonth();
+            const totalDay = getMonthEndDay(
+                startDate.getFullYear(),
+                startDate.getMonth() + 1
+            );
+            for (let day = 1; day <= totalDay; day++) {
+                const date = new Date(year, month, day);
+                const type = this.getDayType(date);
+                let config = {
+                    date,
+                    type,
+                    text: day,
+                    bottomInfo: this.getBottomInfo(type)
+                };
+                if (this.data.formatter) {
+                    config = this.data.formatter(config);
+                }
+                days.push(config);
+            }
+            this.setData({ days });
+        },
+        getMultipleDayType(day) {
+            const { currentDate } = this.data;
+            if (!Array.isArray(currentDate)) {
+                return "";
+            }
+            const isSelected = date =>
+                currentDate.some(item => compareDay(item, date) === 0);
+            if (isSelected(day)) {
+                const prevDay = getPrevDay(day);
+                const nextDay = getNextDay(day);
+                const prevSelected = isSelected(prevDay);
+                const nextSelected = isSelected(nextDay);
+                if (prevSelected && nextSelected) {
+                    return "multiple-middle";
+                }
+                if (prevSelected) {
+                    return "end";
+                }
+                return nextSelected ? "start" : "multiple-selected";
+            }
+            return "";
+        },
+        getRangeDayType(day) {
+            const { currentDate, allowSameDay } = this.data;
+            if (!Array.isArray(currentDate)) {
+                return;
+            }
+            const [startDay, endDay] = currentDate;
+            if (!startDay) {
+                return;
+            }
+            const compareToStart = compareDay(day, startDay);
+            if (!endDay) {
+                return compareToStart === 0 ? "start" : "";
+            }
+            const compareToEnd = compareDay(day, endDay);
+            if (compareToStart === 0 && compareToEnd === 0 && allowSameDay) {
+                return "start-end";
+            }
+            if (compareToStart === 0) {
+                return "start";
+            }
+            if (compareToEnd === 0) {
+                return "end";
+            }
+            if (compareToStart > 0 && compareToEnd < 0) {
+                return "middle";
+            }
+        },
+        getDayType(day) {
+            const { type, minDate, maxDate, currentDate } = this.data;
+            if (compareDay(day, minDate) < 0 || compareDay(day, maxDate) > 0) {
+                return "disabled";
+            }
+            if (type === "single") {
+                return compareDay(day, currentDate) === 0 ? "selected" : "";
+            }
+            if (type === "multiple") {
+                return this.getMultipleDayType(day);
+            }
+            /* istanbul ignore else */
+            if (type === "range") {
+                return this.getRangeDayType(day);
+            }
+        },
+        getBottomInfo(type) {
+            if (this.data.type === "range") {
+                if (type === "start") {
+                    return "开始";
+                }
+                if (type === "end") {
+                    return "结束";
+                }
+                if (type === "start-end") {
+                    return "开始/结束";
+                }
+            }
+        }
+    }
+});

+ 3 - 0
src/ttcomponents/out/calendar/components/month/index.json

@@ -0,0 +1,3 @@
+{
+	"component": true
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 195 - 0
src/ttcomponents/out/calendar/components/month/index.vue


+ 39 - 0
src/ttcomponents/out/calendar/components/month/index.wxml

@@ -0,0 +1,39 @@
+<wxs src="./index.wxs" module="computed"></wxs>
+<wxs src="../../../wxs/utils.wxs" module="utils" />
+
+<view class="van-calendar__month" style="{{ computed.getMonthStyle(visible, date, rowHeight) }}">
+  <view wx:if="{{ showMonthTitle }}" class="van-calendar__month-title">
+    {{ computed.formatMonthTitle(date) }}
+  </view>
+
+  <view wx:if="{{ visible }}" class="van-calendar__days">
+    <view wx:if="{{ showMark }}" class="van-calendar__month-mark">
+      {{ computed.getMark(date) }}
+    </view>
+
+    <view
+      wx:for="{{ days }}"
+      wx:key="index"
+      style="{{ computed.getDayStyle(item.type, index, date, rowHeight, color) }}"
+      class="{{ utils.bem('calendar__day', [item.type]) }} {{ item.className }}"
+      data-index="{{ index }}"
+      bindtap="onClick"
+    >
+      <view wx:if="{{ item.type === 'selected' }}" class="van-calendar__selected-day" style="background: {{ color }}">
+        <view wx:if="{{ item.topInfo }}" class="van-calendar__top-info">{{ item.topInfo }}</view>
+        {{ item.text }}
+        <view wx:if="{{ item.bottomInfo }}" class="van-calendar__bottom-info">
+          {{ item.bottomInfo }}
+        </view>
+      </view>
+
+      <view wx:else>
+        <view wx:if="{{ item.topInfo }}" class="van-calendar__top-info">{{ item.topInfo }}</view>
+        {{ item.text }}
+        <view wx:if="{{ item.bottomInfo }}" class="van-calendar__bottom-info">
+          {{ item.bottomInfo }}
+        </view>
+      </view>
+    </view>
+  </view>
+</view>

+ 67 - 0
src/ttcomponents/out/calendar/components/month/index.wxs

@@ -0,0 +1,67 @@
+/* eslint-disable */
+var utils = require('../../utils.wxs');
+
+function getMark(date) {
+  return getDate(date).getMonth() + 1;
+}
+
+var ROW_HEIGHT = 64;
+
+function getDayStyle(type, index, date, rowHeight, color) {
+  var style = [];
+  var offset = getDate(date).getDay();
+
+  if (index === 0) {
+    style.push(['margin-left', (100 * offset) / 7 + '%']);
+  }
+
+  if (rowHeight !== ROW_HEIGHT) {
+    style.push(['height', rowHeight + 'px']);
+  }
+
+  if (color) {
+    if (
+      type === 'start' ||
+      type === 'end' ||
+      type === 'multiple-selected' ||
+      type === 'multiple-middle'
+    ) {
+      style.push(['background', color]);
+    } else if (type === 'middle') {
+      style.push(['color', color]);
+    }
+  }
+
+  return style
+    .map(function(item) {
+      return item.join(':');
+    })
+    .join(';');
+}
+
+function formatMonthTitle(date) {
+  date = getDate(date);
+  return date.getFullYear() + '年' + (date.getMonth() + 1) + '月';
+}
+
+function getMonthStyle(visible, date, rowHeight) {
+  if (!visible) {
+    date = getDate(date);
+
+    var totalDay = utils.getMonthEndDay(
+      date.getFullYear(),
+      date.getMonth() + 1
+    );
+    var offset = getDate(date).getDay();
+    var padding = Math.ceil((totalDay + offset) / 7) * rowHeight;
+
+    return 'padding-bottom:' + padding + 'px';
+  }
+}
+
+module.exports = {
+  getMark: getMark,
+  getDayStyle: getDayStyle,
+  formatMonthTitle: formatMonthTitle,
+  getMonthStyle: getMonthStyle
+};

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
src/ttcomponents/out/calendar/components/month/index.wxss


+ 1 - 0
src/ttcomponents/out/calendar/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 303 - 0
src/ttcomponents/out/calendar/index.js

@@ -0,0 +1,303 @@
+import { VantComponent } from "../common/component";
+import {
+    ROW_HEIGHT,
+    getNextDay,
+    compareDay,
+    copyDates,
+    calcDateNum,
+    formatMonthTitle,
+    compareMonth,
+    getMonths,
+    getDayByOffset
+} from "./utils";
+import Toast from "../toast/toast";
+import { requestAnimationFrame } from "../common/utils";
+VantComponent({
+    props: {
+        title: {
+            type: String,
+            value: "日期选择"
+        },
+        color: String,
+        show: {
+            type: Boolean,
+            observer(val) {
+                if (val) {
+                    this.initRect();
+                    this.scrollIntoView();
+                }
+            }
+        },
+        formatter: null,
+        confirmText: {
+            type: String,
+            value: "确定"
+        },
+        rangePrompt: String,
+        defaultDate: {
+            type: null,
+            observer(val) {
+                this.setData({ currentDate: val });
+                this.scrollIntoView();
+            }
+        },
+        allowSameDay: Boolean,
+        confirmDisabledText: String,
+        type: {
+            type: String,
+            value: "single",
+            observer: "reset"
+        },
+        minDate: {
+            type: null,
+            value: Date.now()
+        },
+        maxDate: {
+            type: null,
+            value: new Date(
+                new Date().getFullYear(),
+                new Date().getMonth() + 6,
+                new Date().getDate()
+            ).getTime()
+        },
+        position: {
+            type: String,
+            value: "bottom"
+        },
+        rowHeight: {
+            type: null,
+            value: ROW_HEIGHT
+        },
+        round: {
+            type: Boolean,
+            value: true
+        },
+        poppable: {
+            type: Boolean,
+            value: true
+        },
+        showMark: {
+            type: Boolean,
+            value: true
+        },
+        showTitle: {
+            type: Boolean,
+            value: true
+        },
+        showConfirm: {
+            type: Boolean,
+            value: true
+        },
+        showSubtitle: {
+            type: Boolean,
+            value: true
+        },
+        safeAreaInsetBottom: {
+            type: Boolean,
+            value: true
+        },
+        closeOnClickOverlay: {
+            type: Boolean,
+            value: true
+        },
+        maxRange: {
+            type: null,
+            value: null
+        }
+    },
+    data: {
+        subtitle: "",
+        currentDate: null,
+        scrollIntoView: ""
+    },
+    created() {
+        this.setData({
+            currentDate: this.getInitialDate()
+        });
+    },
+    mounted() {
+        if (this.data.show || !this.data.poppable) {
+            this.initRect();
+            this.scrollIntoView();
+        }
+    },
+    methods: {
+        reset() {
+            this.setData({ currentDate: this.getInitialDate() });
+            this.scrollIntoView();
+        },
+        initRect() {
+            if (this.contentObserver != null) {
+                this.contentObserver.disconnect();
+            }
+            const contentObserver = this.createIntersectionObserver({
+                thresholds: [0, 0.1, 0.9, 1],
+                observeAll: true
+            });
+            this.contentObserver = contentObserver;
+            contentObserver.relativeTo(".van-calendar__body");
+            contentObserver.observe(".month", res => {
+                if (res.boundingClientRect.top <= res.relativeRect.top) {
+                    // @ts-ignore
+                    this.setData({
+                        subtitle: formatMonthTitle(res.dataset.date)
+                    });
+                }
+            });
+        },
+        getInitialDate() {
+            const { type, defaultDate, minDate } = this.data;
+            if (type === "range") {
+                const [startDay, endDay] = defaultDate || [];
+                return [
+                    startDay || minDate,
+                    endDay || getNextDay(new Date(minDate)).getTime()
+                ];
+            }
+            if (type === "multiple") {
+                return defaultDate || [minDate];
+            }
+            return defaultDate || minDate;
+        },
+        scrollIntoView() {
+            requestAnimationFrame(() => {
+                const {
+                    currentDate,
+                    type,
+                    show,
+                    poppable,
+                    minDate,
+                    maxDate
+                } = this.data;
+                // @ts-ignore
+                const targetDate =
+                    type === "single" ? currentDate : currentDate[0];
+                const displayed = show || !poppable;
+                if (!targetDate || !displayed) {
+                    return;
+                }
+                const months = getMonths(minDate, maxDate);
+                months.some((month, index) => {
+                    if (compareMonth(month, targetDate) === 0) {
+                        this.setData({ scrollIntoView: `month${index}` });
+                        return true;
+                    }
+                    return false;
+                });
+            });
+        },
+        onOpen() {
+            this.$emit("open");
+        },
+        onOpened() {
+            this.$emit("opened");
+        },
+        onClose() {
+            this.$emit("close");
+        },
+        onClosed() {
+            this.$emit("closed");
+        },
+        onClickDay(event) {
+            const { date } = event.detail;
+            const { type, currentDate, allowSameDay } = this.data;
+            if (type === "range") {
+                // @ts-ignore
+                const [startDay, endDay] = currentDate;
+                if (startDay && !endDay) {
+                    const compareToStart = compareDay(date, startDay);
+                    if (compareToStart === 1) {
+                        this.select([startDay, date], true);
+                    } else if (compareToStart === -1) {
+                        this.select([date, null]);
+                    } else if (allowSameDay) {
+                        this.select([date, date]);
+                    }
+                } else {
+                    this.select([date, null]);
+                }
+            } else if (type === "multiple") {
+                let selectedIndex;
+                // @ts-ignore
+                const selected = currentDate.some((dateItem, index) => {
+                    const equal = compareDay(dateItem, date) === 0;
+                    if (equal) {
+                        selectedIndex = index;
+                    }
+                    return equal;
+                });
+                if (selected) {
+                    // @ts-ignore
+                    const cancelDate = currentDate.splice(selectedIndex, 1);
+                    this.setData({ currentDate });
+                    this.unselect(cancelDate);
+                } else {
+                    // @ts-ignore
+                    this.select([...currentDate, date]);
+                }
+            } else {
+                this.select(date, true);
+            }
+        },
+        unselect(dateArray) {
+            const date = dateArray[0];
+            if (date) {
+                this.$emit("unselect", copyDates(date));
+            }
+        },
+        select(date, complete) {
+            if (complete && this.data.type === "range") {
+                const valid = this.checkRange(date);
+                if (!valid) {
+                    // auto selected to max range if showConfirm
+                    if (this.data.showConfirm) {
+                        this.emit([
+                            date[0],
+                            getDayByOffset(date[0], this.data.maxRange - 1)
+                        ]);
+                    } else {
+                        this.emit(date);
+                    }
+                    return;
+                }
+            }
+            this.emit(date);
+            if (complete && !this.data.showConfirm) {
+                this.onConfirm();
+            }
+        },
+        emit(date) {
+            const getTime = date =>
+                date instanceof Date ? date.getTime() : date;
+            this.setData({
+                currentDate: Array.isArray(date)
+                    ? date.map(getTime)
+                    : getTime(date)
+            });
+            this.$emit("select", copyDates(date));
+        },
+        checkRange(date) {
+            const { maxRange, rangePrompt } = this.data;
+            if (maxRange && calcDateNum(date) > maxRange) {
+                Toast({
+                    context: this,
+                    message: rangePrompt || `选择天数不能超过 ${maxRange} 天`
+                });
+                return false;
+            }
+            return true;
+        },
+        onConfirm() {
+            if (
+                this.data.type === "range" &&
+                !this.checkRange(this.data.currentDate)
+            ) {
+                return;
+            }
+            setTimeout(() => {
+                // @ts-ignore
+                this.$emit("confirm", copyDates(this.data.currentDate));
+            });
+        }
+    }
+});

+ 10 - 0
src/ttcomponents/out/calendar/index.json

@@ -0,0 +1,10 @@
+{
+	"component": true,
+	"usingComponents": {
+		"header": "./components/header/index",
+		"month": "./components/month/index",
+		"van-button": "../button/index",
+		"van-popup": "../popup/index",
+		"van-toast": "../toast/index"
+	}
+}

+ 325 - 0
src/ttcomponents/out/calendar/index.vue

@@ -0,0 +1,325 @@
+<template>
+<uni-shadow-root class="vant-calendar-index"><van-popup v-if="poppable" :custom-class="'van-calendar__popup--'+(position)" close-icon-class="van-calendar__close-icon" :show="show" :round="round" :position="position" :closeable="showTitle || showSubtitle" :close-on-click-overlay="closeOnClickOverlay" @enter="onOpen" @close="onClose" @after-enter="onOpened" @after-leave="onClosed">
+  <include src="calendar.wxml"></include>
+</van-popup>
+
+<include v-else src="calendar.wxml"></include>
+
+<van-toast id="van-toast"></van-toast></uni-shadow-root>
+</template>
+<wxs src="./index.wxs" module="computed"></wxs><wxs src="../wxs/utils.wxs" module="utils"></wxs>
+<script>
+
+const __wxTemplateComponentProps = {}
+import __wxTemplateComponent0 from './calendar.vue'
+
+import Header from './components/header/index.vue'
+import Month from './components/month/index.vue'
+import VanButton from '../button/index.vue'
+import VanPopup from '../popup/index.vue'
+import VanToast from '../toast/index.vue'
+global['__wxVueOptions'] = {components:{'header': Header,'month': Month,'van-button': VanButton,'van-popup': VanPopup,'van-toast': VanToast,}}
+
+global['__wxRoute'] = 'vant/calendar/index'
+import { VantComponent } from '../common/component';
+import {
+  ROW_HEIGHT,
+  getNextDay,
+  compareDay,
+  copyDates,
+  calcDateNum,
+  formatMonthTitle,
+  compareMonth,
+  getMonths,
+  getDayByOffset,
+} from './utils';
+import Toast from '../toast/toast';
+import { requestAnimationFrame } from '../common/utils';
+VantComponent({
+  props: {
+    title: {
+      type: String,
+      value: '日期选择',
+    },
+    color: String,
+    show: {
+      type: Boolean,
+      observer(val) {
+        if (val) {
+          this.initRect();
+          this.scrollIntoView();
+        }
+      },
+    },
+    formatter: null,
+    confirmText: {
+      type: String,
+      value: '确定',
+    },
+    rangePrompt: String,
+    defaultDate: {
+      type: null,
+      observer(val) {
+        this.setData({ currentDate: val });
+        this.scrollIntoView();
+      },
+    },
+    allowSameDay: Boolean,
+    confirmDisabledText: String,
+    type: {
+      type: String,
+      value: 'single',
+      observer: 'reset',
+    },
+    minDate: {
+      type: null,
+      value: Date.now(),
+    },
+    maxDate: {
+      type: null,
+      value: new Date(
+        new Date().getFullYear(),
+        new Date().getMonth() + 6,
+        new Date().getDate()
+      ).getTime(),
+    },
+    position: {
+      type: String,
+      value: 'bottom',
+    },
+    rowHeight: {
+      type: null,
+      value: ROW_HEIGHT,
+    },
+    round: {
+      type: Boolean,
+      value: true,
+    },
+    poppable: {
+      type: Boolean,
+      value: true,
+    },
+    showMark: {
+      type: Boolean,
+      value: true,
+    },
+    showTitle: {
+      type: Boolean,
+      value: true,
+    },
+    showConfirm: {
+      type: Boolean,
+      value: true,
+    },
+    showSubtitle: {
+      type: Boolean,
+      value: true,
+    },
+    safeAreaInsetBottom: {
+      type: Boolean,
+      value: true,
+    },
+    closeOnClickOverlay: {
+      type: Boolean,
+      value: true,
+    },
+    maxRange: {
+      type: null,
+      value: null,
+    },
+  },
+  data: {
+    subtitle: '',
+    currentDate: null,
+    scrollIntoView: '',
+  },
+  created() {
+    this.setData({
+      currentDate: this.getInitialDate(),
+    });
+  },
+  mounted() {
+    if (this.data.show || !this.data.poppable) {
+      this.initRect();
+      this.scrollIntoView();
+    }
+  },
+  methods: {
+    reset() {
+      this.setData({ currentDate: this.getInitialDate() });
+      this.scrollIntoView();
+    },
+    initRect() {
+      if (this.contentObserver != null) {
+        this.contentObserver.disconnect();
+      }
+      const contentObserver = this.createIntersectionObserver({
+        thresholds: [0, 0.1, 0.9, 1],
+        observeAll: true,
+      });
+      this.contentObserver = contentObserver;
+      contentObserver.relativeTo('.van-calendar__body');
+      contentObserver.observe('.month', (res) => {
+        if (res.boundingClientRect.top <= res.relativeRect.top) {
+          // @ts-ignore
+          this.setData({ subtitle: formatMonthTitle(res.dataset.date) });
+        }
+      });
+    },
+    getInitialDate() {
+      const { type, defaultDate, minDate } = this.data;
+      if (type === 'range') {
+        const [startDay, endDay] = defaultDate || [];
+        return [
+          startDay || minDate,
+          endDay || getNextDay(new Date(minDate)).getTime(),
+        ];
+      }
+      if (type === 'multiple') {
+        return defaultDate || [minDate];
+      }
+      return defaultDate || minDate;
+    },
+    scrollIntoView() {
+      requestAnimationFrame(() => {
+        const {
+          currentDate,
+          type,
+          show,
+          poppable,
+          minDate,
+          maxDate,
+        } = this.data;
+        // @ts-ignore
+        const targetDate = type === 'single' ? currentDate : currentDate[0];
+        const displayed = show || !poppable;
+        if (!targetDate || !displayed) {
+          return;
+        }
+        const months = getMonths(minDate, maxDate);
+        months.some((month, index) => {
+          if (compareMonth(month, targetDate) === 0) {
+            this.setData({ scrollIntoView: `month${index}` });
+            return true;
+          }
+          return false;
+        });
+      });
+    },
+    onOpen() {
+      this.$emit('open');
+    },
+    onOpened() {
+      this.$emit('opened');
+    },
+    onClose() {
+      this.$emit('close');
+    },
+    onClosed() {
+      this.$emit('closed');
+    },
+    onClickDay(event) {
+      const { date } = event.detail;
+      const { type, currentDate, allowSameDay } = this.data;
+      if (type === 'range') {
+        // @ts-ignore
+        const [startDay, endDay] = currentDate;
+        if (startDay && !endDay) {
+          const compareToStart = compareDay(date, startDay);
+          if (compareToStart === 1) {
+            this.select([startDay, date], true);
+          } else if (compareToStart === -1) {
+            this.select([date, null]);
+          } else if (allowSameDay) {
+            this.select([date, date]);
+          }
+        } else {
+          this.select([date, null]);
+        }
+      } else if (type === 'multiple') {
+        let selectedIndex;
+        // @ts-ignore
+        const selected = currentDate.some((dateItem, index) => {
+          const equal = compareDay(dateItem, date) === 0;
+          if (equal) {
+            selectedIndex = index;
+          }
+          return equal;
+        });
+        if (selected) {
+          // @ts-ignore
+          const cancelDate = currentDate.splice(selectedIndex, 1);
+          this.setData({ currentDate });
+          this.unselect(cancelDate);
+        } else {
+          // @ts-ignore
+          this.select([...currentDate, date]);
+        }
+      } else {
+        this.select(date, true);
+      }
+    },
+    unselect(dateArray) {
+      const date = dateArray[0];
+      if (date) {
+        this.$emit('unselect', copyDates(date));
+      }
+    },
+    select(date, complete) {
+      if (complete && this.data.type === 'range') {
+        const valid = this.checkRange(date);
+        if (!valid) {
+          // auto selected to max range if showConfirm
+          if (this.data.showConfirm) {
+            this.emit([
+              date[0],
+              getDayByOffset(date[0], this.data.maxRange - 1),
+            ]);
+          } else {
+            this.emit(date);
+          }
+          return;
+        }
+      }
+      this.emit(date);
+      if (complete && !this.data.showConfirm) {
+        this.onConfirm();
+      }
+    },
+    emit(date) {
+      const getTime = (date) => (date instanceof Date ? date.getTime() : date);
+      this.setData({
+        currentDate: Array.isArray(date) ? date.map(getTime) : getTime(date),
+      });
+      this.$emit('select', copyDates(date));
+    },
+    checkRange(date) {
+      const { maxRange, rangePrompt } = this.data;
+      if (maxRange && calcDateNum(date) > maxRange) {
+        Toast({
+          context: this,
+          message: rangePrompt || `选择天数不能超过 ${maxRange} 天`,
+        });
+        return false;
+      }
+      return true;
+    },
+    onConfirm() {
+      if (
+        this.data.type === 'range' &&
+        !this.checkRange(this.data.currentDate)
+      ) {
+        return;
+      }
+      setTimeout(() => {
+        // @ts-ignore
+        this.$emit('confirm', copyDates(this.data.currentDate));
+      });
+    },
+  },
+});
+export default global['__wxComponents']['vant/calendar/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-calendar{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;height:100%;height:var(--calendar-height,100%);background-color:#fff;background-color:var(--calendar-background-color,#fff)}.van-calendar__close-icon{top:11px}.van-calendar__popup--bottom,.van-calendar__popup--top{height:80%;height:var(--calendar-popup-height,80%)}.van-calendar__popup--left,.van-calendar__popup--right{height:100%}.van-calendar__body{-webkit-flex:1;flex:1;overflow:auto;-webkit-overflow-scrolling:touch}.van-calendar__footer{-webkit-flex-shrink:0;flex-shrink:0;padding:0 16px;padding:0 var(--padding-md,16px)}.van-calendar__footer--safe-area-inset-bottom{padding-bottom:env(safe-area-inset-bottom)}.van-calendar__footer+.van-calendar__footer,.van-calendar__footer:empty{display:none}.van-calendar__footer:empty+.van-calendar__footer{display:block!important}.van-calendar__confirm{height:36px!important;height:var(--calendar-confirm-button-height,36px)!important;margin:7px 0!important;margin:var(--calendar-confirm-button-margin,7px 0)!important;line-height:34px!important;line-height:var(--calendar-confirm-button-line-height,34px)!important}
+</style>

+ 25 - 0
src/ttcomponents/out/calendar/index.wxml

@@ -0,0 +1,25 @@
+<wxs src="./index.wxs" module="computed" />
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<import src="./calendar.wxml" />
+
+<van-popup
+  wx:if="{{ poppable }}"
+  custom-class="van-calendar__popup--{{ position }}"
+  close-icon-class="van-calendar__close-icon"
+  show="{{ show }}"
+  round="{{ round }}"
+  position="{{ position }}"
+  closeable="{{ showTitle || showSubtitle }}"
+  close-on-click-overlay="{{ closeOnClickOverlay }}"
+  bind:enter="onOpen"
+  bind:close="onClose"
+  bind:after-enter="onOpened"
+  bind:after-leave="onClosed"
+>
+  <include src="calendar.wxml" />
+</van-popup>
+
+<include wx:else src="calendar.wxml" />
+
+<van-toast id="van-toast" />

+ 37 - 0
src/ttcomponents/out/calendar/index.wxs

@@ -0,0 +1,37 @@
+/* eslint-disable */
+var utils = require('./utils.wxs');
+
+function getMonths(minDate, maxDate) {
+  var months = [];
+  var cursor = getDate(minDate);
+
+  cursor.setDate(1);
+
+  do {
+    months.push(cursor.getTime());
+    cursor.setMonth(cursor.getMonth() + 1);
+  } while (utils.compareMonth(cursor, getDate(maxDate)) !== 1);
+
+  return months;
+}
+
+function getButtonDisabled(type, currentDate) {
+  if (currentDate == null) {
+    return true;
+  }
+
+  if (type === 'range') {
+    return !currentDate[0] || !currentDate[1];
+  }
+
+  if (type === 'multiple') {
+    return !currentDate.length;
+  }
+
+  return !currentDate;
+}
+
+module.exports = {
+  getMonths: getMonths,
+  getButtonDisabled: getButtonDisabled
+};

+ 1 - 0
src/ttcomponents/out/calendar/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-calendar{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;height:100%;height:var(--calendar-height,100%);background-color:#fff;background-color:var(--calendar-background-color,#fff)}.van-calendar__close-icon{top:11px}.van-calendar__popup--bottom,.van-calendar__popup--top{height:80%;height:var(--calendar-popup-height,80%)}.van-calendar__popup--left,.van-calendar__popup--right{height:100%}.van-calendar__body{-webkit-flex:1;flex:1;overflow:auto;-webkit-overflow-scrolling:touch}.van-calendar__footer{-webkit-flex-shrink:0;flex-shrink:0;padding:0 16px;padding:0 var(--padding-md,16px)}.van-calendar__footer--safe-area-inset-bottom{padding-bottom:env(safe-area-inset-bottom)}.van-calendar__footer+.van-calendar__footer,.van-calendar__footer:empty{display:none}.van-calendar__footer:empty+.van-calendar__footer{display:block!important}.van-calendar__confirm{height:36px!important;height:var(--calendar-confirm-button-height,36px)!important;margin:7px 0!important;margin:var(--calendar-confirm-button-margin,7px 0)!important;line-height:34px!important;line-height:var(--calendar-confirm-button-line-height,34px)!important}

+ 17 - 0
src/ttcomponents/out/calendar/utils.d.ts

@@ -0,0 +1,17 @@
+export declare const ROW_HEIGHT = 64;
+export declare function formatMonthTitle(date: Date): string;
+export declare function compareMonth(
+  date1: Date | number,
+  date2: Date | number
+): 0 | 1 | -1;
+export declare function compareDay(
+  day1: Date | number,
+  day2: Date | number
+): 0 | 1 | -1;
+export declare function getDayByOffset(date: Date, offset: number): Date;
+export declare function getPrevDay(date: Date): Date;
+export declare function getNextDay(date: Date): Date;
+export declare function calcDateNum(date: [Date, Date]): number;
+export declare function copyDates(dates: Date | Date[]): Date | Date[];
+export declare function getMonthEndDay(year: number, month: number): number;
+export declare function getMonths(minDate: number, maxDate: number): number[];

+ 78 - 0
src/ttcomponents/out/calendar/utils.js

@@ -0,0 +1,78 @@
+export const ROW_HEIGHT = 64;
+export function formatMonthTitle(date) {
+    if (!(date instanceof Date)) {
+        date = new Date(date);
+    }
+    return `${date.getFullYear()}年${date.getMonth() + 1}月`;
+}
+export function compareMonth(date1, date2) {
+    if (!(date1 instanceof Date)) {
+        date1 = new Date(date1);
+    }
+    if (!(date2 instanceof Date)) {
+        date2 = new Date(date2);
+    }
+    const year1 = date1.getFullYear();
+    const year2 = date2.getFullYear();
+    const month1 = date1.getMonth();
+    const month2 = date2.getMonth();
+    if (year1 === year2) {
+        return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
+    }
+    return year1 > year2 ? 1 : -1;
+}
+export function compareDay(day1, day2) {
+    if (!(day1 instanceof Date)) {
+        day1 = new Date(day1);
+    }
+    if (!(day2 instanceof Date)) {
+        day2 = new Date(day2);
+    }
+    const compareMonthResult = compareMonth(day1, day2);
+    if (compareMonthResult === 0) {
+        const date1 = day1.getDate();
+        const date2 = day2.getDate();
+        return date1 === date2 ? 0 : date1 > date2 ? 1 : -1;
+    }
+    return compareMonthResult;
+}
+export function getDayByOffset(date, offset) {
+    date = new Date(date);
+    date.setDate(date.getDate() + offset);
+    return date;
+}
+export function getPrevDay(date) {
+    return getDayByOffset(date, -1);
+}
+export function getNextDay(date) {
+    return getDayByOffset(date, 1);
+}
+export function calcDateNum(date) {
+    const day1 = new Date(date[0]).getTime();
+    const day2 = new Date(date[1]).getTime();
+    return (day2 - day1) / (1000 * 60 * 60 * 24) + 1;
+}
+export function copyDates(dates) {
+    if (Array.isArray(dates)) {
+        return dates.map(date => {
+            if (date === null) {
+                return date;
+            }
+            return new Date(date);
+        });
+    }
+    return new Date(dates);
+}
+export function getMonthEndDay(year, month) {
+    return 32 - new Date(year, month - 1, 32).getDate();
+}
+export function getMonths(minDate, maxDate) {
+    const months = [];
+    const cursor = new Date(minDate);
+    cursor.setDate(1);
+    do {
+        months.push(cursor.getTime());
+        cursor.setMonth(cursor.getMonth() + 1);
+    } while (compareMonth(cursor, maxDate) !== 1);
+    return months;
+}

+ 25 - 0
src/ttcomponents/out/calendar/utils.wxs

@@ -0,0 +1,25 @@
+/* eslint-disable */
+function getMonthEndDay(year, month) {
+  return 32 -  getDate(year, month - 1, 32).getDate();
+}
+
+function compareMonth(date1, date2) {
+  date1 = getDate(date1);
+  date2 = getDate(date2);
+
+  var year1 = date1.getFullYear();
+  var year2 = date2.getFullYear();
+  var month1 = date1.getMonth();
+  var month2 = date2.getMonth();
+
+  if (year1 === year2) {
+    return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
+  }
+
+  return year1 > year2 ? 1 : -1;
+}
+
+module.exports = {
+  getMonthEndDay: getMonthEndDay,
+  compareMonth: compareMonth
+};

+ 1 - 0
src/ttcomponents/out/card/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 49 - 0
src/ttcomponents/out/card/index.js

@@ -0,0 +1,49 @@
+import { link } from "../mixins/link";
+import { VantComponent } from "../common/component";
+VantComponent({
+    classes: [
+        "num-class",
+        "desc-class",
+        "thumb-class",
+        "title-class",
+        "price-class",
+        "origin-price-class"
+    ],
+    mixins: [link],
+    props: {
+        tag: String,
+        num: String,
+        desc: String,
+        thumb: String,
+        title: String,
+        price: {
+            type: String,
+            observer: "updatePrice"
+        },
+        centered: Boolean,
+        lazyLoad: Boolean,
+        thumbLink: String,
+        originPrice: String,
+        thumbMode: {
+            type: String,
+            value: "aspectFit"
+        },
+        currency: {
+            type: String,
+            value: "¥"
+        }
+    },
+    methods: {
+        updatePrice() {
+            const { price } = this.data;
+            const priceArr = price.toString().split(".");
+            this.setData({
+                integerStr: priceArr[0],
+                decimalStr: priceArr[1] ? `.${priceArr[1]}` : ""
+            });
+        },
+        onClickThumb() {
+            this.jumpLink("thumbLink");
+        }
+    }
+});

+ 6 - 0
src/ttcomponents/out/card/index.json

@@ -0,0 +1,6 @@
+{
+	"component": true,
+	"usingComponents": {
+		"van-tag": "../tag/index"
+	}
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 103 - 0
src/ttcomponents/out/card/index.vue


+ 56 - 0
src/ttcomponents/out/card/index.wxml

@@ -0,0 +1,56 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view class="custom-class van-card">
+  <view class="{{ utils.bem('card__header', { center: centered }) }}">
+    <view class="van-card__thumb" bind:tap="onClickThumb">
+      <image
+        wx:if="{{ thumb }}"
+        src="{{ thumb }}"
+        mode="{{ thumbMode }}"
+        lazy-load="{{ lazyLoad }}"
+        class="van-card__img thumb-class"
+      />
+      <slot wx:else name="thumb" />
+      <van-tag
+        wx:if="{{ tag }}"
+        mark
+        type="danger"
+        custom-class="van-card__tag"
+      >
+        {{ tag }}
+      </van-tag>
+      <slot wx:else name="tag" />
+    </view>
+
+    <view class="van-card__content {{ utils.bem('card__content', { center: centered }) }}">
+      <view>
+        <view wx:if="{{ title }}" class="van-card__title title-class">{{ title }}</view>
+        <slot wx:else name="title" />
+
+        <view wx:if="{{ desc }}" class="van-card__desc desc-class">{{ desc }}</view>
+        <slot wx:else name="desc" />
+
+        <slot name="tags" />
+      </view>
+
+      <view class="van-card__bottom">
+        <slot name="price-top" />
+        <view wx:if="{{ price || price === 0 }}" class="van-card__price price-class">
+          <text>{{ currency }}</text>
+          <text class="van-card__price-integer">{{ integerStr }}</text>
+          <text class="van-card__price-decimal">{{ decimalStr }}</text>
+        </view>
+        <slot wx:else name="price" />
+        <view wx:if="{{ originPrice || originPrice === 0 }}" class="van-card__origin-price origin-price-class">{{ currency }} {{ originPrice }}</view>
+        <slot wx:else name="origin-price" />
+        <view wx:if="{{ num }}" class="van-card__num num-class">x {{ num }}</view>
+        <slot wx:else  name="num" />
+        <slot name="bottom" />
+      </view>
+    </view>
+  </view>
+
+  <view class="van-card__footer">
+    <slot name="footer" />
+  </view>
+</view>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
src/ttcomponents/out/card/index.wxss


+ 1 - 0
src/ttcomponents/out/cell-group/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 10 - 0
src/ttcomponents/out/cell-group/index.js

@@ -0,0 +1,10 @@
+import { VantComponent } from "../common/component";
+VantComponent({
+    props: {
+        title: String,
+        border: {
+            type: Boolean,
+            value: true
+        }
+    }
+});

+ 3 - 0
src/ttcomponents/out/cell-group/index.json

@@ -0,0 +1,3 @@
+{
+	"component": true
+}

+ 27 - 0
src/ttcomponents/out/cell-group/index.vue

@@ -0,0 +1,27 @@
+<template>
+<uni-shadow-root class="vant-cell-group-index"><view v-if="title" class="van-cell-group__title">
+  {{ title }}
+</view>
+<view :class="'custom-class van-cell-group '+(border ? 'van-hairline--top-bottom' : '')">
+  <slot></slot>
+</view></uni-shadow-root>
+</template>
+
+<script>
+
+global['__wxRoute'] = 'vant/cell-group/index'
+import { VantComponent } from '../common/component';
+VantComponent({
+  props: {
+    title: String,
+    border: {
+      type: Boolean,
+      value: true,
+    },
+  },
+});
+export default global['__wxComponents']['vant/cell-group/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-cell-group__title{padding:16px 16px 8px;padding:var(--cell-group-title-padding,16px 16px 8px);font-size:14px;font-size:var(--cell-group-title-font-size,14px);line-height:16px;line-height:var(--cell-group-title-line-height,16px);color:#969799;color:var(--cell-group-title-color,#969799)}
+</style>

+ 9 - 0
src/ttcomponents/out/cell-group/index.wxml

@@ -0,0 +1,9 @@
+<view
+  wx:if="{{ title }}"
+  class="van-cell-group__title"
+>
+  {{ title }}
+</view>
+<view class="custom-class van-cell-group {{ border ? 'van-hairline--top-bottom' : '' }}">
+  <slot />
+</view>

+ 1 - 0
src/ttcomponents/out/cell-group/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-cell-group__title{padding:16px 16px 8px;padding:var(--cell-group-title-padding,16px 16px 8px);font-size:14px;font-size:var(--cell-group-title-font-size,14px);line-height:16px;line-height:var(--cell-group-title-line-height,16px);color:#969799;color:var(--cell-group-title-color,#969799)}

+ 1 - 0
src/ttcomponents/out/cell/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 38 - 0
src/ttcomponents/out/cell/index.js

@@ -0,0 +1,38 @@
+import { link } from "../mixins/link";
+import { VantComponent } from "../common/component";
+VantComponent({
+    classes: [
+        "title-class",
+        "label-class",
+        "value-class",
+        "right-icon-class",
+        "hover-class"
+    ],
+    mixins: [link],
+    props: {
+        title: null,
+        value: null,
+        icon: String,
+        size: String,
+        label: String,
+        center: Boolean,
+        isLink: Boolean,
+        required: Boolean,
+        clickable: Boolean,
+        titleWidth: String,
+        customStyle: String,
+        arrowDirection: String,
+        useLabelSlot: Boolean,
+        border: {
+            type: Boolean,
+            value: true
+        },
+        titleStyle: String
+    },
+    methods: {
+        onClick(event) {
+            this.$emit("click", event.detail);
+            this.jumpLink();
+        }
+    }
+});

+ 6 - 0
src/ttcomponents/out/cell/index.json

@@ -0,0 +1,6 @@
+{
+	"component": true,
+	"usingComponents": {
+		"van-icon": "../icon/index"
+	}
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 73 - 0
src/ttcomponents/out/cell/index.vue


+ 46 - 0
src/ttcomponents/out/cell/index.wxml

@@ -0,0 +1,46 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+<wxs src="./index.wxs" module="computed" />
+
+<view
+  class="custom-class {{ utils.bem('cell', [size, { center, required, borderless: !border, clickable: isLink || clickable }]) }}"
+  hover-class="van-cell--hover hover-class"
+  hover-stay-time="70"
+  style="{{ customStyle }}"
+  bind:tap="onClick"
+>
+  <van-icon
+    wx:if="{{ icon }}"
+    name="{{ icon }}"
+    class="van-cell__left-icon-wrap"
+    custom-class="van-cell__left-icon"
+  />
+  <slot wx:else name="icon" />
+
+  <view
+    style="{{ computed.titleStyle({ titleWidth, titleStyle }) }}"
+    class="van-cell__title title-class"
+  >
+    <block wx:if="{{ title }}">{{ title }}</block>
+    <slot wx:else name="title" />
+
+    <view wx:if="{{ label || useLabelSlot }}" class="van-cell__label label-class">
+      <slot wx:if="{{ useLabelSlot }}" name="label" />
+      <block wx:elif="{{ label }}">{{ label }}</block>
+    </view>
+  </view>
+
+  <view class="van-cell__value value-class">
+    <block wx:if="{{ value || value === 0 }}">{{ value }}</block>
+    <slot wx:else />
+  </view>
+
+  <van-icon
+    wx:if="{{ isLink }}"
+    name="{{ arrowDirection ? 'arrow' + '-' + arrowDirection : 'arrow' }}"
+    class="van-cell__right-icon-wrap right-icon-class"
+    custom-class="van-cell__right-icon"
+  />
+  <slot wx:else name="right-icon" />
+
+  <slot name="extra" />
+</view>

+ 17 - 0
src/ttcomponents/out/cell/index.wxs

@@ -0,0 +1,17 @@
+/* eslint-disable */
+var style = require('../wxs/style.wxs');
+var addUnit = require('../wxs/add-unit.wxs');
+
+function titleStyle(data) {
+  return style([
+    {
+      'max-width': addUnit(data.titleWidth),
+      'min-width': addUnit(data.titleWidth),
+    },
+    data.titleStyle,
+  ]);
+}
+
+module.exports = {
+  titleStyle: titleStyle,
+};

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
src/ttcomponents/out/cell/index.wxss


+ 1 - 0
src/ttcomponents/out/checkbox-group/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 31 - 0
src/ttcomponents/out/checkbox-group/index.js

@@ -0,0 +1,31 @@
+import { useChildren } from "../common/relation";
+import { VantComponent } from "../common/component";
+VantComponent({
+    field: true,
+    relation: useChildren("checkbox", function(target) {
+        this.updateChild(target);
+    }),
+    props: {
+        max: Number,
+        value: {
+            type: Array,
+            observer: "updateChildren"
+        },
+        disabled: {
+            type: Boolean,
+            observer: "updateChildren"
+        }
+    },
+    methods: {
+        updateChildren() {
+            this.children.forEach(child => this.updateChild(child));
+        },
+        updateChild(child) {
+            const { value, disabled } = this.data;
+            child.setData({
+                value: value.indexOf(child.data.name) !== -1,
+                parentDisabled: disabled
+            });
+        }
+    }
+});

+ 3 - 0
src/ttcomponents/out/checkbox-group/index.json

@@ -0,0 +1,3 @@
+{
+	"component": true
+}

+ 43 - 0
src/ttcomponents/out/checkbox-group/index.vue

@@ -0,0 +1,43 @@
+<template>
+<uni-shadow-root class="vant-checkbox-group-index"><slot></slot></uni-shadow-root>
+</template>
+
+<script>
+
+global['__wxRoute'] = 'vant/checkbox-group/index'
+import { useChildren } from '../common/relation';
+import { VantComponent } from '../common/component';
+VantComponent({
+  field: true,
+  relation: useChildren('checkbox', function (target) {
+    this.updateChild(target);
+  }),
+  props: {
+    max: Number,
+    value: {
+      type: Array,
+      observer: 'updateChildren',
+    },
+    disabled: {
+      type: Boolean,
+      observer: 'updateChildren',
+    },
+  },
+  methods: {
+    updateChildren() {
+      this.children.forEach((child) => this.updateChild(child));
+    },
+    updateChild(child) {
+      const { value, disabled } = this.data;
+      child.setData({
+        value: value.indexOf(child.data.name) !== -1,
+        parentDisabled: disabled,
+      });
+    },
+  },
+});
+export default global['__wxComponents']['vant/checkbox-group/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';
+</style>

+ 1 - 0
src/ttcomponents/out/checkbox-group/index.wxml

@@ -0,0 +1 @@
+<slot />

+ 1 - 0
src/ttcomponents/out/checkbox-group/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';

+ 1 - 0
src/ttcomponents/out/checkbox/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 79 - 0
src/ttcomponents/out/checkbox/index.js

@@ -0,0 +1,79 @@
+import { useParent } from "../common/relation";
+import { VantComponent } from "../common/component";
+function emit(target, value) {
+    target.$emit("input", value);
+    target.$emit("change", value);
+}
+VantComponent({
+    field: true,
+    relation: useParent("checkbox-group"),
+    classes: ["icon-class", "label-class"],
+    props: {
+        value: Boolean,
+        disabled: Boolean,
+        useIconSlot: Boolean,
+        checkedColor: String,
+        labelPosition: {
+            type: String,
+            value: "right"
+        },
+        labelDisabled: Boolean,
+        shape: {
+            type: String,
+            value: "round"
+        },
+        iconSize: {
+            type: null,
+            value: 20
+        }
+    },
+    data: {
+        parentDisabled: false
+    },
+    methods: {
+        emitChange(value) {
+            if (this.parent) {
+                this.setParentValue(this.parent, value);
+            } else {
+                emit(this, value);
+            }
+        },
+        toggle() {
+            const { parentDisabled, disabled, value } = this.data;
+            if (!disabled && !parentDisabled) {
+                this.emitChange(!value);
+            }
+        },
+        onClickLabel() {
+            const {
+                labelDisabled,
+                parentDisabled,
+                disabled,
+                value
+            } = this.data;
+            if (!disabled && !labelDisabled && !parentDisabled) {
+                this.emitChange(!value);
+            }
+        },
+        setParentValue(parent, value) {
+            const parentValue = parent.data.value.slice();
+            const { name } = this.data;
+            const { max } = parent.data;
+            if (value) {
+                if (max && parentValue.length >= max) {
+                    return;
+                }
+                if (parentValue.indexOf(name) === -1) {
+                    parentValue.push(name);
+                    emit(parent, parentValue);
+                }
+            } else {
+                const index = parentValue.indexOf(name);
+                if (index !== -1) {
+                    parentValue.splice(index, 1);
+                    emit(parent, parentValue);
+                }
+            }
+        }
+    }
+});

+ 6 - 0
src/ttcomponents/out/checkbox/index.json

@@ -0,0 +1,6 @@
+{
+	"component": true,
+	"usingComponents": {
+		"van-icon": "../icon/index"
+	}
+}

+ 99 - 0
src/ttcomponents/out/checkbox/index.vue

@@ -0,0 +1,99 @@
+<template>
+<uni-shadow-root class="vant-checkbox-index"><view class="van-checkbox custom-class">
+  <view v-if="labelPosition === 'left'" :class="'label-class '+(utils.bem('checkbox__label', [labelPosition, { disabled: disabled || parentDisabled }]))" @click="onClickLabel">
+    <slot></slot>
+  </view>
+  <view class="van-checkbox__icon-wrap" @click="toggle">
+    <slot v-if="useIconSlot" name="icon"></slot>
+    <van-icon v-else name="success" size="0.8em" :class="utils.bem('checkbox__icon', [shape, { disabled: disabled || parentDisabled, checked: value }])" :style="computed.iconStyle(checkedColor, value, disabled, parentDisabled, iconSize)" custom-class="icon-class" custom-style="line-height: 1.25em;"></van-icon>
+  </view>
+  <view v-if="labelPosition === 'right'" :class="'label-class '+(utils.bem('checkbox__label', [labelPosition, { disabled: disabled || parentDisabled }]))" @click="onClickLabel">
+    <slot></slot>
+  </view>
+</view></uni-shadow-root>
+</template>
+<wxs src="../wxs/utils.wxs" module="utils"></wxs><wxs src="./index.wxs" module="computed"></wxs>
+<script>
+import VanIcon from '../icon/index.vue'
+global['__wxVueOptions'] = {components:{'van-icon': VanIcon}}
+
+global['__wxRoute'] = 'vant/checkbox/index'
+import { useParent } from '../common/relation';
+import { VantComponent } from '../common/component';
+function emit(target, value) {
+  target.$emit('input', value);
+  target.$emit('change', value);
+}
+VantComponent({
+  field: true,
+  relation: useParent('checkbox-group'),
+  classes: ['icon-class', 'label-class'],
+  props: {
+    value: Boolean,
+    disabled: Boolean,
+    useIconSlot: Boolean,
+    checkedColor: String,
+    labelPosition: {
+      type: String,
+      value: 'right',
+    },
+    labelDisabled: Boolean,
+    shape: {
+      type: String,
+      value: 'round',
+    },
+    iconSize: {
+      type: null,
+      value: 20,
+    },
+  },
+  data: {
+    parentDisabled: false,
+  },
+  methods: {
+    emitChange(value) {
+      if (this.parent) {
+        this.setParentValue(this.parent, value);
+      } else {
+        emit(this, value);
+      }
+    },
+    toggle() {
+      const { parentDisabled, disabled, value } = this.data;
+      if (!disabled && !parentDisabled) {
+        this.emitChange(!value);
+      }
+    },
+    onClickLabel() {
+      const { labelDisabled, parentDisabled, disabled, value } = this.data;
+      if (!disabled && !labelDisabled && !parentDisabled) {
+        this.emitChange(!value);
+      }
+    },
+    setParentValue(parent, value) {
+      const parentValue = parent.data.value.slice();
+      const { name } = this.data;
+      const { max } = parent.data;
+      if (value) {
+        if (max && parentValue.length >= max) {
+          return;
+        }
+        if (parentValue.indexOf(name) === -1) {
+          parentValue.push(name);
+          emit(parent, parentValue);
+        }
+      } else {
+        const index = parentValue.indexOf(name);
+        if (index !== -1) {
+          parentValue.splice(index, 1);
+          emit(parent, parentValue);
+        }
+      }
+    },
+  },
+});
+export default global['__wxComponents']['vant/checkbox/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-checkbox{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;overflow:hidden;-webkit-user-select:none;user-select:none}.van-checkbox__icon-wrap,.van-checkbox__label{line-height:20px;line-height:var(--checkbox-size,20px)}.van-checkbox__icon-wrap{-webkit-flex:none;flex:none}.van-checkbox__icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;width:1em;height:1em;color:transparent;text-align:center;transition-property:color,border-color,background-color;font-size:20px;font-size:var(--checkbox-size,20px);border:1px solid #c8c9cc;border:1px solid var(--checkbox-border-color,#c8c9cc);transition-duration:.2s;transition-duration:var(--checkbox-transition-duration,.2s)}.van-checkbox__icon--round{border-radius:100%}.van-checkbox__icon--checked{color:#fff;color:var(--white,#fff);background-color:#1989fa;background-color:var(--checkbox-checked-icon-color,#1989fa);border-color:#1989fa;border-color:var(--checkbox-checked-icon-color,#1989fa)}.van-checkbox__icon--disabled{background-color:#ebedf0;background-color:var(--checkbox-disabled-background-color,#ebedf0);border-color:#c8c9cc;border-color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__icon--disabled.van-checkbox__icon--checked{color:#c8c9cc;color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__label{word-wrap:break-word;margin-left:10px;margin-left:var(--checkbox-label-margin,10px);color:#323233;color:var(--checkbox-label-color,#323233)}.van-checkbox__label--left{float:left;margin:0 10px 0 0;margin:0 var(--checkbox-label-margin,10px) 0 0}.van-checkbox__label--disabled{color:#c8c9cc;color:var(--checkbox-disabled-label-color,#c8c9cc)}.van-checkbox__label:empty{margin:0}
+</style>

+ 31 - 0
src/ttcomponents/out/checkbox/index.wxml

@@ -0,0 +1,31 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+<wxs src="./index.wxs" module="computed" />
+
+<view class="van-checkbox custom-class">
+  <view
+    wx:if="{{ labelPosition === 'left' }}"
+    class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled: disabled || parentDisabled }]) }}"
+    bindtap="onClickLabel"
+  >
+    <slot />
+  </view>
+  <view class="van-checkbox__icon-wrap" bindtap="toggle">
+    <slot wx:if="{{ useIconSlot }}" name="icon" />
+    <van-icon
+      wx:else
+      name="success"
+      size="0.8em"
+      class="{{ utils.bem('checkbox__icon', [shape, { disabled: disabled || parentDisabled, checked: value }]) }}"
+      style="{{ computed.iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) }}"
+      custom-class="icon-class"
+      custom-style="line-height: 1.25em;"
+    />
+  </view>
+  <view
+    wx:if="{{ labelPosition === 'right' }}"
+    class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled: disabled || parentDisabled }]) }}"
+    bindtap="onClickLabel"
+  >
+    <slot />
+  </view>
+</view>

+ 20 - 0
src/ttcomponents/out/checkbox/index.wxs

@@ -0,0 +1,20 @@
+/* eslint-disable */
+var style = require('../wxs/style.wxs');
+var addUnit = require('../wxs/add-unit.wxs');
+
+function iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) {
+  var styles = {
+    'font-size': addUnit(iconSize),
+  };
+
+  if (checkedColor && value && !disabled && !parentDisabled) {
+    styles['border-color'] = checkedColor;
+    styles['background-color'] = checkedColor;
+  }
+
+  return style(styles);
+}
+
+module.exports = {
+  iconStyle: iconStyle,
+};

+ 1 - 0
src/ttcomponents/out/checkbox/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-checkbox{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;overflow:hidden;-webkit-user-select:none;user-select:none}.van-checkbox__icon-wrap,.van-checkbox__label{line-height:20px;line-height:var(--checkbox-size,20px)}.van-checkbox__icon-wrap{-webkit-flex:none;flex:none}.van-checkbox__icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;width:1em;height:1em;color:transparent;text-align:center;transition-property:color,border-color,background-color;font-size:20px;font-size:var(--checkbox-size,20px);border:1px solid #c8c9cc;border:1px solid var(--checkbox-border-color,#c8c9cc);transition-duration:.2s;transition-duration:var(--checkbox-transition-duration,.2s)}.van-checkbox__icon--round{border-radius:100%}.van-checkbox__icon--checked{color:#fff;color:var(--white,#fff);background-color:#1989fa;background-color:var(--checkbox-checked-icon-color,#1989fa);border-color:#1989fa;border-color:var(--checkbox-checked-icon-color,#1989fa)}.van-checkbox__icon--disabled{background-color:#ebedf0;background-color:var(--checkbox-disabled-background-color,#ebedf0);border-color:#c8c9cc;border-color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__icon--disabled.van-checkbox__icon--checked{color:#c8c9cc;color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__label{word-wrap:break-word;margin-left:10px;margin-left:var(--checkbox-label-margin,10px);color:#323233;color:var(--checkbox-label-color,#323233)}.van-checkbox__label--left{float:left;margin:0 10px 0 0;margin:0 var(--checkbox-label-margin,10px) 0 0}.van-checkbox__label--disabled{color:#c8c9cc;color:var(--checkbox-disabled-label-color,#c8c9cc)}.van-checkbox__label:empty{margin:0}

+ 6 - 0
src/ttcomponents/out/circle/canvas.d.ts

@@ -0,0 +1,6 @@
+/// <reference types="miniprogram-api-typings" />
+declare type CanvasContext = WechatMiniprogram.CanvasContext;
+export declare function adaptor(
+  ctx: CanvasContext & Record<string, unknown>
+): CanvasContext;
+export {};

+ 43 - 0
src/ttcomponents/out/circle/canvas.js

@@ -0,0 +1,43 @@
+export function adaptor(ctx) {
+    // @ts-ignore
+    return Object.assign(ctx, {
+        setStrokeStyle(val) {
+            ctx.strokeStyle = val;
+        },
+        setLineWidth(val) {
+            ctx.lineWidth = val;
+        },
+        setLineCap(val) {
+            ctx.lineCap = val;
+        },
+        setFillStyle(val) {
+            ctx.fillStyle = val;
+        },
+        setFontSize(val) {
+            ctx.font = String(val);
+        },
+        setGlobalAlpha(val) {
+            ctx.globalAlpha = val;
+        },
+        setLineJoin(val) {
+            ctx.lineJoin = val;
+        },
+        setTextAlign(val) {
+            ctx.textAlign = val;
+        },
+        setMiterLimit(val) {
+            ctx.miterLimit = val;
+        },
+        setShadow(offsetX, offsetY, blur, color) {
+            ctx.shadowOffsetX = offsetX;
+            ctx.shadowOffsetY = offsetY;
+            ctx.shadowBlur = blur;
+            ctx.shadowColor = color;
+        },
+        setTextBaseline(val) {
+            ctx.textBaseline = val;
+        },
+        createCircularGradient() {},
+        draw() {}
+    });
+}

+ 1 - 0
src/ttcomponents/out/circle/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 201 - 0
src/ttcomponents/out/circle/index.js

@@ -0,0 +1,201 @@
+import { BLUE, WHITE } from "../common/color";
+import { VantComponent } from "../common/component";
+import { getSystemInfoSync } from "../common/utils";
+import { isObj } from "../common/validator";
+import { canIUseCanvas2d } from "../common/version";
+import { adaptor } from "./canvas";
+function format(rate) {
+    return Math.min(Math.max(rate, 0), 100);
+}
+const PERIMETER = 2 * Math.PI;
+const BEGIN_ANGLE = -Math.PI / 2;
+const STEP = 1;
+VantComponent({
+    props: {
+        text: String,
+        lineCap: {
+            type: String,
+            value: "round"
+        },
+        value: {
+            type: Number,
+            value: 0,
+            observer: "reRender"
+        },
+        speed: {
+            type: Number,
+            value: 50
+        },
+        size: {
+            type: Number,
+            value: 100,
+            observer() {
+                this.drawCircle(this.currentValue);
+            }
+        },
+        fill: String,
+        layerColor: {
+            type: String,
+            value: WHITE
+        },
+        color: {
+            type: null,
+            value: BLUE,
+            observer() {
+                this.setHoverColor().then(() => {
+                    this.drawCircle(this.currentValue);
+                });
+            }
+        },
+        type: {
+            type: String,
+            value: ""
+        },
+        strokeWidth: {
+            type: Number,
+            value: 4
+        },
+        clockwise: {
+            type: Boolean,
+            value: true
+        }
+    },
+    data: {
+        hoverColor: BLUE
+    },
+    methods: {
+        getContext() {
+            const { type, size } = this.data;
+            if (type === "" || !canIUseCanvas2d()) {
+                const ctx = wx.createCanvasContext("van-circle", this);
+                return Promise.resolve(ctx);
+            }
+            const dpr = getSystemInfoSync().pixelRatio;
+            return new Promise(resolve => {
+                wx.createSelectorQuery()
+                    .in(this)
+                    .select("#van-circle")
+                    .node()
+                    .exec(res => {
+                        const canvas = res[0].node;
+                        const ctx = canvas.getContext(type);
+                        if (!this.inited) {
+                            this.inited = true;
+                            canvas.width = size * dpr;
+                            canvas.height = size * dpr;
+                            ctx.scale(dpr, dpr);
+                        }
+                        resolve(adaptor(ctx));
+                    });
+            });
+        },
+        setHoverColor() {
+            const { color, size } = this.data;
+            if (isObj(color)) {
+                return this.getContext().then(context => {
+                    const LinearColor = context.createLinearGradient(
+                        size,
+                        0,
+                        0,
+                        0
+                    );
+                    Object.keys(color)
+                        .sort((a, b) => parseFloat(a) - parseFloat(b))
+                        .map(key =>
+                            LinearColor.addColorStop(
+                                parseFloat(key) / 100,
+                                color[key]
+                            )
+                        );
+                    this.hoverColor = LinearColor;
+                });
+            }
+            this.hoverColor = color;
+            return Promise.resolve();
+        },
+        presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
+            const { strokeWidth, lineCap, clockwise, size } = this.data;
+            const position = size / 2;
+            const radius = position - strokeWidth / 2;
+            context.setStrokeStyle(strokeStyle);
+            context.setLineWidth(strokeWidth);
+            context.setLineCap(lineCap);
+            context.beginPath();
+            context.arc(
+                position,
+                position,
+                radius,
+                beginAngle,
+                endAngle,
+                !clockwise
+            );
+            context.stroke();
+            if (fill) {
+                context.setFillStyle(fill);
+                context.fill();
+            }
+        },
+        renderLayerCircle(context) {
+            const { layerColor, fill } = this.data;
+            this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
+        },
+        renderHoverCircle(context, formatValue) {
+            const { clockwise } = this.data;
+            // 结束角度
+            const progress = PERIMETER * (formatValue / 100);
+            const endAngle = clockwise
+                ? BEGIN_ANGLE + progress
+                : 3 * Math.PI - (BEGIN_ANGLE + progress);
+            this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle);
+        },
+        drawCircle(currentValue) {
+            const { size } = this.data;
+            this.getContext().then(context => {
+                context.clearRect(0, 0, size, size);
+                this.renderLayerCircle(context);
+                const formatValue = format(currentValue);
+                if (formatValue !== 0) {
+                    this.renderHoverCircle(context, formatValue);
+                }
+                context.draw();
+            });
+        },
+        reRender() {
+            // tofector 动画暂时没有想到好的解决方案
+            const { value, speed } = this.data;
+            if (speed <= 0 || speed > 1000) {
+                this.drawCircle(value);
+                return;
+            }
+            this.clearInterval();
+            this.currentValue = this.currentValue || 0;
+            this.interval = setInterval(() => {
+                if (this.currentValue !== value) {
+                    if (this.currentValue < value) {
+                        this.currentValue += STEP;
+                    } else {
+                        this.currentValue -= STEP;
+                    }
+                    this.drawCircle(this.currentValue);
+                } else {
+                    this.clearInterval();
+                }
+            }, 1000 / speed);
+        },
+        clearInterval() {
+            if (this.interval) {
+                clearInterval(this.interval);
+                this.interval = null;
+            }
+        }
+    },
+    mounted() {
+        this.currentValue = this.data.value;
+        this.setHoverColor().then(() => {
+            this.drawCircle(this.currentValue);
+        });
+    },
+    destroyed() {
+        this.clearInterval();
+    }
+});

+ 3 - 0
src/ttcomponents/out/circle/index.json

@@ -0,0 +1,3 @@
+{
+	"component": true
+}

+ 204 - 0
src/ttcomponents/out/circle/index.vue

@@ -0,0 +1,204 @@
+<template>
+<uni-shadow-root class="vant-circle-index"><view class="van-circle">
+  <canvas class="van-circle__canvas" :type="type" :style="'width: '+(utils.addUnit(size))+';height:'+(utils.addUnit(size))" id="van-circle" canvas-id="van-circle"></canvas>
+  <view v-if="(!text)" class="van-circle__text">
+    <slot></slot>
+  </view>
+  <cover-view v-else class="van-circle__text">{{ text }}</cover-view>
+</view></uni-shadow-root>
+</template>
+<wxs src="../wxs/utils.wxs" module="utils"></wxs>
+<script>
+
+global['__wxRoute'] = 'vant/circle/index'
+import { BLUE, WHITE } from '../common/color';
+import { VantComponent } from '../common/component';
+import { getSystemInfoSync } from '../common/utils';
+import { isObj } from '../common/validator';
+import { canIUseCanvas2d } from '../common/version';
+import { adaptor } from './canvas';
+function format(rate) {
+  return Math.min(Math.max(rate, 0), 100);
+}
+const PERIMETER = 2 * Math.PI;
+const BEGIN_ANGLE = -Math.PI / 2;
+const STEP = 1;
+VantComponent({
+  props: {
+    text: String,
+    lineCap: {
+      type: String,
+      value: 'round',
+    },
+    value: {
+      type: Number,
+      value: 0,
+      observer: 'reRender',
+    },
+    speed: {
+      type: Number,
+      value: 50,
+    },
+    size: {
+      type: Number,
+      value: 100,
+      observer() {
+        this.drawCircle(this.currentValue);
+      },
+    },
+    fill: String,
+    layerColor: {
+      type: String,
+      value: WHITE,
+    },
+    color: {
+      type: null,
+      value: BLUE,
+      observer() {
+        this.setHoverColor().then(() => {
+          this.drawCircle(this.currentValue);
+        });
+      },
+    },
+    type: {
+      type: String,
+      value: '',
+    },
+    strokeWidth: {
+      type: Number,
+      value: 4,
+    },
+    clockwise: {
+      type: Boolean,
+      value: true,
+    },
+  },
+  data: {
+    hoverColor: BLUE,
+  },
+  methods: {
+    getContext() {
+      const { type, size } = this.data;
+      if (type === '' || !canIUseCanvas2d()) {
+        const ctx = wx.createCanvasContext('van-circle', this);
+        return Promise.resolve(ctx);
+      }
+      const dpr = getSystemInfoSync().pixelRatio;
+      return new Promise((resolve) => {
+        wx.createSelectorQuery()
+          .in(this)
+          .select('#van-circle')
+          .node()
+          .exec((res) => {
+            const canvas = res[0].node;
+            const ctx = canvas.getContext(type);
+            if (!this.inited) {
+              this.inited = true;
+              canvas.width = size * dpr;
+              canvas.height = size * dpr;
+              ctx.scale(dpr, dpr);
+            }
+            resolve(adaptor(ctx));
+          });
+      });
+    },
+    setHoverColor() {
+      const { color, size } = this.data;
+      if (isObj(color)) {
+        return this.getContext().then((context) => {
+          const LinearColor = context.createLinearGradient(size, 0, 0, 0);
+          Object.keys(color)
+            .sort((a, b) => parseFloat(a) - parseFloat(b))
+            .map((key) =>
+              LinearColor.addColorStop(parseFloat(key) / 100, color[key])
+            );
+          this.hoverColor = LinearColor;
+        });
+      }
+      this.hoverColor = color;
+      return Promise.resolve();
+    },
+    presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
+      const { strokeWidth, lineCap, clockwise, size } = this.data;
+      const position = size / 2;
+      const radius = position - strokeWidth / 2;
+      context.setStrokeStyle(strokeStyle);
+      context.setLineWidth(strokeWidth);
+      context.setLineCap(lineCap);
+      context.beginPath();
+      context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
+      context.stroke();
+      if (fill) {
+        context.setFillStyle(fill);
+        context.fill();
+      }
+    },
+    renderLayerCircle(context) {
+      const { layerColor, fill } = this.data;
+      this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
+    },
+    renderHoverCircle(context, formatValue) {
+      const { clockwise } = this.data;
+      // 结束角度
+      const progress = PERIMETER * (formatValue / 100);
+      const endAngle = clockwise
+        ? BEGIN_ANGLE + progress
+        : 3 * Math.PI - (BEGIN_ANGLE + progress);
+      this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle);
+    },
+    drawCircle(currentValue) {
+      const { size } = this.data;
+      this.getContext().then((context) => {
+        context.clearRect(0, 0, size, size);
+        this.renderLayerCircle(context);
+        const formatValue = format(currentValue);
+        if (formatValue !== 0) {
+          this.renderHoverCircle(context, formatValue);
+        }
+        context.draw();
+      });
+    },
+    reRender() {
+      // tofector 动画暂时没有想到好的解决方案
+      const { value, speed } = this.data;
+      if (speed <= 0 || speed > 1000) {
+        this.drawCircle(value);
+        return;
+      }
+      this.clearInterval();
+      this.currentValue = this.currentValue || 0;
+      this.interval = setInterval(() => {
+        if (this.currentValue !== value) {
+          if (this.currentValue < value) {
+            this.currentValue += STEP;
+          } else {
+            this.currentValue -= STEP;
+          }
+          this.drawCircle(this.currentValue);
+        } else {
+          this.clearInterval();
+        }
+      }, 1000 / speed);
+    },
+    clearInterval() {
+      if (this.interval) {
+        clearInterval(this.interval);
+        this.interval = null;
+      }
+    },
+  },
+  mounted() {
+    this.currentValue = this.data.value;
+    this.setHoverColor().then(() => {
+      this.drawCircle(this.currentValue);
+    });
+  },
+  destroyed() {
+    this.clearInterval();
+  },
+});
+export default global['__wxComponents']['vant/circle/index']
+</script>
+<style platform="mp-weixin">
+@import '../common/index.css';.van-circle{position:relative;display:inline-block;text-align:center}.van-circle__text{position:absolute;top:50%;left:0;width:100%;-webkit-transform:translateY(-50%);transform:translateY(-50%);color:#323233;color:var(--circle-text-color,#323233)}
+</style>

+ 9 - 0
src/ttcomponents/out/circle/index.wxml

@@ -0,0 +1,9 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view class="van-circle">
+  <canvas class="van-circle__canvas" type="{{ type }}" style="width: {{ utils.addUnit(size) }};height:{{ utils.addUnit(size) }}" id="van-circle" canvas-id="van-circle"></canvas>
+  <view wx:if="{{ !text }}" class="van-circle__text">
+    <slot></slot>
+  </view>
+  <cover-view wx:else class="van-circle__text">{{ text }}</cover-view>
+</view>

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است