Explorar o código

Add demo project

杜府 %!s(int64=3) %!d(string=hai) anos
pai
achega
01e5128abb
Modificáronse 100 ficheiros con 10133 adicións e 0 borrados
  1. 17 0
      demo/README.md
  2. 293 0
      demo/Refresh-auto.py
  3. 1 0
      demo/cdn-list.txt
  4. 13 0
      demo/index.html
  5. 21 0
      demo/package.json
  6. 903 0
      demo/pnpm-lock.yaml
  7. 7 0
      demo/postcss.config.cjs
  8. 0 0
      demo/public/assets/fonts/symbol.svg
  9. BIN=BIN
      demo/public/assets/images/airpods-pro2.png
  10. BIN=BIN
      demo/public/assets/images/avatar_1.jpg
  11. BIN=BIN
      demo/public/assets/images/avatar_2.png
  12. BIN=BIN
      demo/public/assets/images/dota_小牛.png
  13. BIN=BIN
      demo/public/assets/images/dota_斯温.png
  14. BIN=BIN
      demo/public/assets/images/dota_水人.png
  15. BIN=BIN
      demo/public/assets/images/dota_火女.png
  16. BIN=BIN
      demo/public/assets/images/dota_火枪.png
  17. BIN=BIN
      demo/public/assets/images/icon_会员.png
  18. BIN=BIN
      demo/public/assets/images/icon_外卖.png
  19. BIN=BIN
      demo/public/assets/images/icon_游戏.png
  20. BIN=BIN
      demo/public/assets/images/icon_火车票.png
  21. BIN=BIN
      demo/public/assets/images/icon_美食.png
  22. BIN=BIN
      demo/public/assets/images/icon_评价.png
  23. BIN=BIN
      demo/public/assets/images/icon_颁奖.png
  24. BIN=BIN
      demo/public/assets/images/wall_1.jpg
  25. BIN=BIN
      demo/public/assets/images/wall_2.jpg
  26. BIN=BIN
      demo/public/assets/images/wall_3.jpg
  27. BIN=BIN
      demo/public/assets/images/wall_4.jpg
  28. BIN=BIN
      demo/public/assets/logos/adidas.png
  29. BIN=BIN
      demo/public/assets/logos/adobe.png
  30. BIN=BIN
      demo/public/assets/logos/apple.png
  31. BIN=BIN
      demo/public/assets/logos/chrome.png
  32. BIN=BIN
      demo/public/assets/logos/figma.png
  33. BIN=BIN
      demo/public/assets/logos/github.png
  34. BIN=BIN
      demo/public/assets/logos/google.png
  35. BIN=BIN
      demo/public/assets/logos/instagram.png
  36. BIN=BIN
      demo/public/assets/logos/microsoft.png
  37. BIN=BIN
      demo/public/assets/logos/netflix.png
  38. BIN=BIN
      demo/public/assets/logos/nike.png
  39. BIN=BIN
      demo/public/assets/logos/pinterest.png
  40. BIN=BIN
      demo/public/assets/logos/safari.png
  41. BIN=BIN
      demo/public/assets/logos/spotify.png
  42. BIN=BIN
      demo/public/assets/logos/starbucks.png
  43. BIN=BIN
      demo/public/assets/logos/tik-tok.png
  44. BIN=BIN
      demo/public/assets/logos/twitter.png
  45. BIN=BIN
      demo/public/assets/logos/youtube.png
  46. BIN=BIN
      demo/public/assets/stdf_512px.png
  47. BIN=BIN
      demo/public/assets/stdf_dark_512px.png
  48. BIN=BIN
      demo/public/favicon.ico
  49. 87 0
      demo/src/App.svelte
  50. 34 0
      demo/src/app.css
  51. 26 0
      demo/src/components/Aphorism.svelte
  52. 48 0
      demo/src/data/aphorisms.js
  53. 371 0
      demo/src/data/menuList.js
  54. 58 0
      demo/src/main.js
  55. 94 0
      demo/src/pages/actionSheet/ActionSheetDemo.svelte
  56. 94 0
      demo/src/pages/actionSheet/ActionSheetDemo_en.svelte
  57. 746 0
      demo/src/pages/asyncPicker/AsyncPickerDemo.svelte
  58. 728 0
      demo/src/pages/asyncPicker/AsyncPickerDemo_en.svelte
  59. 426 0
      demo/src/pages/asyncPicker/data.js
  60. 407 0
      demo/src/pages/asyncPicker/data_en.js
  61. 82 0
      demo/src/pages/avatar/AvatarDemo.svelte
  62. 82 0
      demo/src/pages/avatar/AvatarDemo_en.svelte
  63. 126 0
      demo/src/pages/badge/BadgeDemo.svelte
  64. 126 0
      demo/src/pages/badge/BadgeDemo_en.svelte
  65. 147 0
      demo/src/pages/bottomSheet/BottomSheetDemo.svelte
  66. 159 0
      demo/src/pages/bottomSheet/BottomSheetDemo_en.svelte
  67. 159 0
      demo/src/pages/button/ButtonDemo.svelte
  68. 159 0
      demo/src/pages/button/ButtonDemo_en.svelte
  69. 176 0
      demo/src/pages/calendar/CalendarDemo.svelte
  70. 180 0
      demo/src/pages/calendar/CalendarDemo_en.svelte
  71. 109 0
      demo/src/pages/cell/CellDemo.svelte
  72. 109 0
      demo/src/pages/cell/CellDemo_en.svelte
  73. 304 0
      demo/src/pages/checkbox/CheckboxDemo.svelte
  74. 328 0
      demo/src/pages/checkbox/CheckboxDemo_en.svelte
  75. 152 0
      demo/src/pages/dialog/DialogDemo.svelte
  76. 152 0
      demo/src/pages/dialog/DialogDemo_en.svelte
  77. 78 0
      demo/src/pages/divider/DividerDemo.svelte
  78. 78 0
      demo/src/pages/divider/DividerDemo_en.svelte
  79. 288 0
      demo/src/pages/grids/GridsDemo.svelte
  80. 288 0
      demo/src/pages/grids/GridsDemo_en.svelte
  81. 65 0
      demo/src/pages/home/Home.svelte
  82. 123 0
      demo/src/pages/icon/IconDemo.svelte
  83. 115 0
      demo/src/pages/icon/IconDemo_en.svelte
  84. 119 0
      demo/src/pages/icon/allIcon.md
  85. 188 0
      demo/src/pages/indexBar/IndexBarDemo.svelte
  86. 189 0
      demo/src/pages/indexBar/IndexBarDemo_en.svelte
  87. 257 0
      demo/src/pages/input/InputDemo.svelte
  88. 264 0
      demo/src/pages/input/InputDemo_en.svelte
  89. 150 0
      demo/src/pages/loading/LoadingDemo.svelte
  90. 150 0
      demo/src/pages/loading/LoadingDemo_en.svelte
  91. 61 0
      demo/src/pages/mask/MaskDemo.svelte
  92. 61 0
      demo/src/pages/mask/MaskDemo_en.svelte
  93. 112 0
      demo/src/pages/modal/ModalDemo.svelte
  94. 112 0
      demo/src/pages/modal/ModalDemo_en.svelte
  95. 68 0
      demo/src/pages/navBar/NavBarDemo.svelte
  96. 67 0
      demo/src/pages/navBar/NavBarDemo_en.svelte
  97. 61 0
      demo/src/pages/noticeBar/NoticeBarDemo.svelte
  98. 61 0
      demo/src/pages/noticeBar/NoticeBarDemo_en.svelte
  99. 127 0
      demo/src/pages/pagination/PaginationDemo.svelte
  100. 127 0
      demo/src/pages/pagination/PaginationDemo_en.svelte

+ 17 - 0
demo/README.md

@@ -0,0 +1,17 @@
+# STDF Demo
+
+## Introduction
+
+This is a demo project for STDF.
+
+It is built with [Vite](https://vitejs.dev) + [Svelte](https://svelte.dev) + [Tailwind CSS](https://tailwindcss.com) + [STDF](https://stdf.design) + [svelte-spa-router](https://github.com/ItalyPaleAle/svelte-spa-router).
+
+## Getting Started
+
+```bash
+pnpm i
+# or
+npm i
+
+npm run dev
+```

+ 293 - 0
demo/Refresh-auto.py

@@ -0,0 +1,293 @@
+#!/usr/bin/env python3
+# coding=utf-8
+# __author__ = 'hanli.zyb'
+# __date__ = '2021-04-23'
+
+'''Check Package'''
+
+try:
+    import os, re, sys, getopt, time, json, logging
+    from aliyunsdkcore.client import AcsClient
+    from aliyunsdkcore.acs_exception.exceptions import ClientException
+    from aliyunsdkcore.acs_exception.exceptions import ServerException
+    from aliyunsdkcdn.request.v20180510.RefreshObjectCachesRequest import RefreshObjectCachesRequest
+    from aliyunsdkcdn.request.v20180510.PushObjectCacheRequest import PushObjectCacheRequest
+    from aliyunsdkcdn.request.v20180510.DescribeRefreshTasksRequest import DescribeRefreshTasksRequest
+    from aliyunsdkcdn.request.v20180510.DescribeRefreshQuotaRequest import DescribeRefreshQuotaRequest
+except:
+    sys.exit("[error] Please pip install aliyun-python-sdk-cdn and aliyun-python-sdk-core and logging,please install now......")
+logging.basicConfig(level=logging.DEBUG, filename='./RefreshAndPredload.log')
+
+class Envariable(object):
+    LISTS = []
+    REGION = 'cn-zhangzhou'
+    AK = os.environ.get("ALIYUN_CDN_AK")
+    SK = os.environ.get("ALIYUN_CDN_SK")
+    FD = None
+    CLI = None
+    TASK_TYPE = None
+    TASK_AREA = None
+    TASK_OTYPE = None
+
+    def set_ak(ak):
+        Envariable.AK = ak
+
+    def get_ak():
+        return Envariable.AK
+
+    def set_sk(sk):
+        Envariable.SK = sk
+
+    def get_sk():
+        return Envariable.SK
+
+    def set_fd(fd):
+        Envariable.FD = fd
+
+    def get_fd():
+        return Envariable.FD
+
+    def set_task_type(task_type):
+        Envariable.TASK_TYPE = task_type
+
+    def get_task_type():
+        return Envariable.TASK_TYPE
+
+    def set_task_area(task_area):
+        Envariable.TASK_AREA = task_area
+
+    def get_task_area():
+        return Envariable.TASK_AREA
+
+    def set_task_otype(task_otype):
+        Envariable.TASK_OTYPE = task_otype
+
+    def get_task_otype():
+        return Envariable.TASK_OTYPE
+
+    def set_acs_client():
+        Envariable.CLI = AcsClient(Envariable.get_ak(), Envariable.get_sk(), Envariable.REGION)
+
+    def get_acs_client():
+        return Envariable.CLI
+
+class InitHandler(object):
+    def __init__(self,ak,sk,region):
+        try:
+            self.client = AcsClient(self,Envariable.get_ak(),Envariable.get_sk(),Envariable.REGION)
+        except Exception:
+            logging.info("[error]: initial AcsClient failed") and exit(1)
+
+class BaseCheck(object):
+
+    def __init__(self):
+        self.invalidurl = ''
+        self.lines = 0
+        self.urllist = Envariable.get_fd()
+
+    def printQuota(self):
+
+        try:
+            if Envariable.get_acs_client():
+                client = Envariable.get_acs_client()
+            else:
+                Envariable.set_acs_client()
+                client = Envariable.get_acs_client()
+            quotas = DescribeRefreshQuotaRequest()
+            quotaResp = json.loads(Envariable.get_acs_client().do_action_with_exception(quotas))
+        except Exception as e:
+            logging.info("\n[error]: initial AcsClient failed\n") and sys.exit(1)
+
+        if Envariable.TASK_TYPE:
+            if Envariable.TASK_TYPE == 'push':
+                if self.lines > int(quotaResp['PreloadRemain']):
+                    sys.exit("\n[error]:PreloadRemain is not enough {0}".format(quotaResp['PreloadRemain']))
+                return True
+            if Envariable.TASK_TYPE == 'clear':
+                if Envariable.get_task_otype() == 'File' and self.lines > int(quotaResp['UrlRemain']):
+                    sys.exit("\n[error]:UrlRemain is not enough {0}".format(quotaResp['UrlRemain']))
+                elif Envariable.get_task_otype() == 'Directory' and self.lines > int(quotaResp['DirRemain']):
+                    sys.exit("\n[error]:DirRemain is not enough {0}".format(quotaResp['DirRemain']))
+                else:
+                    return True
+
+    def urlFormat(self):
+        with open(self.urllist, "r") as f:
+            for line in f.readlines():
+                self.lines += 1
+                if not re.match(r'^((https)|(http))',line):
+                    self.invalidurl = line + '\n' + self.invalidurl
+            if self.invalidurl != '':
+                sys.exit("\n[error]: URL format is illegal \n{0}".format(self.invalidurl))
+            return True
+
+class doTask(object):
+
+    def urlencode_pl(inputs_str):
+        len_str = len(inputs_str)
+        if str == "" or len_str <= 0:
+            return ""
+        index_j = 0
+        index_i = 0
+        result_end = ""
+        for index_i in range(0, len_str):
+            index_sb = index_i + 1
+            chs = inputs_str[index_i:index_sb]
+            if (chs >= 'A' and chs <= 'Z') or (chs >= 'a' and chs <= 'z') or (chs >= '0' and chs <= '9') or (
+                    chs == ":") or (chs == "/"):
+                if result_end == "":
+                    result_end = chs
+                else:
+                    result_end += chs
+            elif chs == ' ':
+                result_end += '+'
+            elif chs == '.' or chs == '-' or chs == '_' or chs == '*':
+                result_end += chs
+            else:
+                result_end = '%s%%%02X' % (result_end, ord(chs))
+
+        return result_end
+
+    def doProd(self):
+        gop = 100
+        mins = 1
+        maxs = gop
+        with open(Envariable.get_fd(), "r") as f:
+            for line in f.readlines():
+                if mins != maxs:
+                    line = line.strip("\n") + "\n"
+                else:
+                    line = line.strip("\n")
+                line = line.strip()
+                line = doTask.urlencode_pl(line) + "\n"
+                Envariable.LISTS.append(line)
+                if mins >= maxs:
+                    yield Envariable.LISTS
+                    mins = maxs
+                    maxs = gop + maxs - 1
+                else:
+                    mins += 1
+            if len(Envariable.LISTS) > 0: yield Envariable.LISTS
+
+    def doRefresh(lists):
+        try:
+            if Envariable.get_acs_client():
+                client = Envariable.get_acs_client()
+            else:
+                Envariable.set_acs_client()
+                client = Envariable.get_acs_client()
+            if Envariable.get_task_type() == 'clear':
+                taskID = 'RefreshTaskId'
+                request = RefreshObjectCachesRequest()
+                if Envariable.get_task_otype():
+                    request.set_ObjectType(Envariable.get_task_otype())
+            elif Envariable.get_task_type() == 'push':
+                taskID = 'PushTaskId'
+                request = PushObjectCacheRequest()
+                if Envariable.get_task_area():
+                    request.set_Area(Envariable.get_task_area())
+            taskreq = DescribeRefreshTasksRequest()
+            request.set_accept_format('json')
+            request.set_ObjectPath(lists)
+            response = json.loads(client.do_action_with_exception(request))
+            print(response)
+            timeout = 0
+            while True:
+                count = 0
+                taskreq.set_accept_format('json')
+                taskreq.set_TaskId(int(response[taskID]))
+                taskresp = json.loads(client.do_action_with_exception(taskreq))
+                print("[" + response[taskID] + "]" + "is doing... ...")
+                for t in taskresp['Tasks']['CDNTask']:
+                    if t['Status'] != 'Complete':
+                        count += 1
+                if count == 0:
+                    logging.info("[" + response[taskID] + "]" + "is finish")
+                    break
+                elif timeout > 5:
+                    logging.info("[" + response[taskID] + "]" + "timeout")
+                    break
+                else:
+                    timeout += 1
+                    time.sleep(5)
+                    continue
+        except Exception as e:
+            logging.info("\n[error]:%s",e) and sys.exit(1)
+
+class Refresh(object):
+
+    def main(self,argv):
+        if len(argv) < 1:
+            sys.exit("\n[usage]: " + sys.argv[0] + " -h ")
+        try:
+            opts, args = getopt.getopt(argv, "hi:k:n:r:t:a:o:")
+        except Exception as e:
+                sys.exit("\n[usage]: " + sys.argv[0] + " -h ")
+
+        for opt, arg in opts:
+            if opt == '-h':
+                self.helps()
+                sys.exit()
+            # elif opt == '-i':
+            #     Envariable.set_ak(arg)
+            # elif opt == '-k':
+            #     Envariable.set_sk(arg)
+            elif opt == '-r':
+                Envariable.set_fd(arg)
+            elif opt == '-t':
+                Envariable.set_task_type(arg)
+            elif opt == '-a':
+                Envariable.set_task_area(arg)
+            elif opt == '-o':
+                Envariable.set_task_otype(arg)
+            elif opt == '-q':
+                Envariable.set_task_id(arg)
+            else:
+                sys.exit("\n[usage]: " + sys.argv[0] + " -h \n")
+
+        try:
+            if not (Envariable.get_ak() and Envariable.get_sk() and Envariable.get_fd() and Envariable.get_task_type()):
+                sys.exit("\n[error]: Must be by parameter '-i', '-k', '-r', '-t'\n")
+
+            if not (Envariable.get_task_type() in ("push", "clear")):
+                sys.exit("\n[error]: taskType Error, '-t' option in 'push' or 'clear'\n")
+
+            if Envariable.get_task_area() and Envariable.get_task_otype():
+                sys.exit("\n[error]: -a and -o cannot exist at same time\n")
+
+            if Envariable.get_task_area():
+                if not Envariable.get_task_area() in ("domestic","overseas"):
+                    sys.exit("\n[error]: Area value Error, '-a' option in 'domestic' or 'overseas'\n")
+
+            if Envariable.get_task_otype():
+                if not Envariable.get_task_otype() in ("File", "Directory"):
+                    sys.exit("\n[error]: ObjectType value Error, '-a' options in 'File' or 'Directory'\n")
+                if Envariable.get_task_type() == 'push':
+                    sys.exit("\n[error]: -t must be clear and 'push' -a use together\n")
+        except Exception as e:
+            logging.info("\n[error]: Parameter {0} error\n".format(str(e))) and sys.exit(1)
+
+        handler = BaseCheck()
+        if  handler.urlFormat() and handler.printQuota():
+            for g in doTask.doProd(Envariable.get_fd()):
+                Envariable.LISTS = []
+                doTask.doRefresh(''.join(g))
+                time.sleep(1)
+
+    def helps(self):
+        print("\nscript options explain: \
+                    \n\t -i <AccessKey>                  访问阿里云凭证,访问控制台上可以获得; \
+                    \n\t -k <AccessKeySecret>            访问阿里云密钥,访问控制台上可以获得; \
+                    \n\t -r <filename>                   filename指“文件所在的路径+文件名称”,自动化脚本运行后将会读取文件内记录的URL;文件内的URL记录方式为每行一条URL,有特殊字符先做URLencode,以http或https开头; \
+                    \n\t -t <taskType>                   任务类型,clear:刷新,push:预热; \
+                    \n\t -a [String,<domestic|overseas>  可选项,预热范围,不传默认是全球;\
+                    \n\t    domestic                     仅中国内地; \
+                    \n\t    overseas                     全球(不包含中国内地); \
+                    \n\t -o [String,<File|Directory>]    可选项,刷新的类型; \
+                    \n\t    File                         文件刷新(默认值); \
+                    \n\t    Directory                    目录刷新")
+
+#TODO
+if __name__ == '__main__':
+    fun = Refresh()
+    fun.main(sys.argv[1:])

+ 1 - 0
demo/cdn-list.txt

@@ -0,0 +1 @@
+https://demo.stdf.design/

+ 13 - 0
demo/index.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="UTF-8" />
+        <link rel="icon" href="./favicon.ico" />
+        <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
+        <title>Demo STDF</title>
+    </head>
+    <body>
+        <div id="app"></div>
+        <script type="module" src="/src/main.js"></script>
+    </body>
+</html>

+ 21 - 0
demo/package.json

@@ -0,0 +1,21 @@
+{
+    "name": "demo-stdf",
+    "private": true,
+    "version": "0.0.0",
+    "type": "module",
+    "scripts": {
+        "dev": "vite",
+        "build": "vite build",
+        "preview": "vite preview"
+    },
+    "devDependencies": {
+        "@sveltejs/vite-plugin-svelte": "^2.0.2",
+        "autoprefixer": "^10.4.13",
+        "postcss": "^8.4.19",
+        "stdf": "^0.1.2",
+        "svelte": "^3.55.1",
+        "svelte-spa-router": "^3.3.0",
+        "tailwindcss": "^3.2.4",
+        "vite": "^4.1.3"
+    }
+}

+ 903 - 0
demo/pnpm-lock.yaml

@@ -0,0 +1,903 @@
+lockfileVersion: '6.0'
+
+devDependencies:
+  '@sveltejs/vite-plugin-svelte':
+    specifier: ^2.0.2
+    version: 2.0.2(svelte@3.55.1)(vite@4.1.3)
+  autoprefixer:
+    specifier: ^10.4.13
+    version: 10.4.13(postcss@8.4.19)
+  postcss:
+    specifier: ^8.4.19
+    version: 8.4.19
+  stdf:
+    specifier: ^0.1.2
+    version: 0.1.2
+  svelte:
+    specifier: ^3.55.1
+    version: 3.55.1
+  svelte-spa-router:
+    specifier: ^3.3.0
+    version: 3.3.0
+  tailwindcss:
+    specifier: ^3.2.4
+    version: 3.2.4(postcss@8.4.19)
+  vite:
+    specifier: ^4.1.3
+    version: 4.1.3
+
+packages:
+
+  /@esbuild/android-arm64@0.16.17:
+    resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/android-arm@0.16.17:
+    resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/android-x64@0.16.17:
+    resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/darwin-arm64@0.16.17:
+    resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/darwin-x64@0.16.17:
+    resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/freebsd-arm64@0.16.17:
+    resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/freebsd-x64@0.16.17:
+    resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-arm64@0.16.17:
+    resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-arm@0.16.17:
+    resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-ia32@0.16.17:
+    resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-loong64@0.16.17:
+    resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==}
+    engines: {node: '>=12'}
+    cpu: [loong64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-mips64el@0.16.17:
+    resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==}
+    engines: {node: '>=12'}
+    cpu: [mips64el]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-ppc64@0.16.17:
+    resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==}
+    engines: {node: '>=12'}
+    cpu: [ppc64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-riscv64@0.16.17:
+    resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==}
+    engines: {node: '>=12'}
+    cpu: [riscv64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-s390x@0.16.17:
+    resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==}
+    engines: {node: '>=12'}
+    cpu: [s390x]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/linux-x64@0.16.17:
+    resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/netbsd-x64@0.16.17:
+    resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [netbsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/openbsd-x64@0.16.17:
+    resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [openbsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/sunos-x64@0.16.17:
+    resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [sunos]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-arm64@0.16.17:
+    resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-ia32@0.16.17:
+    resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@esbuild/win32-x64@0.16.17:
+    resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@jridgewell/sourcemap-codec@1.4.15:
+    resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+    dev: true
+
+  /@nodelib/fs.scandir@2.1.5:
+    resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+    engines: {node: '>= 8'}
+    dependencies:
+      '@nodelib/fs.stat': 2.0.5
+      run-parallel: 1.2.0
+    dev: true
+
+  /@nodelib/fs.stat@2.0.5:
+    resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+    engines: {node: '>= 8'}
+    dev: true
+
+  /@nodelib/fs.walk@1.2.8:
+    resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+    engines: {node: '>= 8'}
+    dependencies:
+      '@nodelib/fs.scandir': 2.1.5
+      fastq: 1.15.0
+    dev: true
+
+  /@sveltejs/vite-plugin-svelte@2.0.2(svelte@3.55.1)(vite@4.1.3):
+    resolution: {integrity: sha512-xCEan0/NNpQuL0l5aS42FjwQ6wwskdxC3pW1OeFtEKNZwRg7Evro9lac9HesGP6TdFsTv2xMes5ASQVKbCacxg==}
+    engines: {node: ^14.18.0 || >= 16}
+    peerDependencies:
+      svelte: ^3.54.0
+      vite: ^4.0.0
+    dependencies:
+      debug: 4.3.4
+      deepmerge: 4.3.1
+      kleur: 4.1.5
+      magic-string: 0.27.0
+      svelte: 3.55.1
+      svelte-hmr: 0.15.2(svelte@3.55.1)
+      vite: 4.1.3
+      vitefu: 0.2.4(vite@4.1.3)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /acorn-node@1.8.2:
+    resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==}
+    dependencies:
+      acorn: 7.4.1
+      acorn-walk: 7.2.0
+      xtend: 4.0.2
+    dev: true
+
+  /acorn-walk@7.2.0:
+    resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
+    engines: {node: '>=0.4.0'}
+    dev: true
+
+  /acorn@7.4.1:
+    resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+    dev: true
+
+  /anymatch@3.1.3:
+    resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+    engines: {node: '>= 8'}
+    dependencies:
+      normalize-path: 3.0.0
+      picomatch: 2.3.1
+    dev: true
+
+  /arg@5.0.2:
+    resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+    dev: true
+
+  /autoprefixer@10.4.13(postcss@8.4.19):
+    resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==}
+    engines: {node: ^10 || ^12 || >=14}
+    hasBin: true
+    peerDependencies:
+      postcss: ^8.1.0
+    dependencies:
+      browserslist: 4.21.7
+      caniuse-lite: 1.0.30001498
+      fraction.js: 4.2.0
+      normalize-range: 0.1.2
+      picocolors: 1.0.0
+      postcss: 8.4.19
+      postcss-value-parser: 4.2.0
+    dev: true
+
+  /binary-extensions@2.2.0:
+    resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /braces@3.0.2:
+    resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+    engines: {node: '>=8'}
+    dependencies:
+      fill-range: 7.0.1
+    dev: true
+
+  /browserslist@4.21.7:
+    resolution: {integrity: sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==}
+    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+    hasBin: true
+    dependencies:
+      caniuse-lite: 1.0.30001498
+      electron-to-chromium: 1.4.427
+      node-releases: 2.0.12
+      update-browserslist-db: 1.0.11(browserslist@4.21.7)
+    dev: true
+
+  /camelcase-css@2.0.1:
+    resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /caniuse-lite@1.0.30001498:
+    resolution: {integrity: sha512-LFInN2zAwx3ANrGCDZ5AKKJroHqNKyjXitdV5zRIVIaQlXKj3GmxUKagoKsjqUfckpAObPCEWnk5EeMlyMWcgw==}
+    dev: true
+
+  /chokidar@3.5.3:
+    resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+    engines: {node: '>= 8.10.0'}
+    dependencies:
+      anymatch: 3.1.3
+      braces: 3.0.2
+      glob-parent: 5.1.2
+      is-binary-path: 2.1.0
+      is-glob: 4.0.3
+      normalize-path: 3.0.0
+      readdirp: 3.6.0
+    optionalDependencies:
+      fsevents: 2.3.2
+    dev: true
+
+  /color-name@1.1.4:
+    resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+    dev: true
+
+  /cssesc@3.0.0:
+    resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+    engines: {node: '>=4'}
+    hasBin: true
+    dev: true
+
+  /debug@4.3.4:
+    resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+    engines: {node: '>=6.0'}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.1.2
+    dev: true
+
+  /deepmerge@4.3.1:
+    resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /defined@1.0.1:
+    resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==}
+    dev: true
+
+  /detective@5.2.1:
+    resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==}
+    engines: {node: '>=0.8.0'}
+    hasBin: true
+    dependencies:
+      acorn-node: 1.8.2
+      defined: 1.0.1
+      minimist: 1.2.8
+    dev: true
+
+  /didyoumean@1.2.2:
+    resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+    dev: true
+
+  /dlv@1.1.3:
+    resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+    dev: true
+
+  /electron-to-chromium@1.4.427:
+    resolution: {integrity: sha512-HK3r9l+Jm8dYAm1ctXEWIC+hV60zfcjS9UA5BDlYvnI5S7PU/yytjpvSrTNrSSRRkuu3tDyZhdkwIczh+0DWaw==}
+    dev: true
+
+  /esbuild@0.16.17:
+    resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==}
+    engines: {node: '>=12'}
+    hasBin: true
+    requiresBuild: true
+    optionalDependencies:
+      '@esbuild/android-arm': 0.16.17
+      '@esbuild/android-arm64': 0.16.17
+      '@esbuild/android-x64': 0.16.17
+      '@esbuild/darwin-arm64': 0.16.17
+      '@esbuild/darwin-x64': 0.16.17
+      '@esbuild/freebsd-arm64': 0.16.17
+      '@esbuild/freebsd-x64': 0.16.17
+      '@esbuild/linux-arm': 0.16.17
+      '@esbuild/linux-arm64': 0.16.17
+      '@esbuild/linux-ia32': 0.16.17
+      '@esbuild/linux-loong64': 0.16.17
+      '@esbuild/linux-mips64el': 0.16.17
+      '@esbuild/linux-ppc64': 0.16.17
+      '@esbuild/linux-riscv64': 0.16.17
+      '@esbuild/linux-s390x': 0.16.17
+      '@esbuild/linux-x64': 0.16.17
+      '@esbuild/netbsd-x64': 0.16.17
+      '@esbuild/openbsd-x64': 0.16.17
+      '@esbuild/sunos-x64': 0.16.17
+      '@esbuild/win32-arm64': 0.16.17
+      '@esbuild/win32-ia32': 0.16.17
+      '@esbuild/win32-x64': 0.16.17
+    dev: true
+
+  /escalade@3.1.1:
+    resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /fast-glob@3.2.12:
+    resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
+    engines: {node: '>=8.6.0'}
+    dependencies:
+      '@nodelib/fs.stat': 2.0.5
+      '@nodelib/fs.walk': 1.2.8
+      glob-parent: 5.1.2
+      merge2: 1.4.1
+      micromatch: 4.0.5
+    dev: true
+
+  /fastq@1.15.0:
+    resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
+    dependencies:
+      reusify: 1.0.4
+    dev: true
+
+  /fill-range@7.0.1:
+    resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      to-regex-range: 5.0.1
+    dev: true
+
+  /fraction.js@4.2.0:
+    resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
+    dev: true
+
+  /fsevents@2.3.2:
+    resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /function-bind@1.1.1:
+    resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+    dev: true
+
+  /glob-parent@5.1.2:
+    resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+    engines: {node: '>= 6'}
+    dependencies:
+      is-glob: 4.0.3
+    dev: true
+
+  /glob-parent@6.0.2:
+    resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+    engines: {node: '>=10.13.0'}
+    dependencies:
+      is-glob: 4.0.3
+    dev: true
+
+  /has@1.0.3:
+    resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+    engines: {node: '>= 0.4.0'}
+    dependencies:
+      function-bind: 1.1.1
+    dev: true
+
+  /is-binary-path@2.1.0:
+    resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+    engines: {node: '>=8'}
+    dependencies:
+      binary-extensions: 2.2.0
+    dev: true
+
+  /is-core-module@2.12.1:
+    resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==}
+    dependencies:
+      has: 1.0.3
+    dev: true
+
+  /is-extglob@2.1.1:
+    resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /is-glob@4.0.3:
+    resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-extglob: 2.1.1
+    dev: true
+
+  /is-number@7.0.0:
+    resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+    engines: {node: '>=0.12.0'}
+    dev: true
+
+  /kleur@4.1.5:
+    resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /lilconfig@2.1.0:
+    resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /magic-string@0.27.0:
+    resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==}
+    engines: {node: '>=12'}
+    dependencies:
+      '@jridgewell/sourcemap-codec': 1.4.15
+    dev: true
+
+  /merge2@1.4.1:
+    resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+    engines: {node: '>= 8'}
+    dev: true
+
+  /micromatch@4.0.5:
+    resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+    engines: {node: '>=8.6'}
+    dependencies:
+      braces: 3.0.2
+      picomatch: 2.3.1
+    dev: true
+
+  /minimist@1.2.8:
+    resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+    dev: true
+
+  /ms@2.1.2:
+    resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+    dev: true
+
+  /nanoid@3.3.6:
+    resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
+    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    hasBin: true
+    dev: true
+
+  /node-releases@2.0.12:
+    resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==}
+    dev: true
+
+  /normalize-path@3.0.0:
+    resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /normalize-range@0.1.2:
+    resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /object-hash@3.0.0:
+    resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /path-parse@1.0.7:
+    resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+    dev: true
+
+  /picocolors@1.0.0:
+    resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+    dev: true
+
+  /picomatch@2.3.1:
+    resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+    engines: {node: '>=8.6'}
+    dev: true
+
+  /pify@2.3.0:
+    resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /postcss-import@14.1.0(postcss@8.4.19):
+    resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
+    engines: {node: '>=10.0.0'}
+    peerDependencies:
+      postcss: ^8.0.0
+    dependencies:
+      postcss: 8.4.19
+      postcss-value-parser: 4.2.0
+      read-cache: 1.0.0
+      resolve: 1.22.2
+    dev: true
+
+  /postcss-js@4.0.1(postcss@8.4.19):
+    resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
+    engines: {node: ^12 || ^14 || >= 16}
+    peerDependencies:
+      postcss: ^8.4.21
+    dependencies:
+      camelcase-css: 2.0.1
+      postcss: 8.4.19
+    dev: true
+
+  /postcss-load-config@3.1.4(postcss@8.4.19):
+    resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
+    engines: {node: '>= 10'}
+    peerDependencies:
+      postcss: '>=8.0.9'
+      ts-node: '>=9.0.0'
+    peerDependenciesMeta:
+      postcss:
+        optional: true
+      ts-node:
+        optional: true
+    dependencies:
+      lilconfig: 2.1.0
+      postcss: 8.4.19
+      yaml: 1.10.2
+    dev: true
+
+  /postcss-nested@6.0.0(postcss@8.4.19):
+    resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==}
+    engines: {node: '>=12.0'}
+    peerDependencies:
+      postcss: ^8.2.14
+    dependencies:
+      postcss: 8.4.19
+      postcss-selector-parser: 6.0.13
+    dev: true
+
+  /postcss-selector-parser@6.0.13:
+    resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==}
+    engines: {node: '>=4'}
+    dependencies:
+      cssesc: 3.0.0
+      util-deprecate: 1.0.2
+    dev: true
+
+  /postcss-value-parser@4.2.0:
+    resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+    dev: true
+
+  /postcss@8.4.19:
+    resolution: {integrity: sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==}
+    engines: {node: ^10 || ^12 || >=14}
+    dependencies:
+      nanoid: 3.3.6
+      picocolors: 1.0.0
+      source-map-js: 1.0.2
+    dev: true
+
+  /postcss@8.4.24:
+    resolution: {integrity: sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==}
+    engines: {node: ^10 || ^12 || >=14}
+    dependencies:
+      nanoid: 3.3.6
+      picocolors: 1.0.0
+      source-map-js: 1.0.2
+    dev: true
+
+  /queue-microtask@1.2.3:
+    resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+    dev: true
+
+  /quick-lru@5.1.1:
+    resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /read-cache@1.0.0:
+    resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+    dependencies:
+      pify: 2.3.0
+    dev: true
+
+  /readdirp@3.6.0:
+    resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+    engines: {node: '>=8.10.0'}
+    dependencies:
+      picomatch: 2.3.1
+    dev: true
+
+  /regexparam@2.0.1:
+    resolution: {integrity: sha512-zRgSaYemnNYxUv+/5SeoHI0eJIgTL/A2pUtXUPLHQxUldagouJ9p+K6IbIZ/JiQuCEv2E2B1O11SjVQy3aMCkw==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /resolve@1.22.2:
+    resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
+    hasBin: true
+    dependencies:
+      is-core-module: 2.12.1
+      path-parse: 1.0.7
+      supports-preserve-symlinks-flag: 1.0.0
+    dev: true
+
+  /reusify@1.0.4:
+    resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+    engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+    dev: true
+
+  /rollup@3.24.1:
+    resolution: {integrity: sha512-REHe5dx30ERBRFS0iENPHy+t6wtSEYkjrhwNsLyh3qpRaZ1+aylvMUdMBUHWUD/RjjLmLzEvY8Z9XRlpcdIkHA==}
+    engines: {node: '>=14.18.0', npm: '>=8.0.0'}
+    hasBin: true
+    optionalDependencies:
+      fsevents: 2.3.2
+    dev: true
+
+  /run-parallel@1.2.0:
+    resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+    dependencies:
+      queue-microtask: 1.2.3
+    dev: true
+
+  /source-map-js@1.0.2:
+    resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /stdf@0.1.2:
+    resolution: {integrity: sha512-TY8zDvUSiDoa7i4UD3A66mHp3bDGxDv9Y5RCdpNYRDcxKE0PnPZUO6HGgGZbMhHay60Qp2ZN9sm7LA1+qK7mBw==}
+    dev: true
+
+  /supports-preserve-symlinks-flag@1.0.0:
+    resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /svelte-hmr@0.15.2(svelte@3.55.1):
+    resolution: {integrity: sha512-q/bAruCvFLwvNbeE1x3n37TYFb3mTBJ6TrCq6p2CoFbSTNhDE9oAtEfpy+wmc9So8AG0Tja+X0/mJzX9tSfvIg==}
+    engines: {node: ^12.20 || ^14.13.1 || >= 16}
+    peerDependencies:
+      svelte: ^3.19.0 || ^4.0.0-next.0
+    dependencies:
+      svelte: 3.55.1
+    dev: true
+
+  /svelte-spa-router@3.3.0:
+    resolution: {integrity: sha512-cwRNe7cxD43sCvSfEeaKiNZg3FCizGxeMcf7CPiWRP3jKXjEma3vxyyuDtPOam6nWbVxl9TNM3hlE/i87ZlqcQ==}
+    dependencies:
+      regexparam: 2.0.1
+    dev: true
+
+  /svelte@3.55.1:
+    resolution: {integrity: sha512-S+87/P0Ve67HxKkEV23iCdAh/SX1xiSfjF1HOglno/YTbSTW7RniICMCofWGdJJbdjw3S+0PfFb1JtGfTXE0oQ==}
+    engines: {node: '>= 8'}
+    dev: true
+
+  /tailwindcss@3.2.4(postcss@8.4.19):
+    resolution: {integrity: sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==}
+    engines: {node: '>=12.13.0'}
+    hasBin: true
+    peerDependencies:
+      postcss: ^8.0.9
+    dependencies:
+      arg: 5.0.2
+      chokidar: 3.5.3
+      color-name: 1.1.4
+      detective: 5.2.1
+      didyoumean: 1.2.2
+      dlv: 1.1.3
+      fast-glob: 3.2.12
+      glob-parent: 6.0.2
+      is-glob: 4.0.3
+      lilconfig: 2.1.0
+      micromatch: 4.0.5
+      normalize-path: 3.0.0
+      object-hash: 3.0.0
+      picocolors: 1.0.0
+      postcss: 8.4.19
+      postcss-import: 14.1.0(postcss@8.4.19)
+      postcss-js: 4.0.1(postcss@8.4.19)
+      postcss-load-config: 3.1.4(postcss@8.4.19)
+      postcss-nested: 6.0.0(postcss@8.4.19)
+      postcss-selector-parser: 6.0.13
+      postcss-value-parser: 4.2.0
+      quick-lru: 5.1.1
+      resolve: 1.22.2
+    transitivePeerDependencies:
+      - ts-node
+    dev: true
+
+  /to-regex-range@5.0.1:
+    resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+    engines: {node: '>=8.0'}
+    dependencies:
+      is-number: 7.0.0
+    dev: true
+
+  /update-browserslist-db@1.0.11(browserslist@4.21.7):
+    resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
+    hasBin: true
+    peerDependencies:
+      browserslist: '>= 4.21.0'
+    dependencies:
+      browserslist: 4.21.7
+      escalade: 3.1.1
+      picocolors: 1.0.0
+    dev: true
+
+  /util-deprecate@1.0.2:
+    resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+    dev: true
+
+  /vite@4.1.3:
+    resolution: {integrity: sha512-0Zqo4/Fr/swSOBmbl+HAAhOjrqNwju+yTtoe4hQX9UsARdcuc9njyOdr6xU0DDnV7YP0RT6mgTTOiRtZgxfCxA==}
+    engines: {node: ^14.18.0 || >=16.0.0}
+    hasBin: true
+    peerDependencies:
+      '@types/node': '>= 14'
+      less: '*'
+      sass: '*'
+      stylus: '*'
+      sugarss: '*'
+      terser: ^5.4.0
+    peerDependenciesMeta:
+      '@types/node':
+        optional: true
+      less:
+        optional: true
+      sass:
+        optional: true
+      stylus:
+        optional: true
+      sugarss:
+        optional: true
+      terser:
+        optional: true
+    dependencies:
+      esbuild: 0.16.17
+      postcss: 8.4.24
+      resolve: 1.22.2
+      rollup: 3.24.1
+    optionalDependencies:
+      fsevents: 2.3.2
+    dev: true
+
+  /vitefu@0.2.4(vite@4.1.3):
+    resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==}
+    peerDependencies:
+      vite: ^3.0.0 || ^4.0.0
+    peerDependenciesMeta:
+      vite:
+        optional: true
+    dependencies:
+      vite: 4.1.3
+    dev: true
+
+  /xtend@4.0.2:
+    resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
+    engines: {node: '>=0.4'}
+    dev: true
+
+  /yaml@1.10.2:
+    resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
+    engines: {node: '>= 6'}
+    dev: true

+ 7 - 0
demo/postcss.config.cjs

@@ -0,0 +1,7 @@
+import tailwind from 'tailwindcss';
+import tailwindConfig from './tailwind.config.cjs';
+import autoprefixer from 'autoprefixer';
+
+export default {
+    plugins: [tailwind(tailwindConfig), autoprefixer],
+};

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
demo/public/assets/fonts/symbol.svg


BIN=BIN
demo/public/assets/images/airpods-pro2.png


BIN=BIN
demo/public/assets/images/avatar_1.jpg


BIN=BIN
demo/public/assets/images/avatar_2.png


BIN=BIN
demo/public/assets/images/dota_小牛.png


BIN=BIN
demo/public/assets/images/dota_斯温.png


BIN=BIN
demo/public/assets/images/dota_水人.png


BIN=BIN
demo/public/assets/images/dota_火女.png


BIN=BIN
demo/public/assets/images/dota_火枪.png


BIN=BIN
demo/public/assets/images/icon_会员.png


BIN=BIN
demo/public/assets/images/icon_外卖.png


BIN=BIN
demo/public/assets/images/icon_游戏.png


BIN=BIN
demo/public/assets/images/icon_火车票.png


BIN=BIN
demo/public/assets/images/icon_美食.png


BIN=BIN
demo/public/assets/images/icon_评价.png


BIN=BIN
demo/public/assets/images/icon_颁奖.png


BIN=BIN
demo/public/assets/images/wall_1.jpg


BIN=BIN
demo/public/assets/images/wall_2.jpg


BIN=BIN
demo/public/assets/images/wall_3.jpg


BIN=BIN
demo/public/assets/images/wall_4.jpg


BIN=BIN
demo/public/assets/logos/adidas.png


BIN=BIN
demo/public/assets/logos/adobe.png


BIN=BIN
demo/public/assets/logos/apple.png


BIN=BIN
demo/public/assets/logos/chrome.png


BIN=BIN
demo/public/assets/logos/figma.png


BIN=BIN
demo/public/assets/logos/github.png


BIN=BIN
demo/public/assets/logos/google.png


BIN=BIN
demo/public/assets/logos/instagram.png


BIN=BIN
demo/public/assets/logos/microsoft.png


BIN=BIN
demo/public/assets/logos/netflix.png


BIN=BIN
demo/public/assets/logos/nike.png


BIN=BIN
demo/public/assets/logos/pinterest.png


BIN=BIN
demo/public/assets/logos/safari.png


BIN=BIN
demo/public/assets/logos/spotify.png


BIN=BIN
demo/public/assets/logos/starbucks.png


BIN=BIN
demo/public/assets/logos/tik-tok.png


BIN=BIN
demo/public/assets/logos/twitter.png


BIN=BIN
demo/public/assets/logos/youtube.png


BIN=BIN
demo/public/assets/stdf_512px.png


BIN=BIN
demo/public/assets/stdf_dark_512px.png


BIN=BIN
demo/public/favicon.ico


+ 87 - 0
demo/src/App.svelte

@@ -0,0 +1,87 @@
+<script>
+    import { setContext } from 'svelte';
+    import Router, { querystring, location, push } from 'svelte-spa-router';
+    import { routes, routes_en } from './route';
+    import { NavBar, Icon } from '../../../../components';
+    import zh_CN from 'stdf/lang/zh_CN';
+    import en_US from 'stdf/lang/en_US';
+    import menuList from './data/menuList';
+
+    // 循环 menuList,将所有元素的 childs 组成一个数组
+    const menuListArr = menuList.reduce((acc, cur) => {
+        if (cur.childs) {
+            acc.push(...cur.childs);
+        }
+        return acc;
+    }, []);
+
+    const params = new URLSearchParams('?' + $querystring); //获取参数
+    const isIframe = params.get('channel') && params.get('channel') === 'iframe' ? '1' : '0'; //判断是否是iframe
+    setContext('iframe', isIframe); //设置iframe
+    let theme = localStorage.getItem('theme') === 'dark' ? 'dark' : 'light';
+    //截取字符?后面的所有字符
+    let urlLang = window.location.href.split('?')[1];
+    let urlParams = new URLSearchParams(urlLang);
+    // 设置语言
+    const isZh = sessionStorage.getItem('lang') === 'zh_CN';
+    setContext('STDF_lang', isZh ? zh_CN : en_US);
+    $: showLeft = isIframe === '1' ? false : $location !== '/';
+    //手动切换主题
+    const toggleFun = () => {
+        if (theme === 'dark') {
+            // 切换到light
+            theme = 'light';
+            localStorage.setItem('theme', 'light');
+            document.documentElement.classList.remove('dark');
+        } else {
+            // 切换到dark
+            theme = 'dark';
+            localStorage.setItem('theme', 'dark');
+            document.documentElement.classList.add('dark');
+        }
+    };
+    const toHomeFun = () => {
+        push(`/`);
+    };
+</script>
+
+<main class="bg-gray9 dark:bg-gray5 text-black dark:text-white/90 relative min-h-screen text-justify w-screen antialiased">
+    <div class="sticky z-10 top-0">
+        <NavBar
+            left={showLeft ? 'back' : ''}
+            title={$location === '/'
+                ? isZh
+                    ? 'STDF 示例'
+                    : 'STDF Demo'
+                : menuListArr.filter(item => item.nav === $location.substring(1))[0][isZh ? 'title_zh' : 'title_en'] +
+                  (isZh ? '示例' : ' Demo')}
+            rightSlot
+            on:clickleft={toHomeFun}
+            injClass="bg-white/60 dark:bg-gray1/60 backdrop-blur"
+        >
+            <div slot="right" class="flex text-center">
+                {#if isIframe === '0'}
+                    <div class="h-12 w-10 leading-10">
+                        <a href="https://github.com/dufu1991/stdf" target="_blank" rel="noreferrer">
+                            <Icon name="ri-github-fill" />
+                        </a>
+                    </div>
+                    <div class="h-12 w-10 leading-10">
+                        <a
+                            href={`https://stdf.design${$location === '/' ? '' : `/#/components?nav=${$location.substring(1)}&tab=0`}`}
+                            target="_blank"
+                            rel="noreferrer"
+                        >
+                            <Icon name="ri-compass-line" />
+                        </a>
+                    </div>
+                {/if}
+                <!-- svelte-ignore a11y-click-events-have-key-events -->
+                <div class="h-12 w-10 leading-10" on:click={toggleFun}>
+                    <Icon name={theme === 'dark' ? 'ri-moon-fill' : 'ri-sun-line'} theme={true} />
+                </div>
+            </div>
+        </NavBar>
+    </div>
+    <Router routes={isZh ? routes : routes_en} />
+</main>

+ 34 - 0
demo/src/app.css

@@ -0,0 +1,34 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+*::-webkit-scrollbar {
+    width: 6px;
+}
+*::-webkit-scrollbar-thumb {
+    border-radius: 3px;
+    background-color: rgba(133, 133, 133, 0.3);
+}
+*::-webkit-scrollbar-track {
+    background-color: rgba(133, 133, 133, 0.1);
+}
+
+html {
+    overflow-y: overlay;
+    -webkit-tap-highlight-color: transparent;
+    scrollbar-width: none; /* Firefox */
+}
+body::-webkit-scrollbar {
+    display: none;
+}
+body {
+    -ms-overflow-style: none;
+}
+
+* {
+    -webkit-overflow-scrolling: touch;
+}
+
+button:focus {
+    outline: none;
+}

+ 26 - 0
demo/src/components/Aphorism.svelte

@@ -0,0 +1,26 @@
+<script>
+    // 引入数据
+    // import data
+    import aphorisms from '../data/aphorisms';
+
+    // 显示条数
+    // number of items to display
+    export let num = 0;
+
+    // 是否紧凑模式
+    // whether to use compact mode
+    export let compact = false;
+
+    // 从 aphorisms 随机取出 num 条数据
+    // get num items from aphorisms randomly
+    const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
+</script>
+
+<div class={`${compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5`}>
+    {#each aphorismsList as item}
+        <div class:py-6={num > 1}>
+            <div class="text-sm text-justify">{item.text}</div>
+            <div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
+        </div>
+    {/each}
+</div>

+ 48 - 0
demo/src/data/aphorisms.js

@@ -0,0 +1,48 @@
+export default [
+    { text: '爱是永恒不变的力量,能够超越所有维度,当我归来,你已垂暮,我一次呼吸划过了你一辈子的岁月。', from: '—— 《星际穿越》' },
+    { text: '爱一朵花不猜它能开多久,放宽了心情,把什么都变美了。', from: '—— 郭静《在树上唱歌》' },
+    { text: '不是所有的坚持都有结果,但是总有一些坚持,能从一寸冰封的土地里,培育出十万朵怒放的蔷薇。', from: '—— 八月长安《最好的我们》' },
+    { text: '当没有任何一个人信任你的时候,沉默和坚持就是最好的反击和证明。', from: '—— 《沉默的羔羊》' },
+    { text: '既不回头,何必不忘。既然无缘,何需誓言。今日种种,似水无痕。明夕何夕,君已陌路。', from: '—— 《仙剑奇侠传一》' },
+    { text: '没有值得不值得,只有愿意不愿意。', from: '—— 彩衣' },
+    { text: '每朵云都下落不明,每盏月亮都不知所踪。', from: '—— 八月长安《暗恋》' },
+    { text: '让人类永远保持理智,是一种奢求。', from: '—— MOSS' },
+    { text: '生命的闪耀不坚持到底怎能看到 ,与其苟延残喘不如纵情燃烧 。', from: '—— 《追梦赤子心》' },
+    { text: '生活坏到一定程度就会好起来,因为它无法更坏,努力过后,才知道许多事情,坚持坚持,就过来了。', from: '—— 宫崎骏《千与千寻》' },
+    {
+        text: '我每天醒在鸟声里。我从梦里就听到鸟叫,直到我醒来。我听得出几种极熟悉的叫声,那是每天都叫的,似乎每天都在那个固定的枝头。',
+        from: '—— 汪曾祺',
+    },
+    { text: '我相信人类的勇气可以跨越时间,跨越当下,跨越未来。', from: '—— 《流浪地球2》' },
+    {
+        text: '于千万人之中遇见你所要遇见的人,于千万年之中,时间的无涯的荒野里,没有早一步,也没有晚一步,刚巧赶上了,那也没有别的话可说,惟有轻轻地问一声:“噢,你也在这里吗?”',
+        from: '—— 张爱玲《爱》',
+    },
+    { text: '御剑乘风来,除魔天地间,有酒乐逍遥,无酒我亦癫。一饮尽江河,再饮吞日月,千杯醉不倒,唯我酒剑仙。', from: '—— 酒剑仙' },
+    { text: '最美的不是下雨天,是曾与你躲过雨的屋檐。', from: '—— 周杰伦《不能说的秘密》' },
+
+    { text: 'All the splendor in the world is not worth a good friend.', from: '— Voltaire' },
+    { text: 'Continuous labor is the life of the iron law, also the art of iron.', from: '— Balzac' },
+    {
+        text: 'Do not go gentle into that good night; Old age should burn and rave at close of day. Rage, rage against the dying of the light.',
+        from: '— Dylan Thomas',
+    },
+    {
+        text: 'Hope is a good thing, maybe the best of things and no good thing ever dies.',
+        from: '— The Shawshank Redemption',
+        fromItalic: true,
+    },
+    { text: 'Honesty and diligence should be your eternal mates.', from: '— Franklin' },
+    { text: 'If a man deceives me once, shame on him; if twice,shame on me.', from: '— John Ray' },
+    { text: 'Life is a kind of endless yearning, eager to continue to rise, become more great and noble.', from: '— Du Charm' },
+    { text: 'The best way to find yourself is to lose yourself in the service of others.', from: '— Gandhi' },
+    { text: 'The best way to cheer yourself up is to try to cheer somebody else up.', from: '— Mark Twain' },
+    {
+        text: 'The body is always in the end. In addition to thinking, there is no beautiful and interesting things to stay, because thought is life.',
+        from: '— Bernard Shaw',
+    },
+    {
+        text: "We should not be at any price to keep our friendship, so that it is defiled. If you have to sacrifice friendship for that great love, that's no way to do it; but if you can keep it, it will be a perfect state.",
+        from: '— Tagore',
+    },
+];

+ 371 - 0
demo/src/data/menuList.js

@@ -0,0 +1,371 @@
+export default [
+    {
+        class: '通用',
+        class_en: 'Universal',
+        childs: [
+            {
+                title: '按钮 Button',
+                title_zh: '按钮',
+                title_en: 'Button',
+                nav: 'button',
+                tip: '按下它,让世界变得更美好吧。',
+                tip_en: 'Press it and make the world a better place.',
+                alias: 'button|按钮',
+            },
+            {
+                title: '底部浮窗 BottomSheet',
+                title_zh: '底部浮窗',
+                title_en: 'BottomSheet',
+                nav: 'bottomSheet',
+                tip: '浮窗犹如小偷,突然出现让你焦灼,却也能唤起你的警觉。',
+                tip_en: 'The floating window is like a thief, suddenly appearing to make you anxious, but it can also arouse your alertness.',
+                alias: 'bottomSheet|底部浮窗|底部|底|部|浮窗|bottomSheet底部浮窗|bottomSheet 底部浮窗|底部弹窗|bottomSheet底部弹窗|bottomSheet 底部弹窗|底部弹出框|bottomSheet底部弹出框|bottomSheet 底部弹出框|底部弹出层|bottomSheet底部弹出层|bottomSheet 底部弹出层',
+            },
+            {
+                title: '图标 Icon',
+                title_zh: '图标',
+                title_en: 'Icon',
+                nav: 'icon',
+                tip: '使用 SVG Sprites,请参照指南引入与使用。',
+                tip_en: 'Use SVG Sprites, please refer to the guide to import and use.',
+                alias: 'icon|图标|svg',
+            },
+            {
+                title: '遮罩 Mask',
+                title_zh: '遮罩',
+                title_en: 'Mask',
+                nav: 'mask',
+                tip: '遮罩虽能掩盖身形,却无法掩藏内心。',
+                tip_en: 'Although the mask can cover the figure, it cannot hide the heart.',
+                alias: 'mask|遮罩|遮|罩|mask遮罩|mask 遮罩|遮罩层|mask遮罩层|mask 遮罩层|Overlay|maskOverlay|mask Overlay',
+            },
+            {
+                title: '弹出层 Popup',
+                title_zh: '弹出层',
+                title_en: 'Popup',
+                nav: 'popup',
+                tip: '机会就像弹珠,只有你努力地推它,它才会弹出来。',
+                tip_en: 'Opportunity is like a marble, only if you push it hard, it will pop out.',
+                alias: 'popup|弹出层|弹出|弹|出|层|popup弹出层|popup 弹出层|弹窗|popup弹窗|popup 弹窗|弹出框|popup弹出框|popup 弹出框|弹出层|popup弹出层|popup 弹出层',
+            },
+        ],
+    },
+    {
+        class: '布局',
+        class_en: 'Layout',
+        childs: [
+            {
+                title: '分割线 Divider',
+                title_zh: '分割线',
+                title_en: 'Divider',
+                nav: 'divider',
+                tip: '分开的日子越久,最初的喜悦越发淡薄。',
+                tip_en: 'The longer the days are separated, the more the initial joy fades.',
+                alias: 'divider|分割线|分割|line',
+            },
+            {
+                title: '网格 Grids',
+                title_zh: '网格',
+                title_en: 'Grids',
+                nav: 'grids',
+                tip: '可是怎么说,总觉得,我们之间留了太多空白格。',
+                tip_en: 'How can I say, I always feel that there are too many blank grids between us.',
+                alias: 'grids|网格|grid|row|col|column',
+            },
+            {
+                title: '占位符 Placeholder',
+                title_zh: '占位符',
+                title_en: 'Placeholder',
+                nav: 'placeholder',
+                tip: '人生重要的不是所站的位置,而是所朝的方向。',
+                tip_en: 'What is important in life is not the position you stand, but the direction you face.',
+                alias: 'placeholder|占位符|占位',
+            },
+            {
+                title: '骨架屏 Skeleton',
+                title_zh: '骨架屏',
+                title_en: 'Skeleton',
+                nav: 'skeleton',
+                tip: '骨架是支撑身体的关键,而人生信念则是支撑生命的骨架。',
+                tip_en: 'The skeleton is the key to supporting the body, and the belief in life is the skeleton that supports life.',
+                alias: 'skeleton|骨架屏|骨架',
+            },
+        ],
+    },
+    {
+        class: '导航',
+        class_en: 'Navigation',
+        childs: [
+            {
+                title: '索引栏 IndexBar',
+                title_zh: '索引栏',
+                title_en: 'IndexBar',
+                nav: 'indexBar',
+                tip: '你不迷途知返,我怎么给你以索引?',
+                tip_en: "If you don't know the way back, how can I give you an index?",
+                alias: 'indexBar|索引栏|indexbar|index|bar|索引|index 栏|索引条|index条|index 条',
+            },
+            {
+                title: '导航栏 NavBar',
+                title_zh: '导航栏',
+                title_en: 'NavBar',
+                nav: 'navBar',
+                tip: '没有指引,在黑暗中只能乱撞。',
+                tip_en: 'Without guidance, you can only bump in the dark.',
+                alias: 'navBar|导航栏|navbar|nav|bar|导航|nav-bar|nav bar',
+            },
+            {
+                title: '分页 Pagination',
+                title_zh: '分页',
+                title_en: 'Pagination',
+                nav: 'pagination',
+                tip: '人生就像一部电影,不论多么精彩,也有谢幕的时候。',
+                tip_en: 'Life is like a movie, no matter how wonderful it is, there is a curtain call.',
+                alias: 'pagination|分页|page|分|页|pagination分页|pagination 分页|page分页|page 分页',
+            },
+            {
+                title: '步骤条 Steps',
+                title_zh: '步骤条',
+                title_en: 'Steps',
+                nav: 'steps',
+                tip: '人生没有白走的路,每一步都算数。',
+                tip_en: 'Life has no wasted steps, every step counts.',
+                alias: 'steps|step|步骤条|步骤|step条|step 条|步骤栏|step栏|step 栏',
+            },
+            {
+                title: '标签栏 TabBar',
+                title_zh: '标签栏',
+                title_en: 'TabBar',
+                nav: 'tabBar',
+                tip: '看脚下一片黑暗,望头顶星光璀璨。',
+                tip_en: "Looking down, it's all darkness; looking up, the stars are shining brightly.",
+                alias: 'tabBar|标签栏|tabbar|tab|bar|标签|tab 栏',
+            },
+            {
+                title: '标签页 Tabs',
+                title_zh: '标签页',
+                title_en: 'Tabs',
+                nav: 'tabs',
+                tip: '偶尔隐藏,是为了在合适的时候更好地绽放。',
+                tip_en: 'Occasionally hide, it is to bloom better at the right time.',
+                alias: 'tabs|tab|标签页|标签|tab页',
+            },
+        ],
+    },
+    {
+        class: '数据输入',
+        class_en: 'Data entry',
+        childs: [
+            {
+                title: '动作面板 ActionSheet',
+                title_zh: '动作面板',
+                title_en: 'ActionSheet',
+                nav: 'actionSheet',
+                tip: '我的世界只有一个选项,就是你。',
+                tip_en: 'There is only one option in my world, and that is you.',
+                alias: 'actionSheet|动作面板|动作|动|作|面板|actionSheet动作面板|actionSheet 动作面板|动作面板|actionSheet动作面板|actionSheet 动作面板|动作面板|actionSheet动作面板|actionSheet 动作面板',
+            },
+            {
+                title: '异步选择器 AsyncPicker',
+                title_zh: '异步选择器',
+                title_en: 'AsyncPicker',
+                nav: 'asyncPicker',
+                tip: '错过的话,就请错过一辈子吧!',
+                tip_en: 'If you miss it, please miss it for a lifetime!',
+                alias: 'asyncPicker|异步选择器|异步|asyncPicker异步选择器|asyncPicker 异步选择器|async picker|asyncpicker|异步picker|异步picker',
+            },
+            {
+                title: '日历 Calendar',
+                title_zh: '日历',
+                title_en: 'Calendar',
+                nav: 'calendar',
+                tip: '在无人问津日子里,正是登峰造极的好时机。',
+                tip_en: 'In the days when no one cares, it is a good time to reach the peak.',
+                alias: 'calendar|日历|日|历|calendar日历|calendar 日历|日期|calendar日期|calendar 日期|周选择|calendar周选择|calendar 周选择|周|calendar周|calendar 周|日期区间|月选择|日期范围选择',
+            },
+            {
+                title: '复选框 Checkbox',
+                title_zh: '复选框',
+                title_en: 'Checkbox',
+                nav: 'checkbox',
+                tip: '要么全不,要么全部。',
+                tip_en: 'Either all or none.',
+                alias: 'checkbox|复选框|复选|checkbox复选框|checkbox 复选框|复选按钮|checkbox复选按钮|checkbox 复选按钮|多选框|多选|checkbox多选框|checkbox 多选框|多选按钮|checkbox多选按钮|checkbox 多选按钮',
+            },
+            {
+                title: '输入框 Input',
+                title_zh: '输入框',
+                title_en: 'Input',
+                nav: 'input',
+                tip: '对方正在输入......',
+                tip_en: 'The other party is typing...',
+                alias: 'input|输入框|输入|input输入框|input 输入框|Textarea|textarea|文本域|文本框|文本|textarea文本域|textarea 文本域|多行输入框|多行输入|多行|textarea多行输入框|textarea 多行输入框',
+            },
+            {
+                title: '选择器 Picker',
+                title_zh: '选择器',
+                title_en: 'Picker',
+                nav: 'picker',
+                tip: '采摘花瓣时,你得不到花的美丽。',
+                tip_en: 'When you pick petals, you don’t get the beauty of the flower.',
+                alias: 'picker|选择器|选择|picker选择器|picker 选择器',
+            },
+            {
+                title: '单选框 Radio',
+                title_zh: '单选框',
+                title_en: 'Radio',
+                nav: 'radio',
+                tip: '如果要在正确和善良中选择一个,请选择善良。',
+                tip_en: 'If you have to choose between right and good, choose good.',
+                alias: 'radio|单选框|单选|radio单选框|radio 单选框|单选按钮|radio单选按钮|radio 单选按钮',
+            },
+            {
+                title: '评分 Rate',
+                title_zh: '评分',
+                title_en: 'Rate',
+                nav: 'rate',
+                tip: '散场时,对方剩余的手机电量,就是这场约会的评分。',
+                tip_en: 'At the end of the game, the remaining battery power of the other party is the score of this date.',
+                alias: 'rate|评分|评|分|rate评分|rate 评分',
+            },
+            {
+                title: '滑块 Slider',
+                title_zh: '滑块',
+                title_en: 'Slider',
+                nav: 'slider',
+                tip: '请滑动解锁您的烦恼。',
+                tip_en: 'Please slide to unlock your troubles.',
+                alias: 'slider|滑块|滑|块|slider滑块|slider 滑块',
+            },
+            {
+                title: '开关 Switch',
+                title_zh: '开关',
+                title_en: 'Switch',
+                nav: 'switch',
+                tip: '死亡是一个开关,活着却是一根绳索。',
+                tip_en: 'Death is a switch, but life is a rope.',
+                alias: 'switch|开关|开|关|switch开关|switch 开关',
+            },
+            {
+                title: '时间选择器 TimePicker',
+                title_zh: '时间选择器',
+                title_en: 'TimePicker',
+                nav: 'timePicker',
+                tip: '死亡不是失去生命,而是走出了时间的枷锁。',
+                tip_en: 'Death is not the loss of life, but the release of the shackles of time.',
+                alias: 'timePicker|时间选择器|时间|timePicker时间选择器|timePicker 时间选择器|time picker|timepicker|时间picker|时间picker|日期选择器|日期|datePicker日期选择器|datePicker 日期选择器|date picker|datepicker|日期picker|日期picker',
+            },
+        ],
+    },
+    {
+        class: '信息展示',
+        class_en: 'Info display',
+        childs: [
+            {
+                title: '头像 Avatar',
+                title_zh: '头像',
+                title_en: 'Avatar',
+                nav: 'avatar',
+                tip: '其实我发给您的头像,是情侣头像...',
+                tip_en: 'Actually, the avatar I sent to you is a couple avatar...',
+                alias: 'avatar|头像|头|像|avatar头像|avatar 头像',
+            },
+            {
+                title: '徽标 Badge',
+                title_zh: '徽标',
+                title_en: 'Badge',
+                nav: 'badge',
+                tip: '在标记消失之前,回到我身边。',
+                tip_en: 'Before the mark disappears, come back to me.',
+                alias: 'badge|徽标|徽|标|badge徽标|badge 徽标|标记|badge标记|badge 标记',
+            },
+            {
+                title: '单元格 Cell',
+                title_zh: '单元格',
+                title_en: 'Cell',
+                nav: 'cell',
+                tip: '当全世界抛弃您的时候请记住,您身上有几亿细胞都在为你而活。',
+                tip_en: 'When the whole world abandons you, remember that there are billions of cells on your body that are living for you.',
+                alias: 'cell|单元格|单元|cell单元格|cell 单元格',
+            },
+            {
+                title: '通告栏 NoticeBar',
+                title_zh: '通告栏',
+                title_en: 'NoticeBar',
+                nav: 'noticeBar',
+                tip: '我方开放地下城,这是告知,不是商量。',
+                tip_en: 'Our side opens the dungeon, this is to inform, not to discuss.',
+                alias: 'noticeBar|通告栏|通告|通|栏|noticeBar通告栏|noticeBar 通告栏|通知栏|noticeBar通知栏|noticeBar 通知栏|公告栏|noticeBar公告栏|noticeBar 公告栏',
+            },
+            {
+                title: '进度条 Progress',
+                title_zh: '进度条',
+                title_en: 'Progress',
+                nav: 'progress',
+                tip: '好运进度:▓▓▓▓▓▓▓▓▓▓▓▓ 100%',
+                tip_en: 'Good luck progr: ▓▓▓▓▓▓▓▓▓▓▓▓ 100%',
+                alias: 'progress|进度条|进度|进|度|progress进度条|progress 进度条',
+            },
+            {
+                title: '进度环 ProgressLoop',
+                title_zh: '进度环',
+                title_en: 'ProgressLoop',
+                nav: 'progressLoop',
+                tip: '人生不是一个完美的圆环,一旦完美,你就再没有任何可能性。',
+                tip_en: 'Life is not a perfect circle. Once perfect, you have no possibility.',
+                alias: 'progressLoop|进度环|进度|进|度|progressLoop进度环|progressLoop 进度环|环形进度条|progressLoop环形进度条|progressLoop 环形进度条|progress loop|progress-loop',
+            },
+            {
+                title: '轮播 Swiper',
+                title_zh: '轮播',
+                title_en: 'Swiper',
+                nav: 'swiper',
+                tip: '人世间悲喜烂剧,昼夜轮播不停。',
+                tip_en: 'The ups and downs of life, day and night, are not stopping.',
+                alias: 'swiper|轮播|轮|播|swiper轮播|swiper 轮播|轮播图|swiper轮播图|swiper 轮播图|走马灯|swiper走马灯|swiper 走马灯|carousel',
+            },
+        ],
+    },
+    {
+        class: '反馈',
+        class_en: 'Feedback',
+        childs: [
+            {
+                title: '对话框 Dialog',
+                title_zh: '对话框',
+                title_en: 'Dialog',
+                nav: 'dialog',
+                tip: '无法确定任何事情,尤其是按下“确定”键的那一刻,我最不确定。',
+                tip_en: 'Nothing can be determined, especially at the moment when the "OK" button is pressed, I am the most uncertain.',
+                alias: 'dialog|对话框|对话|对|话|框|dialog对话框|dialog 对话框|对话框|dialog对话框|dialog 对话框|对话框|dialog对话框|dialog 对话框|对话框|dialog对话框|dialog 对话框',
+            },
+            {
+                title: '加载 Loading',
+                title_zh: '加载',
+                title_en: 'Loading',
+                nav: 'loading',
+                tip: '不要再苦苦等待答案了,没有回复已是答案。',
+                tip_en: "Don't wait for the answer, no reply is the answer.",
+                alias: 'loading|加载|加载中|loading加载|loading 加载|loading加载中|loading 加载中|loading加载中...|loading 加载中...',
+            },
+            {
+                title: '弹框 Modal',
+                title_zh: '弹框',
+                title_en: 'Modal',
+                nav: 'modal',
+                tip: '弹框即人生,要么选择关闭,要么选择继续。',
+                tip_en: 'The modal is life, either choose to close or choose to continue.',
+                alias: 'modal|弹框|弹|框|modal弹框|modal 弹框|弹窗|modal弹窗|modal 弹窗|弹出框|modal弹出框|modal 弹出框|弹框|modal弹框|modal 弹框|模态框|modal模态框|modal 模态框',
+            },
+            {
+                title: '轻提示 Toast',
+                title_zh: '轻提示',
+                title_en: 'Toast',
+                nav: 'toast',
+                tip: '总有一些东西,要用消失来证明它的珍贵。',
+                tip_en: 'There are always some things that have to disappear to prove their value.',
+                alias: 'toast|轻提示|轻|提示|toast轻提示|toast 轻提示|轻弹窗|toast轻弹窗|toast 轻弹窗|轻提示框|toast轻提示框|toast 轻提示框|吐司|toast吐司|toast 吐司',
+            },
+        ],
+    },
+];

+ 58 - 0
demo/src/main.js

@@ -0,0 +1,58 @@
+import App from './App.svelte';
+import './app.css';
+
+//截取字符?后面的所有字符
+let urlLang = window.location.href.split('?')[1];
+let urlParams = new URLSearchParams(urlLang);
+// 设置语言
+let lang = urlParams.get('lang') ? urlParams.get('lang') : sessionStorage.getItem('lang') ? sessionStorage.getItem('lang') : 'zh_CN';
+sessionStorage.setItem('lang', lang);
+setTimeout(() => {
+    window.history.replaceState({}, 0, window.location.href.split('?')[0]);
+}, 300);
+
+// 设置主题
+if (localStorage.getItem('theme') === 'dark') {
+    document.documentElement.classList.add('dark');
+} else if (localStorage.getItem('theme') === 'light') {
+    document.documentElement.classList.remove('dark');
+} else {
+    // if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
+    //     document.documentElement.classList.add('dark');
+    // } else {
+    document.documentElement.classList.remove('dark');
+    // }
+}
+//解决ios不支持按钮:active伪类
+document.body.addEventListener('touchstart', function () {
+    //...空函数即可
+});
+
+// 阻止双击放大
+document.addEventListener('touchstart', function (event) {
+    if (event.touches.length > 1) {
+        event.preventDefault();
+    }
+});
+let lastTouchEnd = 0;
+document.addEventListener(
+    'touchend',
+    function (event) {
+        const now = new Date().getTime();
+        if (now - lastTouchEnd <= 300) {
+            event.preventDefault();
+        }
+        lastTouchEnd = now;
+    },
+    false
+);
+// 阻止双指放大
+document.addEventListener('gesturestart', function (event) {
+    event.preventDefault();
+});
+
+const app = new App({
+    target: document.getElementById('app'),
+});
+
+export default app;

+ 94 - 0
demo/src/pages/actionSheet/ActionSheetDemo.svelte

@@ -0,0 +1,94 @@
+<!-- ActionSheet Demo -->
+<script>
+    import { Cell, ActionSheet, Toast } from '../../../../components';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+    let visible12 = false;
+
+    const actions = [{ content: '选项一' }, { content: '选项二' }, { content: '选项三' }];
+    const actions1 = [
+        { content: '常规选项' },
+        { content: '主题选项', style: 'theme' },
+        { content: '禁用选项', style: 'disabled' },
+        { content: '警告选项', style: 'danger' },
+    ];
+    const actions2 = [
+        { content: '选项一' },
+        { content: '选项二', desc: '这里是描述信息' },
+        { content: '选项三', style: 'danger', desc: '这里是描述信息' },
+    ];
+    const action3 = [
+        { content: '火女', showImg: true, imgSrc: './assets/images/dota_火女.png', imgRadius: 'base' },
+        { content: '小牛', showImg: true, imgSrc: './assets/images/dota_小牛.png', imgRadius: 'base' },
+        { content: '水人', showImg: true, imgSrc: './assets/images/dota_水人.png', imgRadius: 'base' },
+    ];
+    const action4 = [
+        { content: 'Apple', showImg: true, imgSrc: './assets/logos/apple.png', imgRadius: 'none' },
+        { content: 'Google', showImg: true, imgSrc: './assets/logos/google.png', imgRadius: 'none' },
+        { content: 'Microsoft', showImg: true, imgSrc: './assets/logos/microsoft.png', imgRadius: 'none' },
+        { content: 'Adobe', showImg: true, imgSrc: './assets/logos/adobe.png', imgRadius: 'none' },
+        { content: 'Figma', showImg: true, imgSrc: './assets/logos/figma.png', imgRadius: 'none' },
+    ];
+
+    let toastVisible1 = false;
+    let toastVisible2 = false;
+    let toastVisible3 = false;
+    let index = 0;
+    let item = {};
+    const clickActionFunc = e => {
+        index = e.detail.index;
+        item = e.detail.item;
+        toastVisible3 = true;
+    };
+</script>
+
+<div class="py-4">
+    <Cell title="基础用法" on:click={() => (visible1 = true)} />
+    <ActionSheet bind:visible={visible1} {actions} />
+
+    <Cell title="有取消操作且点击遮罩不可关闭" on:click={() => (visible2 = true)} />
+    <ActionSheet bind:visible={visible2} {actions} showCancel popup={{ maskClosable: false }} />
+
+    <Cell title="不同样式" on:click={() => (visible3 = true)} />
+    <ActionSheet bind:visible={visible3} actions={actions1} />
+
+    <Cell title="带标题和描述信息" on:click={() => (visible4 = true)} />
+    <ActionSheet bind:visible={visible4} actions={actions2} title="这里是标题,可以简要说明以下操作。" />
+
+    <Cell title="顶部来点圆角" on:click={() => (visible5 = true)} />
+    <ActionSheet bind:visible={visible5} {actions} popup={{ radius: 'xl' }} />
+
+    <Cell title="两侧有间距" on:click={() => (visible6 = true)} />
+    <ActionSheet bind:visible={visible6} {actions} popup={{ radius: 'xl', px: '2' }} />
+
+    <Cell title="监听关闭事件" on:click={() => (visible7 = true)} />
+    <ActionSheet bind:visible={visible7} {actions} on:close={() => (toastVisible1 = true)} />
+    <Toast bind:visible={toastVisible1} message="关闭了 ActionSheet!" />
+
+    <Cell title="监听取消事件" on:click={() => (visible8 = true)} />
+    <ActionSheet bind:visible={visible8} {actions} showCancel on:cancel={() => (toastVisible2 = true)} />
+    <Toast bind:visible={toastVisible2} message="点击了取消!" />
+
+    <Cell title="监听选项点击事件" on:click={() => (visible9 = true)} />
+    <ActionSheet bind:visible={visible9} {actions} on:clickAction={clickActionFunc} />
+    <Toast bind:visible={toastVisible3} message={`点击了第 ${index + 1} 项,${item.content}!`} />
+
+    <Cell title="点击选项不关闭" on:click={() => (visible10 = true)} />
+    <ActionSheet bind:visible={visible10} {actions} actionClosable={false} />
+
+    <Cell title="选项带图片" on:click={() => (visible11 = true)} />
+    <ActionSheet bind:visible={visible11} actions={action3} />
+
+    <Cell title="选项左对齐" on:click={() => (visible12 = true)} />
+    <ActionSheet bind:visible={visible12} actions={action4} align="left" />
+</div>

+ 94 - 0
demo/src/pages/actionSheet/ActionSheetDemo_en.svelte

@@ -0,0 +1,94 @@
+<!-- ActionSheet Demo -->
+<script>
+    import { Cell, ActionSheet, Toast } from '../../../../components';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+    let visible12 = false;
+
+    const actions = [{ content: 'Option one' }, { content: 'Option twoion two' }, { content: 'Option three' }];
+    const actions1 = [
+        { content: 'Conventional option' },
+        { content: 'Theme option', style: 'theme' },
+        { content: 'Disable option', style: 'disabled' },
+        { content: 'Warning option', style: 'danger' },
+    ];
+    const actions2 = [
+        { content: 'Option one' },
+        { content: 'Option two', desc: 'Here is description information description information' },
+        { content: 'Option three', style: 'Here is description information' },
+    ];
+    const action3 = [
+        { content: 'Fire girl', showImg: true, imgSrc: './assets/images/dota_火女.png', imgRadius: 'base' },
+        { content: 'calf', showImg: true, imgSrc: './assets/images/dota_小牛.png', imgRadius: 'base' },
+        { content: 'water man', showImg: true, imgSrc: './assets/images/dota_水人.png', imgRadius: 'base' },
+    ];
+    const action4 = [
+        { content: 'Apple', showImg: true, imgSrc: './assets/logos/apple.png', imgRadius: 'none' },
+        { content: 'Google', showImg: true, imgSrc: './assets/logos/google.png', imgRadius: 'none' },
+        { content: 'Microsoft', showImg: true, imgSrc: './assets/logos/microsoft.png', imgRadius: 'none' },
+        { content: 'Adobe', showImg: true, imgSrc: './assets/logos/adobe.png', imgRadius: 'none' },
+        { content: 'Figma', showImg: true, imgSrc: './assets/logos/figma.png', imgRadius: 'none' },
+    ];
+
+    let toastVisible1 = false;
+    let toastVisible2 = false;
+    let toastVisible3 = false;
+    let index = 0;
+    let item = {};
+    const clickActionFunc = e => {
+        index = e.detail.index;
+        item = e.detail.item;
+        toastVisible3 = true;
+    };
+</script>
+
+<div class="py-4">
+    <Cell title="Basic usage" on:click={() => (visible1 = true)} />
+    <ActionSheet bind:visible={visible1} {actions} />
+
+    <Cell title="If you have canceled operation and click on the mask, you cannot turn off" on:click={() => (visible2 = true)} />
+    <ActionSheet bind:visible={visible2} {actions} showCancel popup={{ maskClosable: false }} />
+
+    <Cell title="Different styles" on:click={() => (visible3 = true)} />
+    <ActionSheet bind:visible={visible3} actions={actions1} />
+
+    <Cell title="Title and description information" on:click={() => (visible4 = true)} />
+    <ActionSheet bind:visible={visible4} actions={actions2} title="This is the title, which can be briefly explained." />
+
+    <Cell title="Come on the top" on:click={() => (visible5 = true)} />
+    <ActionSheet bind:visible={visible5} {actions} popup={{ radius: 'xl' }} />
+
+    <Cell title="There is a spacing on both sides" on:click={() => (visible6 = true)} />
+    <ActionSheet bind:visible={visible6} {actions} popup={{ radius: 'xl', px: '2' }} />
+
+    <Cell title="Supervision and closing incident" on:click={() => (visible7 = true)} />
+    <ActionSheet bind:visible={visible7} {actions} on:close={() => (toastVisible1 = true)} />
+    <Toast bind:visible={toastVisible1} message="closed ActionSheet!" />
+
+    <Cell title="Supervision and canceling incident" on:click={() => (visible8 = true)} />
+    <ActionSheet bind:visible={visible8} {actions} showCancel on:cancel={() => (toastVisible2 = true)} />
+    <Toast bind:visible={toastVisible2} message="Click to cancel!" />
+
+    <Cell title="Survening options click event" on:click={() => (visible9 = true)} />
+    <ActionSheet bind:visible={visible9} {actions} on:clickAction={clickActionFunc} />
+    <Toast bind:visible={toastVisible3} message={`Click the ${index + 1} item,${item.content}!`} />
+
+    <Cell title="Click the option not to be closed" on:click={() => (visible10 = true)} />
+    <ActionSheet bind:visible={visible10} {actions} actionClosable={false} />
+
+    <Cell title="Options with pictures" on:click={() => (visible11 = true)} />
+    <ActionSheet bind:visible={visible11} actions={action3} />
+
+    <Cell title="Option left" on:click={() => (visible12 = true)} />
+    <ActionSheet bind:visible={visible12} actions={action4} align="left" />
+</div>

+ 746 - 0
demo/src/pages/asyncPicker/AsyncPickerDemo.svelte

@@ -0,0 +1,746 @@
+<!-- AsyncPicker Demo -->
+<script>
+    import { AsyncPicker, Cell } from '../../../../components';
+    // 为避免 Demo 页面杂乱,具体参考数据放在 data.js 文件内,可查看此页面底部注释。
+    import { linkageData, linkageDiffLabeData } from './data';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+
+    let data = linkageData;
+    let currentLevel = 0;
+    let lastLevel = false;
+    let firstLevel = true;
+    let level1Data = linkageData[0].children;
+    let titleBind = '请选择省级';
+
+    // 模拟 3 秒后获取到数据
+    const nextFunc = e => {
+        const { index } = e.detail;
+        if (currentLevel === 0) {
+            const nextData = linkageData[index].children;
+            level1Data = nextData;
+            setTimeout(() => {
+                data = nextData;
+                currentLevel = 1;
+                titleBind = '请选择市级';
+                firstLevel = false;
+            }, 3000);
+        } else if (currentLevel === 1) {
+            const nextData = level1Data[index].children;
+            setTimeout(() => {
+                data = nextData;
+                currentLevel = 2;
+                titleBind = '请选择区级';
+                lastLevel = true;
+            }, 3000);
+        } else {
+            console.log('最后一级');
+        }
+    };
+    const prevFunc = () => {
+        if (currentLevel === 1) {
+            const prevData = linkageData;
+            setTimeout(() => {
+                data = prevData;
+                currentLevel = 0;
+                titleBind = '请选择省级';
+                firstLevel = true;
+            }, 3000);
+        } else if (currentLevel === 2) {
+            const prevData = level1Data;
+            setTimeout(() => {
+                data = prevData;
+                currentLevel = 1;
+                titleBind = '请选择市级';
+                lastLevel = false;
+            }, 3000);
+        } else {
+            console.log('第一级');
+        }
+    };
+
+    let allIndexs = [];
+    let allItems = [];
+    const getAllDataFunc = e => {
+        const { items, indexs } = e.detail;
+        allItems = items;
+        allIndexs = indexs;
+    };
+
+    // 每一级对应的 labelKey 不同时的处理逻辑
+    let diffLabelKeyData = linkageDiffLabeData;
+    let labelKey = 'province';
+    let diffLabelKeyCurrentLevel = 0;
+    let diffLabelKeyLastLevel = false;
+    let diffLabelKeyFirstLevel = true;
+    let diffLabelKeyLevel1Data = linkageDiffLabeData[0].children;
+    const diffLabelKeyNextFunc = e => {
+        const { index } = e.detail;
+        if (diffLabelKeyCurrentLevel === 0) {
+            const nextData = linkageDiffLabeData[index].children;
+            diffLabelKeyLevel1Data = nextData;
+            setTimeout(() => {
+                diffLabelKeyData = nextData;
+                labelKey = 'city';
+                diffLabelKeyCurrentLevel = 1;
+                diffLabelKeyFirstLevel = false;
+            }, 3000);
+        } else if (diffLabelKeyCurrentLevel === 1) {
+            const nextData = diffLabelKeyLevel1Data[index].children;
+            setTimeout(() => {
+                diffLabelKeyData = nextData;
+                diffLabelKeyCurrentLevel = 2;
+                labelKey = 'region';
+                diffLabelKeyLastLevel = true;
+            }, 3000);
+        } else {
+            console.log('最后一级');
+        }
+    };
+    const diffLabelKeyPrevFunc = () => {
+        if (diffLabelKeyCurrentLevel === 1) {
+            const prevData = linkageDiffLabeData;
+            setTimeout(() => {
+                diffLabelKeyData = prevData;
+                diffLabelKeyCurrentLevel = 0;
+                diffLabelKeyFirstLevel = true;
+                labelKey = 'province';
+            }, 3000);
+        } else if (diffLabelKeyCurrentLevel === 2) {
+            const prevData = diffLabelKeyLevel1Data;
+            setTimeout(() => {
+                diffLabelKeyData = prevData;
+                diffLabelKeyCurrentLevel = 1;
+                labelKey = 'city';
+                diffLabelKeyLastLevel = false;
+            }, 3000);
+        } else {
+            console.log('第一级');
+        }
+    };
+</script>
+
+<div class="py-4">
+    <div class="px-4">
+        {#if allItems.length}
+            当前选定了:
+            {#each allItems as item}
+                <span class="mr-2 text-primary dark:text-dark">{item.label}</span>
+            {/each}
+        {:else}
+            <div>请选定数据</div>
+        {/if}
+    </div>
+    <div class="px-4">
+        {#if allIndexs.length}
+            当前选定值位于所在列的索引值分别为:
+            {#each allIndexs as index}
+                <span class="mr-2 text-primary dark:text-dark">{index}</span>
+            {/each}
+        {:else}
+            <div>请选定数据</div>
+        {/if}
+    </div>
+    <Cell
+        title="基础用法"
+        on:click={() => {
+            visible1 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible1}
+        bind:data
+        bind:lastLevel
+        bind:firstLevel
+        on:next={nextFunc}
+        on:prev={prevFunc}
+        on:confirm={getAllDataFunc}
+    />
+
+    <Cell
+        title="可见 7 行数为"
+        on:click={() => {
+            visible2 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker bind:visible={visible2} bind:data bind:lastLevel bind:firstLevel on:next={nextFunc} on:prev={prevFunc} showRow={7} />
+
+    <Cell
+        title="左对齐"
+        on:click={() => {
+            visible3 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker bind:visible={visible3} bind:data bind:lastLevel bind:firstLevel align="left" on:next={nextFunc} on:prev={prevFunc} />
+
+    <Cell
+        title="自定义上下一步文字"
+        on:click={() => {
+            visible5 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible5}
+        bind:data
+        bind:lastLevel
+        bind:firstLevel
+        on:next={nextFunc}
+        on:prev={prevFunc}
+        nextText="继续"
+        prevText="返回"
+    />
+
+    <Cell
+        title="不同级别使用不同的 labelKey"
+        on:click={() => {
+            visible4 = true;
+            diffLabelKeyData = linkageDiffLabeData;
+            labelKey = 'province';
+            diffLabelKeyCurrentLevel = 0;
+            diffLabelKeyLastLevel = false;
+            diffLabelKeyFirstLevel = true;
+            diffLabelKeyLevel1Data = linkageDiffLabeData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible4}
+        bind:data={diffLabelKeyData}
+        bind:lastLevel={diffLabelKeyLastLevel}
+        bind:firstLevel={diffLabelKeyFirstLevel}
+        bind:labelKey
+        on:next={diffLabelKeyNextFunc}
+        on:prev={diffLabelKeyPrevFunc}
+    />
+
+    <Cell
+        title="换一个 Loading 效果"
+        on:click={() => {
+            visible6 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible6}
+        bind:data
+        bind:lastLevel
+        bind:firstLevel
+        on:next={nextFunc}
+        on:prev={prevFunc}
+        loading={{ type: '1_15', width: 12, height: 12 }}
+    />
+
+    <Cell
+        title="顶部来点圆角"
+        on:click={() => {
+            visible8 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible8}
+        bind:data
+        bind:lastLevel
+        bind:firstLevel
+        on:next={nextFunc}
+        on:prev={prevFunc}
+        popup={{ radius: 'xl' }}
+    />
+
+    <Cell
+        title="显示已选选项"
+        on:click={() => {
+            visible7 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker bind:visible={visible7} bind:data bind:lastLevel bind:firstLevel on:next={nextFunc} on:prev={prevFunc} showSelected />
+
+    <Cell
+        title="动态改变标题"
+        on:click={() => {
+            visible9 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            titleBind = '请选择省级';
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible9}
+        bind:data
+        bind:lastLevel
+        bind:firstLevel
+        bind:title={titleBind}
+        on:next={nextFunc}
+        on:prev={prevFunc}
+    />
+</div>
+<!-- 
+const linkageData = [
+    {
+        label: '云南',
+        children: [
+            {
+                label: '昆明',
+                children: [
+                    { label: '盘龙区' },
+                    { label: '五华区' },
+                    { label: '官渡区' },
+                    { label: '西山区' },
+                    { label: '东川区' },
+                    { label: '呈贡区' },
+                    { label: '晋宁区' },
+                    { label: '富民县' },
+                    { label: '宜良县' },
+                    { label: '石林彝族自治县' },
+                    { label: '嵩明县' },
+                    { label: '禄劝彝族苗族自治县' },
+                    { label: '寻甸回族彝族自治县' },
+                    { label: '安宁市' },
+                ],
+            },
+            {
+                label: '曲靖',
+                children: [
+                    { label: '麒麟区' },
+                    { label: '沾益区' },
+                    { label: '马龙县' },
+                    { label: '陆良县' },
+                    { label: '师宗县' },
+                    { label: '罗平县' },
+                    { label: '富源县' },
+                    { label: '会泽县' },
+                    { label: '宣威市' },
+                ],
+            },
+            {
+                label: '玉溪',
+                children: [
+                    { label: '红塔区' },
+                    { label: '江川区' },
+                    { label: '澄江县' },
+                    { label: '通海县' },
+                    { label: '华宁县' },
+                    { label: '易门县' },
+                    { label: '峨山彝族自治县' },
+                    { label: '新平彝族傣族自治县' },
+                    { label: '元江哈尼族彝族傣族自治县' },
+                ],
+            },
+            {
+                label: '保山',
+                children: [
+                    { label: '隆阳区' },
+                    { label: '施甸县' },
+                    { label: '龙陵县' },
+                    { label: '昌宁县' },
+                    { label: '腾冲市' },
+                    { label: '龙陵县' },
+                ],
+            },
+            {
+                label: '丽江',
+                children: [
+                    { label: '古城区' },
+                    { label: '永胜县' },
+                    { label: '华坪县' },
+                    { label: '玉龙纳西族自治县' },
+                    { label: '宁蒗彝族自治县' },
+                ],
+            },
+            {
+                label: '普洱',
+                children: [
+                    { label: '思茅区' },
+                    { label: '宁洱哈尼族彝族自治县' },
+                    { label: '墨江哈尼族自治县' },
+                    { label: '景东彝族自治县' },
+                    { label: '景谷傣族彝族自治县' },
+                    { label: '镇沅彝族哈尼族拉祜族自治县' },
+                    { label: '江城哈尼族彝族自治县' },
+                    { label: '孟连傣族拉祜族佤族自治县' },
+                    { label: '澜沧拉祜族自治县' },
+                    { label: '西盟佤族自治县' },
+                ],
+            },
+            {
+                label: '临沧',
+                children: [
+                    { label: '临翔区' },
+                    { label: '凤庆县' },
+                    { label: '云县' },
+                    { label: '永德县' },
+                    { label: '镇康县' },
+                    { label: '双江拉祜族佤族布朗族傣族自治县' },
+                    { label: '耿马傣族佤族自治县' },
+                    { label: '沧源佤族自治县' },
+                ],
+            },
+            {
+                label: '楚雄',
+                children: [
+                    { label: '楚雄市' },
+                    { label: '双柏县' },
+                    { label: '牟定县' },
+                    { label: '南华县' },
+                    { label: '姚安县' },
+                    { label: '大姚县' },
+                    { label: '永仁县' },
+                    { label: '元谋县' },
+                    { label: '武定县' },
+                    { label: '禄丰县' },
+                ],
+            },
+            {
+                label: '红河',
+                children: [
+                    { label: '个旧市' },
+                    { label: '开远市' },
+                    { label: '蒙自市' },
+                    { label: '弥勒市' },
+                    { label: '屏边苗族自治县' },
+                    { label: '建水县' },
+                    { label: '石屏县' },
+                    { label: '泸西县' },
+                    { label: '元阳县' },
+                    { label: '红河县' },
+                    { label: '金平苗族瑶族傣族自治县' },
+                    { label: '绿春县' },
+                    { label: '河口瑶族自治县' },
+                ],
+            },
+            {
+                label: '文山',
+                children: [
+                    { label: '文山市' },
+                    { label: '砚山县' },
+                    { label: '西畴县' },
+                    { label: '麻栗坡县' },
+                    { label: '马关县' },
+                    { label: '丘北县' },
+                    { label: '广南县' },
+                    { label: '富宁县' },
+                ],
+            },
+        ],
+    },
+    {
+        label: '广东',
+        children: [
+            {
+                label: '广州',
+                children: [
+                    { label: '天河区' },
+                    { label: '海珠区' },
+                    { label: '荔湾区' },
+                    { label: '越秀区' },
+                    { label: '白云区' },
+                    { label: '黄埔区' },
+                ],
+            },
+            {
+                label: '深圳',
+                children: [
+                    { label: '罗湖区' },
+                    { label: '福田区' },
+                    { label: '南山区' },
+                    { label: '宝安区' },
+                    { label: '龙岗区' },
+                    { label: '盐田区' },
+                ],
+            },
+            {
+                label: '珠海',
+                children: [{ label: '香洲区' }, { label: '斗门区' }, { label: '金湾区' }],
+            },
+            {
+                label: '汕头',
+                children: [
+                    { label: '龙湖区' },
+                    { label: '金平区' },
+                    { label: '濠江区' },
+                    { label: '潮阳区' },
+                    { label: '潮南区' },
+                    { label: '澄海区' },
+                ],
+            },
+            {
+                label: '佛山',
+                children: [{ label: '禅城区' }, { label: '南海区' }, { label: '顺德区' }, { label: '三水区' }, { label: '高明区' }],
+            },
+        ],
+    },
+    {
+        label: '四川',
+        children: [
+            {
+                label: '成都',
+                children: [
+                    { label: '锦江区' },
+                    { label: '青羊区' },
+                    { label: '金牛区' },
+                    { label: '武侯区' },
+                    { label: '成华区' },
+                    { label: '龙泉驿区' },
+                ],
+            },
+            {
+                label: '绵阳',
+                children: [
+                    { label: '涪城区' },
+                    { label: '游仙区' },
+                    { label: '安州区' },
+                    { label: '三台县' },
+                    { label: '盐亭县' },
+                    { label: '梓潼县' },
+                ],
+            },
+            {
+                label: '自贡',
+                children: [
+                    { label: '自流井区' },
+                    { label: '贡井区' },
+                    { label: '大安区' },
+                    { label: '沿滩区' },
+                    { label: '荣县' },
+                    { label: '富顺县' },
+                ],
+            },
+            {
+                label: '攀枝花',
+                children: [{ label: '东区' }, { label: '西区' }, { label: '仁和区' }, { label: '米易县' }, { label: '盐边县' }],
+            },
+        ],
+    },
+    {
+        label: '北京',
+        children: [
+            {
+                label: '北京市',
+                children: [
+                    { label: '东城区' },
+                    { label: '西城区' },
+                    { label: '朝阳区' },
+                    { label: '丰台区' },
+                    { label: '石景山区' },
+                    { label: '海淀区' },
+                ],
+            },
+        ],
+    },
+    {
+        label: '浙江',
+        children: [
+            {
+                label: '杭州',
+                children: [
+                    { label: '上城区' },
+                    { label: '下城区' },
+                    { label: '江干区' },
+                    { label: '拱墅区' },
+                    { label: '西湖区' },
+                    { label: '滨江区' },
+                ],
+            },
+            {
+                label: '宁波',
+                children: [
+                    { label: '海曙区' },
+                    { label: '江东区' },
+                    { label: '江北区' },
+                    { label: '北仑区' },
+                    { label: '镇海区' },
+                    { label: '鄞州区' },
+                ],
+            },
+            {
+                label: '温州',
+                children: [
+                    { label: '鹿城区' },
+                    { label: '龙湾区' },
+                    { label: '瓯海区' },
+                    { label: '洞头区' },
+                    { label: '永嘉县' },
+                    { label: '平阳县' },
+                ],
+            },
+            {
+                label: '嘉兴',
+                children: [
+                    { label: '南湖区' },
+                    { label: '秀洲区' },
+                    { label: '嘉善县' },
+                    { label: '海盐县' },
+                    { label: '海宁市' },
+                    { label: '平湖市' },
+                ],
+            },
+            {
+                label: '湖州',
+                children: [{ label: '吴兴区' }, { label: '南浔区' }, { label: '德清县' }, { label: '长兴县' }, { label: '安吉县' }],
+            },
+        ],
+    },
+];
+
+const linkageDiffLabeData = [
+    {
+        province: '云南',
+        children: [
+            {
+                city: '昆明',
+                children: [
+                    { region: '盘龙区' },
+                    { region: '五华区' },
+                    { region: '官渡区' },
+                    { region: '西山区' },
+                    { region: '东川区' },
+                    { region: '呈贡区' },
+                    { region: '晋宁区' },
+                    { region: '富民县' },
+                    { region: '宜良县' },
+                    { region: '石林彝族自治县' },
+                    { region: '嵩明县' },
+                    { region: '禄劝彝族苗族自治县' },
+                    { region: '寻甸回族彝族自治县' },
+                    { region: '安宁市' },
+                ],
+            },
+            {
+                city: '曲靖',
+                children: [
+                    { region: '麒麟区' },
+                    { region: '沾益区' },
+                    { region: '马龙县' },
+                    { region: '陆良县' },
+                    { region: '师宗县' },
+                    { region: '罗平县' },
+                    { region: '富源县' },
+                    { region: '会泽县' },
+                    { region: '宣威市' },
+                ],
+            },
+            {
+                city: '玉溪',
+                children: [
+                    { region: '红塔区' },
+                    { region: '江川区' },
+                    { region: '澄江县' },
+                    { region: '通海县' },
+                    { region: '华宁县' },
+                    { region: '易门县' },
+                    { region: '峨山彝族自治县' },
+                    { region: '新平彝族傣族自治县' },
+                    { region: '元江哈尼族彝族傣族自治县' },
+                ],
+            },
+            {
+                city: '保山',
+                children: [
+                    { region: '隆阳区' },
+                    { region: '施甸县' },
+                    { region: '龙陵县' },
+                    { region: '昌宁县' },
+                    { region: '腾冲市' },
+                    { region: '龙陵县' },
+                ],
+            },
+            {
+                city: '丽江',
+                children: [
+                    { region: '古城区' },
+                    { region: '永胜县' },
+                    { region: '华坪县' },
+                    { region: '玉龙纳西族自治县' },
+                    { region: '宁蒗彝族自治县' },
+                ],
+            },
+            {
+                city: '普洱',
+                children: [
+                    { region: '思茅区' },
+                    { region: '宁洱哈尼族彝族自治县' },
+                    { region: '墨江哈尼族自治县' },
+                    { region: '景东彝族自治县' },
+                    { region: '景谷傣族彝族自治县' },
+                    { region: '镇沅彝族哈尼族拉祜族自治县' },
+                    { region: '江城哈尼族彝族自治县' },
+                    { region: '孟连傣族拉祜族佤族自治县' },
+                    { region: '澜沧拉祜族自治县' },
+                    { region: '西盟佤族自治县' },
+                ],
+            },
+        ],
+    },
+    {
+        province: '广东',
+        children: [
+            {
+                city: '广州',
+                children: [
+                    { region: '天河区' },
+                    { region: '海珠区' },
+                    { region: '荔湾区' },
+                    { region: '越秀区' },
+                    { region: '白云区' },
+                    { region: '黄埔区' },
+                ],
+            },
+            {
+                city: '深圳',
+                children: [
+                    { region: '罗湖区' },
+                    { region: '福田区' },
+                    { region: '南山区' },
+                    { region: '宝安区' },
+                    { region: '龙岗区' },
+                    { region: '盐田区' },
+                ],
+            },
+        ],
+    },
+];
+
+export { linkageData, linkageDiffLabeData }; -->

+ 728 - 0
demo/src/pages/asyncPicker/AsyncPickerDemo_en.svelte

@@ -0,0 +1,728 @@
+<!-- AsyncPicker Demo -->
+<script>
+    import { AsyncPicker, Cell } from '../../../../components';
+    // In order to avoid the messy Demo page, the specific reference data is placed in the data.js file, and you can view the bottom of the page.
+    import { linkageData, linkageDiffLabeData } from './data_en';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+
+    let data = linkageData;
+    let currentLevel = 0;
+    let lastLevel = false;
+    let firstLevel = true;
+    let level1Data = linkageData[0].children;
+    let titleBind = 'Please select the provincial level';
+
+    // Get the data after simulation for 3 seconds
+    const nextFunc = e => {
+        const { index } = e.detail;
+        if (currentLevel === 0) {
+            const nextData = linkageData[index].children;
+            level1Data = nextData;
+            setTimeout(() => {
+                data = nextData;
+                currentLevel = 1;
+                titleBind = 'Please select the city level';
+                firstLevel = false;
+            }, 3000);
+        } else if (currentLevel === 1) {
+            const nextData = level1Data[index].children;
+            setTimeout(() => {
+                data = nextData;
+                currentLevel = 2;
+                titleBind = 'Please select the district level';
+                lastLevel = true;
+            }, 3000);
+        } else {
+            console.log('Last Level');
+        }
+    };
+    const prevFunc = () => {
+        if (currentLevel === 1) {
+            const prevData = linkageData;
+            setTimeout(() => {
+                data = prevData;
+                currentLevel = 0;
+                titleBind = 'Please select the provincial level';
+                firstLevel = true;
+            }, 3000);
+        } else if (currentLevel === 2) {
+            const prevData = level1Data;
+            setTimeout(() => {
+                data = prevData;
+                currentLevel = 1;
+                titleBind = 'Please select the city level';
+                lastLevel = false;
+            }, 3000);
+        } else {
+            console.log('First level');
+        }
+    };
+
+    let allIndexs = [];
+    let allItems = [];
+    const getAllDataFunc = e => {
+        const { items, indexs } = e.detail;
+        allItems = items;
+        allIndexs = indexs;
+    };
+
+    // The processing logic of Labelkey at each level at different times
+    let diffLabelKeyData = linkageDiffLabeData;
+    let labelKey = 'province';
+    let diffLabelKeyCurrentLevel = 0;
+    let diffLabelKeyLastLevel = false;
+    let diffLabelKeyFirstLevel = true;
+    let diffLabelKeyLevel1Data = linkageDiffLabeData[0].children;
+    const diffLabelKeyNextFunc = e => {
+        const { index } = e.detail;
+        if (diffLabelKeyCurrentLevel === 0) {
+            const nextData = linkageDiffLabeData[index].children;
+            diffLabelKeyLevel1Data = nextData;
+            setTimeout(() => {
+                diffLabelKeyData = nextData;
+                labelKey = 'city';
+                diffLabelKeyCurrentLevel = 1;
+                diffLabelKeyFirstLevel = false;
+            }, 3000);
+        } else if (diffLabelKeyCurrentLevel === 1) {
+            const nextData = diffLabelKeyLevel1Data[index].children;
+            setTimeout(() => {
+                diffLabelKeyData = nextData;
+                diffLabelKeyCurrentLevel = 2;
+                labelKey = 'region';
+                diffLabelKeyLastLevel = true;
+            }, 3000);
+        } else {
+            console.log('Last level');
+        }
+    };
+    const diffLabelKeyPrevFunc = () => {
+        if (diffLabelKeyCurrentLevel === 1) {
+            const prevData = linkageDiffLabeData;
+            setTimeout(() => {
+                diffLabelKeyData = prevData;
+                diffLabelKeyCurrentLevel = 0;
+                diffLabelKeyFirstLevel = true;
+                labelKey = 'province';
+            }, 3000);
+        } else if (diffLabelKeyCurrentLevel === 2) {
+            const prevData = diffLabelKeyLevel1Data;
+            setTimeout(() => {
+                diffLabelKeyData = prevData;
+                diffLabelKeyCurrentLevel = 1;
+                labelKey = 'city';
+                diffLabelKeyLastLevel = false;
+            }, 3000);
+        } else {
+            console.log('First level');
+        }
+    };
+</script>
+
+<div class="py-4 text-left">
+    <div class="px-4">
+        {#if allItems.length}
+            Currently selected:
+            {#each allItems as item}
+                <span class="mr-2 text-primary dark:text-dark">{item.label}</span>
+            {/each}
+        {:else}
+            <div>Please select the data</div>
+        {/if}
+    </div>
+    <div class="px-4">
+        {#if allIndexs.length}
+            The index value of the current selection value is located::
+            {#each allIndexs as index}
+                <span class="mr-2 text-primary dark:text-dark">{index}</span>
+            {/each}
+        {:else}
+            <div>Please select the data</div>
+        {/if}
+    </div>
+    <Cell
+        title="Basic usage"
+        on:click={() => {
+            visible1 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible1}
+        bind:data
+        bind:lastLevel
+        bind:firstLevel
+        on:next={nextFunc}
+        on:prev={prevFunc}
+        on:confirm={getAllDataFunc}
+    />
+
+    <Cell
+        title="It can be seen that the number of 7 lines is"
+        on:click={() => {
+            visible2 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker bind:visible={visible2} bind:data bind:lastLevel bind:firstLevel on:next={nextFunc} on:prev={prevFunc} showRow={7} />
+
+    <Cell
+        title="Left -handed alignment"
+        on:click={() => {
+            visible3 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker bind:visible={visible3} bind:data bind:lastLevel bind:firstLevel align="left" on:next={nextFunc} on:prev={prevFunc} />
+
+    <Cell
+        title="Customize the next text"
+        on:click={() => {
+            visible5 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible5}
+        bind:data
+        bind:lastLevel
+        bind:firstLevel
+        on:next={nextFunc}
+        on:prev={prevFunc}
+        nextText="continue"
+        prevText="return"
+    />
+
+    <Cell
+        title="Use different Labelkey at different levels"
+        on:click={() => {
+            visible4 = true;
+            diffLabelKeyData = linkageDiffLabeData;
+            labelKey = 'province';
+            diffLabelKeyCurrentLevel = 0;
+            diffLabelKeyLastLevel = false;
+            diffLabelKeyFirstLevel = true;
+            diffLabelKeyLevel1Data = linkageDiffLabeData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible4}
+        bind:data={diffLabelKeyData}
+        bind:lastLevel={diffLabelKeyLastLevel}
+        bind:firstLevel={diffLabelKeyFirstLevel}
+        bind:labelKey
+        on:next={diffLabelKeyNextFunc}
+        on:prev={diffLabelKeyPrevFunc}
+    />
+
+    <Cell
+        title="Change a loading"
+        on:click={() => {
+            visible6 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible6}
+        bind:data
+        bind:lastLevel
+        bind:firstLevel
+        on:next={nextFunc}
+        on:prev={prevFunc}
+        loading={{ type: '1_15', width: 12, height: 12 }}
+    />
+
+    <Cell
+        title="Radius on the top"
+        on:click={() => {
+            visible8 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible8}
+        bind:data
+        bind:lastLevel
+        bind:firstLevel
+        on:next={nextFunc}
+        on:prev={prevFunc}
+        popup={{ radius: 'xl' }}
+    />
+
+    <Cell
+        title="Show selected options"
+        on:click={() => {
+            visible7 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker bind:visible={visible7} bind:data bind:lastLevel bind:firstLevel on:next={nextFunc} on:prev={prevFunc} showSelected />
+
+    <Cell
+        title="Dynamic change title"
+        on:click={() => {
+            visible9 = true;
+            data = linkageData;
+            lastLevel = false;
+            firstLevel = true;
+            currentLevel = 0;
+            titleBind = 'Please select the provincial level';
+            level1Data = linkageData[0].children;
+        }}
+    />
+    <AsyncPicker
+        bind:visible={visible9}
+        bind:data
+        bind:lastLevel
+        bind:firstLevel
+        bind:title={titleBind}
+        on:next={nextFunc}
+        on:prev={prevFunc}
+    />
+</div>
+<!-- 
+const linkageData = [
+    {
+        label: 'Yunnan',
+        children: [
+            {
+                label: 'Kunming',
+                children: [
+                    { label: 'Panlong District' },
+                    { label: 'Wuhua District' },
+                    { label: 'Guandu District' },
+                    { label: 'Xishan District' },
+                ],
+            },
+            {
+                label: 'Qujing',
+                children: [
+                    { label: 'Qilin District' },
+                    { label: 'Zhanyi District' },
+                    { label: 'Malong County' },
+                    { label: 'Luliang County' },
+                    { label: 'Shizong County' },
+                    { label: 'Luoping County' },
+                    { label: 'Fuyuan County' },
+                    { label: 'Huize County' },
+                    { label: 'Xuanwei City' },
+                ],
+            },
+            {
+                label: 'Yuxi',
+                children: [
+                    { label: 'Hongta District' },
+                    { label: 'Jiangchuan District' },
+                    { label: 'Chengjiang County' },
+                    { label: 'Tonghai County' },
+                    { label: 'Huaning County' },
+                ],
+            },
+            {
+                label: 'Baoshan',
+                children: [
+                    { label: 'Longyang District' },
+                    { label: 'Shidian County' },
+                    { label: 'Longling County' },
+                    { label: 'Changning County' },
+                    { label: 'Tengchong City' },
+                    { label: 'Longling County' },
+                ],
+            },
+            {
+                label: 'Lijiang',
+                children: [
+                    { label: 'Gucheng District' },
+                    { label: 'Yongsheng County' },
+                    { label: 'Huaping County' },
+                    { label: 'Yulong Naxi Autonomous County' },
+                    { label: 'Ninglang Yi Autonomous County' },
+                ],
+            },
+            {
+                label: "Pu'er",
+                children: [
+                    { label: 'Simao District' },
+                    { label: "Ning'er Hani and Yi Autonomous County" },
+                    { label: 'Mojiang Hani Autonomous County' },
+                    { label: 'Jingdong Yi Autonomous County' },
+                    { label: 'Jinggu Dai and Yi Autonomous County' },
+                ],
+            },
+            {
+                label: 'Lincang',
+                children: [
+                    { label: 'Linxiang District' },
+                    { label: 'Fengqing County' },
+                    { label: 'Yun County' },
+                    { label: 'Yongde County' },
+                    { label: 'Zhenkang County' },
+                ],
+            },
+            {
+                label: 'Chuxiong',
+                children: [
+                    { label: 'Chuxiong City' },
+                    { label: 'Shuangbai County' },
+                    { label: 'Mouding County' },
+                    { label: 'Nanhua County' },
+                    { label: "Yao'an County" },
+                    { label: 'Dayao County' },
+                ],
+            },
+            {
+                label: 'Honghe',
+                children: [
+                    { label: 'Gejiu City' },
+                    { label: 'Kaiyuan City' },
+                    { label: 'Mengzi City' },
+                    { label: 'Mile City' },
+                    { label: 'Pingbian Miao Autonomous County' },
+                    { label: 'Jianshui County' },
+                ],
+            },
+            {
+                label: 'Wenshan',
+                children: [
+                    { label: 'Wenshan City' },
+                    { label: 'Yanshan County' },
+                    { label: 'Xichou County' },
+                    { label: 'Malipo County' },
+                    { label: 'Maguan County' },
+                    { label: 'Qiubei County' },
+                    { label: 'Guangnan County' },
+                    { label: 'Funing County' },
+                ],
+            },
+        ],
+    },
+    {
+        label: 'Guangdong',
+        children: [
+            {
+                label: 'Guangzhou',
+                children: [
+                    { label: 'Tianhe District' },
+                    { label: 'Haizhu District' },
+                    { label: 'Liwan District' },
+                    { label: 'Yuexiu District' },
+                    { label: 'Baiyun District' },
+                    { label: 'Huangpu District' },
+                ],
+            },
+            {
+                label: 'Shenzhen',
+                children: [
+                    { label: 'Luohu District' },
+                    { label: 'Futian District' },
+                    { label: 'Nanshan District' },
+                    { label: "Bao'an District" },
+                    { label: 'Longgang District' },
+                    { label: 'Yantian District' },
+                ],
+            },
+            { label: 'Zhuhai', children: [{ label: 'Xiangzhou District' }, { label: 'Doumen District' }, { label: 'Jinwan District' }] },
+            {
+                label: 'Shantou',
+                children: [
+                    { label: 'Longhu District' },
+                    { label: 'Jinping District' },
+                    { label: 'Gongjing District' },
+                    { label: 'Chaoyang District' },
+                    { label: 'Chaonan District' },
+                    { label: 'Chenghai District' },
+                ],
+            },
+            {
+                label: 'Foshan',
+                children: [
+                    { label: 'Chancheng District' },
+                    { label: 'Nanhai District' },
+                    { label: 'Shunde District' },
+                    { label: 'Sanshui District' },
+                    { label: 'Gaoming District' },
+                ],
+            },
+        ],
+    },
+    {
+        label: 'Sichuan',
+        children: [
+            {
+                label: 'Chengdu',
+                children: [
+                    { label: 'Jinjiang District' },
+                    { label: 'Qingyang District' },
+                    { label: 'Jinniu District' },
+                    { label: 'Wuhou District' },
+                    { label: 'Chenghua District' },
+                    { label: 'Longquanyi District' },
+                ],
+            },
+            {
+                label: 'Mianyang',
+                children: [
+                    { label: 'Fucheng District' },
+                    { label: 'Youxian District' },
+                    { label: 'Anzhou District' },
+                    { label: 'Santai County' },
+                    { label: 'Yanting County' },
+                    { label: 'Zitong County' },
+                ],
+            },
+            {
+                label: 'Zigong',
+                children: [
+                    { label: 'Ziliujing District' },
+                    { label: 'Gongjing District' },
+                    { label: "Da'an District" },
+                    { label: 'Yantan District' },
+                    { label: 'Rong County' },
+                    { label: 'Fushun County' },
+                ],
+            },
+            {
+                label: 'Panzhihua',
+                children: [
+                    { label: 'Dong District' },
+                    { label: 'Xi District' },
+                    { label: 'Renhe District' },
+                    { label: 'Miyi County' },
+                    { label: 'Yanbian County' },
+                ],
+            },
+        ],
+    },
+    {
+        label: 'Beijing',
+        children: [
+            {
+                label: 'Beijing',
+                children: [
+                    { label: 'Dongcheng District' },
+                    { label: 'Xicheng District' },
+                    { label: 'Chaoyang District' },
+                    { label: 'Fengtai District' },
+                    { label: 'Shijingshan District' },
+                    { label: 'Haidian District' },
+                ],
+            },
+        ],
+    },
+    {
+        label: 'Zhejiang',
+        children: [
+            {
+                label: 'Hangzhou',
+                children: [
+                    { label: 'Shangcheng District' },
+                    { label: 'Xiacheng District' },
+                    { label: 'Jianggan District' },
+                    { label: 'Gongshu District' },
+                    { label: 'Xihu District' },
+                    { label: 'Binjiang District' },
+                ],
+            },
+            {
+                label: 'Ningbo',
+                children: [
+                    { label: 'Haishu District' },
+                    { label: 'Jiangdong District' },
+                    { label: 'Jiangbei District' },
+                    { label: 'Beilun District' },
+                    { label: 'Zhenhai District' },
+                    { label: 'Yinzhou District' },
+                ],
+            },
+            {
+                label: 'Wenzhou',
+                children: [
+                    { label: 'Lucheng District' },
+                    { label: 'Longwan District' },
+                    { label: 'Ouhai District' },
+                    { label: 'Dongtou District' },
+                    { label: 'Yongjia County' },
+                    { label: 'Pingyang County' },
+                ],
+            },
+            {
+                label: 'Jiaxing',
+                children: [
+                    { label: 'Nanhu District' },
+                    { label: 'Xiuzhou District' },
+                    { label: 'Jiashan County' },
+                    { label: 'Haiyan County' },
+                    { label: 'Haining City' },
+                    { label: 'Pinghu City' },
+                ],
+            },
+            {
+                label: 'Huzhou',
+                children: [
+                    { label: 'Wuxing District' },
+                    { label: 'Nanxun District' },
+                    { label: 'Deqing County' },
+                    { label: 'Changxing County' },
+                    { label: 'Anji County' },
+                ],
+            },
+        ],
+    },
+];
+
+const linkageDiffLabeData = [
+    {
+        province: 'Yunnan',
+        children: [
+            {
+                city: 'Kunming',
+                children: [
+                    { region: 'Panlong District' },
+                    { region: 'Wuhua District' },
+                    { region: 'Guandu District' },
+                    { region: 'Xishan District' },
+                    { region: 'Dongchuan District' },
+                    { region: 'Chenggong District' },
+                    { region: 'Jinning District' },
+                    { region: 'Fumin County' },
+                    { region: 'Yiliang County' },
+                    { region: 'Shilin Yi Autonomous County' },
+                    { region: 'Songming County' },
+                    { region: 'Luquan Yi and Miao Autonomous County' },
+                    { region: 'Xundian Hui and Yi Autonomous County' },
+                    { region: 'Anning City' },
+                ],
+            },
+            {
+                city: 'Qujing',
+                children: [
+                    { region: 'Qilin District' },
+                    { region: 'Zhanyi District' },
+                    { region: 'Malong County' },
+                    { region: 'Luliang County' },
+                    { region: 'Shizong County' },
+                    { region: 'Luoping County' },
+                    { region: 'Fuyuan County' },
+                    { region: 'Huize County' },
+                    { region: 'Xuanwei City' },
+                ],
+            },
+            {
+                city: 'Yuxi',
+                children: [
+                    { region: 'Hongta District' },
+                    { region: 'Jiangchuan District' },
+                    { region: 'Chengjiang County' },
+                    { region: 'Tonghai County' },
+                    { region: 'Huaning County' },
+                    { region: 'Yimen County' },
+                    { region: 'Eshan Yi Autonomous County' },
+                    { region: 'Xinping Yi and Dai Autonomous County' },
+                    { region: 'Yuanjiang Hani, Yi and Dai Autonomous County' },
+                ],
+            },
+            {
+                city: 'Baoshan',
+                children: [
+                    { region: 'Longyang District' },
+                    { region: 'Shidian County' },
+                    { region: 'Longling County' },
+                    { region: 'Changning County' },
+                    { region: 'Tengchong City' },
+                ],
+            },
+            {
+                city: 'Lijiang',
+                children: [
+                    { region: 'Gucheng District' },
+                    { region: 'Yongsheng County' },
+                    { region: 'Huaping County' },
+                    { region: 'Yulong Naxi Autonomous County' },
+                    { region: 'Ninglang Yi Autonomous County' },
+                ],
+            },
+            {
+                city: "Pu'er",
+                children: [
+                    { region: 'Simao District' },
+                    { region: "Ning'er Hani and Yi Autonomous County" },
+                    { region: 'Mojiang Hani Autonomous County' },
+                    { region: 'Jingdong Yi Autonomous County' },
+                    { region: 'Jinggu Dai and Yi Autonomous County' },
+                    { region: 'Zhenyuan Yi, Hani and Lahu Autonomous County' },
+                    { region: 'Jiangcheng Hani and Yi Autonomous County' },
+                    { region: 'Menglian Dai, Lahu and Va Autonomous County' },
+                    { region: 'Lancang Lahu Autonomous County' },
+                    { region: 'Ximeng Va Autonomous County' },
+                ],
+            },
+        ],
+    },
+    {
+        province: 'Guangdong',
+        children: [
+            {
+                city: 'Guangzhou',
+                children: [
+                    { region: 'Tianhe District' },
+                    { region: 'Haizhu District' },
+                    { region: 'Liwan District' },
+                    { region: 'Yuexiu District' },
+                    { region: 'Baiyun District' },
+                    { region: 'Huangpu District' },
+                ],
+            },
+            {
+                city: 'Shenzhen',
+                children: [
+                    { region: 'Luohu District' },
+                    { region: 'Futian District' },
+                    { region: 'Nanshan District' },
+                    { region: "Bao'an District" },
+                    { region: 'Longgang District' },
+                    { region: 'Yantian District' },
+                ],
+            },
+        ],
+    },
+];
+
+export { linkageData, linkageDiffLabeData };
+-->

+ 426 - 0
demo/src/pages/asyncPicker/data.js

@@ -0,0 +1,426 @@
+const linkageData = [
+    {
+        label: '云南',
+        children: [
+            {
+                label: '昆明',
+                children: [
+                    { label: '盘龙区' },
+                    { label: '五华区' },
+                    { label: '官渡区' },
+                    { label: '西山区' },
+                    { label: '东川区' },
+                    { label: '呈贡区' },
+                    { label: '晋宁区' },
+                    { label: '富民县' },
+                    { label: '宜良县' },
+                    { label: '石林彝族自治县' },
+                    { label: '嵩明县' },
+                    { label: '禄劝彝族苗族自治县' },
+                    { label: '寻甸回族彝族自治县' },
+                    { label: '安宁市' },
+                ],
+            },
+            {
+                label: '曲靖',
+                children: [
+                    { label: '麒麟区' },
+                    { label: '沾益区' },
+                    { label: '马龙县' },
+                    { label: '陆良县' },
+                    { label: '师宗县' },
+                    { label: '罗平县' },
+                    { label: '富源县' },
+                    { label: '会泽县' },
+                    { label: '宣威市' },
+                ],
+            },
+            {
+                label: '玉溪',
+                children: [
+                    { label: '红塔区' },
+                    { label: '江川区' },
+                    { label: '澄江县' },
+                    { label: '通海县' },
+                    { label: '华宁县' },
+                    { label: '易门县' },
+                    { label: '峨山彝族自治县' },
+                    { label: '新平彝族傣族自治县' },
+                    { label: '元江哈尼族彝族傣族自治县' },
+                ],
+            },
+            {
+                label: '保山',
+                children: [
+                    { label: '隆阳区' },
+                    { label: '施甸县' },
+                    { label: '龙陵县' },
+                    { label: '昌宁县' },
+                    { label: '腾冲市' },
+                    { label: '龙陵县' },
+                ],
+            },
+            {
+                label: '丽江',
+                children: [
+                    { label: '古城区' },
+                    { label: '永胜县' },
+                    { label: '华坪县' },
+                    { label: '玉龙纳西族自治县' },
+                    { label: '宁蒗彝族自治县' },
+                ],
+            },
+            {
+                label: '普洱',
+                children: [
+                    { label: '思茅区' },
+                    { label: '宁洱哈尼族彝族自治县' },
+                    { label: '墨江哈尼族自治县' },
+                    { label: '景东彝族自治县' },
+                    { label: '景谷傣族彝族自治县' },
+                    { label: '镇沅彝族哈尼族拉祜族自治县' },
+                    { label: '江城哈尼族彝族自治县' },
+                    { label: '孟连傣族拉祜族佤族自治县' },
+                    { label: '澜沧拉祜族自治县' },
+                    { label: '西盟佤族自治县' },
+                ],
+            },
+            {
+                label: '临沧',
+                children: [
+                    { label: '临翔区' },
+                    { label: '凤庆县' },
+                    { label: '云县' },
+                    { label: '永德县' },
+                    { label: '镇康县' },
+                    { label: '双江拉祜族佤族布朗族傣族自治县' },
+                    { label: '耿马傣族佤族自治县' },
+                    { label: '沧源佤族自治县' },
+                ],
+            },
+            {
+                label: '楚雄',
+                children: [
+                    { label: '楚雄市' },
+                    { label: '双柏县' },
+                    { label: '牟定县' },
+                    { label: '南华县' },
+                    { label: '姚安县' },
+                    { label: '大姚县' },
+                    { label: '永仁县' },
+                    { label: '元谋县' },
+                    { label: '武定县' },
+                    { label: '禄丰县' },
+                ],
+            },
+            {
+                label: '红河',
+                children: [
+                    { label: '个旧市' },
+                    { label: '开远市' },
+                    { label: '蒙自市' },
+                    { label: '弥勒市' },
+                    { label: '屏边苗族自治县' },
+                    { label: '建水县' },
+                    { label: '石屏县' },
+                    { label: '泸西县' },
+                    { label: '元阳县' },
+                    { label: '红河县' },
+                    { label: '金平苗族瑶族傣族自治县' },
+                    { label: '绿春县' },
+                    { label: '河口瑶族自治县' },
+                ],
+            },
+            {
+                label: '文山',
+                children: [
+                    { label: '文山市' },
+                    { label: '砚山县' },
+                    { label: '西畴县' },
+                    { label: '麻栗坡县' },
+                    { label: '马关县' },
+                    { label: '丘北县' },
+                    { label: '广南县' },
+                    { label: '富宁县' },
+                ],
+            },
+        ],
+    },
+    {
+        label: '广东',
+        children: [
+            {
+                label: '广州',
+                children: [
+                    { label: '天河区' },
+                    { label: '海珠区' },
+                    { label: '荔湾区' },
+                    { label: '越秀区' },
+                    { label: '白云区' },
+                    { label: '黄埔区' },
+                ],
+            },
+            {
+                label: '深圳',
+                children: [
+                    { label: '罗湖区' },
+                    { label: '福田区' },
+                    { label: '南山区' },
+                    { label: '宝安区' },
+                    { label: '龙岗区' },
+                    { label: '盐田区' },
+                ],
+            },
+            {
+                label: '珠海',
+                children: [{ label: '香洲区' }, { label: '斗门区' }, { label: '金湾区' }],
+            },
+            {
+                label: '汕头',
+                children: [
+                    { label: '龙湖区' },
+                    { label: '金平区' },
+                    { label: '濠江区' },
+                    { label: '潮阳区' },
+                    { label: '潮南区' },
+                    { label: '澄海区' },
+                ],
+            },
+            {
+                label: '佛山',
+                children: [{ label: '禅城区' }, { label: '南海区' }, { label: '顺德区' }, { label: '三水区' }, { label: '高明区' }],
+            },
+        ],
+    },
+    {
+        label: '四川',
+        children: [
+            {
+                label: '成都',
+                children: [
+                    { label: '锦江区' },
+                    { label: '青羊区' },
+                    { label: '金牛区' },
+                    { label: '武侯区' },
+                    { label: '成华区' },
+                    { label: '龙泉驿区' },
+                ],
+            },
+            {
+                label: '绵阳',
+                children: [
+                    { label: '涪城区' },
+                    { label: '游仙区' },
+                    { label: '安州区' },
+                    { label: '三台县' },
+                    { label: '盐亭县' },
+                    { label: '梓潼县' },
+                ],
+            },
+            {
+                label: '自贡',
+                children: [
+                    { label: '自流井区' },
+                    { label: '贡井区' },
+                    { label: '大安区' },
+                    { label: '沿滩区' },
+                    { label: '荣县' },
+                    { label: '富顺县' },
+                ],
+            },
+            {
+                label: '攀枝花',
+                children: [{ label: '东区' }, { label: '西区' }, { label: '仁和区' }, { label: '米易县' }, { label: '盐边县' }],
+            },
+        ],
+    },
+    {
+        label: '北京',
+        children: [
+            {
+                label: '北京市',
+                children: [
+                    { label: '东城区' },
+                    { label: '西城区' },
+                    { label: '朝阳区' },
+                    { label: '丰台区' },
+                    { label: '石景山区' },
+                    { label: '海淀区' },
+                ],
+            },
+        ],
+    },
+    {
+        label: '浙江',
+        children: [
+            {
+                label: '杭州',
+                children: [
+                    { label: '上城区' },
+                    { label: '下城区' },
+                    { label: '江干区' },
+                    { label: '拱墅区' },
+                    { label: '西湖区' },
+                    { label: '滨江区' },
+                ],
+            },
+            {
+                label: '宁波',
+                children: [
+                    { label: '海曙区' },
+                    { label: '江东区' },
+                    { label: '江北区' },
+                    { label: '北仑区' },
+                    { label: '镇海区' },
+                    { label: '鄞州区' },
+                ],
+            },
+            {
+                label: '温州',
+                children: [
+                    { label: '鹿城区' },
+                    { label: '龙湾区' },
+                    { label: '瓯海区' },
+                    { label: '洞头区' },
+                    { label: '永嘉县' },
+                    { label: '平阳县' },
+                ],
+            },
+            {
+                label: '嘉兴',
+                children: [
+                    { label: '南湖区' },
+                    { label: '秀洲区' },
+                    { label: '嘉善县' },
+                    { label: '海盐县' },
+                    { label: '海宁市' },
+                    { label: '平湖市' },
+                ],
+            },
+            {
+                label: '湖州',
+                children: [{ label: '吴兴区' }, { label: '南浔区' }, { label: '德清县' }, { label: '长兴县' }, { label: '安吉县' }],
+            },
+        ],
+    },
+];
+
+const linkageDiffLabeData = [
+    {
+        province: '云南',
+        children: [
+            {
+                city: '昆明',
+                children: [
+                    { region: '盘龙区' },
+                    { region: '五华区' },
+                    { region: '官渡区' },
+                    { region: '西山区' },
+                    { region: '东川区' },
+                    { region: '呈贡区' },
+                    { region: '晋宁区' },
+                    { region: '富民县' },
+                    { region: '宜良县' },
+                    { region: '石林彝族自治县' },
+                    { region: '嵩明县' },
+                    { region: '禄劝彝族苗族自治县' },
+                    { region: '寻甸回族彝族自治县' },
+                    { region: '安宁市' },
+                ],
+            },
+            {
+                city: '曲靖',
+                children: [
+                    { region: '麒麟区' },
+                    { region: '沾益区' },
+                    { region: '马龙县' },
+                    { region: '陆良县' },
+                    { region: '师宗县' },
+                    { region: '罗平县' },
+                    { region: '富源县' },
+                    { region: '会泽县' },
+                    { region: '宣威市' },
+                ],
+            },
+            {
+                city: '玉溪',
+                children: [
+                    { region: '红塔区' },
+                    { region: '江川区' },
+                    { region: '澄江县' },
+                    { region: '通海县' },
+                    { region: '华宁县' },
+                    { region: '易门县' },
+                    { region: '峨山彝族自治县' },
+                    { region: '新平彝族傣族自治县' },
+                    { region: '元江哈尼族彝族傣族自治县' },
+                ],
+            },
+            {
+                city: '保山',
+                children: [
+                    { region: '隆阳区' },
+                    { region: '施甸县' },
+                    { region: '龙陵县' },
+                    { region: '昌宁县' },
+                    { region: '腾冲市' },
+                    { region: '龙陵县' },
+                ],
+            },
+            {
+                city: '丽江',
+                children: [
+                    { region: '古城区' },
+                    { region: '永胜县' },
+                    { region: '华坪县' },
+                    { region: '玉龙纳西族自治县' },
+                    { region: '宁蒗彝族自治县' },
+                ],
+            },
+            {
+                city: '普洱',
+                children: [
+                    { region: '思茅区' },
+                    { region: '宁洱哈尼族彝族自治县' },
+                    { region: '墨江哈尼族自治县' },
+                    { region: '景东彝族自治县' },
+                    { region: '景谷傣族彝族自治县' },
+                    { region: '镇沅彝族哈尼族拉祜族自治县' },
+                    { region: '江城哈尼族彝族自治县' },
+                    { region: '孟连傣族拉祜族佤族自治县' },
+                    { region: '澜沧拉祜族自治县' },
+                    { region: '西盟佤族自治县' },
+                ],
+            },
+        ],
+    },
+    {
+        province: '广东',
+        children: [
+            {
+                city: '广州',
+                children: [
+                    { region: '天河区' },
+                    { region: '海珠区' },
+                    { region: '荔湾区' },
+                    { region: '越秀区' },
+                    { region: '白云区' },
+                    { region: '黄埔区' },
+                ],
+            },
+            {
+                city: '深圳',
+                children: [
+                    { region: '罗湖区' },
+                    { region: '福田区' },
+                    { region: '南山区' },
+                    { region: '宝安区' },
+                    { region: '龙岗区' },
+                    { region: '盐田区' },
+                ],
+            },
+        ],
+    },
+];
+
+export { linkageData, linkageDiffLabeData };

+ 407 - 0
demo/src/pages/asyncPicker/data_en.js

@@ -0,0 +1,407 @@
+const linkageData = [
+    {
+        label: 'Yunnan',
+        children: [
+            {
+                label: 'Kunming',
+                children: [
+                    { label: 'Panlong District' },
+                    { label: 'Wuhua District' },
+                    { label: 'Guandu District' },
+                    { label: 'Xishan District' },
+                ],
+            },
+            {
+                label: 'Qujing',
+                children: [
+                    { label: 'Qilin District' },
+                    { label: 'Zhanyi District' },
+                    { label: 'Malong County' },
+                    { label: 'Luliang County' },
+                    { label: 'Shizong County' },
+                    { label: 'Luoping County' },
+                    { label: 'Fuyuan County' },
+                    { label: 'Huize County' },
+                    { label: 'Xuanwei City' },
+                ],
+            },
+            {
+                label: 'Yuxi',
+                children: [
+                    { label: 'Hongta District' },
+                    { label: 'Jiangchuan District' },
+                    { label: 'Chengjiang County' },
+                    { label: 'Tonghai County' },
+                    { label: 'Huaning County' },
+                ],
+            },
+            {
+                label: 'Baoshan',
+                children: [
+                    { label: 'Longyang District' },
+                    { label: 'Shidian County' },
+                    { label: 'Longling County' },
+                    { label: 'Changning County' },
+                    { label: 'Tengchong City' },
+                    { label: 'Longling County' },
+                ],
+            },
+            {
+                label: 'Lijiang',
+                children: [
+                    { label: 'Gucheng District' },
+                    { label: 'Yongsheng County' },
+                    { label: 'Huaping County' },
+                    { label: 'Yulong Naxi Autonomous County' },
+                    { label: 'Ninglang Yi Autonomous County' },
+                ],
+            },
+            {
+                label: "Pu'er",
+                children: [
+                    { label: 'Simao District' },
+                    { label: "Ning'er Hani and Yi Autonomous County" },
+                    { label: 'Mojiang Hani Autonomous County' },
+                    { label: 'Jingdong Yi Autonomous County' },
+                    { label: 'Jinggu Dai and Yi Autonomous County' },
+                ],
+            },
+            {
+                label: 'Lincang',
+                children: [
+                    { label: 'Linxiang District' },
+                    { label: 'Fengqing County' },
+                    { label: 'Yun County' },
+                    { label: 'Yongde County' },
+                    { label: 'Zhenkang County' },
+                ],
+            },
+            {
+                label: 'Chuxiong',
+                children: [
+                    { label: 'Chuxiong City' },
+                    { label: 'Shuangbai County' },
+                    { label: 'Mouding County' },
+                    { label: 'Nanhua County' },
+                    { label: "Yao'an County" },
+                    { label: 'Dayao County' },
+                ],
+            },
+            {
+                label: 'Honghe',
+                children: [
+                    { label: 'Gejiu City' },
+                    { label: 'Kaiyuan City' },
+                    { label: 'Mengzi City' },
+                    { label: 'Mile City' },
+                    { label: 'Pingbian Miao Autonomous County' },
+                    { label: 'Jianshui County' },
+                ],
+            },
+            {
+                label: 'Wenshan',
+                children: [
+                    { label: 'Wenshan City' },
+                    { label: 'Yanshan County' },
+                    { label: 'Xichou County' },
+                    { label: 'Malipo County' },
+                    { label: 'Maguan County' },
+                    { label: 'Qiubei County' },
+                    { label: 'Guangnan County' },
+                    { label: 'Funing County' },
+                ],
+            },
+        ],
+    },
+    {
+        label: 'Guangdong',
+        children: [
+            {
+                label: 'Guangzhou',
+                children: [
+                    { label: 'Tianhe District' },
+                    { label: 'Haizhu District' },
+                    { label: 'Liwan District' },
+                    { label: 'Yuexiu District' },
+                    { label: 'Baiyun District' },
+                    { label: 'Huangpu District' },
+                ],
+            },
+            {
+                label: 'Shenzhen',
+                children: [
+                    { label: 'Luohu District' },
+                    { label: 'Futian District' },
+                    { label: 'Nanshan District' },
+                    { label: "Bao'an District" },
+                    { label: 'Longgang District' },
+                    { label: 'Yantian District' },
+                ],
+            },
+            { label: 'Zhuhai', children: [{ label: 'Xiangzhou District' }, { label: 'Doumen District' }, { label: 'Jinwan District' }] },
+            {
+                label: 'Shantou',
+                children: [
+                    { label: 'Longhu District' },
+                    { label: 'Jinping District' },
+                    { label: 'Gongjing District' },
+                    { label: 'Chaoyang District' },
+                    { label: 'Chaonan District' },
+                    { label: 'Chenghai District' },
+                ],
+            },
+            {
+                label: 'Foshan',
+                children: [
+                    { label: 'Chancheng District' },
+                    { label: 'Nanhai District' },
+                    { label: 'Shunde District' },
+                    { label: 'Sanshui District' },
+                    { label: 'Gaoming District' },
+                ],
+            },
+        ],
+    },
+    {
+        label: 'Sichuan',
+        children: [
+            {
+                label: 'Chengdu',
+                children: [
+                    { label: 'Jinjiang District' },
+                    { label: 'Qingyang District' },
+                    { label: 'Jinniu District' },
+                    { label: 'Wuhou District' },
+                    { label: 'Chenghua District' },
+                    { label: 'Longquanyi District' },
+                ],
+            },
+            {
+                label: 'Mianyang',
+                children: [
+                    { label: 'Fucheng District' },
+                    { label: 'Youxian District' },
+                    { label: 'Anzhou District' },
+                    { label: 'Santai County' },
+                    { label: 'Yanting County' },
+                    { label: 'Zitong County' },
+                ],
+            },
+            {
+                label: 'Zigong',
+                children: [
+                    { label: 'Ziliujing District' },
+                    { label: 'Gongjing District' },
+                    { label: "Da'an District" },
+                    { label: 'Yantan District' },
+                    { label: 'Rong County' },
+                    { label: 'Fushun County' },
+                ],
+            },
+            {
+                label: 'Panzhihua',
+                children: [
+                    { label: 'Dong District' },
+                    { label: 'Xi District' },
+                    { label: 'Renhe District' },
+                    { label: 'Miyi County' },
+                    { label: 'Yanbian County' },
+                ],
+            },
+        ],
+    },
+    {
+        label: 'Beijing',
+        children: [
+            {
+                label: 'Beijing',
+                children: [
+                    { label: 'Dongcheng District' },
+                    { label: 'Xicheng District' },
+                    { label: 'Chaoyang District' },
+                    { label: 'Fengtai District' },
+                    { label: 'Shijingshan District' },
+                    { label: 'Haidian District' },
+                ],
+            },
+        ],
+    },
+    {
+        label: 'Zhejiang',
+        children: [
+            {
+                label: 'Hangzhou',
+                children: [
+                    { label: 'Shangcheng District' },
+                    { label: 'Xiacheng District' },
+                    { label: 'Jianggan District' },
+                    { label: 'Gongshu District' },
+                    { label: 'Xihu District' },
+                    { label: 'Binjiang District' },
+                ],
+            },
+            {
+                label: 'Ningbo',
+                children: [
+                    { label: 'Haishu District' },
+                    { label: 'Jiangdong District' },
+                    { label: 'Jiangbei District' },
+                    { label: 'Beilun District' },
+                    { label: 'Zhenhai District' },
+                    { label: 'Yinzhou District' },
+                ],
+            },
+            {
+                label: 'Wenzhou',
+                children: [
+                    { label: 'Lucheng District' },
+                    { label: 'Longwan District' },
+                    { label: 'Ouhai District' },
+                    { label: 'Dongtou District' },
+                    { label: 'Yongjia County' },
+                    { label: 'Pingyang County' },
+                ],
+            },
+            {
+                label: 'Jiaxing',
+                children: [
+                    { label: 'Nanhu District' },
+                    { label: 'Xiuzhou District' },
+                    { label: 'Jiashan County' },
+                    { label: 'Haiyan County' },
+                    { label: 'Haining City' },
+                    { label: 'Pinghu City' },
+                ],
+            },
+            {
+                label: 'Huzhou',
+                children: [
+                    { label: 'Wuxing District' },
+                    { label: 'Nanxun District' },
+                    { label: 'Deqing County' },
+                    { label: 'Changxing County' },
+                    { label: 'Anji County' },
+                ],
+            },
+        ],
+    },
+];
+
+const linkageDiffLabeData = [
+    {
+        province: 'Yunnan',
+        children: [
+            {
+                city: 'Kunming',
+                children: [
+                    { region: 'Panlong District' },
+                    { region: 'Wuhua District' },
+                    { region: 'Guandu District' },
+                    { region: 'Xishan District' },
+                    { region: 'Dongchuan District' },
+                    { region: 'Chenggong District' },
+                    { region: 'Jinning District' },
+                    { region: 'Fumin County' },
+                    { region: 'Yiliang County' },
+                    { region: 'Shilin Yi Autonomous County' },
+                    { region: 'Songming County' },
+                    { region: 'Luquan Yi and Miao Autonomous County' },
+                    { region: 'Xundian Hui and Yi Autonomous County' },
+                    { region: 'Anning City' },
+                ],
+            },
+            {
+                city: 'Qujing',
+                children: [
+                    { region: 'Qilin District' },
+                    { region: 'Zhanyi District' },
+                    { region: 'Malong County' },
+                    { region: 'Luliang County' },
+                    { region: 'Shizong County' },
+                    { region: 'Luoping County' },
+                    { region: 'Fuyuan County' },
+                    { region: 'Huize County' },
+                    { region: 'Xuanwei City' },
+                ],
+            },
+            {
+                city: 'Yuxi',
+                children: [
+                    { region: 'Hongta District' },
+                    { region: 'Jiangchuan District' },
+                    { region: 'Chengjiang County' },
+                    { region: 'Tonghai County' },
+                    { region: 'Huaning County' },
+                    { region: 'Yimen County' },
+                    { region: 'Eshan Yi Autonomous County' },
+                    { region: 'Xinping Yi and Dai Autonomous County' },
+                    { region: 'Yuanjiang Hani, Yi and Dai Autonomous County' },
+                ],
+            },
+            {
+                city: 'Baoshan',
+                children: [
+                    { region: 'Longyang District' },
+                    { region: 'Shidian County' },
+                    { region: 'Longling County' },
+                    { region: 'Changning County' },
+                    { region: 'Tengchong City' },
+                ],
+            },
+            {
+                city: 'Lijiang',
+                children: [
+                    { region: 'Gucheng District' },
+                    { region: 'Yongsheng County' },
+                    { region: 'Huaping County' },
+                    { region: 'Yulong Naxi Autonomous County' },
+                    { region: 'Ninglang Yi Autonomous County' },
+                ],
+            },
+            {
+                city: "Pu'er",
+                children: [
+                    { region: 'Simao District' },
+                    { region: "Ning'er Hani and Yi Autonomous County" },
+                    { region: 'Mojiang Hani Autonomous County' },
+                    { region: 'Jingdong Yi Autonomous County' },
+                    { region: 'Jinggu Dai and Yi Autonomous County' },
+                    { region: 'Zhenyuan Yi, Hani and Lahu Autonomous County' },
+                    { region: 'Jiangcheng Hani and Yi Autonomous County' },
+                    { region: 'Menglian Dai, Lahu and Va Autonomous County' },
+                    { region: 'Lancang Lahu Autonomous County' },
+                    { region: 'Ximeng Va Autonomous County' },
+                ],
+            },
+        ],
+    },
+    {
+        province: 'Guangdong',
+        children: [
+            {
+                city: 'Guangzhou',
+                children: [
+                    { region: 'Tianhe District' },
+                    { region: 'Haizhu District' },
+                    { region: 'Liwan District' },
+                    { region: 'Yuexiu District' },
+                    { region: 'Baiyun District' },
+                    { region: 'Huangpu District' },
+                ],
+            },
+            {
+                city: 'Shenzhen',
+                children: [
+                    { region: 'Luohu District' },
+                    { region: 'Futian District' },
+                    { region: 'Nanshan District' },
+                    { region: "Bao'an District" },
+                    { region: 'Longgang District' },
+                    { region: 'Yantian District' },
+                ],
+            },
+        ],
+    },
+];
+
+export { linkageData, linkageDiffLabeData };

+ 82 - 0
demo/src/pages/avatar/AvatarDemo.svelte

@@ -0,0 +1,82 @@
+<!-- Avatar Demo -->
+<script>
+    import { Avatar } from '../../../../components';
+
+    const icons = [
+        { icon: { name: 'ri-aliens-fill', theme: true, top: -1, size: 16 }, size: 'xs' },
+        { icon: { name: 'ri-user-smile-line', top: -1 }, size: 'sm' },
+        { icon: { name: 'ri-shield-user-line', theme: true, top: 0, size: 32 }, size: 'md' },
+        { icon: { name: 'ri-emotion-line', theme: true, top: -1, size: 46 }, size: 'lg' },
+    ];
+</script>
+
+<div class="py-8 px-4">
+    <div class="font-bold">不同圆角</div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar />
+        <Avatar radius="none" />
+        <Avatar radius="full" />
+    </div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar radius="xl" />
+        <Avatar radius="2xl" />
+        <Avatar radius="3xl" />
+    </div>
+
+    <div class="font-bold">不同图片类型与大小</div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar image="./assets/images/avatar_2.png" imgSize="s" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" />
+        <Avatar image="./assets/images/avatar_2.png" />
+        <Avatar image="./assets/images/avatar_1.jpg" />
+    </div>
+
+    <div class="font-bold">自定义背景色</div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" injClass="!bg-success" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" injClass="!bg-[#D65786]" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0] !text-white" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" injClass="!bg-[rgba(0,0,0,0)]" />
+    </div>
+
+    <div class="font-bold">不同边框</div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" line="solid" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" line="dashed" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" line="dotted" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" line="solid" injClass="border-[red] dark:border-[green]" />
+    </div>
+
+    <div class="font-bold">替换文本</div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar alt="张" altSize="xs" />
+        <Avatar alt="张" altSize="sm" />
+        <Avatar alt="张" />
+        <Avatar alt="张" altSize="lg" />
+    </div>
+
+    <div class="font-bold">替换 Icon</div>
+    <div class="flex justify-between mt-4 mb-8">
+        {#each icons as icon}
+            <Avatar icon={icon.icon} size={icon.size} />
+        {/each}
+    </div>
+
+    <div class="font-bold">不同大小</div>
+    <div class="flex justify-between">
+        <div class="flex flex-col items-center space-y-4 mt-4 mb-8">
+            <Avatar size="xs" icon={{ name: 'ri-bear-smile-line', size: 16, theme: true }} />
+            <Avatar size="sm" image="./assets/images/avatar_1.jpg" />
+            <Avatar line="solid" />
+            <Avatar size="lg" image="./assets/images/avatar_2.png" imgSize="m" />
+            <Avatar size="xl" alt="张" altSize="xl" />
+        </div>
+        <div class="flex flex-col items-center space-y-4 mt-4 mb-8">
+            <Avatar radius="full" size="xs" icon={{ name: 'ri-bear-smile-line', size: 16, theme: true }} />
+            <Avatar radius="full" size="sm" image="./assets/images/avatar_1.jpg" />
+            <Avatar radius="full" line="solid" />
+            <Avatar radius="full" size="lg" image="./assets/images/avatar_2.png" imgSize="m" />
+            <Avatar radius="full" size="xl" alt="张" altSize="xl" />
+        </div>
+    </div>
+</div>

+ 82 - 0
demo/src/pages/avatar/AvatarDemo_en.svelte

@@ -0,0 +1,82 @@
+<!-- Avatar Demo -->
+<script>
+    import { Avatar } from '../../../../components';
+
+    const icons = [
+        { icon: { name: 'ri-aliens-fill', theme: true, top: -1, size: 16 }, size: 'xs' },
+        { icon: { name: 'ri-user-smile-line', top: -1 }, size: 'sm' },
+        { icon: { name: 'ri-shield-user-line', theme: true, top: 0, size: 32 }, size: 'md' },
+        { icon: { name: 'ri-emotion-line', theme: true, top: -1, size: 46 }, size: 'lg' },
+    ];
+</script>
+
+<div class="py-8 px-4">
+    <div class="font-bold">Different rounded corners</div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar />
+        <Avatar radius="none" />
+        <Avatar radius="full" />
+    </div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar radius="xl" />
+        <Avatar radius="2xl" />
+        <Avatar radius="3xl" />
+    </div>
+
+    <div class="font-bold">Different picture types and size</div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar image="./assets/images/avatar_2.png" imgSize="s" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" />
+        <Avatar image="./assets/images/avatar_2.png" />
+        <Avatar image="./assets/images/avatar_1.jpg" />
+    </div>
+
+    <div class="font-bold">Custom background color</div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" injClass="!bg-success" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" injClass="!bg-[#D65786]" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0] !text-white" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" injClass="!bg-[rgba(0,0,0,0)]" />
+    </div>
+
+    <div class="font-bold">Different border</div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" line="solid" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" line="dashed" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" line="dotted" />
+        <Avatar image="./assets/images/avatar_2.png" imgSize="m" line="solid" injClass="border-[red] dark:border-[green]" />
+    </div>
+
+    <div class="font-bold">Replace text</div>
+    <div class="flex justify-between mt-4 mb-8">
+        <Avatar alt="A" altSize="xs" />
+        <Avatar alt="A" altSize="sm" />
+        <Avatar alt="A" />
+        <Avatar alt="A" altSize="lg" />
+    </div>
+
+    <div class="font-bold">Replace Icon</div>
+    <div class="flex justify-between mt-4 mb-8">
+        {#each icons as icon}
+            <Avatar icon={icon.icon} size={icon.size} />
+        {/each}
+    </div>
+
+    <div class="font-bold">Different size</div>
+    <div class="flex justify-between">
+        <div class="flex flex-col items-center space-y-4 mt-4 mb-8">
+            <Avatar size="xs" icon={{ name: 'ri-bear-smile-line', size: 16, theme: true }} />
+            <Avatar size="sm" image="./assets/images/avatar_1.jpg" />
+            <Avatar line="solid" />
+            <Avatar size="lg" image="./assets/images/avatar_2.png" imgSize="m" />
+            <Avatar size="xl" alt="A" altSize="xl" />
+        </div>
+        <div class="flex flex-col items-center space-y-4 mt-4 mb-8">
+            <Avatar radius="full" size="xs" icon={{ name: 'ri-bear-smile-line', size: 16, theme: true }} />
+            <Avatar radius="full" size="sm" image="./assets/images/avatar_1.jpg" />
+            <Avatar radius="full" line="solid" />
+            <Avatar radius="full" size="lg" image="./assets/images/avatar_2.png" imgSize="m" />
+            <Avatar radius="full" size="xl" alt="A" altSize="xl" />
+        </div>
+    </div>
+</div>

+ 126 - 0
demo/src/pages/badge/BadgeDemo.svelte

@@ -0,0 +1,126 @@
+<!-- Badge Demo -->
+<script>
+    import { Badge, Avatar, Button, Icon, Input, Cell } from '../../../../components';
+
+    let isShow = true;
+    const changeShowFun = () => {
+        isShow = !isShow;
+    };
+</script>
+
+<div class="pt-1 pb-4">
+    <div class="mx-4 mt-8 font-bold text-lg">基础用法</div>
+    <div class="p-4 flex justify-around">
+        <Badge>
+            <Avatar />
+        </Badge>
+        <Badge text="24">
+            <Avatar />
+        </Badge>
+        <Badge text="99+">
+            <Avatar />
+        </Badge>
+        <Badge text="New">
+            <Avatar />
+        </Badge>
+    </div>
+
+    <div class="mx-4 mt-8 font-bold text-lg">不同圆角</div>
+    <div class="p-4 flex justify-around">
+        <Badge radius="base">
+            <Avatar />
+        </Badge>
+        <Badge text="24" radius="none">
+            <Avatar />
+        </Badge>
+        <Badge text="24" radius="base">
+            <Avatar />
+        </Badge>
+        <Badge text="Hot" radius="leaf">
+            <Avatar />
+        </Badge>
+    </div>
+
+    <div class="mx-4 mt-8 font-bold text-lg">位于左侧</div>
+    <div class="p-4 flex justify-around">
+        <Badge isLeft>
+            <Avatar />
+        </Badge>
+        <Badge isLeft text="24">
+            <Avatar />
+        </Badge>
+        <Badge isLeft text="24" radius="leaf">
+            <Avatar />
+        </Badge>
+        <Badge isLeft text="厉害">
+            <Avatar />
+        </Badge>
+    </div>
+
+    <div class="mx-4 mt-8 font-bold text-lg">搭配其他组件</div>
+    <div class="p-4 flex justify-around">
+        <Badge text="帅" radius="leaf">
+            <Icon name="ri-spy-fill" />
+        </Badge>
+        <Badge text="棒" radius="leaf">
+            <Icon name="ri-medal-fill" />
+        </Badge>
+        <Badge text="Happy" radius="leaf" offsetX={-12}>
+            <Icon name="ri-cake-2-fill" />
+        </Badge>
+    </div>
+    <Badge text="Hot" offsetX={18} offsetY={8}>
+        <Button>搭配 Button</Button>
+    </Badge>
+    <Badge text="必填" offsetX={18} offsetY={26}>
+        <Input title="搭配 Input" />
+    </Badge>
+    <Cell title="搭配 Cell" detail="slot">
+        <span slot="detail"><Badge isInner /></span>
+    </Cell>
+    <Cell title="搭配 Cell" detail="slot" line={false}>
+        <span slot="detail"><Badge text="99+" isInner /></span>
+    </Cell>
+    <Cell title="搭配无圆角 Cell" detail="slot" radius="none">
+        <span slot="detail"><Badge text="新版本" radius="base" isInner /></span>
+    </Cell>
+    <Cell title="搭配全圆角 Cell" detail="slot" radius="full">
+        <span slot="detail"><Badge isInner /></span>
+    </Cell>
+
+    <div class="mx-4 mt-8 font-bold text-lg">徽标动画</div>
+    <div class="p-4 flex justify-around">
+        <Badge {isShow}>
+            <Avatar />
+        </Badge>
+        <Badge text="24" {isShow}>
+            <Avatar />
+        </Badge>
+        <Badge text="24" radius="base" {isShow}>
+            <Avatar />
+        </Badge>
+        <Badge text="Hot" radius="leaf" {isShow}>
+            <Avatar />
+        </Badge>
+    </div>
+    <Cell title={!isShow ? '隐藏' : '显示'} detail="slot">
+        <span slot="detail"><Badge isInner {isShow} /></span>
+    </Cell>
+    <Button on:click={changeShowFun}>点击{isShow ? '隐藏' : '显示'}徽标</Button>
+
+    <div class="mx-4 mt-8 font-bold text-lg">自定义背景色与边框</div>
+    <div class="p-4 flex justify-around">
+        <Badge text="Theme" injClass="!bg-primary dark:!bg-dark text-white dark:text-black">
+            <Avatar />
+        </Badge>
+        <Badge text="New" injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]">
+            <Avatar />
+        </Badge>
+        <Badge radius="base" injClass="ring-2 ring-[#ebeef2] dark:ring-[#414248]">
+            <Avatar image="./assets/images/avatar_1.jpg" />
+        </Badge>
+        <Badge offsetX={9} offsetY={9} injClass="ring-2 ring-[#ebeef2] dark:ring-[#414248]">
+            <Avatar radius="full" image="./assets/images/avatar_1.jpg" />
+        </Badge>
+    </div>
+</div>

+ 126 - 0
demo/src/pages/badge/BadgeDemo_en.svelte

@@ -0,0 +1,126 @@
+<!-- Badge Demo -->
+<script>
+    import { Badge, Avatar, Button, Icon, Input, Cell } from '../../../../components';
+
+    let isShow = true;
+    const changeShowFun = () => {
+        isShow = !isShow;
+    };
+</script>
+
+<div class="pt-1 pb-4">
+    <div class="mx-4 mt-8 font-bold text-lg">Basic usage</div>
+    <div class="p-4 flex justify-around">
+        <Badge>
+            <Avatar />
+        </Badge>
+        <Badge text="24">
+            <Avatar />
+        </Badge>
+        <Badge text="99+">
+            <Avatar />
+        </Badge>
+        <Badge text="New">
+            <Avatar />
+        </Badge>
+    </div>
+
+    <div class="mx-4 mt-8 font-bold text-lg">Different rounded corners</div>
+    <div class="p-4 flex justify-around">
+        <Badge radius="base">
+            <Avatar />
+        </Badge>
+        <Badge text="24" radius="none">
+            <Avatar />
+        </Badge>
+        <Badge text="24" radius="base">
+            <Avatar />
+        </Badge>
+        <Badge text="Hot" radius="leaf">
+            <Avatar />
+        </Badge>
+    </div>
+
+    <div class="mx-4 mt-8 font-bold text-lg">Located on the left</div>
+    <div class="p-4 flex justify-around">
+        <Badge isLeft>
+            <Avatar />
+        </Badge>
+        <Badge isLeft text="24">
+            <Avatar />
+        </Badge>
+        <Badge isLeft text="24" radius="leaf">
+            <Avatar />
+        </Badge>
+        <Badge isLeft text="sharp">
+            <Avatar />
+        </Badge>
+    </div>
+
+    <div class="mx-4 mt-8 font-bold text-lg">Match other components</div>
+    <div class="p-4 flex justify-around">
+        <Badge text="Cool" radius="leaf" offsetX={-6}>
+            <Icon name="ri-spy-fill" />
+        </Badge>
+        <Badge text="Great" radius="leaf" offsetX={-10}>
+            <Icon name="ri-medal-fill" />
+        </Badge>
+        <Badge text="Happy" radius="leaf" offsetX={-12}>
+            <Icon name="ri-cake-2-fill" />
+        </Badge>
+    </div>
+    <Badge text="Hot" offsetX={18} offsetY={8}>
+        <Button>Match Button</Button>
+    </Badge>
+    <Badge text="Required" offsetX={30} offsetY={26}>
+        <Input title="Match Input" />
+    </Badge>
+    <Cell title="Match Cell" detail="slot">
+        <span slot="detail"><Badge isInner /></span>
+    </Cell>
+    <Cell title="Match Cell" detail="slot" line={false}>
+        <span slot="detail"><Badge text="99+" isInner /></span>
+    </Cell>
+    <Cell title="Match no radius corner Cell" detail="slot" radius="none">
+        <span slot="detail"><Badge text="new version" radius="base" isInner /></span>
+    </Cell>
+    <Cell title="Match full radius Cell" detail="slot" radius="full">
+        <span slot="detail"><Badge isInner /></span>
+    </Cell>
+
+    <div class="mx-4 mt-8 font-bold text-lg">Badge animation</div>
+    <div class="p-4 flex justify-around">
+        <Badge {isShow}>
+            <Avatar />
+        </Badge>
+        <Badge text="24" {isShow}>
+            <Avatar />
+        </Badge>
+        <Badge text="24" radius="base" {isShow}>
+            <Avatar />
+        </Badge>
+        <Badge text="Hot" radius="leaf" {isShow}>
+            <Avatar />
+        </Badge>
+    </div>
+    <Cell title={!isShow ? 'Hidden' : 'Show'} detail="slot">
+        <span slot="detail"><Badge isInner {isShow} /></span>
+    </Cell>
+    <Button on:click={changeShowFun}>Click {isShow ? 'Hidden' : 'Show'} Badge</Button>
+
+    <div class="mx-4 mt-8 font-bold text-lg">Custom background color and border</div>
+    <div class="p-4 flex justify-around">
+        <Badge text="Theme" injClass="!bg-primary dark:!bg-dark text-white dark:text-black">
+            <Avatar />
+        </Badge>
+        <Badge text="New" injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0]">
+            <Avatar />
+        </Badge>
+        <Badge radius="base" injClass="ring-2 ring-[#ebeef2] dark:ring-[#414248]">
+            <Avatar image="./assets/images/avatar_1.jpg" />
+        </Badge>
+        <Badge offsetX={9} offsetY={9} injClass="ring-2 ring-[#ebeef2] dark:ring-[#414248]">
+            <Avatar radius="full" image="./assets/images/avatar_1.jpg" />
+        </Badge>
+    </div>
+</div>

+ 147 - 0
demo/src/pages/bottomSheet/BottomSheetDemo.svelte

@@ -0,0 +1,147 @@
+<!-- BottomSheet Demo -->
+<script>
+    import { getContext } from 'svelte';
+    import { BottomSheet, Cell, Toast, Button, NoticeBar } from '../../../../components';
+    import Aphorism from '../../components/Aphorism.svelte';
+
+    const isIframe = getContext('iframe') === '1'; //判断是否是iframe
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+    let visible12 = false;
+    let visible13 = false;
+    let visible14 = false;
+
+    let toastBackVisible = false;
+    let toastCloseVisible = false;
+
+    const stayHeightList = [40, 60, 80];
+    let currentHeight = 60;
+    const heightChangeFunc = e => (currentHeight = e.detail);
+</script>
+
+{#if isIframe}
+    <NoticeBar textList={['BottomSheet 头部区域绑定了 Touch 事件,请直接在移动设备或通过开发者工具模拟移动设备预览。']} right="none" />
+{/if}
+<div class="py-4">
+    <Cell title="基础用法" on:click={() => (visible1 = true)} />
+    <BottomSheet bind:visible={visible1} title="此区域支持滑动">
+        <div class="text-center h-full flex flex-col justify-center">
+            <div>这里是内容区域</div>
+        </div>
+    </BottomSheet>
+
+    <Cell title="内容区域滚动" on:click={() => (visible8 = true)} />
+    <BottomSheet bind:visible={visible8}>
+        <Aphorism num={12} />
+    </BottomSheet>
+
+    <Cell title="有返回按钮" on:click={() => (visible2 = true)} />
+    <BottomSheet
+        bind:visible={visible2}
+        showBackIcon
+        title="点击返回与关闭可触发事件"
+        on:back={() => (toastBackVisible = true)}
+        on:close={() => (toastCloseVisible = true)}
+    >
+        <Aphorism num={12} />
+    </BottomSheet>
+    <Toast bind:visible={toastBackVisible} message="触发了 BottomSheet 返回事件!" />
+    <Toast bind:visible={toastCloseVisible} message="触发了 BottomSheet 关闭事件!" />
+
+    <Cell title="初始高度为 90" on:click={() => (visible3 = true)} />
+    <BottomSheet bind:visible={visible3} stayHeightIndex={2}>
+        <Aphorism num={12} />
+    </BottomSheet>
+
+    <Cell title="固定高度为 40/60/80" on:click={() => (visible4 = true)} />
+    <BottomSheet bind:visible={visible4} {stayHeightList} on:heightChange={heightChangeFunc} title={`当前固定高度为${currentHeight}`}>
+        <Aphorism num={12} />
+    </BottomSheet>
+
+    <Cell title="点击遮罩可关闭" on:click={() => (visible5 = true)} />
+    <BottomSheet bind:visible={visible5} maskClosable>
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="出现过渡时间为 1 秒" on:click={() => (visible6 = true)} />
+    <BottomSheet bind:visible={visible6} duration={1000}>
+        <Aphorism num={12} />
+    </BottomSheet>
+
+    <Cell title="遮罩完全透明且模糊" on:click={() => (visible7 = true)} />
+    <BottomSheet bind:visible={visible7} mask={{ opacity: 0, backdropBlur: 'base' }}>
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="头部不显示任何内容" on:click={() => (visible9 = true)} />
+    <BottomSheet bind:visible={visible9} showDivider={false} closeContent="" title="">
+        <div class="px-4 py-8 h-full flex flex-col justify-around text-center">
+            <div>头部区域</div>
+            <div>标题</div>
+            <div>返回与关闭图标</div>
+            <div>分割线</div>
+            <div>都不显示</div>
+            <div>位置依旧保留作为滑动触控区域</div>
+            <div class="mb-8">
+                <Button on:click={() => (visible9 = false)}>关闭</Button>
+            </div>
+        </div>
+    </BottomSheet>
+
+    <Cell title="隐藏关闭图标且标题居中" on:click={() => (visible10 = true)} />
+    <BottomSheet bind:visible={visible10} closeContent="" titleAlign="center" maskClosable title="点击遮罩关闭">
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="另一种关闭图标" on:click={() => (visible13 = true)} />
+    <BottomSheet bind:visible={visible13} closeContent="closeIcon">
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="关闭区域自定义文字" on:click={() => (visible14 = true)} />
+    <BottomSheet bind:visible={visible14} closeContent="完成">
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="图标不同圆角风格" on:click={() => (visible12 = true)} />
+    <BottomSheet bind:visible={visible12} radius="base" showBackIcon>
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="可下滑到底部关闭" on:click={() => (visible11 = true)} />
+    <BottomSheet bind:visible={visible11} closeHeight={10} closeContent="">
+        <div class="p-4">将 closeHeight 设置为 10,如果滑动结束时位置距离页面底部小于页面高度的 10% 则自动关闭。</div>
+    </BottomSheet>
+</div>
+
+<!-- Aphorism.svelte -->
+<!-- 
+<script>
+    import aphorisms from '../data/aphorisms'; //引入数据
+
+    export let num = 0; //显示条数
+    export let compact = false; //是否紧凑模式
+
+    //从 aphorisms 随机取出 num 条数据
+    const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
+</script>
+
+<div class={`${compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5`}>
+    {#each aphorismsList as item}
+        <div class:py-6={num > 1}>
+            <div class="text-sm text-justify">{item.text}</div>
+            <div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
+        </div>
+    {/each}
+</div>
+-->

+ 159 - 0
demo/src/pages/bottomSheet/BottomSheetDemo_en.svelte

@@ -0,0 +1,159 @@
+<!-- BottomSheet Demo -->
+<script>
+    import { getContext } from 'svelte';
+    import { BottomSheet, Cell, Toast, Button, NoticeBar } from '../../../../components';
+    import Aphorism from '../../components/Aphorism.svelte';
+
+    const isIframe = getContext('iframe') === '1'; //Determine whether it is iframe
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+    let visible12 = false;
+    let visible13 = false;
+    let visible14 = false;
+
+    let toastBackVisible = false;
+    let toastCloseVisible = false;
+
+    const stayHeightList = [40, 60, 80];
+    let currentHeight = 60;
+    const heightChangeFunc = e => (currentHeight = e.detail);
+</script>
+
+{#if isIframe}
+    <NoticeBar
+        textList={[
+            'The Touch event is bound to the BottomSheet head area, Please preview the mobile device directly on the mobile device or through the developer tool.',
+        ]}
+        right="none"
+    />
+{/if}
+<div class="py-4">
+    <Cell title="Basic usage" on:click={() => (visible1 = true)} />
+    <BottomSheet bind:visible={visible1} title="This area supports sliding">
+        <div class="text-center h-full flex flex-col justify-center">
+            <div>This is the content area</div>
+        </div>
+    </BottomSheet>
+
+    <Cell title="Content area scrolling" on:click={() => (visible8 = true)} />
+    <BottomSheet bind:visible={visible8}>
+        <Aphorism num={12} />
+    </BottomSheet>
+
+    <Cell title="There is a return button" on:click={() => (visible2 = true)} />
+    <BottomSheet
+        bind:visible={visible2}
+        showBackIcon
+        title="Click back and closed to trigger events"
+        on:back={() => (toastBackVisible = true)}
+        on:close={() => (toastCloseVisible = true)}
+    >
+        <Aphorism num={12} />
+    </BottomSheet>
+    <Toast bind:visible={toastBackVisible} message="Trigger BottomSheet Return to the incident!" />
+    <Toast bind:visible={toastCloseVisible} message="Trigger BottomSheet Close the event!" />
+
+    <Cell title="The initial height is 90" on:click={() => (visible3 = true)} />
+    <BottomSheet bind:visible={visible3} stayHeightIndex={2}>
+        <Aphorism num={12} />
+    </BottomSheet>
+
+    <Cell title="Fixed height 40/60/80" on:click={() => (visible4 = true)} />
+    <BottomSheet
+        bind:visible={visible4}
+        {stayHeightList}
+        on:heightChange={heightChangeFunc}
+        title={`The current fixed height is ${currentHeight}`}
+    >
+        <Aphorism num={12} />
+    </BottomSheet>
+
+    <Cell title="Click the mask to close" on:click={() => (visible5 = true)} />
+    <BottomSheet bind:visible={visible5} maskClosable>
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="The transition time is 1s" on:click={() => (visible6 = true)} />
+    <BottomSheet bind:visible={visible6} duration={1000}>
+        <Aphorism num={12} />
+    </BottomSheet>
+
+    <Cell title="The mask is completely transparent and blurred" on:click={() => (visible7 = true)} />
+    <BottomSheet bind:visible={visible7} mask={{ opacity: 0, backdropBlur: 'base' }}>
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="No content on the head" on:click={() => (visible9 = true)} />
+    <BottomSheet bind:visible={visible9} showDivider={false} closeContent="" title="">
+        <div class="px-4 py-8 h-full flex flex-col justify-around text-center">
+            <div>Head area</div>
+            <div>title</div>
+            <div>Return and close icons</div>
+            <div>Dividing line</div>
+            <div>No display</div>
+            <div>The location still retains as a sliding touch area</div>
+            <div class="mb-8">
+                <Button on:click={() => (visible9 = false)}>closure</Button>
+            </div>
+        </div>
+    </BottomSheet>
+
+    <Cell title="Hide off the icon and the title is centered" on:click={() => (visible10 = true)} />
+    <BottomSheet bind:visible={visible10} closeContent="" titleAlign="center" maskClosable title="Click the mask to close">
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="Another turning off icon" on:click={() => (visible13 = true)} />
+    <BottomSheet bind:visible={visible13} closeContent="closeIcon">
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="Close the area custom text" on:click={() => (visible14 = true)} />
+    <BottomSheet bind:visible={visible14} closeContent="Finish">
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="The icon is different from the corner style" on:click={() => (visible12 = true)} />
+    <BottomSheet bind:visible={visible12} radius="base" showBackIcon>
+        <Aphorism num={2} />
+    </BottomSheet>
+
+    <Cell title="Can decline to the end to close" on:click={() => (visible11 = true)} />
+    <BottomSheet bind:visible={visible11} closeHeight={10} closeContent="">
+        <div class="p-4">
+            Set the Closeheight to 10. If the position from the bottom of the page is less than 10% at the bottom of the page at the end of
+            the sliding, it will automatically turn off.
+        </div>
+    </BottomSheet>
+</div>
+
+<!-- Aphorism.svelte -->
+<!-- 
+<script>
+    import aphorisms from '../data/aphorisms'; //Introduce data
+
+    export let num = 0; //Display number
+    export let compact = false; //Whether to compact mode
+
+    //Randomly remove NUM data from Aphorisms
+    const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
+</script>
+
+<div class={`${compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5`}>
+    {#each aphorismsList as item}
+        <div class:py-6={num > 1}>
+            <div class="text-sm text-justify">{item.text}</div>
+            <div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
+        </div>
+    {/each}
+</div>
+-->

+ 159 - 0
demo/src/pages/button/ButtonDemo.svelte

@@ -0,0 +1,159 @@
+<!-- Button Demo -->
+<script>
+    import { Button, Icon, Toast, Loading } from '../../../../components';
+
+    let visible = false;
+</script>
+
+<div class="flex flex-col space-y-8 py-8">
+    <div>
+        <div class="p-4 font-bold">不同状态色</div>
+        <Button>默认</Button>
+        <Button state="success">成功</Button>
+        <Button state="warning">警告</Button>
+        <Button state="error">错误</Button>
+        <Button state="info">信息</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">不同圆角风格</div>
+        <Button>默认</Button>
+        <Button radius="none">无圆角</Button>
+        <Button radius="xl">大圆角</Button>
+        <Button radius="2xl">更大圆角</Button>
+        <Button radius="full">全圆角</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">不同填充模式</div>
+        <Button>默认</Button>
+        <Button fill="line">无色线性</Button>
+        <Button fill="lineLight">浅色线性</Button>
+        <Button fill="lineTheme">主题色线性</Button>
+        <Button fill="text">无色纯文本</Button>
+        <Button fill="textTheme">主题色纯文本</Button>
+        <Button fill="colorLight">浅色填充</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">不同边框风格</div>
+        <Button fill="lineTheme">实线</Button>
+        <Button fill="lineTheme" line="dashed">虚线</Button>
+        <Button fill="lineTheme" line="dotted">点线</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">不同大小</div>
+        <Button size="full" radius="none">通栏且无圆角</Button>
+        <Button>默认</Button>
+        <Button size="md">中号</Button>
+        <Button size="sm">小号</Button>
+        <Button size="auto">AUTO</Button>
+        <Button size="auto">
+            <div class="px-1">
+                <Icon name="ri-plane-fill" size={20} top={-2} />
+            </div>
+        </Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">不同高度</div>
+        <Button heightOut="0">外部高度为0</Button>
+        <Button heightIn="0">内部高度为0</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">固定大小</div>
+        <div class="flex justify-around items-center">
+            <Button customSize customWidth={40} customHeight={40} radius="full">宽</Button>
+            <Button customSize customWidth={40} customHeight={40} radius="xl">高</Button>
+            <Button customSize customWidth={40} customHeight={40}>一</Button>
+            <Button customSize customWidth={40} customHeight={40} radius="none">致</Button>
+            <Button fill="lineTheme" customSize customWidth={40} customHeight={40}>
+                <Icon name="ri-plane-fill" size={20} top={-2} />
+            </Button>
+            <Button radius="full" fill="lineTheme" customSize customWidth={40} customHeight={40}>
+                <Icon name="ri-plane-fill" size={20} top={-2} />
+            </Button>
+            <Button radius="full" line="dashed" fill="lineTheme" customSize customWidth={40} customHeight={40}>
+                <Icon name="ri-plane-fill" size={20} top={-2} />
+            </Button>
+            <Button radius="full" customSize customWidth={24} customHeight={24} heightIn="0">
+                <Icon name="ri-plane-fill" size={12} top={-2} />
+            </Button>
+        </div>
+    </div>
+    <div>
+        <div class="p-4 font-bold">禁用</div>
+        <Button disabled>禁用</Button>
+        <Button fill="lineTheme" disabled>禁用</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">加载</div>
+        <Button>
+            <Loading inverse height="6" width="6" />
+        </Button>
+        <Button>
+            <Loading inverse width="16" height="6" type="1_17" />
+        </Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">带图标</div>
+        <Button>
+            <Icon name="ri-share-forward-2-fill" size={18} top={-2} />
+            投掷二向箔
+        </Button>
+        <Button fill="lineTheme">
+            <Icon name="ri-mic-off-fill" size={16} top={-2} />
+            启动面壁计划
+        </Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">关爱版</div>
+        <Button love>关爱版按钮</Button>
+        <Button love fill="lineTheme">
+            <Icon name="ri-hand-heart-line" size={22} top={-2} />
+            关爱版按钮
+        </Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">自定义</div>
+        <Button injClass="bg-[#C84031] dark:bg-[#77B941]">纯色填充</Button>
+        <Button injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0] !text-white">渐变填充</Button>
+        <Button fill="line" injClass="border-[#C84031] dark:border-[#77B941] !text-[#C84031] dark:!text-[#77B941]">线性</Button>
+        <Button injClass="shadow-md shadow-black/30 dark:shadow-white/30">阴影</Button>
+        <Button radius="full" injClass="shadow-lg shadow-primary/40 dark:shadow-dark/40">颜色阴影</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">按钮组</div>
+        <Button fill="lineTheme" heightIn="0" group>
+            <div class="flex">
+                <div class="flex-1 border-r py-2 active:opacity-80">
+                    <Icon name="ri-apps-2-line" size={18} top={-2} />
+                    应用
+                </div>
+                <div class="flex-1 border-r py-2 active:opacity-80">
+                    <Icon name="ri-star-line" size={18} top={-2} />
+                    收藏
+                </div>
+                <!-- svelte-ignore a11y-click-events-have-key-events -->
+                <div class="flex-1 py-2 active:opacity-80" on:click={() => (visible = true)}>
+                    <Icon name="ri-share-forward-line" size={18} top={-2} />
+                    分享
+                </div>
+            </div>
+        </Button>
+        <Button radius="full" heightIn="0" group>
+            <div class="flex">
+                <div class="flex-1 border-r py-2 active:opacity-80">
+                    <Icon name="ri-apps-2-line" size={18} top={-2} />
+                    应用
+                </div>
+                <div class="flex-1 border-r py-2 active:opacity-80">
+                    <Icon name="ri-star-line" size={18} top={-2} />
+                    收藏
+                </div>
+                <!-- svelte-ignore a11y-click-events-have-key-events -->
+                <div class="flex-1 py-2 active:opacity-80" on:click={() => (visible = true)} role="button">
+                    <Icon name="ri-share-forward-line" size={18} top={-2} />
+                    分享
+                </div>
+            </div>
+        </Button>
+    </div>
+</div>
+<Toast bind:visible message="点击了按钮组中的分享!" />

+ 159 - 0
demo/src/pages/button/ButtonDemo_en.svelte

@@ -0,0 +1,159 @@
+<!-- Button Demo -->
+<script>
+    import { Button, Icon, Toast, Loading } from '../../../../components';
+
+    let visible = false;
+</script>
+
+<div class="flex flex-col space-y-8 py-8">
+    <div>
+        <div class="p-4 font-bold">Different states</div>
+        <Button>Default</Button>
+        <Button state="success">Success</Button>
+        <Button state="warning">Warning</Button>
+        <Button state="error">Error</Button>
+        <Button state="info">Information</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Different rounded style</div>
+        <Button>Default</Button>
+        <Button radius="none">No rounded</Button>
+        <Button radius="xl">Large rounded corner</Button>
+        <Button radius="2xl">Larger corner</Button>
+        <Button radius="full">Full rounded corner</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Different fill mode</div>
+        <Button>Default</Button>
+        <Button fill="line">Colorless linear</Button>
+        <Button fill="lineLight">Light color linearity</Button>
+        <Button fill="lineTheme">Theme color linear</Button>
+        <Button fill="text">Colorless pure text</Button>
+        <Button fill="textTheme">Pure text of theme color</Button>
+        <Button fill="colorLight">Light color filling</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Different border style</div>
+        <Button fill="lineTheme">Solid line</Button>
+        <Button fill="lineTheme" line="dashed">Dashed line</Button>
+        <Button fill="lineTheme" line="dotted">Dotted line</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Different size</div>
+        <Button size="full" radius="none">There is no rounded corner</Button>
+        <Button>Default</Button>
+        <Button size="md">Medium</Button>
+        <Button size="sm">Small</Button>
+        <Button size="auto">AUTO</Button>
+        <Button size="auto">
+            <div class="px-1">
+                <Icon name="ri-plane-fill" size={20} top={-2} />
+            </div>
+        </Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Different heights</div>
+        <Button heightOut="0">The external height is 0</Button>
+        <Button heightIn="0">Internal height is 0</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Fixed size</div>
+        <div class="flex justify-around items-center">
+            <Button customSize customWidth={40} customHeight={40} radius="full">W</Button>
+            <Button customSize customWidth={40} customHeight={40} radius="xl">&</Button>
+            <Button customSize customWidth={40} customHeight={40}>H</Button>
+            <Button customSize customWidth={40} customHeight={40} radius="none">equal</Button>
+            <Button fill="lineTheme" customSize customWidth={40} customHeight={40}>
+                <Icon name="ri-plane-fill" size={20} top={-2} />
+            </Button>
+            <Button radius="full" fill="lineTheme" customSize customWidth={40} customHeight={40}>
+                <Icon name="ri-plane-fill" size={20} top={-2} />
+            </Button>
+            <Button radius="full" line="dashed" fill="lineTheme" customSize customWidth={40} customHeight={40}>
+                <Icon name="ri-plane-fill" size={20} top={-2} />
+            </Button>
+            <Button radius="full" customSize customWidth={24} customHeight={24} heightIn="0">
+                <Icon name="ri-plane-fill" size={12} top={-2} />
+            </Button>
+        </div>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Disable</div>
+        <Button disabled>Disable</Button>
+        <Button fill="lineTheme" disabled>Disable</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Load</div>
+        <Button>
+            <Loading inverse height="6" width="6" />
+        </Button>
+        <Button>
+            <Loading inverse width="16" height="6" type="1_17" />
+        </Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Icon</div>
+        <Button>
+            <Icon name="ri-share-forward-2-fill" size={18} top={-2} />
+            Throw the two way foil
+        </Button>
+        <Button fill="lineTheme">
+            <Icon name="ri-mic-off-fill" size={16} top={-2} />
+            Start the surface wall plan
+        </Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Love version</div>
+        <Button love>Care version button</Button>
+        <Button love fill="lineTheme">
+            <Icon name="ri-hand-heart-line" size={22} top={-2} />
+            Care version button
+        </Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Customize</div>
+        <Button injClass="bg-[#C84031] dark:bg-[#77B941]">Solid color filling</Button>
+        <Button injClass="bg-gradient-to-r from-[#CE9FFC] to-[#7367F0] !text-white">Gradient filling</Button>
+        <Button fill="line" injClass="border-[#C84031] dark:border-[#77B941] !text-[#C84031] dark:!text-[#77B941]">Linear</Button>
+        <Button injClass="shadow-md shadow-black/30 dark:shadow-white/30">Shadow</Button>
+        <Button radius="full" injClass="shadow-lg shadow-primary/40 dark:shadow-dark/40">Shadow</Button>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Button group</div>
+        <Button fill="lineTheme" heightIn="0" group>
+            <div class="flex">
+                <div class="flex-1 border-r py-2 active:opacity-80">
+                    <Icon name="ri-apps-2-line" size={18} top={-2} />
+                    Application
+                </div>
+                <div class="flex-1 border-r py-2 active:opacity-80">
+                    <Icon name="ri-star-line" size={18} top={-2} />
+                    Collect
+                </div>
+                <!-- svelte-ignore a11y-click-events-have-key-events -->
+                <div class="flex-1 py-2 active:opacity-80" on:click={() => (visible = true)}>
+                    <Icon name="ri-share-forward-line" size={18} top={-2} />
+                    Share
+                </div>
+            </div>
+        </Button>
+        <Button radius="full" heightIn="0" group>
+            <div class="flex">
+                <div class="flex-1 border-r py-2 active:opacity-80">
+                    <Icon name="ri-apps-2-line" size={18} top={-2} />
+                    Application
+                </div>
+                <div class="flex-1 border-r py-2 active:opacity-80">
+                    <Icon name="ri-star-line" size={18} top={-2} />
+                    Collect
+                </div>
+                <!-- svelte-ignore a11y-click-events-have-key-events -->
+                <div class="flex-1 py-2 active:opacity-80" on:click={() => (visible = true)} role="button">
+                    <Icon name="ri-share-forward-line" size={18} top={-2} />
+                    Share
+                </div>
+            </div>
+        </Button>
+    </div>
+</div>
+<Toast bind:visible message="Click share in the button group!" />

+ 176 - 0
demo/src/pages/calendar/CalendarDemo.svelte

@@ -0,0 +1,176 @@
+<!-- Calendar Demo -->
+<script>
+    import { Cell, Calendar } from '../../../../components';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+    let visible12 = false;
+    let visible13 = false;
+    let visible14 = false;
+    let visible15 = false;
+    let visible16 = false;
+    let visible17 = false;
+    let visible18 = false;
+    let visible19 = false;
+    let visible20 = false;
+    let visible21 = false;
+    let visible22 = false;
+    let visible23 = false;
+
+    // 随机取出当前日期后的6天,组成 infoDates 数组,其中 date 格式为 YYYYMMDD,月和日补足2位
+    const now = new Date();
+    const infoDates = [];
+    for (let i = 0; i < 6; i++) {
+        const date = new Date(now.getTime() + i * 24 * 60 * 60 * 1000);
+        infoDates.push(
+            `${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}`
+        );
+    }
+    // 循环 infoDates ,按照顺序,将每一项转为对象,date 为日期,info分别为出发、入住、购物、 拍照、离店、回程
+    infoDates.forEach((date, index) => {
+        infoDates[index] = {
+            date,
+            info: ['出发', '入住', '购物', '拍照', '离店', '回程'][index],
+        };
+    });
+
+    // 获取当前日期的前7天和后7天共14天,组成数组 disabledDates,其中 date 格式为 YYYYMMDD,月和日补足2位
+    const disabledDates = [];
+    const before7 = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
+    for (let i = 0; i < 14; i++) {
+        const date = new Date(before7.getTime() + i * 24 * 60 * 60 * 1000);
+        disabledDates.push(
+            `${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}`
+        );
+    }
+    // 传入数字 n,返回当前月份往前推第 n 个月的月份,格式为 YYYYMM,月份补足2位
+    const getInitMonth = n => {
+        const now = new Date();
+        const year = now.getFullYear();
+        const month = now.getMonth() + 1;
+        const newMonth = month - n;
+        if (newMonth > 0) {
+            return `${year}${newMonth.toString().padStart(2, '0')}`;
+        } else {
+            return `${year - 1}${(12 + newMonth).toString().padStart(2, '0')}`;
+        }
+    };
+    const initMonth = getInitMonth(3);
+
+    const quickSelects = ['week', 'month', 'quarter', -3, -7, -30, 3, 7, 30];
+    const quickSelectsDay = [-5, -2, 3, 7];
+
+    let selectedDates = [];
+    const getSelectedDatesFunc = e => {
+        selectedDates = e.detail.dates;
+    };
+
+    let selectedFormatDates = [];
+    const getSelectedFormatDatesFunc = e => {
+        selectedFormatDates = e.detail.dates;
+    };
+</script>
+
+<div class="py-4">
+    <Cell title="基础用法" on:click={() => (visible1 = true)} />
+    <Calendar bind:visible={visible1} />
+
+    <Cell title="多选" on:click={() => (visible7 = true)} />
+    <Calendar bind:visible={visible7} mode="multiple" />
+
+    <Cell title="范围选择" on:click={() => (visible8 = true)} />
+    <Calendar bind:visible={visible8} mode="range" />
+
+    <Cell title="从周日开始" on:click={() => (visible2 = true)} />
+    <Calendar bind:visible={visible2} startSunday />
+
+    <Cell title="周末文字标红" on:click={() => (visible3 = true)} />
+    <Calendar bind:visible={visible3} weekendRed />
+
+    <Cell title="不使用卡片样式且加水印" on:click={() => (visible4 = true)} />
+    <Calendar bind:visible={visible4} monthCard={false} monthMark />
+
+    <Cell title="高一点" on:click={() => (visible5 = true)} />
+    <Calendar bind:visible={visible5} height={60} />
+
+    <Cell title="自定义显示信息的日期" on:click={() => (visible6 = true)} />
+    <Calendar bind:visible={visible6} {infoDates} />
+
+    <Cell title="不要圆角" on:click={() => (visible9 = true)} />
+    <Calendar bind:visible={visible9} mode="range" radius="none" />
+
+    <Cell title="加大圆角" on:click={() => (visible10 = true)} />
+    <Calendar bind:visible={visible10} mode="range" radius="2xl" />
+
+    <Cell title="滚动时关闭动画" on:click={() => (visible18 = true)} />
+    <Calendar bind:visible={visible18} useAnimation={false} />
+
+    <Cell title="配置确认按钮样式" on:click={() => (visible11 = true)} />
+    <Calendar bind:visible={visible11} button={{ radius: 'full' }} />
+
+    <Cell title="顶部来点圆角" on:click={() => (visible19 = true)} />
+    <Calendar bind:visible={visible19} popup={{ radius: 'xl' }} />
+
+    <Cell title="定义开始与结束月" on:click={() => (visible12 = true)} />
+    <Calendar bind:visible={visible12} startMonth="202101" endMonth="202106" />
+
+    <Cell title="自定义不可选日期" on:click={() => (visible13 = true)} />
+    <Calendar bind:visible={visible13} {disabledDates} mode="range" />
+
+    <Cell title="多选或范围选择时不显示已选天数" on:click={() => (visible14 = true)} />
+    <Calendar bind:visible={visible14} mode="range" showSelectedDay={false} />
+
+    <Cell title="自定义初始显示月份" subTitle="开始月份为当前月份前第三个月" on:click={() => (visible15 = true)} />
+    <Calendar bind:visible={visible15} {initMonth} />
+
+    <Cell title="展示一些快速选择项" on:click={() => (visible16 = true)} />
+    <Calendar bind:visible={visible16} mode="range" {quickSelects} />
+
+    <Cell title="快速选择天数时包含当天" on:click={() => (visible23 = true)} />
+    <Calendar bind:visible={visible23} mode="range" quickSelects={quickSelectsDay} includeToday />
+
+    <Cell title="从周日开始快速选择本周" on:click={() => (visible17 = true)} />
+    <Calendar bind:visible={visible17} mode="range" startSunday quickSelects={['week']} />
+
+    <div class="px-4">
+        {#if selectedDates.length}
+            当前选定了以下共 {selectedDates.length} 天:
+        {:else}
+            <div>请选定日期</div>
+        {/if}
+    </div>
+    <div class="grid grid-cols-4 gap-2 p-2 text-primary dark:text-dark">
+        {#each selectedDates as item}
+            <div class="text-center">{item}</div>
+        {/each}
+    </div>
+    <Cell title="获取返回的选定日期" on:click={() => (visible20 = true)} />
+    <Calendar bind:visible={visible20} mode="range" on:confirm={getSelectedDatesFunc} />
+
+    <div class="px-4">
+        {#if selectedFormatDates.length}
+            当前选定了以下共 {selectedFormatDates.length} 天:
+        {:else}
+            <div>请选定日期</div>
+        {/if}
+    </div>
+    <div class="grid grid-cols-3 gap-2 p-2 text-primary dark:text-dark text-sm">
+        {#each selectedFormatDates as item}
+            <div class="text-center">{item}</div>
+        {/each}
+    </div>
+    <Cell title="自定义返回的日期格式" on:click={() => (visible21 = true)} />
+    <Calendar bind:visible={visible21} mode="range" outFormat="Y年M月D日" on:confirm={getSelectedFormatDatesFunc} />
+
+    <Cell title="今日日期关闭高亮显示" on:click={() => (visible22 = true)} />
+    <Calendar bind:visible={visible22} highlightToday={false} />
+</div>

+ 180 - 0
demo/src/pages/calendar/CalendarDemo_en.svelte

@@ -0,0 +1,180 @@
+<!-- Calendar Demo -->
+<script>
+    import { Cell, Calendar } from '../../../../components';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+    let visible12 = false;
+    let visible13 = false;
+    let visible14 = false;
+    let visible15 = false;
+    let visible16 = false;
+    let visible17 = false;
+    let visible18 = false;
+    let visible19 = false;
+    let visible20 = false;
+    let visible21 = false;
+    let visible22 = false;
+    let visible23 = false;
+
+    // The 6 days after the current date randomly takes out the INFODATES array, the Date format is yyyymmdd, and the month and day make up for 2 digits
+    const now = new Date();
+    const infoDates = [];
+    for (let i = 0; i < 6; i++) {
+        const date = new Date(now.getTime() + i * 24 * 60 * 60 * 1000);
+        infoDates.push(
+            `${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}`
+        );
+    }
+    // Loop infoDates, in turn, each item is converted to an object, date is the date, and info is respectively departure, check-in, shopping, photography, check-out, and return
+    infoDates.forEach((date, index) => {
+        infoDates[index] = {
+            date,
+            info: ['Set off', 'Stay', 'Shopping', 'Photo', 'Leave', 'Return'][index],
+        };
+    });
+
+    // For a total of 14 days before the current date and 7 days after 7 days, the formation of the array DisableDates. The DATE format is yyyymmdd, and the month and day are added.
+    const disabledDates = [];
+    const before7 = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
+    for (let i = 0; i < 14; i++) {
+        const date = new Date(before7.getTime() + i * 24 * 60 * 60 * 1000);
+        disabledDates.push(
+            `${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}`
+        );
+    }
+    // Pass the number N and return to the month of the N -month month in the current month. The format is yyyymm, and the month is added 2 digits.
+    const getInitMonth = n => {
+        const now = new Date();
+        const year = now.getFullYear();
+        const month = now.getMonth() + 1;
+        const newMonth = month - n;
+        if (newMonth > 0) {
+            return `${year}${newMonth.toString().padStart(2, '0')}`;
+        } else {
+            return `${year - 1}${(12 + newMonth).toString().padStart(2, '0')}`;
+        }
+    };
+    const initMonth = getInitMonth(3);
+
+    const quickSelects = ['week', 'month', 'quarter', -3, -7, -30, 3, 7, 30];
+    const quickSelectsDay = [-5, -2, 3, 7];
+
+    let selectedDates = [];
+    const getSelectedDatesFunc = e => {
+        selectedDates = e.detail.dates;
+    };
+
+    let selectedFormatDates = [];
+    const getSelectedFormatDatesFunc = e => {
+        selectedFormatDates = e.detail.dates;
+    };
+</script>
+
+<div class="py-4">
+    <Cell title="Basic usage" on:click={() => (visible1 = true)} />
+    <Calendar bind:visible={visible1} />
+
+    <Cell title="Choice" on:click={() => (visible7 = true)} />
+    <Calendar bind:visible={visible7} mode="multiple" />
+
+    <Cell title="Range selection" on:click={() => (visible8 = true)} />
+    <Calendar bind:visible={visible8} mode="range" />
+
+    <Cell title="Starting from Sunday" on:click={() => (visible2 = true)} />
+    <Calendar bind:visible={visible2} startSunday />
+
+    <Cell title="Weekend text marking red" on:click={() => (visible3 = true)} />
+    <Calendar bind:visible={visible3} weekendRed />
+
+    <Cell title="No card style but add watermark" on:click={() => (visible4 = true)} />
+    <Calendar bind:visible={visible4} monthCard={false} monthMark />
+
+    <Cell title="Higher" on:click={() => (visible5 = true)} />
+    <Calendar bind:visible={visible5} height={60} />
+
+    <Cell title="Customize the date of display information" on:click={() => (visible6 = true)} />
+    <Calendar bind:visible={visible6} {infoDates} />
+
+    <Cell title="Do not round the corner" on:click={() => (visible9 = true)} />
+    <Calendar bind:visible={visible9} mode="range" radius="none" />
+
+    <Cell title="Increase the corner" on:click={() => (visible10 = true)} />
+    <Calendar bind:visible={visible10} mode="range" radius="2xl" />
+
+    <Cell title="Turn off the animation when rolling" on:click={() => (visible18 = true)} />
+    <Calendar bind:visible={visible18} useAnimation={false} />
+
+    <Cell title="Configure confirmation button style" on:click={() => (visible11 = true)} />
+    <Calendar bind:visible={visible11} button={{ radius: 'full' }} />
+
+    <Cell title="Top rounded corner" on:click={() => (visible19 = true)} />
+    <Calendar bind:visible={visible19} popup={{ radius: 'xl' }} />
+
+    <Cell title="Definition start and end month" on:click={() => (visible12 = true)} />
+    <Calendar bind:visible={visible12} startMonth="202101" endMonth="202106" />
+
+    <Cell title="Customize the unsalented date" on:click={() => (visible13 = true)} />
+    <Calendar bind:visible={visible13} {disabledDates} mode="range" />
+
+    <Cell title="No showed days have been displayed" on:click={() => (visible14 = true)} />
+    <Calendar bind:visible={visible14} mode="range" showSelectedDay={false} />
+
+    <Cell
+        title="Customized initial display month"
+        subTitle="Third month before the current month"
+        on:click={() => (visible15 = true)}
+    />
+    <Calendar bind:visible={visible15} {initMonth} />
+
+    <Cell title="Show some fast selection items" on:click={() => (visible16 = true)} />
+    <Calendar bind:visible={visible16} mode="range" {quickSelects} />
+
+    <Cell title="Quickly choose to include that day" on:click={() => (visible23 = true)} />
+    <Calendar bind:visible={visible23} mode="range" quickSelects={quickSelectsDay} includeToday />
+
+    <Cell title="Select this week from Sunday" on:click={() => (visible17 = true)} />
+    <Calendar bind:visible={visible17} mode="range" startSunday quickSelects={['week']} />
+
+    <div class="px-4">
+        {#if selectedDates.length}
+            The following is the following total {selectedDates.length} day:
+        {:else}
+            <div>Please select the date</div>
+        {/if}
+    </div>
+    <div class="grid grid-cols-4 gap-2 p-2 text-primary dark:text-dark">
+        {#each selectedDates as item}
+            <div class="text-center">{item}</div>
+        {/each}
+    </div>
+    <Cell title="Get the selection date of returning" on:click={() => (visible20 = true)} />
+    <Calendar bind:visible={visible20} mode="range" on:confirm={getSelectedDatesFunc} />
+
+    <div class="px-4">
+        {#if selectedFormatDates.length}
+            The following is the following total {selectedFormatDates.length} day:
+        {:else}
+            <div>Please select the date</div>
+        {/if}
+    </div>
+    <div class="grid grid-cols-3 gap-2 p-2 text-primary dark:text-dark text-sm">
+        {#each selectedFormatDates as item}
+            <div class="text-center">{item}</div>
+        {/each}
+    </div>
+    <Cell title="Customized date format" on:click={() => (visible21 = true)} />
+    <Calendar bind:visible={visible21} mode="range" outFormat="M/D/Y" on:confirm={getSelectedFormatDatesFunc} />
+
+    <Cell title="Turn off today's highlight display" on:click={() => (visible22 = true)} />
+    <Calendar bind:visible={visible22} highlightToday={false} />
+</div>

+ 109 - 0
demo/src/pages/cell/CellDemo.svelte

@@ -0,0 +1,109 @@
+<!-- Cell Demo -->
+<script>
+    import { Cell, CellGroup, Toast } from '../../../../components';
+
+    let visible = false;
+</script>
+
+<div class="flex flex-col space-y-8 py-8">
+    <div>
+        <Cell title="基础用法" />
+        <Cell title="右侧有详情" detail="归零者" />
+        <Cell title="详情使用 Slot" detail="slot">
+            <span slot="detail" class="text-primary dark:text-dark text-xs">我是插槽内容</span>
+        </Cell>
+        <Cell title="右侧无箭头" right="none" />
+        <Cell title="点击事件" detail="请点击我" on:click={() => (visible = true)} />
+        <Toast bind:visible message="你戳到我了!" />
+        <Cell title="右侧有详情无箭头" detail="归零者" right="none" />
+        <Cell title="右侧开关(点击整行皆可触发开关)" right={{ type: 'switch' }} />
+        <Cell title="开关带详情" detail="解释一下" right={{ type: 'switch' }} />
+        <Cell title="开关带文字" right={{ type: 'switch', switch: { inside: ['😭', '😄'] } }} />
+        <Cell title="开关全圆角" right={{ type: 'switch', switch: { radius: 'full' } }} />
+        <Cell title="左侧使用 Icon 组件" left={{ name: 'ri-bank-line', size: 20, theme: true, top: -2 }} />
+        <Cell title="右侧使用 Icon 组件" right={{ type: 'icon', name: 'ri-battery-charge-line', size: 20, theme: true }} />
+        <Cell title="左侧自定义图片" left="slot">
+            <div slot="left" class="w-6 h-6 mr-1">
+                <img class="w-auto" src="/assets/images/icon_颁奖.png" alt="" />
+            </div>
+        </Cell>
+        <Cell title="左右都自定义图片" left="slot" right="slot">
+            <div slot="left" class="w-6 h-6 mr-1">
+                <img class="w-auto" src="/assets/images/icon_评价.png" alt="" />
+            </div>
+            <div slot="right" class="w-6 h-6 mr-1">
+                <img class="w-auto" src="/assets/images/icon_美食.png" alt="" />
+            </div>
+        </Cell>
+        <Cell title="来张大点的图" left="slot">
+            <div slot="left" class="w-10 h-10 mr-1">
+                <img class="w-auto" src="/assets/images/icon_会员.png" alt="" />
+            </div>
+        </Cell>
+        <Cell title="左侧有次级标题" subTitle="我是次,但我不次" />
+        <Cell title="有次级标题和右侧详情" subTitle="我是次,但我不次" detail="归零者" />
+        <Cell title="右侧有次级信息" detail="归零者" info="重启者" />
+        <Cell title="左右侧都有次级内容" subTitle="我是次,但我不次" detail="归零者" info="重启者" />
+        <Cell title="左右侧都有次级内容" subTitle="我是次,但我不次" detail="再来个箭头" info="重启者" />
+        <Cell
+            title="右右侧都有次级内容"
+            subTitle="左侧再来个 Icon"
+            detail="再来个箭头"
+            info="重启者"
+            left={{ name: 'ri-shopping-basket-line', theme: true }}
+        />
+        <Cell title="图片什么也来吧" left="slot" subTitle="左侧自定义图片" detail="右侧箭头" info="底部无分割线">
+            <div slot="left" class="w-10 h-10 mr-1">
+                <img class="w-auto" src="/assets/images/icon_火车票.png" alt="" />
+            </div>
+        </Cell>
+        <Cell
+            title="标题超长长长长长长长长长长长长长长长长长长长,自动换行。"
+            subTitle="我这个次级标题也很长长长长长长长长长长长长长长长长长长长长长长长长长长。"
+        />
+        <Cell
+            title="左侧自定义大图片,标题超长,自动换行。其余的搭配自己去尝试吧。"
+            subTitle="我这个次级标题也很...哦不长了。"
+            left="slot"
+            line={false}
+        >
+            <div slot="left" class="w-28 h-6 mr-1">
+                <img class="w-auto" src="/assets/images/icon_外卖.png" alt="" />
+            </div>
+        </Cell>
+    </div>
+
+    <CellGroup>
+        <Cell title="组合使用" mx="0" my="0" shadow="none" line radius="none" />
+        <Cell title="组合使用" mx="0" my="0" shadow="none" radius="none" />
+    </CellGroup>
+    <CellGroup mx="0" radius="none">
+        <Cell title="组合使用" detail="无横向间距" mx="0" my="0" shadow="none" line radius="none" />
+        <Cell title="组合使用" detail="无圆角" mx="0" my="0" shadow="none" radius="none" />
+    </CellGroup>
+    <CellGroup shadow="xl" radius="2xl">
+        <Cell title="组合使用" detail="加大投影" mx="0" my="0" shadow="none" line radius="none" />
+        <Cell title="组合使用" detail="加大圆角" mx="0" my="0" shadow="none" radius="none" />
+    </CellGroup>
+
+    <div>
+        <Cell title="左右无间距" mx="0" radius="none" />
+        <Cell title="无圆角" radius="none" />
+        <Cell title="基础圆角" radius="base" />
+        <Cell title="中等圆角" radius="md" />
+        <Cell title="大圆角" radius="lg" />
+        <Cell title="加大圆角" radius="xl" />
+        <Cell title="更大圆角" radius="2xl" />
+        <Cell title="全圆角" radius="full" />
+        <Cell title="加大投影" shadow="lg" />
+    </div>
+    <div>
+        <Cell title="自定义文字颜色" injClass="text-primary dark:text-dark" />
+        <Cell title="自定义背景颜色" injClass="!bg-purple/20 active:!bg-purple/10" line={false} />
+    </div>
+    <div>
+        <Cell love title="关爱版" />
+        <Cell love title="关爱版" detail="关爱版" />
+        <Cell love title="关爱版" left={{ name: 'ri-hand-heart-line', theme: true }} />
+    </div>
+</div>

+ 109 - 0
demo/src/pages/cell/CellDemo_en.svelte

@@ -0,0 +1,109 @@
+<!-- Cell Demo -->
+<script>
+    import { Cell, CellGroup, Toast } from '../../../../components';
+
+    let visible = false;
+</script>
+
+<div class="flex flex-col space-y-8 py-8">
+    <div>
+        <Cell title="Basic usage" />
+        <Cell title="There are details on the right are details on the right" detail="Zero" />
+        <Cell title="Use for details Slot" detail="slot">
+            <span slot="detail" class="text-primary dark:text-dark text-xs">I am a slot content</span>
+        </Cell>
+        <Cell title="There is no arrow on the right" right="none" />
+        <Cell title="Click event" detail="Please click me" on:click={() => (visible = true)} />
+        <Toast bind:visible message="You poke to me!" />
+        <Cell title="There are details on the right without arrows" detail="Zero" right="none" />
+        <Cell title="The right switch (click the whole line to trigger the switch)" right={{ type: 'switch' }} />
+        <Cell title="Switch with details" detail="explain" right={{ type: 'switch' }} />
+        <Cell title="Switch with text" right={{ type: 'switch', switch: { inside: ['😭', '😄'] } }} />
+        <Cell title="Switch full round corner" right={{ type: 'switch', switch: { radius: 'full' } }} />
+        <Cell title="Use on the left Icon" left={{ name: 'ri-bank-line', size: 20, theme: true, top: -2 }} />
+        <Cell title="Use on the right side Icon" right={{ type: 'icon', name: 'ri-battery-charge-line', size: 20, theme: true }} />
+        <Cell title="Left custom picture" left="slot">
+            <div slot="left" class="w-6 h-6 mr-1">
+                <img class="w-auto" src="/assets/images/icon_颁奖.png" alt="" />
+            </div>
+        </Cell>
+        <Cell title="Custom pictures are all left and right" left="slot" right="slot">
+            <div slot="left" class="w-6 h-6 mr-1">
+                <img class="w-auto" src="/assets/images/icon_评价.png" alt="" />
+            </div>
+            <div slot="right" class="w-6 h-6 mr-1">
+                <img class="w-auto" src="/assets/images/icon_美食.png" alt="" />
+            </div>
+        </Cell>
+        <Cell title="Come to a big picture" left="slot">
+            <div slot="left" class="w-10 h-10 mr-1">
+                <img class="w-auto" src="/assets/images/icon_会员.png" alt="" />
+            </div>
+        </Cell>
+        <Cell title="There is a secondary title on the left" subTitle="I am, but I am not second" />
+        <Cell title="There are secondary title and right details" subTitle="I am, but I am not second" detail="Zero" />
+        <Cell title="There is secondary information on the right" detail="Zero" info="Restart" />
+        <Cell title="There are secondary content on the left and right sides" subTitle="I am, but I am not second" detail="Zero" info="Restart" />
+        <Cell title="There are secondary content on the left and right sides" subTitle="I am, but I am not second" detail="Come again" info="Restart" />
+        <Cell
+            title="There are secondary content on the right and right"
+            subTitle="Come again on the left Icon"
+            detail="Come again"
+            info="Restart"
+            left={{ name: 'ri-shopping-basket-line', theme: true }}
+        />
+        <Cell title="Come on the picture too" left="slot" subTitle="Left custom picture" detail="Right arrow" info="There is no segmentation line at the bottom">
+            <div slot="left" class="w-10 h-10 mr-1">
+                <img class="w-auto" src="/assets/images/icon_火车票.png" alt="" />
+            </div>
+        </Cell>
+        <Cell
+            title="The title is long, long, long, long, long, long, long, long, long, long, long, long, long, long, and long, and automatically changed."
+            subTitle="My secondary title is also very long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long, long."
+        />
+        <Cell
+            title="The big picture on the left is a big picture, the title is super long, and it is automatically changed. Try the rest of the match."
+            subTitle="My secondary title is also very good...Oh not long."
+            left="slot"
+            line={false}
+        >
+            <div slot="left" class="w-28 h-6 mr-1">
+                <img class="w-auto" src="/assets/images/icon_外卖.png" alt="" />
+            </div>
+        </Cell>
+    </div>
+
+    <CellGroup>
+        <Cell title="Group" mx="0" my="0" shadow="none" line radius="none" />
+        <Cell title="Group" mx="0" my="0" shadow="none" radius="none" />
+    </CellGroup>
+    <CellGroup mx="0" radius="none">
+        <Cell title="Group" detail="No horizontal spacing" mx="0" my="0" shadow="none" line radius="none" />
+        <Cell title="Group" detail="Non rounded" mx="0" my="0" shadow="none" radius="none" />
+    </CellGroup>
+    <CellGroup shadow="xl" radius="2xl">
+        <Cell title="Group" detail="Increase projection" mx="0" my="0" shadow="none" line radius="none" />
+        <Cell title="Group" detail="Increase the corner" mx="0" my="0" shadow="none" radius="none" />
+    </CellGroup>
+
+    <div>
+        <Cell title="Left -right distance" mx="0" radius="none" />
+        <Cell title="Non -rounded" radius="none" />
+        <Cell title="Basic rounded corner" radius="base" />
+        <Cell title="Medium corner" radius="md" />
+        <Cell title="Large rounded corner" radius="lg" />
+        <Cell title="Increase the corner" radius="xl" />
+        <Cell title="Larger corner" radius="2xl" />
+        <Cell title="All -rounded corner" radius="full" />
+        <Cell title="Increase projection" shadow="lg" />
+    </div>
+    <div>
+        <Cell title="Custom text color" injClass="text-primary dark:text-dark" />
+        <Cell title="Custom background color" injClass="!bg-purple/20 active:!bg-purple/10" line={false} />
+    </div>
+    <div>
+        <Cell love title="Love version" />
+        <Cell love title="Love version" detail="Love version" />
+        <Cell love title="Love version" left={{ name: 'ri-hand-heart-line', theme: true }} />
+    </div>
+</div>

+ 304 - 0
demo/src/pages/checkbox/CheckboxDemo.svelte

@@ -0,0 +1,304 @@
+<!-- Checkbox Demo -->
+<script>
+    import { CheckboxGroup, Checkbox, Divider, Button } from '../../../../components';
+    import { onMount } from 'svelte';
+    import { quintOut } from 'svelte/easing';
+    import { crossfade } from 'svelte/transition';
+    import { flip } from 'svelte/animate';
+
+    const dota = [
+        { label: '主宰', name: '奶棒人', desc: '主宰是一个近战敏捷英雄,他能够迅速切入战斗。' },
+        { label: '白牛', name: '令狐冲', desc: '巴拉森,裂魂人是一个强大的 Gank 型的力量型近战英雄。' },
+        { label: '光法', name: '光之守卫', desc: '伊扎洛,光之守卫,他是一个著名的辅助性智力英雄。' },
+        { label: '猛犸', name: '马格纳斯', desc: '猛犸?为什么不 BAN 猛犸?为什么不 BAN 猛犸?' },
+    ];
+    let checkeds = [];
+    const dotaFun = e => {
+        checkeds = e.detail;
+    };
+
+    const dotaImgs = ['火女', '小牛', '水人', '火枪', '斯温'];
+    let imgCheckeds = ['火女'];
+    const dotaImgsFun = e => {
+        imgCheckeds = e.detail;
+    };
+
+    const dotaVoices = [
+        { label: '祈求者', name: '祈求者', voices: ['“来自于伟大的奥秘。”'] },
+        { label: '风暴之灵', name: '风暴之灵', voices: ['“喂~快醒醒,快喝点咖啡,我方上塔正遭受攻击。”'] },
+        {
+            label: '蝙蝠骑士',
+            name: '蝙蝠骑士',
+            voices: ['“哦,莉娜,当我的压寨夫人怎么样?”', '“哦,风行者,见着我你不用跑。”', '“水晶室女,你就像一个装满冰水的高脚杯。”'],
+        },
+        { label: '潮汐猎人', name: '潮汐猎人', voices: ['“我还能吃下一根海藻。”'] },
+    ];
+    let voiceCheckeds = [];
+    const dotaVoicesFun = e => {
+        voiceCheckeds = e.detail;
+    };
+
+    const dotaInlines = ['火女', '小牛', '水人', '火枪', '斯温', '祈求者', '潮汐', '蝙蝠', '猛犸'];
+    let checkInlines = ['小牛', '水人'];
+    const dotaInlineFun = e => {
+        checkInlines = e.detail;
+    };
+
+    const dotaAll = ['火女', '小牛', '水人', '火枪', '斯温', '祈求者', '潮汐', '蝙蝠', '猛犸'];
+    let checkDotas = ['火枪', '斯温'];
+    $: noCheckDotas = dotaAll.filter(a => !checkDotas.some(b => b === a));
+    let outControl = true;
+    // 点击单项
+    const dotaAllFun = e => {
+        outControl = false;
+        checkDotas = e.detail;
+    };
+    // 全选
+    const checkAllFun = () => {
+        outControl = true;
+        checkDotas = dotaAll;
+    };
+    // 全不选
+    const checkNoneFun = () => {
+        outControl = true;
+        checkDotas = [];
+    };
+    // 反选
+    const checkReverseFun = () => {
+        outControl = true;
+        checkDotas = dotaAll.filter(a => !checkDotas.some(b => b === a));
+    };
+
+    const animates = ['火女', '小牛', '水人', '火枪', '斯温', '祈求者', '潮汐', '蝙蝠', '猛犸'];
+    let animateNos = ['火女', '小牛', '水人', '火枪', '斯温', '祈求者'];
+    $: animateYess = animates.filter(a => !animateNos.some(b => b === a));
+    const checkAnimateNoFun = e => {
+        animateNos = animateNos.filter(a => !e.detail.some(b => b === a));
+    };
+    const checkAnimaYesFun = e => {
+        animateNos = animates.filter(a => !e.detail.some(b => b === a));
+    };
+    const [send, receive] = crossfade({
+        duration: d => Math.sqrt(d * 150),
+        fallback(node, params) {
+            const style = getComputedStyle(node);
+            const transform = style.transform === 'none' ? '' : style.transform;
+            return {
+                duration: 600,
+                easing: quintOut,
+                css: t => `
+					transform: ${transform} scale(${t});
+					opacity: ${t}
+				`,
+            };
+        },
+    });
+    // 设定高度,避免页面高度变化影响点击体验。
+    let heights = 0;
+    let animateHeight = 0;
+    onMount(() => {
+        animateHeight = (heights / 6) * 9 + 32;
+    });
+</script>
+
+<div class="px-4">
+    <div class="mt-8 mb-4 font-bold text-2xl">横向排列</div>
+    <div class="mt-6 mb-4 font-bold text-lg">简单用法</div>
+    <CheckboxGroup layout="h">
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name}>{item.label}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">文字在不同位置</div>
+    <CheckboxGroup layout="h">
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name} textPosition="l">{item.label}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+    <Divider />
+    <CheckboxGroup layout="h">
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name} textPosition="b">{item.label}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+    <Divider />
+    <CheckboxGroup layout="h">
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name} textPosition="t">{item.label}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">自定义图标</div>
+    <CheckboxGroup layout="h">
+        <Checkbox checkeds={[]} icon={{ name: 'ri-checkbox-blank-circle-line' }} iconChecked={{ name: 'ri-radio-button-fill' }} name="奶棒人">主宰</Checkbox>
+        <Checkbox checkeds={[]} icon={{ name: 'ri-checkbox-circle-line' }} iconChecked={{ name: 'ri-checkbox-circle-fill' }} name="令狐冲">白牛</Checkbox>
+        <Checkbox checkeds={[]} icon={{ name: 'ri-checkbox-multiple-line' }} iconChecked={{ name: 'ri-checkbox-multiple-fill' }} name="光之守卫">光法</Checkbox>
+        <Checkbox checkeds={[]} icon={{ name: 'ri-check-line' }} iconChecked={{ name: 'ri-check-fill' }} name="马格纳斯">猛犸</Checkbox>
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">图片选项</div>
+    <CheckboxGroup layout="h" on:change={dotaImgsFun}>
+        {#each dotaImgs as dota}
+            <Checkbox
+                name={dota}
+                textPosition="t"
+                icon={{ name: 'ri-arrow-up-s-line' }}
+                iconChecked={{ name: 'ri-arrow-up-s-fill' }}
+                outControl
+                checkeds={imgCheckeds}
+            >
+                <div class={`w-12 h-12 mb-1 rounded overflow-hidden ${imgCheckeds.includes(dota) ? 'ring-2 ring-primary dark:ring-dark' : ''}`}>
+                    <img class="w-full h-full object-cover" src={`./assets/images/dota_${dota}.png`} alt="" />
+                </div>
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+    <div class="text-sm">
+        {imgCheckeds.length > 0 ? '已选' : '未选择任何英雄。'}
+        <span class="text-[red]">{imgCheckeds.join(' + ')}</span>{imgCheckeds.length > 0 ? '。' : ''}
+    </div>
+
+    <div class="mt-8 mb-4 font-bold text-lg">不用图标 && 使用 Button</div>
+    <CheckboxGroup layout="h" on:change={dotaFun}>
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name} icon="none" iconChecked="none">
+                <Button fill={checkeds.includes(item.name) ? 'base' : 'lineLight'} size="auto" injClass="px-4">{item.label}</Button>
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">不用图标 && 自定义选中效果</div>
+    <CheckboxGroup layout="h" on:change={dotaFun}>
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name} icon="none" iconChecked="none">
+                <div
+                    class={`border py-0.5 px-5 text-sm rounded ${
+                        checkeds.includes(item.name)
+                            ? 'text-primary dark:text-dark bg-primary/10 dark:bg-dark/10'
+                            : 'bg-gray9 dark:bg-gray4 border-gray8 dark:border-gray5 text-gray6'
+                    }`}
+                >
+                    {item.label}
+                </div>
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+</div>
+<Divider />
+
+<div class="px-4">
+    <div class="mb-4 font-bold text-2xl">行内元素排列</div>
+    <div class="mt-8 mb-4 font-bold text-lg">不用图标 && 行内元素排列</div>
+    <CheckboxGroup layout="inline" wrap on:change={dotaInlineFun}>
+        {#each dotaInlines as item}
+            <Checkbox name={item} checkeds={checkInlines} icon="none" iconChecked="none">
+                <div
+                    class={`border py-0.5 px-1 m-1 text-sm rounded ${
+                        checkInlines.includes(item)
+                            ? 'text-primary dark:text-dark bg-primary/10 dark:bg-dark/10'
+                            : 'bg-gray9 dark:bg-gray4 border-gray8 dark:border-gray5 text-gray6'
+                    }`}
+                >
+                    {item}
+                </div>
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+    <div class="text-xs mt-2">已选:{checkInlines.join('-')}</div>
+</div>
+<Divider />
+
+<div class="px-4 pb-8">
+    <div class="mb-4 font-bold text-2xl">纵向排列</div>
+    <div class="mt-8 mb-4 font-bold text-lg">基础用法</div>
+    <CheckboxGroup>
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name}>{item.label}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">长文字选项</div>
+    <CheckboxGroup>
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name}>{item.desc}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">文字靠左</div>
+    <CheckboxGroup>
+        {#each dota as item, i}
+            <Checkbox {checkeds} name={item.name} textPosition="l">
+                {item.label}
+                {#if i !== dota.length - 1}
+                    <div class="h-px mt-1 bg-gray9 dark:bg-gray5"></div>
+                {/if}
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">复杂选项 && 自定义选中效果</div>
+    <CheckboxGroup on:change={dotaVoicesFun}>
+        {#each dotaVoices as item, i}
+            <Checkbox checkeds={voiceCheckeds} name={item.name}>
+                <div class={`ml-2 ${voiceCheckeds.includes(item.name) ? 'text-primary dark:text-dark' : ''}`}>
+                    {item.label}
+                    {#each item.voices as voice}
+                        <div class="text-xs">{voice}</div>
+                    {/each}
+                    {#if i !== dotaVoices.length - 1}
+                        <div class="h-px mt-1 bg-gray9 dark:bg-gray5"></div>
+                    {/if}
+                </div>
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">批量操作</div>
+    <CheckboxGroup on:change={dotaAllFun}>
+        {#each dotaAll as item}
+            <Checkbox checkeds={checkDotas} name={item} {outControl}>{item}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+    <div class="text-xs mt-2">已选:{checkDotas.join('-')}</div>
+    <div class="text-xs mt-2">未选:{noCheckDotas.join('-')}</div>
+    <div class="flex mt-2">
+        <div class="flex-1">
+            <Button fill="lineTheme" heightIn="1" on:click={checkAllFun}>全选</Button>
+        </div>
+        <div class="flex-1">
+            <Button fill="lineTheme" heightIn="1" on:click={checkNoneFun}>全不选</Button>
+        </div>
+        <div class="flex-1">
+            <Button fill="lineTheme" heightIn="1" on:click={checkReverseFun}>反选</Button>
+        </div>
+    </div>
+
+    <div class="mt-8 mb-4 font-bold text-lg">带动画</div>
+    <div class="flex" style="height: {animateHeight}px;">
+        <div class="flex-1">
+            <div class="pb-2">未选</div>
+            <div bind:clientHeight={heights}>
+                <CheckboxGroup on:change={checkAnimateNoFun}>
+                    {#each animateNos as item, index (item)}
+                        <div in:receive={{ key: item }} out:send={{ key: item }} animate:flip={{ duration: 600 }}>
+                            <Checkbox name={item} outControl checkeds={[]}>{item}</Checkbox>
+                        </div>
+                    {/each}
+                </CheckboxGroup>
+            </div>
+        </div>
+        <div class="flex-1">
+            <div class="pb-2">已选</div>
+            <CheckboxGroup on:change={checkAnimaYesFun}>
+                {#each animateYess as item, index (item)}
+                    <div in:receive={{ key: item }} out:send={{ key: item }} animate:flip={{ duration: 600 }}>
+                        <Checkbox outControl checkeds={animateYess} name={item}>
+                            {item}
+                        </Checkbox>
+                    </div>
+                {/each}
+            </CheckboxGroup>
+        </div>
+    </div>
+</div>

+ 328 - 0
demo/src/pages/checkbox/CheckboxDemo_en.svelte

@@ -0,0 +1,328 @@
+<!-- Checkbox Demo -->
+<script>
+    import { CheckboxGroup, Checkbox, Divider, Button } from '../../../../components';
+    import { onMount } from 'svelte';
+    import { quintOut } from 'svelte/easing';
+    import { crossfade } from 'svelte/transition';
+    import { flip } from 'svelte/animate';
+
+    const dota = [
+        { label: 'Jugg', name: 'Juggernaut', desc: 'The master is a melee agile hero, and he can quickly cut into the battle.' },
+        { label: 'SB', name: 'Spirit Breaker', desc: 'Barlason, the soul -cracked man is a powerful Gank -type melee hero.' },
+        { label: 'Kotl', name: 'Keeper of the Light', desc: 'Izalo, Guardian of Light, he is a famous auxiliary intellectual hero.' },
+        { label: 'Mag', name: 'Magnus', desc: 'Mighty? Why not BAN mighty? Why not BAN mighty?' },
+    ];
+    let checkeds = [];
+    const dotaFun = e => {
+        checkeds = e.detail;
+    };
+
+    const dotaImgs = ['Lina', 'ES', 'Mor', 'Sni', 'SV'];
+    const dotaForImgs = ['火女', '小牛', '水人', '火枪', '斯温'];
+    let imgCheckeds = ['Lina'];
+    const dotaImgsFun = e => {
+        imgCheckeds = e.detail;
+    };
+
+    const dotaVoices = [
+        { label: 'karl', name: 'karl', voices: ['"From the great mystery."'] },
+        { label: 'Storm', name: 'Storm', voices: ['"Hey ~ Quickly wake up, drink coffee, we are attacked on the tower."'] },
+        {
+            label: 'Bat',
+            name: 'Bat',
+            voices: [
+                '"Oh, Lina, what about Mrs. My Village?"',
+                "'Oh, popular, you don't have to run when you see me.'",
+                '"Crystal room woman, you are like a tall cup full of ice water."',
+            ],
+        },
+        { label: 'Tide', name: 'Tide', voices: ['"I can still eat a seaweed."'] },
+    ];
+    let voiceCheckeds = [];
+    const dotaVoicesFun = e => {
+        voiceCheckeds = e.detail;
+    };
+
+    const dotaInlines = ['Lina', 'ES', 'Mor', 'Sni', 'SV', 'karl', 'Tide', 'Bat', 'Mag'];
+    let checkInlines = ['ES', 'Mor'];
+    const dotaInlineFun = e => {
+        checkInlines = e.detail;
+    };
+
+    const dotaAll = ['Lina', 'ES', 'Mor', 'Sni', 'SV', 'karl', 'Tide', 'Bat', 'Mag'];
+    let checkDotas = ['Sni', 'SV'];
+    $: noCheckDotas = dotaAll.filter(a => !checkDotas.some(b => b === a));
+    let outControl = true;
+    // Click the single item
+    const dotaAllFun = e => {
+        outControl = false;
+        checkDotas = e.detail;
+    };
+    // select all
+    const checkAllFun = () => {
+        outControl = true;
+        checkDotas = dotaAll;
+    };
+    // unselect all
+    const checkNoneFun = () => {
+        outControl = true;
+        checkDotas = [];
+    };
+    // Counter -selection
+    const checkReverseFun = () => {
+        outControl = true;
+        checkDotas = dotaAll.filter(a => !checkDotas.some(b => b === a));
+    };
+
+    const animates = ['Lina', 'ES', 'Mor', 'Sni', 'SV', 'karl', 'Tide', 'Bat', 'Mag'];
+    let animateNos = ['Lina', 'ES', 'Mor', 'Sni', 'SV', 'karl'];
+    $: animateYess = animates.filter(a => !animateNos.some(b => b === a));
+    const checkAnimateNoFun = e => {
+        animateNos = animateNos.filter(a => !e.detail.some(b => b === a));
+    };
+    const checkAnimaYesFun = e => {
+        animateNos = animates.filter(a => !e.detail.some(b => b === a));
+    };
+    const [send, receive] = crossfade({
+        duration: d => Math.sqrt(d * 150),
+        fallback(node, params) {
+            const style = getComputedStyle(node);
+            const transform = style.transform === 'none' ? '' : style.transform;
+            return {
+                duration: 600,
+                easing: quintOut,
+                css: t => `
+					transform: ${transform} scale(${t});
+					opacity: ${t}
+				`,
+            };
+        },
+    });
+    // Set the height to avoid changes in page height and affect the click experience.
+    let heights = 0;
+    let animateHeight = 0;
+    onMount(() => {
+        animateHeight = (heights / 6) * 9 + 32;
+    });
+</script>
+
+<div class="px-4  text-left">
+    <div class="mt-8 mb-4 font-bold text-2xl">Horizontal arrangement</div>
+    <div class="mt-6 mb-4 font-bold text-lg">Simple usage</div>
+    <CheckboxGroup layout="h">
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name}>{item.label}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">Text is in different positions</div>
+    <CheckboxGroup layout="h">
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name} textPosition="l">{item.label}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+    <Divider />
+    <CheckboxGroup layout="h">
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name} textPosition="b">{item.label}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+    <Divider />
+    <CheckboxGroup layout="h">
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name} textPosition="t">{item.label}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">Custom icon</div>
+    <CheckboxGroup layout="h">
+        <Checkbox
+            checkeds={[]}
+            icon={{ name: 'ri-checkbox-blank-circle-line' }}
+            iconChecked={{ name: 'ri-radio-button-fill' }}
+            name="Daemon">Jugg</Checkbox
+        >
+        <Checkbox
+            checkeds={[]}
+            icon={{ name: 'ri-checkbox-circle-line' }}
+            iconChecked={{ name: 'ri-checkbox-circle-fill' }}
+            name="Linghuchong">Mor</Checkbox
+        >
+        <Checkbox
+            checkeds={[]}
+            icon={{ name: 'ri-checkbox-multiple-line' }}
+            iconChecked={{ name: 'ri-checkbox-multiple-fill' }}
+            name="Light Light methodard">Kotl</Checkbox
+        >
+        <Checkbox checkeds={[]} icon={{ name: 'ri-check-line' }} iconChecked={{ name: 'ri-check-fill' }} name="Magnas">Mag</Checkbox>
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">Picture option</div>
+    <CheckboxGroup layout="h" on:change={dotaImgsFun}>
+        {#each dotaImgs as dota, i}
+            <Checkbox
+                name={dota}
+                textPosition="t"
+                icon={{ name: 'ri-arrow-up-s-line' }}
+                iconChecked={{ name: 'ri-arrow-up-s-fill' }}
+                outControl
+                checkeds={imgCheckeds}
+            >
+                <div
+                    class={`w-12 h-12 mb-1 rounded overflow-hidden ${
+                        imgCheckeds.includes(dota) ? 'ring-2 ring-primary dark:ring-dark' : ''
+                    }`}
+                >
+                    <img class="w-full h-full object-cover" src={`./assets/images/dota_${dotaForImgs[i]}.png`} alt="" />
+                </div>
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+    <div class="text-sm">
+        {imgCheckeds.length > 0 ? 'selected' : 'No hero is selected.'}
+        <span class="text-[red]">{imgCheckeds.join(' + ')}</span>{imgCheckeds.length > 0 ? '。' : ''}
+    </div>
+
+    <div class="mt-8 mb-4 font-bold text-lg">No icon && use Button</div>
+    <CheckboxGroup layout="h" on:change={dotaFun}>
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name} icon="none" iconChecked="none">
+                <Button fill={checkeds.includes(item.name) ? 'base' : 'lineLight'} size="auto" injClass="px-4">{item.label}</Button>
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">No icon && Customized selection effect</div>
+    <CheckboxGroup layout="h" on:change={dotaFun}>
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name} icon="none" iconChecked="none">
+                <div
+                    class={`border py-0.5 px-5 text-sm rounded ${
+                        checkeds.includes(item.name)
+                            ? 'text-primary dark:text-dark bg-primary/10 dark:bg-dark/10'
+                            : 'bg-gray9 dark:bg-gray4 border-gray8 dark:border-gray5 text-gray6'
+                    }`}
+                >
+                    {item.label}
+                </div>
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+</div>
+<Divider />
+
+<div class="px-4">
+    <div class="mb-4 font-bold">Elemental element arrangementtal element arrangement</div>
+    <div class="mt-8 mb-4 font-bold">No icon && Elemental element arrangement</div>
+    <CheckboxGroup layout="inline" wrap on:change={dotaInlineFun}>
+        {#each dotaInlines as item}
+            <Checkbox name={item} checkeds={checkInlines} icon="none" iconChecked="none">
+                <div
+                    class={`border py-0.5 px-1 m-1 text-sm rounded ${
+                        checkInlines.includes(item)
+                            ? 'text-primary dark:text-dark bg-primary/10 dark:bg-dark/10'
+                            : 'bg-gray9 dark:bg-gray4 border-gray8 dark:border-gray5 text-gray6'
+                    }`}
+                >
+                    {item}
+                </div>
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+    <div class="text-xs mt-2">selected:{checkInlines.join('-')}</div>
+</div>
+<Divider />
+
+<div class="px-4 pb-8">
+    <div class="mb-4 font-bold text-2xl">Vertical arrangement</div>
+    <div class="mt-8 mb-4 font-bold text-lg">Basic usage</div>
+    <CheckboxGroup>
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name}>{item.label}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">Long text option</div>
+    <CheckboxGroup>
+        {#each dota as item}
+            <Checkbox {checkeds} name={item.name}>{item.desc}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">Text to left</div>
+    <CheckboxGroup>
+        {#each dota as item, i}
+            <Checkbox {checkeds} name={item.name} textPosition="l">
+                {item.label}
+                {#if i !== dota.length - 1}
+                    <div class="h-px mt-1 bg-gray9 dark:bg-gray5" />
+                {/if}
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">Complicated option && Customized selection effect</div>
+    <CheckboxGroup on:change={dotaVoicesFun}>
+        {#each dotaVoices as item, i}
+            <Checkbox checkeds={voiceCheckeds} name={item.name}>
+                <div class={`ml-2 ${voiceCheckeds.includes(item.name) ? 'text-primary dark:text-dark' : ''}`}>
+                    {item.label}
+                    {#each item.voices as voice}
+                        <div class="text-xs">{voice}</div>
+                    {/each}
+                    {#if i !== dotaVoices.length - 1}
+                        <div class="h-px mt-1 bg-gray9 dark:bg-gray5" />
+                    {/if}
+                </div>
+            </Checkbox>
+        {/each}
+    </CheckboxGroup>
+
+    <div class="mt-8 mb-4 font-bold text-lg">Batch operation</div>
+    <CheckboxGroup on:change={dotaAllFun}>
+        {#each dotaAll as item}
+            <Checkbox checkeds={checkDotas} name={item} {outControl}>{item}</Checkbox>
+        {/each}
+    </CheckboxGroup>
+    <div class="text-xs mt-2">selected:{checkDotas.join('-')}</div>
+    <div class="text-xs mt-2">Une selected:{noCheckDotas.join('-')}</div>
+    <div class="flex mt-2">
+        <div class="flex-1">
+            <Button fill="lineTheme" heightIn="1" on:click={checkAllFun}>select all</Button>
+        </div>
+        <div class="flex-1">
+            <Button fill="lineTheme" heightIn="1" on:click={checkNoneFun}>unselect all</Button>
+        </div>
+        <div class="flex-1">
+            <Button fill="lineTheme" heightIn="1" on:click={checkReverseFun}>Counter -selection</Button>
+        </div>
+    </div>
+
+    <div class="mt-8 mb-4 font-bold text-lg">Animation</div>
+    <div class="flex" style="height: {animateHeight}px;">
+        <div class="flex-1">
+            <div class="pb-2">Unsteady</div>
+            <div bind:clientHeight={heights}>
+                <CheckboxGroup on:change={checkAnimateNoFun}>
+                    {#each animateNos as item, index (item)}
+                        <div in:receive={{ key: item }} out:send={{ key: item }} animate:flip={{ duration: 600 }}>
+                            <Checkbox name={item} outControl checkeds={[]}>{item}</Checkbox>
+                        </div>
+                    {/each}
+                </CheckboxGroup>
+            </div>
+        </div>
+        <div class="flex-1">
+            <div class="pb-2">selected</div>
+            <CheckboxGroup on:change={checkAnimaYesFun}>
+                {#each animateYess as item, index (item)}
+                    <div in:receive={{ key: item }} out:send={{ key: item }} animate:flip={{ duration: 600 }}>
+                        <Checkbox outControl checkeds={animateYess} name={item}>
+                            {item}
+                        </Checkbox>
+                    </div>
+                {/each}
+            </CheckboxGroup>
+        </div>
+    </div>
+</div>

+ 152 - 0
demo/src/pages/dialog/DialogDemo.svelte

@@ -0,0 +1,152 @@
+<!-- Dialog Demo -->
+<script>
+    import { Dialog, Cell, Toast, Loading } from '../../../../components';
+    import Aphorism from '../../components/Aphorism.svelte';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+    let visible12 = false;
+    let visible13 = false;
+    let visible14 = false;
+    let visible15 = false;
+    let visible16 = false;
+    let visible17 = false;
+    let visible18 = false;
+    let visible19 = false;
+
+    let toastVisible = false;
+    let toastVisible2 = false;
+    let toastVisible3 = false;
+    let toastVisible4 = false;
+
+    $: if (visible8) {
+        setTimeout(() => {
+            visible8 = false;
+        }, 3000);
+    }
+
+    let loading = false;
+    const somethingFnc = () => {
+        loading = true;
+        setTimeout(() => {
+            loading = false;
+            visible18 = false;
+            toastVisible4 = true;
+        }, 3000);
+    };
+</script>
+
+<div class="py-4">
+    <Cell title="基础用法" on:click={() => (visible1 = true)} />
+    <Dialog bind:visible={visible1} title="李逍遥" content="你确认前往仙灵岛吗?" />
+
+    <Cell title="内容使用插槽" on:click={() => (visible2 = true)} />
+    <Dialog bind:visible={visible2} contentSlot>
+        <Aphorism slot="content" num={1} compact />
+    </Dialog>
+
+    <Cell title="不显示标题" on:click={() => (visible3 = true)} />
+    <Dialog bind:visible={visible3} title="" />
+
+    <Cell title="点击遮罩关闭" on:click={() => (visible5 = true)} />
+    <Dialog bind:visible={visible5} popup={{ maskClosable: true }} />
+
+    <Cell title="自定义图标" on:click={() => (visible6 = true)} />
+    <Dialog
+        bind:visible={visible6}
+        content="请佩戴口罩!"
+        showIcon
+        icon={{ name: 'ri-surgical-mask-fill', size: 40, injClass: 'text-[#48a1b4]' }}
+        secondaryText="没携带"
+        primaryText="好的"
+    />
+
+    <Cell title="内容使用插槽且滚动" on:click={() => (visible4 = true)} />
+    <Dialog bind:visible={visible4} contentSlot>
+        <div slot="content" class="max-h-56 overflow-auto">
+            <Aphorism num={6} compact />
+        </div>
+    </Dialog>
+
+    <Cell title="另一种动画效果" on:click={() => (visible11 = true)} />
+    <Dialog bind:visible={visible11} content="回弹过渡" popup={{ easeType: 'backOut' }} />
+
+    <Cell title="标题居左" on:click={() => (visible7 = true)} />
+    <Dialog bind:visible={visible7} title="标题居左" titleAlign="left" />
+
+    <Cell title="自动关闭" on:click={() => (visible8 = true)} />
+    <Dialog bind:visible={visible8} content="别动!3 秒后我立即消失!" />
+
+    <Cell title="主按钮占比多一点" on:click={() => (visible9 = true)} />
+    <Dialog bind:visible={visible9} btnRatio={[3, 2]} />
+
+    <Cell title="主次按钮位置反转" on:click={() => (visible10 = true)} />
+    <Dialog bind:visible={visible10} btnReverse />
+
+    <Cell title="按钮间距大一点" on:click={() => (visible19 = true)} />
+    <Dialog bind:visible={visible19} btnGap="16" />
+
+    <Cell title="按钮为纯文字" on:click={() => (visible12 = true)} />
+    <Dialog bind:visible={visible12} btnStyle="text" />
+
+    <Cell title="按钮为纯文字有分割线" on:click={() => (visible13 = true)} />
+    <Dialog bind:visible={visible13} btnStyle="textLine" />
+
+    <Cell title="全圆角按钮" on:click={() => (visible15 = true)} />
+    <Dialog bind:visible={visible15} primaryButton={{ radius: 'full' }} secondaryButton={{ radius: 'full' }} />
+
+    <Cell title="监听次要事件" on:click={() => (visible14 = true)} />
+    <Dialog bind:visible={visible14} on:secondary={() => (toastVisible = true)} />
+    <Toast bind:visible={toastVisible} message="点击了取消!" />
+
+    <Cell title="监听关闭事件" on:click={() => (visible16 = true)} />
+    <Dialog bind:visible={visible16} on:close={() => (toastVisible2 = true)} />
+    <Toast bind:visible={toastVisible2} message="关闭了 Dialog!" />
+
+    <Cell title="监听主要事件" on:click={() => (visible17 = true)} />
+    <Dialog bind:visible={visible17} on:primary={() => (toastVisible3 = true)} />
+    <Toast bind:visible={toastVisible3} message="点击了确认!" />
+
+    <Cell title="异步执行主要事件" on:click={() => (visible18 = true)} />
+    <Dialog bind:visible={visible18} on:primary={somethingFnc} primarySlot title="小鬼" content="你一定要进入锁妖塔吗?">
+        <span slot="primary">
+            {#if loading}
+                <Loading slot="primary" inverse width="12" height="6" type="1_17" />
+            {:else}
+                进入
+            {/if}
+        </span>
+    </Dialog>
+    <Toast bind:visible={toastVisible4} message="已进入锁妖塔!" />
+</div>
+
+<!-- Aphorism.svelte -->
+<!-- 
+<script>
+    import aphorisms from '../data/aphorisms'; //引入数据
+
+    export let num = 0; //显示条数
+    export let compact = false; //是否紧凑模式
+
+    //从 aphorisms 随机取出 num 条数据
+    const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
+</script>
+
+<div class={`${compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5`}>
+    {#each aphorismsList as item}
+        <div class:py-6={num > 1}>
+            <div class="text-sm text-justify">{item.text}</div>
+            <div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
+        </div>
+    {/each}
+</div>
+-->

+ 152 - 0
demo/src/pages/dialog/DialogDemo_en.svelte

@@ -0,0 +1,152 @@
+<!-- Dialog Demo -->
+<script>
+    import { Dialog, Cell, Toast, Loading } from '../../../../components';
+    import Aphorism from '../../components/Aphorism.svelte';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+    let visible12 = false;
+    let visible13 = false;
+    let visible14 = false;
+    let visible15 = false;
+    let visible16 = false;
+    let visible17 = false;
+    let visible18 = false;
+    let visible19 = false;
+
+    let toastVisible = false;
+    let toastVisible2 = false;
+    let toastVisible3 = false;
+    let toastVisible4 = false;
+
+    $: if (visible8) {
+        setTimeout(() => {
+            visible8 = false;
+        }, 3000);
+    }
+
+    let loading = false;
+    const somethingFnc = () => {
+        loading = true;
+        setTimeout(() => {
+            loading = false;
+            visible18 = false;
+            toastVisible4 = true;
+        }, 3000);
+    };
+</script>
+
+<div class="py-4">
+    <Cell title="Basic usage" on:click={() => (visible1 = true)} />
+    <Dialog bind:visible={visible1} title="Li Xiaoyao" content="Do you confirm that going to Xianling Island?" />
+
+    <Cell title="Content use slot" on:click={() => (visible2 = true)} />
+    <Dialog bind:visible={visible2} contentSlot>
+        <Aphorism slot="content" num={1} compact />
+    </Dialog>
+
+    <Cell title="Display the title" on:click={() => (visible3 = true)} />
+    <Dialog bind:visible={visible3} title="" />
+
+    <Cell title="Click the mask to close" on:click={() => (visible5 = true)} />
+    <Dialog bind:visible={visible5} popup={{ maskClosable: true }} />
+
+    <Cell title="Custom icon" on:click={() => (visible6 = true)} />
+    <Dialog
+        bind:visible={visible6}
+        content="Please wear a mask!"
+        showIcon
+        icon={{ name: 'ri-surgical-mask-fill', size: 40, injClass: 'text-[#48a1b4]' }}
+        secondaryText="Not carried"
+        primaryText="OK"
+    />
+
+    <Cell title="The content uses slot and rolls" on:click={() => (visible4 = true)} />
+    <Dialog bind:visible={visible4} contentSlot>
+        <div slot="content" class="max-h-56 overflow-auto">
+            <Aphorism num={6} compact />
+        </div>
+    </Dialog>
+
+    <Cell title="Another animation effect" on:click={() => (visible11 = true)} />
+    <Dialog bind:visible={visible11} content="Rebound transition" popup={{ easeType: 'backOut' }} />
+
+    <Cell title="Title left" on:click={() => (visible7 = true)} />
+    <Dialog bind:visible={visible7} title="Title left" titleAlign="left" />
+
+    <Cell title="Automatically close" on:click={() => (visible8 = true)} />
+    <Dialog bind:visible={visible8} content="do not move!I disappeared immediately after 3 seconds!" />
+
+    <Cell title="The main button accounts for a little more" on:click={() => (visible9 = true)} />
+    <Dialog bind:visible={visible9} btnRatio={[3, 2]} />
+
+    <Cell title="Primary button position reverse" on:click={() => (visible10 = true)} />
+    <Dialog bind:visible={visible10} btnReverse />
+
+    <Cell title="The button spacing is larger" on:click={() => (visible19 = true)} />
+    <Dialog bind:visible={visible19} btnGap="16" />
+
+    <Cell title="The button is pure text" on:click={() => (visible12 = true)} />
+    <Dialog bind:visible={visible12} btnStyle="text" />
+
+    <Cell title="There is a division of the button for the button" on:click={() => (visible13 = true)} />
+    <Dialog bind:visible={visible13} btnStyle="textLine" />
+
+    <Cell title="Full rounded button" on:click={() => (visible15 = true)} />
+    <Dialog bind:visible={visible15} primaryButton={{ radius: 'full' }} secondaryButton={{ radius: 'full' }} />
+
+    <Cell title="Monitoring secondary event" on:click={() => (visible14 = true)} />
+    <Dialog bind:visible={visible14} on:secondary={() => (toastVisible = true)} />
+    <Toast bind:visible={toastVisible} message="Click to cancel!" />
+
+    <Cell title="Supervision and closing incident" on:click={() => (visible16 = true)} />
+    <Dialog bind:visible={visible16} on:close={() => (toastVisible2 = true)} />
+    <Toast bind:visible={toastVisible2} message="Close Dialog!" />
+
+    <Cell title="Main incident" on:click={() => (visible17 = true)} />
+    <Dialog bind:visible={visible17} on:primary={() => (toastVisible3 = true)} />
+    <Toast bind:visible={toastVisible3} message="Click to confirm!" />
+
+    <Cell title="Main events asynchronous execution" on:click={() => (visible18 = true)} />
+    <Dialog bind:visible={visible18} on:primary={somethingFnc} primarySlot title="Ghost" content="Do you have to enter the lock demon tower?">
+        <span slot="primary">
+            {#if loading}
+                <Loading slot="primary" inverse width="12" height="6" type="1_17" />
+            {:else}
+                Enter
+            {/if}
+        </span>
+    </Dialog>
+    <Toast bind:visible={toastVisible4} message="Enter the lock demon tower!he lock demon tower!" />
+</div>
+
+<!-- Aphorism.svelte -->
+<!-- 
+<script>
+    import aphorisms from '../data/aphorisms'; //Introduce data
+
+    export let num = 0; //Display number
+    export let compact = false; //Whether to compact mode
+
+    //Randomly remove NUM data from Aphorisms
+    const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
+</script>
+
+<div class={`${compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5`}>
+    {#each aphorismsList as item}
+        <div class:py-6={num > 1}>
+            <div class="text-sm text-justify">{item.text}</div>
+            <div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
+        </div>
+    {/each}
+</div>
+-->

+ 78 - 0
demo/src/pages/divider/DividerDemo.svelte

@@ -0,0 +1,78 @@
+<!-- Divider Demo -->
+<script>
+    import { Divider } from '../../../../components';
+</script>
+
+<div class="flex flex-col space-y-8 py-8">
+    <div>
+        <div class="p-4 font-bold">不同长度</div>
+        <Divider />
+        <Divider px="4" />
+        <Divider px="8" />
+        <Divider px="16" />
+        <Divider px="36" />
+    </div>
+    <div>
+        <div class="p-4 font-bold">包含文字</div>
+        <Divider text="古筝计划" />
+        <Divider px="4" text="红岸基地" />
+    </div>
+    <div>
+        <div class="p-4 font-bold">不同高度</div>
+        <div class="px-4 text-sm">开始</div>
+        <Divider py="0" />
+        <div class="px-4 text-sm">高度为0</div>
+        <Divider />
+        <div class="px-4 text-sm">高度为4</div>
+        <Divider py="8" />
+        <div class="px-4 text-sm">高度为8</div>
+    </div>
+
+    <div>
+        <div class="p-4 font-bold">文字位置</div>
+        <Divider text="左侧" align="left" />
+        <Divider text="居中" />
+        <Divider text="右侧" align="right" />
+    </div>
+    <div>
+        <div class="p-4 font-bold">线条风格</div>
+        <Divider text="实线" />
+        <Divider line="dashed" text="虚线" />
+        <Divider line="dotted" text="点线" />
+    </div>
+    <div>
+        <div class="p-4 font-bold">自定义颜色</div>
+        <Divider injClass="border-blue dark:border-yellow" />
+        <Divider text="自定义线条" injClass="border-[red] dark:border-[green]" />
+        <Divider text="自定义文字" injClass="text-[red]" />
+        <Divider text="自定义线条与文字" injClass="border-[red] text-[blue] dark:text-[yellow]" />
+        <Divider line="dashed" text="自定义虚线" injClass="border-[#FF5722]" />
+    </div>
+    <div class="px-4">
+        <div class="py-4 font-bold">垂直分割线</div>
+        <div class="text-sm">
+            三日凌空<Divider layout="v" />三日连珠<Divider layout="v" />人列计算机
+        </div>
+    </div>
+    <div>
+        <div class="p-4 font-bold">不同粗细</div>
+        <Divider />
+        <Divider weight="2" />
+        <Divider weight="4" />
+        <div class="px-4 text-sm">
+            执剑人<Divider layout="v" />三日凌空<Divider layout="v" weight="2" />三日连珠<Divider layout="v" weight="4" />人列计算机
+        </div>
+    </div>
+    <div class="px-4">
+        <div class="py-4 font-bold">自定义垂直分割线</div>
+        <div class="text-sm">
+            加大间距
+            <Divider layout="v" mx="4" />
+            自定义
+            <Divider layout="v" mx="4" injClass="border-[red] dark:border-[green]" />
+            颜色
+            <Divider line="dashed" layout="v" mx="4" injClass="border-[red] dark:border-[green]" />
+            与线条风格
+        </div>
+    </div>
+</div>

+ 78 - 0
demo/src/pages/divider/DividerDemo_en.svelte

@@ -0,0 +1,78 @@
+<!-- Divider Demo -->
+<script>
+    import { Divider } from '../../../../components';
+</script>
+
+<div class="flex flex-col space-y-8 py-8 text-left">
+    <div>
+        <div class="p-4 font-bold">Different length</div>
+        <Divider />
+        <Divider px="4" />
+        <Divider px="8" />
+        <Divider px="16" />
+        <Divider px="36" />
+    </div>
+    <div>
+        <div class="p-4 font-bold">Include text</div>
+        <Divider text="Zheng Plan" />
+        <Divider px="4" text="Red bank base" />
+    </div>
+    <div>
+        <div class="p-4 font-bold">Different heights</div>
+        <div class="px-4 text-sm">start</div>
+        <Divider py="0" />
+        <div class="px-4 text-sm">Height is 0</div>
+        <Divider />
+        <div class="px-4 text-sm">Height is 4</div>
+        <Divider py="8" />
+        <div class="px-4 text-sm">Height is 8</div>
+    </div>
+
+    <div>
+        <div class="p-4 font-bold">Text location</div>
+        <Divider text="Left" align="left" />
+        <Divider text="Center" />
+        <Divider text="Right" align="right" />
+    </div>
+    <div>
+        <div class="p-4 font-bold">Line style</div>
+        <Divider text="solid line" />
+        <Divider line="dashed" text="Dashed line" />
+        <Divider line="dotted" text="Dotted line" />
+    </div>
+    <div>
+        <div class="p-4 font-bold">Custom color</div>
+        <Divider injClass="border-blue dark:border-yellow" />
+        <Divider text="Custom line" injClass="border-[red] dark:border-[green]" />
+        <Divider text="Custom text" injClass="text-[red]" />
+        <Divider text="Custom lines and text" injClass="border-[red] text-[blue] dark:text-[yellow]" />
+        <Divider line="dashed" text="Custom dotted line" injClass="border-[#FF5722]" />
+    </div>
+    <div class="px-4">
+        <div class="py-4 font-bold">Vertical segmentation line</div>
+        <div class="text-sm">
+            Three -day volley<Divider layout="v" />Three -day Lianzhu<Divider layout="v" />Person computer
+        </div>
+    </div>
+    <div>
+        <div class="p-4 font-bold">Different thickness</div>
+        <Divider />
+        <Divider weight="2" />
+        <Divider weight="4" />
+        <div class="px-4 text-sm">
+            Sword<Divider layout="v" />Three -day volley<Divider layout="v" weight="2" />Three -day Lianzhu<Divider layout="v" weight="4" />Person computer
+        </div>
+    </div>
+    <div class="px-4">
+        <div class="py-4 font-bold">Custom vertical division line</div>
+        <div class="text-sm">
+            Increase
+            <Divider layout="v" mx="4" />
+            customize
+            <Divider layout="v" mx="4" injClass="border-[red] dark:border-[green]" />
+            color
+            <Divider line="dashed" layout="v" mx="4" injClass="border-[red] dark:border-[green]" />
+            Line style
+        </div>
+    </div>
+</div>

+ 288 - 0
demo/src/pages/grids/GridsDemo.svelte

@@ -0,0 +1,288 @@
+<!-- Grids Demo -->
+<script>
+    import { Grids, Grid, Placeholder, Switch, Icon, Button } from '../../../../components';
+
+    let devices = ['iOS', 'Android', 'Windows', 'macOS', 'Ubuntu'];
+    let curentIndex = 0;
+    $: currentDevice = devices[curentIndex];
+    const changeDeviceFun = () => {
+        curentIndex === devices.length - 1 ? (curentIndex = 0) : curentIndex++;
+    };
+    let color = false;
+    $: colorCss = `${color ? ' bg-gradient-to-tr from-purple/70 to-orange/70' : ' bg-gray8 dark:bg-gray4'}`;
+    const changeColorFun = e => {
+        color = e.detail;
+    };
+    //获取当前时间
+    const date = new Date();
+    //获取当前月份转为汉字
+    const monthArr = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
+    const monthIndex = date.getMonth();
+    $: month = monthArr[monthIndex];
+    const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
+    const hour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
+    const minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
+    $: time = `${hour}:${minute}`;
+    //获取中文周几
+    const week = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
+    $: weekDay = week[date.getDay()];
+</script>
+
+<div class="font-bold px-4 mt-8">使用占位符示例 3﹡4</div>
+<Grids cols={4}>
+    <Grid row="3">
+        <Placeholder>3﹡1</Placeholder>
+    </Grid>
+    <Grid col="3">
+        <Placeholder>1﹡3</Placeholder>
+    </Grid>
+    <Grid row="2">
+        <Placeholder>2﹡1</Placeholder>
+    </Grid>
+    <Grid col="2">
+        <Placeholder>1﹡2</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+</Grids>
+
+<div class="font-bold px-4 mt-8">使用占位符示例 4﹡6</div>
+<Grids>
+    <Grid row={3} col={2}>
+        <Placeholder>3﹡2</Placeholder>
+    </Grid>
+    <Grid col={3}>
+        <Placeholder>1﹡3</Placeholder>
+    </Grid>
+    <Grid row={4}>
+        <Placeholder>4﹡1</Placeholder>
+    </Grid>
+    <Grid row={2}>
+        <Placeholder>2﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid col={4}>
+        <Placeholder>1﹡4</Placeholder>
+    </Grid>
+</Grids>
+
+<div class="font-bold px-4 mt-8">增加外边距与单元格间距</div>
+<Grids cols={4} gap="4" mx="8" my="8">
+    <Grid row={3}>
+        <Placeholder>3﹡1</Placeholder>
+    </Grid>
+    <Grid col={3}>
+        <Placeholder>1﹡3</Placeholder>
+    </Grid>
+    <Grid row={2}>
+        <Placeholder>2﹡1</Placeholder>
+    </Grid>
+    <Grid col={2}>
+        <Placeholder>1﹡2</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+</Grids>
+
+<div class="font-bold px-4 mt-8">场景示例 6﹡5</div>
+<div class="pb-8 pt-2">
+    <div class={`mx-2 rounded-xl p-2 shadow transition duration-300${colorCss}`}>
+        <Grids cols={5} mx="0" my="0">
+            <Grid row={3}>
+                <div
+                    class="flex flex-col justify-between bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xs text-center shadow dark:shadow-white/10"
+                >
+                    <div>{weekDay}</div>
+                    <div class="text-4xl">{day}</div>
+                    <div class="text-gray6">{month}</div>
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xl font-bold text-center flex flex-col justify-center shadow dark:shadow-white/10"
+                >
+                    {time}
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xs text-center flex flex-col justify-around shadow dark:shadow-white/10"
+                >
+                    <div class="flex justify-center">
+                        <Switch inside="slot" radius="full" on:change={changeColorFun}>
+                            <div slot="false">
+                                <Icon name="ri-paint-brush-line" size={12} />
+                            </div>
+                            <div slot="true">
+                                <Icon name="ri-paint-brush-fill" size={12} theme />
+                            </div>
+                        </Switch>
+                    </div>
+                    <div>彩 色</div>
+                </div>
+            </Grid>
+
+            <Grid row={2} col={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 h-full rounded-lg text-xs text-center flex flex-col justify-center shadow dark:shadow-white/10"
+                >
+                    <Button fill="lineTheme" radius="full" on:click={changeDeviceFun}>切换设备</Button>
+                </div>
+            </Grid>
+            <Grid row={2} col={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xs text-center flex justify-around shadow dark:shadow-white/10 py-1"
+                >
+                    <div class="flex flex-col justify-center">
+                        {#if currentDevice === 'iOS'}
+                            <Icon name="ri-apple-fill" size={30} />
+                        {:else if currentDevice === 'Android'}
+                            <Icon name="ri-android-fill" size={30} />
+                        {:else if currentDevice === 'Windows'}
+                            <Icon name="ri-windows-fill" size={30} />
+                        {:else if currentDevice === 'macOS'}
+                            <Icon name="ri-command-fill" size={30} />
+                        {:else}
+                            <Icon name="ri-ubuntu-fill" size={30} />
+                        {/if}
+                    </div>
+                    <div class="flex flex-col justify-around">
+                        <div class="text-sm">
+                            {#if currentDevice === 'iOS'}
+                                A15 Bionic
+                            {:else if currentDevice === 'Android'}
+                                骁龙8 Gen1
+                            {:else if currentDevice === 'Windows'}
+                                AMD YES
+                            {:else if currentDevice === 'macOS'}
+                                M1 Ultra
+                            {:else}
+                                Intel
+                            {/if}
+                        </div>
+                        <div>
+                            {#if currentDevice === 'iOS'}
+                                iPhone
+                            {:else if currentDevice === 'Android'}
+                                Android
+                            {:else if currentDevice === 'Windows'}
+                                Windows
+                            {:else if currentDevice === 'macOS'}
+                                MacBook Pro
+                            {:else}
+                                Ubuntu
+                            {/if}
+                        </div>
+                    </div>
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xs text-center flex flex-col justify-around shadow dark:shadow-white/10"
+                >
+                    <div class="flex justify-center">
+                        <Switch inside="slot" radius="full">
+                            <div slot="false">
+                                <Icon name="ri-bluetooth-line" size={12} top={-1} />
+                            </div>
+                            <div slot="true">
+                                <Icon name="ri-bluetooth-connect-line" size={12} theme top={-1} />
+                            </div>
+                        </Switch>
+                    </div>
+                    <div>蓝 牙</div>
+                </div>
+            </Grid>
+            <Grid row={4}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 h-full rounded-lg text-xs text-center flex flex-col justify-around items-center shadow dark:shadow-white/10"
+                >
+                    <div class="w-1/2 overflow-hidden">
+                        <img class="block dark:hidden" src="./assets/stdf_512px.png" alt="" />
+                        <img class="hidden dark:block" src="./assets/stdf_dark_512px.png" alt="" />
+                    </div>
+                    <div>STDF</div>
+                </div>
+            </Grid>
+            <Grid row={3}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 h-full rounded-lg text-xs text-center flex flex-col justify-around shadow dark:shadow-white/10"
+                >
+                    <div>92%</div>
+                    <div class="animate-pulse">
+                        <Icon name="ri-battery-2-charge-line" size={30} injClass="text-[green]" />
+                    </div>
+                    <div>充电中</div>
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 h-full rounded-lg text-xs text-center flex flex-col justify-center shadow dark:shadow-white/10"
+                >
+                    {#if currentDevice === 'iOS'}
+                        <Icon name="ri-smartphone-line" size={30} />
+                    {:else if currentDevice === 'Android'}
+                        <Icon name="ri-tablet-line" size={30} />
+                    {:else if currentDevice === 'Windows'}
+                        <Icon name="ri-computer-line" size={30} />
+                    {:else if currentDevice === 'macOS'}
+                        <Icon name="ri-macbook-fill" size={30} />
+                    {:else}
+                        <Icon name="ri-ubuntu-line" size={30} />
+                    {/if}
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 h-full rounded-lg text-xs text-center flex flex-col justify-around items-center shadow dark:shadow-white/10 py-1"
+                >
+                    <div>
+                        <Icon name="ri-sun-line" size={20} />
+                    </div>
+                    <div>
+                        <div>68%</div>
+                    </div>
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xs text-center flex flex-col justify-around shadow dark:shadow-white/10"
+                >
+                    <div class="flex justify-center">
+                        <Switch inside="slot" radius="full">
+                            <div slot="false">
+                                <Icon name="ri-wifi-off-line" size={12} />
+                            </div>
+                            <div slot="true">
+                                <Icon name="ri-wifi-line" size={12} theme />
+                            </div>
+                        </Switch>
+                    </div>
+                    <div>Wi-Fi</div>
+                </div>
+            </Grid>
+        </Grids>
+    </div>
+</div>

+ 288 - 0
demo/src/pages/grids/GridsDemo_en.svelte

@@ -0,0 +1,288 @@
+<!-- Grids Demo -->
+<script>
+    import { Grids, Grid, Placeholder, Switch, Icon, Button } from '../../../../components';
+
+    let devices = ['iOS', 'Android', 'Windows', 'macOS', 'Ubuntu'];
+    let curentIndex = 0;
+    $: currentDevice = devices[curentIndex];
+    const changeDeviceFun = () => {
+        curentIndex === devices.length - 1 ? (curentIndex = 0) : curentIndex++;
+    };
+    let color = false;
+    $: colorCss = `${color ? ' bg-gradient-to-tr from-purple/70 to-orange/70' : ' bg-gray8 dark:bg-gray4'}`;
+    const changeColorFun = e => {
+        color = e.detail;
+    };
+    //Get the current time
+    const date = new Date();
+    //Get the current month and turn into Chinese characters
+    const monthArr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+    const monthIndex = date.getMonth();
+    $: month = monthArr[monthIndex];
+    const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
+    const hour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
+    const minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
+    $: time = `${hour}:${minute}`;
+    //Get Chinese week
+    const week = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
+    $: weekDay = week[date.getDay()];
+</script>
+
+<div class="font-bold px-4 mt-8 text-left">Example of using a placeholder 3﹡4</div>
+<Grids cols={4}>
+    <Grid row="3">
+        <Placeholder>3﹡1</Placeholder>
+    </Grid>
+    <Grid col="3">
+        <Placeholder>1﹡3</Placeholder>
+    </Grid>
+    <Grid row="2">
+        <Placeholder>2﹡1</Placeholder>
+    </Grid>
+    <Grid col="2">
+        <Placeholder>1﹡2</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+</Grids>
+
+<div class="font-bold px-4 mt-8">Example of using a placeholder 4﹡6</div>
+<Grids>
+    <Grid row={3} col={2}>
+        <Placeholder>3﹡2</Placeholder>
+    </Grid>
+    <Grid col={3}>
+        <Placeholder>1﹡3</Placeholder>
+    </Grid>
+    <Grid row={4}>
+        <Placeholder>4﹡1</Placeholder>
+    </Grid>
+    <Grid row={2}>
+        <Placeholder>2﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid col={4}>
+        <Placeholder>1﹡4</Placeholder>
+    </Grid>
+</Grids>
+
+<div class="font-bold px-4 mt-8">Increase the outer marginal and unit grid spacing</div>
+<Grids cols={4} gap="4" mx="8" my="8">
+    <Grid row={3}>
+        <Placeholder>3﹡1</Placeholder>
+    </Grid>
+    <Grid col={3}>
+        <Placeholder>1﹡3</Placeholder>
+    </Grid>
+    <Grid row={2}>
+        <Placeholder>2﹡1</Placeholder>
+    </Grid>
+    <Grid col={2}>
+        <Placeholder>1﹡2</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+    <Grid>
+        <Placeholder>1﹡1</Placeholder>
+    </Grid>
+</Grids>
+
+<div class="font-bold px-4 mt-8">Scene example 6﹡5</div>
+<div class="pb-8 pt-2">
+    <div class={`mx-2 rounded-xl p-2 shadow transition duration-300${colorCss}`}>
+        <Grids cols={5} mx="0" my="0">
+            <Grid row={3}>
+                <div
+                    class="flex flex-col justify-between bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xs text-center shadow dark:shadow-white/10"
+                >
+                    <div>{weekDay}</div>
+                    <div class="text-4xl">{day}</div>
+                    <div class="text-gray6">{month}</div>
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xl font-bold text-center flex flex-col justify-center shadow dark:shadow-white/10"
+                >
+                    {time}
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xs text-center flex flex-col justify-around shadow dark:shadow-white/10"
+                >
+                    <div class="flex justify-center">
+                        <Switch inside="slot" radius="full" on:change={changeColorFun}>
+                            <div slot="false">
+                                <Icon name="ri-paint-brush-line" size={12} />
+                            </div>
+                            <div slot="true">
+                                <Icon name="ri-paint-brush-fill" size={12} theme />
+                            </div>
+                        </Switch>
+                    </div>
+                    <div>Colorful</div>
+                </div>
+            </Grid>
+
+            <Grid row={2} col={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 h-full rounded-lg text-xs text-center flex flex-col justify-center shadow dark:shadow-white/10"
+                >
+                    <Button fill="lineTheme" radius="full" on:click={changeDeviceFun}>Switching</Button>
+                </div>
+            </Grid>
+            <Grid row={2} col={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xs text-center flex justify-around shadow dark:shadow-white/10 py-1"
+                >
+                    <div class="flex flex-col justify-center">
+                        {#if currentDevice === 'iOS'}
+                            <Icon name="ri-apple-fill" size={30} />
+                        {:else if currentDevice === 'Android'}
+                            <Icon name="ri-android-fill" size={30} />
+                        {:else if currentDevice === 'Windows'}
+                            <Icon name="ri-windows-fill" size={30} />
+                        {:else if currentDevice === 'macOS'}
+                            <Icon name="ri-command-fill" size={30} />
+                        {:else}
+                            <Icon name="ri-ubuntu-fill" size={30} />
+                        {/if}
+                    </div>
+                    <div class="flex flex-col justify-around">
+                        <div class="text-sm">
+                            {#if currentDevice === 'iOS'}
+                                A15 Bionic
+                            {:else if currentDevice === 'Android'}
+                                Snapdragon 8 Gen1
+                            {:else if currentDevice === 'Windows'}
+                                AMD YES
+                            {:else if currentDevice === 'macOS'}
+                                M1 Ultra
+                            {:else}
+                                Intel
+                            {/if}
+                        </div>
+                        <div>
+                            {#if currentDevice === 'iOS'}
+                                iPhone
+                            {:else if currentDevice === 'Android'}
+                                Android
+                            {:else if currentDevice === 'Windows'}
+                                Windows
+                            {:else if currentDevice === 'macOS'}
+                                MacBook Pro
+                            {:else}
+                                Ubuntu
+                            {/if}
+                        </div>
+                    </div>
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xs text-center flex flex-col justify-around shadow dark:shadow-white/10"
+                >
+                    <div class="flex justify-center">
+                        <Switch inside="slot" radius="full">
+                            <div slot="false">
+                                <Icon name="ri-bluetooth-line" size={12} top={-1} />
+                            </div>
+                            <div slot="true">
+                                <Icon name="ri-bluetooth-connect-line" size={12} theme top={-1} />
+                            </div>
+                        </Switch>
+                    </div>
+                    <div>Bluetooth</div>
+                </div>
+            </Grid>
+            <Grid row={4}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 h-full rounded-lg text-xs text-center flex flex-col justify-around items-center shadow dark:shadow-white/10"
+                >
+                    <div class="w-1/2 overflow-hidden">
+                        <img class="block dark:hidden" src="./assets/stdf_512px.png" alt="" />
+                        <img class="hidden dark:block" src="./assets/stdf_dark_512px.png" alt="" />
+                    </div>
+                    <div>STDF</div>
+                </div>
+            </Grid>
+            <Grid row={3}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 h-full rounded-lg text-xs text-center flex flex-col justify-around shadow dark:shadow-white/10"
+                >
+                    <div>92%</div>
+                    <div class="animate-pulse">
+                        <Icon name="ri-battery-2-charge-line" size={30} injClass="text-[green]" />
+                    </div>
+                    <div>charging</div>
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 h-full rounded-lg text-xs text-center flex flex-col justify-center shadow dark:shadow-white/10"
+                >
+                    {#if currentDevice === 'iOS'}
+                        <Icon name="ri-smartphone-line" size={30} />
+                    {:else if currentDevice === 'Android'}
+                        <Icon name="ri-tablet-line" size={30} />
+                    {:else if currentDevice === 'Windows'}
+                        <Icon name="ri-computer-line" size={30} />
+                    {:else if currentDevice === 'macOS'}
+                        <Icon name="ri-macbook-fill" size={30} />
+                    {:else}
+                        <Icon name="ri-ubuntu-line" size={30} />
+                    {/if}
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 h-full rounded-lg text-xs text-center flex flex-col justify-around items-center shadow dark:shadow-white/10 py-1"
+                >
+                    <div>
+                        <Icon name="ri-sun-line" size={20} />
+                    </div>
+                    <div>
+                        <div>68%</div>
+                    </div>
+                </div>
+            </Grid>
+            <Grid row={2}>
+                <div
+                    class="bg-white/50 dark:bg-gray2/50 p-1 h-full rounded-lg text-xs text-center flex flex-col justify-around shadow dark:shadow-white/10"
+                >
+                    <div class="flex justify-center">
+                        <Switch inside="slot" radius="full">
+                            <div slot="false">
+                                <Icon name="ri-wifi-off-line" size={12} />
+                            </div>
+                            <div slot="true">
+                                <Icon name="ri-wifi-line" size={12} theme />
+                            </div>
+                        </Switch>
+                    </div>
+                    <div>Wi-Fi</div>
+                </div>
+            </Grid>
+        </Grids>
+    </div>
+</div>

+ 65 - 0
demo/src/pages/home/Home.svelte

@@ -0,0 +1,65 @@
+<script>
+    import { push } from 'svelte-spa-router';
+    import { Cell, CellGroup } from '../../../../components';
+    import menuList from '../../data/menuList';
+
+    // 循环 menuList,将所有元素的 childs 组成一个数组
+    const menuListArr = menuList.reduce((acc, cur) => {
+        if (cur.childs) {
+            acc.push(...cur.childs);
+        }
+        return acc;
+    }, []);
+
+    const pushFun = child => {
+        push(`/${child.nav}`);
+    };
+
+    const isZh = sessionStorage.getItem('lang') === 'zh_CN';
+
+    const changeLangFunc = () => {
+        sessionStorage.setItem('lang', isZh ? 'en_US' : 'zh_CN');
+        window.location.reload();
+    };
+</script>
+
+<div class="h-14 mt-8 mb-2 flex flex-col justify-center items-center">
+    <svg viewBox="0 0 90 80">
+        <path
+            class="fill-primary dark:fill-dark"
+            d="M0 0H20H40H50C64.8056 0 77.7325 8.04398 84.6487 20H50H40V22.6757V30H50C55.5229 30 60 34.4771 60 40C60 45.5229 55.5229 50 50 50H40V57.3243V78.7398V80H20V66.4583V20H15.3513H0V0ZM50 80C72.0914 80 90 62.0914 90 40C90 36.547 89.5625 33.1962 88.7398 30H67.3244C69.0261 32.9417 70 36.3571 70 40C70 51.0457 61.0457 60 50 60V80Z"
+        />
+        <path class="fill-dark dark:fill-primary" d="M20 30V0L0 50H20V80L40 30H20Z" />
+    </svg>
+</div>
+<a href="https://stdf.design" target="_blank" rel="noreferrer">
+    <div class="text-center text-lg underline">stdf.design</div>
+</a>
+
+<div class="flex flex-col py-4">
+    <div>
+        {#each menuList as menu}
+            <div class="text-sm px-4 mt-8 mb-2 text-gray6">{isZh ? menu.class : menu.class_en}</div>
+            <CellGroup>
+                {#each menu.childs as child, i}
+                    <Cell
+                        title={isZh ? child.title : child.title_en}
+                        mx="0"
+                        my="0"
+                        shadow="none"
+                        radius="none"
+                        line={i !== menu.childs.length - 1}
+                        on:click={() => pushFun(child)}
+                    />
+                {/each}
+            </CellGroup>
+        {/each}
+    </div>
+    <div class="p-4">{isZh ? '当前组件总数:' : 'Current number of components: '}{menuListArr.length}</div>
+    <div class="flex text-xs justify-around p-4 text-primary dark:text-dark underline">
+        <!-- svelte-ignore a11y-click-events-have-key-events -->
+        <div on:click={changeLangFunc}>
+            {isZh ? 'English' : '简体中文'}
+        </div>
+    </div>
+</div>

+ 123 - 0
demo/src/pages/icon/IconDemo.svelte

@@ -0,0 +1,123 @@
+<!-- Icon Demo,请确保已引入 symbol.svg 文件。 -->
+<script>
+    import { Icon } from '../../../../components';
+
+    const icons = ['ri-spy-fill', 'ri-chrome-fill', 'ri-riding-line', 'ri-switch-fill'];
+</script>
+
+<div class="felx felx-col space-y-12 px-4 py-8">
+    <!-- 基础用法 -->
+    <div>
+        <div class="mb-2 font-bold text-xl">基础用法</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icon} />
+                    <div class="text-xs mt-2 text-gray6">{icon}</div>
+                </div>
+            {/each}
+        </div>
+    </div>
+    <!-- 跟随主题色 -->
+    <div>
+        <div class="mb-2 font-bold text-xl">跟随主题色</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icon} theme />
+                </div>
+            {/each}
+        </div>
+    </div>
+    <!-- 不同大小 -->
+    <div>
+        <div class="mb-2 font-bold text-xl">不同大小</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon, i}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icon} size={18 + i * 6} />
+                    <div class="text-xs mt-2 text-gray6">{18 + i * 6}</div>
+                </div>
+            {/each}
+        </div>
+    </div>
+    <!-- 不同透明度 -->
+    <div>
+        <div class="mb-2 font-bold text-xl">不同透明度</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon, i}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icon} alpha={Number((0.2 + i * 0.2).toFixed(1))} />
+                    <div class="text-xs mt-2 text-gray6">{(0.2 + i * 0.2).toFixed(1)}</div>
+                </div>
+            {/each}
+        </div>
+    </div>
+    <!-- 自定义颜色(通过 injClass) -->
+    <div>
+        <div class="mb-2 font-bold text-xl">
+            自定义颜色<span class="ml-2 text-xs text-gray6 font-normal">通过 injClass</span>
+        </div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icon} injClass="text-[red] dark:text-green" />
+                </div>
+            {/each}
+        </div>
+    </div>
+    <!-- 自定义颜色(通过 slot) -->
+    <div>
+        <div class="mb-2 font-bold text-xl">
+            自定义颜色<span class="ml-2 text-xs text-gray6 font-normal">通过 slot</span>
+        </div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon}
+                <div class="py-2 text-center flex-1">
+                    <Icon name="slot">
+                        <i class="text-[#266CF6] dark:text-[#C84031]">
+                            <Icon name={icon} />
+                        </i>
+                    </Icon>
+                </div>
+            {/each}
+        </div>
+    </div>
+    <!-- 插槽 -->
+    <div>
+        <div class="mb-2 font-bold text-xl">插槽</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon}
+                <div class="py-2 text-center flex-1">
+                    <Icon name="slot">
+                        <svg
+                            height="24"
+                            width="24"
+                            aria-hidden="true"
+                            viewBox="0 0 16 16"
+                            data-view-component="true"
+                            style="display: inline;"
+                        >
+                            <path
+                                fill-rule="evenodd"
+                                d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
+                            />
+                        </svg>
+                    </Icon>
+                </div>
+            {/each}
+        </div>
+    </div>
+    <!-- 偏移 -->
+    <div>
+        <div class="mb-2 font-bold text-xl">偏移</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon, i}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icons[1]} top={-4 + i * 2} />
+                    top:{-4 + i * 2}
+                </div>
+            {/each}
+        </div>
+    </div>
+</div>

+ 115 - 0
demo/src/pages/icon/IconDemo_en.svelte

@@ -0,0 +1,115 @@
+<!-- Icon Demo, Please make sure you have been introduced symbol.svg file. -->
+<script>
+    import { Icon } from '../../../../components';
+
+    const icons = ['ri-spy-fill', 'ri-chrome-fill', 'ri-riding-line', 'ri-switch-fill'];
+</script>
+
+<div class="felx felx-col space-y-12 px-4 py-8">
+    <div>
+        <div class="mb-2 font-bold text-xl">Basic usage</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icon} />
+                    <div class="text-xs mt-2 text-gray6">{icon}</div>
+                </div>
+            {/each}
+        </div>
+    </div>
+    <div>
+        <div class="mb-2 font-bold text-xl">Follow the theme color</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icon} theme />
+                </div>
+            {/each}
+        </div>
+    </div>
+    <div>
+        <div class="mb-2 font-bold text-xl">Different size</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon, i}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icon} size={18 + i * 6} />
+                    <div class="text-xs mt-2 text-gray6">{18 + i * 6}</div>
+                </div>
+            {/each}
+        </div>
+    </div>
+    <div>
+        <div class="mb-2 font-bold text-xl">Different transparency</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon, i}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icon} alpha={Number((0.2 + i * 0.2).toFixed(1))} />
+                    <div class="text-xs mt-2 text-gray6">{(0.2 + i * 0.2).toFixed(1)}</div>
+                </div>
+            {/each}
+        </div>
+    </div>
+    <div>
+        <div class="mb-2 font-bold text-xl">
+            Custom color<span class="ml-2 text-xs text-gray6 font-normal">By injClass</span>
+        </div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icon} injClass="text-[red] dark:text-green" />
+                </div>
+            {/each}
+        </div>
+    </div>
+    <div>
+        <div class="mb-2 font-bold text-xl">
+            Custom color<span class="ml-2 text-xs text-gray6 font-normal">by slot</span>
+        </div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon}
+                <div class="py-2 text-center flex-1">
+                    <Icon name="slot">
+                        <i class="text-[#266CF6] dark:text-[#C84031]">
+                            <Icon name={icon} />
+                        </i>
+                    </Icon>
+                </div>
+            {/each}
+        </div>
+    </div>
+    <div>
+        <div class="mb-2 font-bold text-xl">Slot</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon}
+                <div class="py-2 text-center flex-1">
+                    <Icon name="slot">
+                        <svg
+                            height="24"
+                            width="24"
+                            aria-hidden="true"
+                            viewBox="0 0 16 16"
+                            data-view-component="true"
+                            style="display: inline;"
+                        >
+                            <path
+                                fill-rule="evenodd"
+                                d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
+                            />
+                        </svg>
+                    </Icon>
+                </div>
+            {/each}
+        </div>
+    </div>
+    <div>
+        <div class="mb-2 font-bold text-xl">Offset</div>
+        <div class="flex flex-wrap justify-between">
+            {#each icons as icon, i}
+                <div class="py-2 text-center flex-1">
+                    <Icon name={icons[1]} top={-4 + i * 2} />
+                    top:{-4 + i * 2}
+                </div>
+            {/each}
+        </div>
+    </div>
+</div>

+ 119 - 0
demo/src/pages/icon/allIcon.md

@@ -0,0 +1,119 @@
+Demo 中用到的所有 Remixicon 如下:
+
+-   ri-arrow-left-s-line
+-   ri-arrow-right-s-line
+-   ri-user-3-line
+-   ri-radio-button-line
+-   ri-checkbox-blank-circle-line
+-   ri-checkbox-fill
+-   ri-checkbox-line
+-   ri-close-circle-fill
+-   ri-image-2-fill
+-   ri-movie-2-fill
+-   ri-code-box-fill
+-   ri-qr-code-fill
+-   ri-barcode-fill
+-   ri-star-fill
+-   ri-close-line
+-   ri-volume-down-line
+-   ri-arrow-down-s-line
+-   ri-plane-fill
+-   ri-share-forward-2-fill
+-   ri-mic-off-fill
+-   ri-hand-heart-line
+-   ri-apps-2-line
+-   ri-star-line
+-   ri-share-forward-line
+-   ri-spy-fill
+-   ri-chrome-fill
+-   ri-riding-line
+-   ri-switch-fill
+-   ri-home-7-line
+-   ri-customer-service-2-line
+-   ri-paint-brush-line
+-   ri-share-line
+-   ri-command-line
+-   ri-drag-move-line
+-   ri-indent-decrease
+-   ri-service-line
+-   ri-parent-line
+-   ri-bank-line
+-   ri-battery-charge-line
+-   ri-shopping-basket-line
+-   ri-moon-line
+-   ri-sun-line
+-   ri-bear-smile-line
+-   ri-aliens-fill
+-   ri-user-smile-line
+-   ri-shield-user-line
+-   ri-emotion-line
+-   ri-plane-line
+-   ri-ship-2-line
+-   ri-train-line
+-   ri-car-line
+-   ri-home-3-line
+-   ri-home-3-fill
+-   ri-compass-3-line
+-   ri-compass-3-fill
+-   ri-discuss-line
+-   ri-discuss-fill
+-   ri-account-circle-line
+-   ri-account-circle-fill
+-   ri-money-cny-circle-line
+-   ri-fingerprint-line
+-   ri-hotel-bed-line
+-   ri-restaurant-2-line
+-   ri-cup-line
+-   ri-emotion-sad-line
+-   ri-zzz-line
+-   ri-hotel-bed-fill
+-   ri-restaurant-2-fill
+-   ri-cup-fill
+-   ri-emotion-sad-fill
+-   ri-zzz-fill
+-   ri-checkbox-circle-line
+-   ri-checkbox-circle-fill
+-   ri-checkbox-multiple-line
+-   ri-checkbox-multiple-fill
+-   ri-check-line
+-   ri-check-fill
+-   ri-arrow-up-s-line
+-   ri-arrow-up-s-fill
+-   ri-radio-button-fill
+-   ri-close-fill
+-   ri-lock-line
+-   ri-qr-scan-line
+-   ri-paint-brush-fill
+-   ri-ubuntu-fill
+-   ri-command-fill
+-   ri-windows-fill
+-   ri-android-fill
+-   ri-apple-fill
+-   ri-bluetooth-line
+-   ri-bluetooth-connect-line
+-   ri-battery-2-charge-line
+-   ri-ubuntu-line
+-   ri-macbook-fill
+-   ri-computer-line
+-   ri-tablet-line
+-   ri-smartphone-line
+-   ri-wifi-off-line
+-   ri-wifi-line
+-   ri-heart-3-fill
+-   ri-volume-mute-line
+-   ri-volume-up-line
+-   ri-medal-fill
+-   ri-cake-2-fill
+-   ri-notification-2-line
+-   ri-wireless-charging-line
+-   ri-thumb-up-fill
+-   ri-phone-fill
+-   ri-surgical-mask-fill
+-   ri-github-fill
+-   ri-compass-line
+-   ri-moon-fill
+-   ri-close-circle-line
+-   ri-error-warning-line
+-   ri-information-line
+-   ri-more-line
+-   ri-more-fill

+ 188 - 0
demo/src/pages/indexBar/IndexBarDemo.svelte

@@ -0,0 +1,188 @@
+<!-- IndexBar Demo -->
+<script>
+    import { getContext } from 'svelte';
+    import { IndexBar, Button, NoticeBar, Toast } from '../../../../components';
+
+    const isIframe = getContext('iframe') === '1'; //判断是否是iframe
+
+    const addressList = [
+        { index: 'A', title: 'A', child: [{ text: '澳门' }, { text: '安宁' }, { text: '安庆' }, { text: '鞍山' }] },
+        { index: 'B', title: 'B', child: [{ text: '北京' }, { text: '保定' }, { text: '包头' }, { text: '宝鸡' }] },
+        { index: 'C', title: 'C', child: [{ text: '承德' }, { text: '沧州' }, { text: '赤峰' }] },
+        { index: 'D', title: 'D', child: [{ text: '大同' }, { text: '大连' }, { text: '大理' }] },
+        { index: 'E', title: 'E', child: [{ text: '恩施' }, { text: '鄂尔多斯' }, { text: '峨眉山' }] },
+        { index: 'F', title: 'F', child: [{ text: '抚顺' }, { text: '佛山' }, { text: '福泉' }] },
+        { index: 'G', title: 'G', child: [{ text: '个旧' }, { text: '桂林' }, { text: '赣州' }] },
+        { index: 'H', title: 'H', child: [{ text: '邯郸' }, { text: '呼和浩特' }, { text: '呼伦贝尔' }] },
+        { index: 'J', title: 'J', child: [{ text: '吉林' }, { text: '酒泉' }, { text: '晋江' }] },
+        { index: 'K', title: 'K', child: [{ text: '昆明' }, { text: '昆山' }, { text: '开封' }] },
+        { index: 'L', title: 'L', child: [{ text: '拉萨' }, { text: '兰州' }, { text: '泸州' }] },
+        { index: 'M', title: 'M', child: [{ text: '绵阳' }, { text: '马鞍山' }, { text: '牡丹江' }] },
+        { index: 'N', title: 'N', child: [{ text: '南昌' }, { text: '南京' }, { text: '宁波' }] },
+        { index: 'P', title: 'P', child: [{ text: '莆田' }, { text: '攀枝花' }, { text: '平顶山' }] },
+        { index: 'Q', title: 'Q', child: [{ text: '曲靖' }, { text: '青岛' }, { text: '齐齐哈尔' }] },
+        { index: 'R', title: 'R', child: [{ text: '瑞丽' }, { text: '瑞安' }, { text: '瑞金' }] },
+        { index: 'S', title: 'S', child: [{ text: '三亚' }, { text: '上海' }, { text: '深圳' }] },
+        { index: 'T', title: 'T', child: [{ text: '台州' }, { text: '太原' }, { text: '天津' }] },
+        { index: 'W', title: 'W', child: [{ text: '武汉' }, { text: '无锡' }, { text: '芜湖' }] },
+        { index: 'X', title: 'X', child: [{ text: '西安' }, { text: '厦门' }, { text: '宣威' }] },
+        { index: 'Y', title: 'Y', child: [{ text: '义乌' }, { text: '银川' }, { text: '玉溪' }] },
+        { index: 'Z', title: 'Z', child: [{ text: '昭通' }, { text: '遵义' }, { text: '张家界' }] },
+    ];
+    const emojiList = [
+        { index: '😀', title: '表情与情感', child: [{ text: '😂' }, { text: '🥰' }, { text: '🥱' }, { text: '🧐' }] },
+        { index: '👋', title: '人物与身体', child: [{ text: '👌' }, { text: '🤝' }, { text: '👨‍💻' }, { text: '💪' }] },
+        { index: '🐵', title: '动物与自然', child: [{ text: '🦄' }, { text: '🌱' }, { text: '🦁' }, { text: '🐶' }] },
+        { index: '🍎', title: '食物与饮料', child: [{ text: '🍑' }, { text: '🍞' }, { text: '🍽️' }, { text: '🍩' }] },
+        { index: '🌍', title: '旅行与地理', child: [{ text: '🏔️' }, { text: '🚆' }, { text: '✈️' }, { text: '🛵' }] },
+        { index: '🏆', title: '活动', child: [{ text: '⚽' }, { text: '🎨' }, { text: '🏀' }, { text: '🧨' }] },
+        { index: '📱', title: '物品', child: [{ text: '🎩' }, { text: '💻' }, { text: '🎒' }, { text: '📖' }] },
+        { index: '⚠️', title: '符号标志', child: [{ text: '🚫' }, { text: '⚛️' }, { text: '🛄' }, { text: '🔱' }] },
+        { index: '🏁', title: '旗帜', child: [{ text: '🇨🇳' }, { text: '🇺🇸' }, { text: '🇧🇻' }, { text: '🇦🇹' }] },
+    ];
+    const movieTVList = [
+        {
+            index: '三',
+            title: '三体',
+            child: [
+                { text: '地球往事' },
+                { text: '黑暗森林' },
+                { text: '死神永生' },
+                { text: '科学边界' },
+                { text: '射手和农场主' },
+                { text: '寂静的春天' },
+                { text: '宇宙闪烁' },
+                { text: '地球叛军' },
+                { text: '古筝行动' },
+                { text: '智子' },
+                { text: '面壁者' },
+                { text: '咒语' },
+                { text: '黑暗森林' },
+                { text: '危机纪元' },
+                { text: '威慑纪元' },
+                { text: '广播纪元' },
+                { text: '掩体纪元' },
+                { text: '银河纪元' },
+                { text: '时间开始' },
+                { text: '时间之外,我们的宇宙' },
+            ],
+        },
+        {
+            index: '流',
+            title: '流浪地球',
+            child: [
+                { text: '人类的勇气和坚毅必将被镌刻在星空之下。' },
+                { text: '希望是像钻石一样珍贵的东西!' },
+                { text: '希望,希望是我们唯一回家的方向。' },
+                { text: '让人类永远保持理智,是一种奢求。' },
+                { text: '道路千万条,安全第一条;行车不规范,亲人两行泪!' },
+                { text: '那时候人们还没注意到太阳,人们更喜欢叫做钱的东西。' },
+                { text: '为了我们的孩子,没有什么不能失去的了' },
+                { text: 'moss没有叛逃!' },
+                { text: '火石没了,我老婆孩子全他妈白死了!' },
+            ],
+        },
+        {
+            index: '仙',
+            title: '仙剑奇侠传',
+            child: [
+                { text: '既不回头,何必不忘。既然无缘,何必誓言。' },
+                { text: '没有值得不值得,只有愿意不愿意。' },
+                { text: '不曾得到,谈何放下。既已得到,又如何放下。' },
+                { text: '轮回的是故人,不变的是初心!' },
+                { text: '明夕何夕,君已陌路。' },
+                { text: '我曾经也拥有过爱,只是,我放弃了。' },
+                { text: '你以为每天看到的东西,就会抓得住吗?' },
+                { text: '世有无情人,却有痴情妖。' },
+                { text: '君子,小人,皆在一念思量。' },
+                { text: '到家了,一定要叫醒我,我怕我醒不过来。' },
+                { text: '如果得道就是牺牲所有人来成全自己,我宁愿执迷不悟。' },
+                { text: '我们今日一别,让我们十年后再相见,不见不散!' },
+                { text: '一杯愁绪,几段情缘,莫过,与君对酒当歌。' },
+            ],
+        },
+    ];
+    const navHeight = 48;
+    const bottomHeight = 50;
+    const height = window.innerHeight - navHeight - bottomHeight;
+    let radius = 'base';
+    let dataFlag = 0;
+    let scrollAlign = true;
+    let injClassList = [];
+    const changeRadiusFun = () => {
+        radius = radius === 'base' ? 'full' : radius === 'full' ? 'none' : 'base';
+    };
+    const changeListFun = () => {
+        dataFlag = dataFlag === 0 ? 1 : dataFlag === 1 ? 2 : 0;
+    };
+    const changeScrollAlignFun = () => {
+        scrollAlign = !scrollAlign;
+    };
+    const changeClassFun = () => {
+        injClassList = !injClassList.length ? ['!text-3xl text-center', 'text-xs text-center !py-1'] : [];
+    };
+    let visible = false;
+    let toastObj = { index: 0, group: {}, childIndex: 0, child: {} };
+</script>
+
+{#if dataFlag === 0}
+    <IndexBar
+        data={addressList}
+        {radius}
+        {height}
+        {scrollAlign}
+        titleInjClass={injClassList[0]}
+        textInjClass={injClassList[1]}
+        top={navHeight}
+        on:clickchild={e => {
+            toastObj = e.detail;
+            visible = true;
+        }}
+    />
+{:else if dataFlag === 1}
+    <IndexBar
+        data={emojiList}
+        {radius}
+        {height}
+        {scrollAlign}
+        titleInjClass={injClassList[0]}
+        textInjClass={injClassList[1]}
+        top={navHeight}
+        on:clickchild={e => {
+            toastObj = e.detail;
+            visible = true;
+        }}
+    />
+{:else}
+    <IndexBar
+        data={movieTVList}
+        {radius}
+        {height}
+        {scrollAlign}
+        titleInjClass={injClassList[0]}
+        textInjClass={injClassList[1]}
+        top={navHeight}
+        on:clickchild={e => {
+            toastObj = e.detail;
+            visible = true;
+        }}
+    />
+{/if}
+<Toast
+    bind:visible
+    message={`点击了第 ${toastObj.index + 1} 组(${toastObj.group.title})中的第 ${toastObj.childIndex + 1} 项(${toastObj.child.text})`}
+/>
+
+{#if isIframe}
+    <div class="fixed top-12 w-full bg-white dark:bg-gray1">
+        <NoticeBar textList={['右侧 Bar 区域绑定了 Touch 事件,请直接在移动设备或通过开发者工具模拟移动设备预览。']} right="none" />
+    </div>
+{/if}
+<div class="sticky flex justify-between bottom-0 px-2 z-10 bg-white/90 dark:bg-black/90">
+    <Button fill="lineTheme" size="auto" injClass="text-xs px-2" on:click={changeListFun}>切换数据</Button>
+    <Button fill="lineTheme" size="auto" injClass="text-xs px-2" on:click={changeScrollAlignFun}>
+        {scrollAlign ? '关闭' : '开启'}滚动对齐
+    </Button>
+    <Button fill="lineTheme" size="auto" injClass="text-xs px-2" on:click={changeRadiusFun}>切换圆角</Button>
+    <Button fill="lineTheme" size="auto" injClass="text-xs px-2" on:click={changeClassFun}>切换样式</Button>
+</div>

+ 189 - 0
demo/src/pages/indexBar/IndexBarDemo_en.svelte

@@ -0,0 +1,189 @@
+<!-- IndexBar Demo -->
+<script>
+    import { getContext } from 'svelte';
+    import { IndexBar, Button, NoticeBar, Toast } from '../../../../components';
+
+    const isIframe = getContext('iframe') === '1'; //Determine whether it is iframe
+
+    const addressList = [
+        { index: 'A', title: 'A', child: [{ text: 'Macau' }, { text: 'Anning' }, { text: 'Anqing' }, { text: 'Anshan' }] },
+        { index: 'B', title: 'B', child: [{ text: 'Beijing' }, { text: 'Baoding' }, { text: 'Baotou' }, { text: 'Baoji' }] },
+        { index: 'C', title: 'C', child: [{ text: 'Chengde' }, { text: 'Cangzhou' }, { text: 'Chifeng' }] },
+        { index: 'D', title: 'D', child: [{ text: 'Datong' }, { text: 'Dalian' }, { text: 'Dali' }] },
+        { index: 'E', title: 'E', child: [{ text: 'Enshi' }, { text: 'Ordos' }, { text: 'Emeishan' }] },
+        { index: 'F', title: 'F', child: [{ text: 'Fushun' }, { text: 'Foshan' }, { text: 'Fuquan' }] },
+        { index: 'G', title: 'G', child: [{ text: 'Gejiu' }, { text: 'Guilin' }, { text: 'Ganzhou' }] },
+        { index: 'H', title: 'H', child: [{ text: 'Handan' }, { text: 'Hohhot' }, { text: 'Hulunbuir' }] },
+        { index: 'J', title: 'J', child: [{ text: 'Jilin' }, { text: 'Jiuquan' }, { text: 'Jinjiang' }] },
+        { index: 'K', title: 'K', child: [{ text: 'Kunming' }, { text: 'Kunshan' }, { text: 'Kaifeng' }] },
+        { index: 'L', title: 'L', child: [{ text: 'Lhasa' }, { text: 'Lanzhou' }, { text: 'Luzhou' }] },
+        { index: 'M', title: 'M', child: [{ text: 'Mianyang' }, { text: 'Maans' }, { text: 'Mudanjiang' }] },
+        { index: 'N', title: 'N', child: [{ text: 'Nanchang' }, { text: 'Nanjing' }, { text: 'Ningbo' }] },
+        { index: 'P', title: 'P', child: [{ text: 'Putian' }, { text: 'Panzhihua' }, { text: 'Pingdingshan' }] },
+        { index: 'Q', title: 'Q', child: [{ text: 'Qujing' }, { text: 'Qingdao' }, { text: 'Qiqihar' }] },
+        { index: 'R', title: 'R', child: [{ text: 'Ruili' }, { text: 'Ruian' }, { text: 'Ruijin' }] },
+        { index: 'S', title: 'S', child: [{ text: 'Sanya' }, { text: 'Shanghai' }, { text: 'Shenzhen' }] },
+        { index: 'T', title: 'T', child: [{ text: 'Taizhou' }, { text: 'Taiyuan' }, { text: 'Tianjin' }] },
+        { index: 'W', title: 'W', child: [{ text: 'Wuhan' }, { text: 'Wuxi' }, { text: 'Wuhu' }] },
+        { index: 'X', title: 'X', child: [{ text: 'Xi an' }, { text: 'Xiamen' }, { text: 'Xuanwei' }] },
+        { index: 'Y', title: 'Y', child: [{ text: 'Yiwu' }, { text: 'Yinchuan' }, { text: 'Yuxi' }] },
+        { index: 'Z', title: 'Z', child: [{ text: 'Zhaotong' }, { text: 'Zunyi' }, { text: 'Zhangjiajie' }] },
+    ];
+
+    const emojiList = [
+        { index: '😀', title: 'Smileys & Emotion', child: [{ text: '😂' }, { text: '🥰' }, { text: '🥱' }, { text: '🧐' }] },
+        { index: '👋', title: 'People & Body', child: [{ text: '👌' }, { text: '🤝' }, { text: '👨‍💻' }, { text: '💪' }] },
+        { index: '🐵', title: 'Animals & Nature', child: [{ text: '🦄' }, { text: '🌱' }, { text: '🦁' }, { text: '🐶' }] },
+        { index: '🍎', title: 'Food & Drink', child: [{ text: '🍑' }, { text: '🍞' }, { text: '🍽️' }, { text: '🍩' }] },
+        { index: '🌍', title: 'Travel & Places', child: [{ text: '🏔️' }, { text: '🚆' }, { text: '✈️' }, { text: '🛵' }] },
+        { index: '🏆', title: 'Activities', child: [{ text: '⚽' }, { text: '🎨' }, { text: '🏀' }, { text: '🧨' }] },
+        { index: '📱', title: 'Objects', child: [{ text: '🎩' }, { text: '💻' }, { text: '🎒' }, { text: '📖' }] },
+        { index: '⚠️', title: 'Symbols', child: [{ text: '🚫' }, { text: '⚛️' }, { text: '🛄' }, { text: '🔱' }] },
+        { index: '🏁', title: 'Flags', child: [{ text: '🇨🇳' }, { text: '🇺🇸' }, { text: '🇧🇻' }, { text: '🇦🇹' }] },
+    ];
+    const movieTVList = [
+        {
+            index: '三',
+            title: '三体',
+            child: [
+                { text: '地球往事' },
+                { text: '黑暗森林' },
+                { text: '死神永生' },
+                { text: '科学边界' },
+                { text: '射手和农场主' },
+                { text: '寂静的春天' },
+                { text: '宇宙闪烁' },
+                { text: '地球叛军' },
+                { text: '古筝行动' },
+                { text: '智子' },
+                { text: '面壁者' },
+                { text: '咒语' },
+                { text: '黑暗森林' },
+                { text: '危机纪元' },
+                { text: '威慑纪元' },
+                { text: '广播纪元' },
+                { text: '掩体纪元' },
+                { text: '银河纪元' },
+                { text: '时间开始' },
+                { text: '时间之外,我们的宇宙' },
+            ],
+        },
+        {
+            index: '流',
+            title: '流浪地球',
+            child: [
+                { text: '人类的勇气和坚毅必将被镌刻在星空之下。' },
+                { text: '希望是像钻石一样珍贵的东西!' },
+                { text: '希望,希望是我们唯一回家的方向。' },
+                { text: '让人类永远保持理智,是一种奢求。' },
+                { text: '道路千万条,安全第一条;行车不规范,亲人两行泪!' },
+                { text: '那时候人们还没注意到太阳,人们更喜欢叫做钱的东西。' },
+                { text: '为了我们的孩子,没有什么不能失去的了' },
+                { text: 'moss没有叛逃!' },
+                { text: '火石没了,我老婆孩子全他妈白死了!' },
+            ],
+        },
+        {
+            index: '仙',
+            title: '仙剑奇侠传',
+            child: [
+                { text: '既不回头,何必不忘。既然无缘,何必誓言。' },
+                { text: '没有值得不值得,只有愿意不愿意。' },
+                { text: '不曾得到,谈何放下。既已得到,又如何放下。' },
+                { text: '轮回的是故人,不变的是初心!' },
+                { text: '明夕何夕,君已陌路。' },
+                { text: '我曾经也拥有过爱,只是,我放弃了。' },
+                { text: '你以为每天看到的东西,就会抓得住吗?' },
+                { text: '世有无情人,却有痴情妖。' },
+                { text: '君子,小人,皆在一念思量。' },
+                { text: '到家了,一定要叫醒我,我怕我醒不过来。' },
+                { text: '如果得道就是牺牲所有人来成全自己,我宁愿执迷不悟。' },
+                { text: '我们今日一别,让我们十年后再相见,不见不散!' },
+                { text: '一杯愁绪,几段情缘,莫过,与君对酒当歌。' },
+            ],
+        },
+    ];
+    const navHeight = 48;
+    const bottomHeight = 50;
+    const height = window.innerHeight - navHeight - bottomHeight;
+    let radius = 'base';
+    let dataFlag = 0;
+    let scrollAlign = true;
+    let injClassList = [];
+    const changeRadiusFun = () => {
+        radius = radius === 'base' ? 'full' : radius === 'full' ? 'none' : 'base';
+    };
+    const changeListFun = () => {
+        dataFlag = dataFlag === 0 ? 1 : dataFlag === 1 ? 2 : 0;
+    };
+    const changeScrollAlignFun = () => {
+        scrollAlign = !scrollAlign;
+    };
+    const changeClassFun = () => {
+        injClassList = !injClassList.length ? ['!text-3xl text-center', 'text-xs text-center !py-1'] : [];
+    };
+    let visible = false;
+    let toastObj = { index: 0, group: {}, childIndex: 0, child: {} };
+</script>
+
+{#if dataFlag === 0}
+    <IndexBar
+        data={addressList}
+        {radius}
+        {height}
+        {scrollAlign}
+        titleInjClass={injClassList[0]}
+        textInjClass={injClassList[1]}
+        top={navHeight}
+        on:clickchild={e => {
+            toastObj = e.detail;
+            visible = true;
+        }}
+    />
+{:else if dataFlag === 1}
+    <IndexBar
+        data={emojiList}
+        {radius}
+        {height}
+        {scrollAlign}
+        titleInjClass={injClassList[0]}
+        textInjClass={injClassList[1]}
+        top={navHeight}
+        on:clickchild={e => {
+            toastObj = e.detail;
+            visible = true;
+        }}
+    />
+{:else}
+    <IndexBar
+        data={movieTVList}
+        {radius}
+        {height}
+        {scrollAlign}
+        titleInjClass={injClassList[0]}
+        textInjClass={injClassList[1]}
+        top={navHeight}
+        on:clickchild={e => {
+            toastObj = e.detail;
+            visible = true;
+        }}
+    />
+{/if}
+<Toast
+    bind:visible
+    message={`Clicked ${toastObj.index + 1} group(${toastObj.group.title}) ${toastObj.childIndex + 1} item(${toastObj.child.text})`}
+/>
+
+{#if isIframe}
+    <div class="fixed top-12 w-full bg-white dark:bg-gray1">
+        <NoticeBar textList={['The Touch event is bound to the BAR area on the right,Please preview the mobile device directly on the mobile device or through the developer tool.']} right="none" />
+    </div>
+{/if}
+<div class="sticky flex justify-between bottom-0 px-2 z-10 bg-white/90 dark:bg-black/90">
+    <Button fill="lineTheme" size="auto" injClass="text-xs px-2" on:click={changeListFun}>Switch data</Button>
+    <Button fill="lineTheme" size="auto" injClass="text-xs px-2" on:click={changeScrollAlignFun}>
+        {scrollAlign ? 'open' : 'close'} Align
+    </Button>
+    <Button fill="lineTheme" size="auto" injClass="text-xs px-2" on:click={changeRadiusFun}>Switch rounded</Button>
+    <Button fill="lineTheme" size="auto" injClass="text-xs px-2" on:click={changeClassFun}>Switch style</Button>
+</div>

+ 257 - 0
demo/src/pages/input/InputDemo.svelte

@@ -0,0 +1,257 @@
+<!-- Input Demo -->
+<script>
+    import { getContext } from 'svelte';
+    import { Input, Button, Icon, Toast } from '../../../../components';
+
+    let value = '初始文本';
+    let visible = false;
+
+    let IdCard = '';
+
+    const isIframe = getContext('iframe') === '1'; //判断是否是iframe
+
+    $: placeholderIdCard = IdCard === '' ? '请输入身份证号' : '';
+    const clickLabel4Fun = () => {
+        placeholderIdCard = '两秒后识别完毕......';
+        setTimeout(() => {
+            IdCard = '1234567890XXX-XX';
+        }, 2000);
+    };
+    let mobileLength = 0;
+    const changeStateFun = e => {
+        mobileLength = e.detail.length;
+    };
+    $: mobileState = mobileLength === 11 ? 'success' : mobileLength === 0 ? 'theme' : 'error';
+</script>
+
+<div class="px-4 pt-8 font-bold text-xl">基础用法</div>
+<Input title="文本" />
+
+<div class="px-4 pt-8 font-bold text-xl">不带标题</div>
+<Input placeholder="请输入文本" />
+
+<div class="px-4 pt-8 font-bold text-xl">自定义 placeholder</div>
+<Input title="文本" placeholder="我是自定义的 placeholder" />
+
+<div class="px-4 pt-8 font-bold text-xl">
+    不同输入类型
+    {#if isIframe}
+        <span class="text-xs opacity-50 ml-2">请在移动设备查看键盘类型。</span>
+    {/if}
+</div>
+<Input title="任意文本(常规键盘)" />
+<Input title="密码" type="password" />
+<Input title="数字(任意)" type="number" />
+<Input title="数字(整数)" type="numeric" />
+<Input title="数字(允许小数点)" type="decimal" />
+<Input title="邮箱" type="email" />
+<Input title="电话号码" type="tel" />
+<Input title="链接地址" type="url" />
+<Input title="搜索内容" type="search" />
+<Input title="文本(不使用虚拟键盘)" type="none" />
+
+<div class="px-4 pt-8 font-bold text-xl">线性风格</div>
+<Input title="文本" inputStyle="line" />
+<Input title="文本(线条居中过渡)" inputStyle="line" lineTransition="center" />
+<Input title="文本(线条左侧过渡)" inputStyle="line" lineTransition="left" />
+
+<div class="px-4 pt-8 font-bold text-xl">不同过渡时间</div>
+<Input title="过渡快" duration="fast" />
+<Input title="过渡正常" />
+<Input title="过渡较慢" duration="slower" />
+<Input title="线性过渡正常" inputStyle="line" lineTransition="center" />
+<Input title="线性过渡较慢" inputStyle="line" lineTransition="center" duration="slower" />
+
+<div class="px-4 pt-8 font-bold text-xl">不同标题位置</div>
+<Input title="标题(外部)" />
+<Input title="标题(内部)" titlePosition="in" />
+<Input title="标题(无)" titlePosition="none" />
+
+<div class="px-4 pt-8 font-bold text-xl">不同输入文字位置</div>
+<Input title="文本" />
+<Input title="文本" inputPosition="right" />
+
+<div class="px-4 pt-8 font-bold text-xl">不同圆角风格</div>
+<Input title="文本" />
+<Input title="文本" radius="xl" />
+<Input title="文本" radius="full" />
+<Input title="文本" radius="none" />
+<Input title="线性风格圆角无效" radius="full" inputStyle="line" />
+
+<div class="px-4 pt-8 font-bold text-xl">不同垂直间距</div>
+<Input placeholder="请输入文本(间距为 0)" py="0" inputStyle="line" />
+<Input placeholder="请输入文本(间距为 0)" py="0" inputStyle="line" />
+<Input placeholder="请输入文本(间距为 0)" py="0" inputStyle="line" />
+<Input placeholder="请输入文本(间距为 4)" py="4" inputStyle="line" />
+<Input placeholder="请输入文本(间距为 4)" py="4" inputStyle="line" />
+<Input placeholder="请输入文本(间距为 4)" py="4" inputStyle="line" />
+
+<div class="px-4 pt-8 font-bold text-xl">带清除</div>
+<Input title="文本" clear />
+
+<div class="px-4 pt-8 font-bold text-xl">禁用</div>
+<Input title="文本" disabled value="已禁用" />
+
+<div class="px-4 pt-8 font-bold text-xl">不同状态色</div>
+<Input title="成功" state="success" />
+<Input title="警告" state="warning" />
+<Input title="错误" state="error" />
+<Input title="信息" state="info" />
+<Input title="警告&线性" inputStyle="line" state="error" />
+<Input title="警告&线性&动画" inputStyle="line" state="error" lineTransition="center" />
+<Input title="动态改变状态色" type="tel" placeholder="请输入11位手机号" maxlength={11} state={mobileState} on:change={changeStateFun} />
+
+<div class="px-4 pt-8 font-bold text-xl">左侧带图标</div>
+<Input title="密码" type="password" label1={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />
+<Input
+    title="用户名"
+    label1={{ name: 'ri-arrow-down-s-line', size: 16, alpha: 0.5 }}
+    label3={{ name: 'ri-shield-user-line', size: 16, alpha: 0.5 }}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">左侧带文字</div>
+<Input title="账号" label2="账号" />
+
+<div class="px-4 pt-8 font-bold text-xl">左侧带图标与文字</div>
+<Input title="密码" type="password" label1={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} label2="密码" />
+
+<div class="px-4 pt-8 font-bold text-xl">左侧带文字与图标</div>
+<Input title="密码" type="password" label2="密码" label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />
+
+<div class="px-4 pt-8 font-bold text-xl">左侧带图标、文字、图标</div>
+<Input
+    title="密码"
+    type="password"
+    label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label2="密码"
+    label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">右侧带图标</div>
+<Input title="身份证号" label4={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }} />
+<Input
+    title="用户名"
+    label4={{ name: 'ri-arrow-down-s-line', size: 16, alpha: 0.5 }}
+    label6={{ name: 'ri-shield-user-line', size: 16, alpha: 0.5 }}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">右侧带文字</div>
+<Input title="金额" type="number" label5="元" />
+
+<div class="px-4 pt-8 font-bold text-xl">右侧带图标与文字</div>
+<Input title="密码" type="password" label4={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} label5="密码" />
+
+<div class="px-4 pt-8 font-bold text-xl">右侧带文字与图标</div>
+<Input title="密码" type="password" label5="密码" label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />
+
+<div class="px-4 pt-8 font-bold text-xl">右侧带图标、文字、图标</div>
+<Input
+    title="密码"
+    type="password"
+    label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label5="密码"
+    label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">左侧带文字右侧带图标</div>
+<Input label2="身份证号" label6={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }} placeholder="请输入身份证号" />
+
+<div class="px-4 pt-8 font-bold text-xl">左右六项全带</div>
+<Input
+    title="密码"
+    type="password"
+    label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label2="密码"
+    label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
+    label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label5="密码"
+    label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">提示信息与数据项组合</div>
+<Input title="文本" tip="提示信息" />
+<Input title="文本" data1="数据项1" />
+<Input title="文本" data1="数据项1" data2="数据项2" />
+<Input title="文本" data3="数据项3" />
+<Input title="文本" data1="数据项1" tip="提示信息" />
+<Input title="文本" data3="数据项3" tip="提示信息" />
+
+<div class="px-4 pt-8 font-bold text-xl">展示所有可配置项</div>
+<Input
+    title="标题"
+    placeholder="请输入文本"
+    label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label2="标签2"
+    label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
+    label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label5="标签5"
+    label6={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }}
+    data1="数据项1"
+    data2="数据项2"
+    data3="数据项3"
+    tip="提示信息"
+    clear
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">label1 和 label4 使用插槽</div>
+<Input title="验证码" label1="slot" label4="slot">
+    <div slot="label1">
+        <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+            <path
+                d="M511.198384 637.07798c-17.170101 0-31.08202 13.911919-31.08202 31.08202v124.302222c0 17.157172 13.924848 31.08202 31.08202 31.08202s31.069091-13.924848 31.069091-31.08202v-124.302222c0-17.170101-13.911919-31.08202-31.069091-31.08202z m0 0"
+                fill="#515151"
+            />
+            <path
+                d="M759.815758 513.331717V264.145455C759.815758 126.823434 648.520404 15.515152 511.198384 15.515152c-137.309091 0-248.630303 111.308283-248.630303 248.630303v249.186262C223.702626 565.20404 200.40404 629.423838 200.40404 699.229091c0 171.649293 139.145051 310.794343 310.794344 310.794343s310.794343-139.145051 310.794343-310.794343c0-69.805253-23.311515-134.025051-62.176969-185.897374zM324.719192 264.145455c0-102.994747 83.497374-186.479192 186.479192-186.479192 102.981818 0 186.466263 83.484444 186.466262 186.479192v186.88c-51.975758-39.111111-116.402424-62.577778-186.466262-62.577778s-134.490505 23.453737-186.479192 62.577778V264.145455z m186.479192 683.726868c-137.309091 0-248.630303-111.321212-248.630303-248.643232 0-137.309091 111.308283-248.617374 248.630303-248.617374 132.628687 0 248.617374 115.988687 248.617374 248.617374 0 137.32202-111.295354 248.643232-248.617374 248.643232z m0 0"
+                fill="#515151"
+            />
+        </svg>
+    </div>
+    <div slot="label4">
+        <Button size="auto" heightOut="0" heightIn="1" fill="lineTheme">
+            <div class="px-2">获取验证码</div>
+        </Button>
+    </div>
+</Input>
+
+<div class="px-4 pt-8 font-bold text-xl">动态显示</div>
+<Input
+    title="动态显示 label5"
+    type="tel"
+    placeholder="请输入11位手机号"
+    maxlength={11}
+    state={mobileState}
+    on:change={changeStateFun}
+    label5="slot"
+>
+    <div slot="label5">
+        {#if mobileLength === 11}
+            <Icon name="ri-check-fill" injClass="text-[green]" size={14} />
+        {:else if mobileLength === 0}
+            <!-- none -->
+        {:else}
+            <Icon name="ri-close-fill" injClass="text-[red]" size={14} />
+        {/if}
+    </div>
+</Input>
+
+<div class="px-4 pt-8 font-bold text-xl">绑定 value</div>
+<Input title="文本" bind:value />
+<Button on:click={() => (visible = true)}>显示当前值</Button>
+<Toast bind:visible message={`当前输入文本:${value}`} />
+
+<div class="px-4 pt-8 font-bold text-xl">点击 label4 触发事件</div>
+<Input
+    title="身份证号"
+    placeholder={placeholderIdCard}
+    bind:value={IdCard}
+    label4={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }}
+    on:clicklabel4={clickLabel4Fun}
+    clear
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">textarea</div>
+<Input placeholder="请输入内容" type="textarea" />
+
+<div class="px-4 pt-8 font-bold text-xl">textarea 自动高度</div>
+<Input placeholder="请输入内容" type="textarea" autosize />

+ 264 - 0
demo/src/pages/input/InputDemo_en.svelte

@@ -0,0 +1,264 @@
+<!-- Input Demo -->
+<script>
+    import { getContext } from 'svelte';
+    import { Input, Button, Icon, Toast } from '../../../../components';
+
+    let value = 'Init text';
+    let visible = false;
+
+    let IdCard = '';
+
+    const isIframe = getContext('iframe') === '1'; //判断是否是iframe
+
+    $: placeholderIdCard = IdCard === '' ? 'Please enter identification number' : '';
+    const clickLabel4Fun = () => {
+        placeholderIdCard = 'After two seconds, the recognition is complete......';
+        setTimeout(() => {
+            IdCard = '1234567890XXX-XX';
+        }, 2000);
+    };
+    let mobileLength = 0;
+    const changeStateFun = e => {
+        mobileLength = e.detail.length;
+    };
+    $: mobileState = mobileLength === 11 ? 'success' : mobileLength === 0 ? 'theme' : 'error';
+</script>
+
+<div class="px-4 pt-8 font-bold text-xl">Basic usage</div>
+<Input title="text" />
+
+<div class="px-4 pt-8 font-bold text-xl">Without the title</div>
+<Input placeholder="Please enter the text" />
+
+<div class="px-4 pt-8 font-bold text-xl">customize placeholder</div>
+<Input title="text" placeholder="customize placeholder" />
+
+<div class="px-4 pt-8 font-bold text-xl">
+    Different input types
+    {#if isIframe}
+        <span class="text-xs opacity-50 ml-2">Please check the keyboard type on your mobile device.</span>
+    {/if}
+</div>
+<Input title="Any text (conventional keyboard)" />
+<Input title="password" type="password" />
+<Input title="Number (arbitrarily)" type="number" />
+<Input title="Number (integer)" type="numeric" />
+<Input title="Number (allowing decimal points)" type="decimal" />
+<Input title="Mail" type="email" />
+<Input title="telephone number" type="tel" />
+<Input title="Url" type="url" />
+<Input title="Search" type="search" />
+<Input title="Text (not using virtual keyboard)" type="none" />
+
+<div class="px-4 pt-8 font-bold text-xl">Linear style</div>
+<Input title="text" inputStyle="line" />
+<Input title="Text (the line of the line is in the middle of the line)" inputStyle="line" lineTransition="center" />
+<Input title="Text (transition from the left side of the line)" inputStyle="line" lineTransition="left" />
+
+<div class="px-4 pt-8 font-bold text-xl">Different transition time</div>
+<Input title="quick" duration="fast" />
+<Input title="normal" />
+<Input title="Slower" duration="slower" />
+<Input title="line normally" inputStyle="line" lineTransition="center" />
+<Input title="line slower" inputStyle="line" lineTransition="center" duration="slower" />
+
+<div class="px-4 pt-8 font-bold text-xl">Different title positions</div>
+<Input title="Title (outside)" />
+<Input title="Title (inside)" titlePosition="in" />
+<Input title="Title (none)" titlePosition="none" />
+
+<div class="px-4 pt-8 font-bold text-xl">Different input text position</div>
+<Input title="text" />
+<Input title="text" inputPosition="right" />
+
+<div class="px-4 pt-8 font-bold text-xl">Different rounded style</div>
+<Input title="text" />
+<Input title="text" radius="xl" />
+<Input title="text" radius="full" />
+<Input title="text" radius="none" />
+<Input title="Linear style rounded corners are invalid" radius="full" inputStyle="line" />
+
+<div class="px-4 pt-8 font-bold text-xl">Different vertical spacing</div>
+<Input placeholder="Spacing 0" py="0" inputStyle="line" />
+<Input placeholder="Spacing 0" py="0" inputStyle="line" />
+<Input placeholder="Spacing 0" py="0" inputStyle="line" />
+<Input placeholder="Spacing 4" py="4" inputStyle="line" />
+<Input placeholder="Spacing 4" py="4" inputStyle="line" />
+<Input placeholder="Spacing 4" py="4" inputStyle="line" />
+
+<div class="px-4 pt-8 font-bold text-xl">Removal</div>
+<Input title="text" clear />
+
+<div class="px-4 pt-8 font-bold text-xl">Disable</div>
+<Input title="text" disabled value="Disabled" />
+
+<div class="px-4 pt-8 font-bold text-xl">Different states</div>
+<Input title="success" state="success" />
+<Input title="warning" state="warning" />
+<Input title="error" state="error" />
+<Input title="info" state="info" />
+<Input title="warning & line" inputStyle="line" state="error" />
+<Input title="warning & line & Animation" inputStyle="line" state="error" lineTransition="center" />
+<Input
+    title="Dynamic change status color"
+    type="tel"
+    placeholder="Please enter the 11 -digit mobile phone number"
+    maxlength={11}
+    state={mobileState}
+    on:change={changeStateFun}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">Left with icon</div>
+<Input title="password" type="password" label1={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />
+<Input
+    title="username"
+    label1={{ name: 'ri-arrow-down-s-line', size: 16, alpha: 0.5 }}
+    label3={{ name: 'ri-shield-user-line', size: 16, alpha: 0.5 }}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">Left with text</div>
+<Input title="account" label2="account" />
+
+<div class="px-4 pt-8 font-bold text-xl">The left with icon and text</div>
+<Input title="password" type="password" label1={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} label2="password" />
+
+<div class="px-4 pt-8 font-bold text-xl">The left with text and icon</div>
+<Input title="password" type="password" label2="password" label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />
+
+<div class="px-4 pt-8 font-bold text-xl">left with icon & text & icon</div>
+<Input
+    title="password"
+    type="password"
+    label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label2="password"
+    label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">left with icon</div>
+<Input title="ID number" label4={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }} />
+<Input
+    title="User"
+    label4={{ name: 'ri-arrow-down-s-line', size: 16, alpha: 0.5 }}
+    label6={{ name: 'ri-shield-user-line', size: 16, alpha: 0.5 }}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">right with text</div>
+<Input title="Amount" type="number" label5="$" />
+
+<div class="px-4 pt-8 font-bold text-xl">right with iocn and text</div>
+<Input title="password" type="password" label4={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} label5="password" />
+
+<div class="px-4 pt-8 font-bold text-xl">right with text and icon</div>
+<Input title="password" type="password" label5="password" label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }} />
+
+<div class="px-4 pt-8 font-bold text-xl">right with icon & text & icon</div>
+<Input
+    title="password"
+    type="password"
+    label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label5="password"
+    label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">left with text, right with icon</div>
+<Input label2="身份证号" label6={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }} placeholder="请输入身份证号" />
+
+<div class="px-4 pt-8 font-bold text-xl">Six left and right all band</div>
+<Input
+    title="password"
+    type="password"
+    label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label2="password"
+    label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
+    label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label5="password"
+    label6={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">Prompt information and data item combination</div>
+<Input title="text" tip="Prompt information" />
+<Input title="text" data1="data1" />
+<Input title="text" data1="data1" data2="data2" />
+<Input title="text" data3="data3" />
+<Input title="text" data1="data1" tip="information" />
+<Input title="text" data3="data3" tip="information" />
+
+<div class="px-4 pt-8 font-bold text-xl">Show all configuration items</div>
+<Input
+    title="title"
+    placeholder="Please enter the text"
+    label1={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label2="label2"
+    label3={{ name: 'ri-lock-line', size: 16, alpha: 0.5 }}
+    label4={{ name: 'ri-bank-line', size: 16, alpha: 0.5 }}
+    label5="label5"
+    label6={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }}
+    data1="data1"
+    data2="data2"
+    data3="data3"
+    tip="tip"
+    clear
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">label1 and label4 use slot</div>
+<Input title="Verification code" label1="slot" label4="slot">
+    <div slot="label1">
+        <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+            <path
+                d="M511.198384 637.07798c-17.170101 0-31.08202 13.911919-31.08202 31.08202v124.302222c0 17.157172 13.924848 31.08202 31.08202 31.08202s31.069091-13.924848 31.069091-31.08202v-124.302222c0-17.170101-13.911919-31.08202-31.069091-31.08202z m0 0"
+                fill="#515151"
+            />
+            <path
+                d="M759.815758 513.331717V264.145455C759.815758 126.823434 648.520404 15.515152 511.198384 15.515152c-137.309091 0-248.630303 111.308283-248.630303 248.630303v249.186262C223.702626 565.20404 200.40404 629.423838 200.40404 699.229091c0 171.649293 139.145051 310.794343 310.794344 310.794343s310.794343-139.145051 310.794343-310.794343c0-69.805253-23.311515-134.025051-62.176969-185.897374zM324.719192 264.145455c0-102.994747 83.497374-186.479192 186.479192-186.479192 102.981818 0 186.466263 83.484444 186.466262 186.479192v186.88c-51.975758-39.111111-116.402424-62.577778-186.466262-62.577778s-134.490505 23.453737-186.479192 62.577778V264.145455z m186.479192 683.726868c-137.309091 0-248.630303-111.321212-248.630303-248.643232 0-137.309091 111.308283-248.617374 248.630303-248.617374 132.628687 0 248.617374 115.988687 248.617374 248.617374 0 137.32202-111.295354 248.643232-248.617374 248.643232z m0 0"
+                fill="#515151"
+            />
+        </svg>
+    </div>
+    <div slot="label4">
+        <Button size="auto" heightOut="0" heightIn="1" fill="lineTheme">
+            <div class="px-2">Get code</div>
+        </Button>
+    </div>
+</Input>
+
+<div class="px-4 pt-8 font-bold text-xl">Dynamic display</div>
+<Input
+    title="Dynamic display label5"
+    type="tel"
+    placeholder="Please enter the 11 -digit mobile phone number"
+    maxlength={11}
+    state={mobileState}
+    on:change={changeStateFun}
+    label5="slot"
+>
+    <div slot="label5">
+        {#if mobileLength === 11}
+            <Icon name="ri-check-fill" injClass="text-[green]" size={14} />
+        {:else if mobileLength === 0}
+            <!-- none -->
+        {:else}
+            <Icon name="ri-close-fill" injClass="text-[red]" size={14} />
+        {/if}
+    </div>
+</Input>
+
+<div class="px-4 pt-8 font-bold text-xl">bind value</div>
+<Input title="text" bind:value />
+<Button on:click={() => (visible = true)}>Display the current value</Button>
+<Toast bind:visible message={`Currently entering text:${value}`} />
+
+<div class="px-4 pt-8 font-bold text-xl">click label4 trigger event</div>
+<Input
+    title="ID number"
+    placeholder={placeholderIdCard}
+    bind:value={IdCard}
+    label4={{ name: 'ri-qr-scan-line', size: 16, alpha: 0.5 }}
+    on:clicklabel4={clickLabel4Fun}
+    clear
+/>
+
+<div class="px-4 pt-8 font-bold text-xl">textarea</div>
+<Input placeholder="Please enter the content" type="textarea" />
+
+<div class="px-4 pt-8 font-bold text-xl">textarea automatic height</div>
+<Input placeholder="Please enter the content" type="textarea" autosize />

+ 150 - 0
demo/src/pages/loading/LoadingDemo.svelte

@@ -0,0 +1,150 @@
+<!--Loading Demo-->
+<script>
+    import { Loading, Tabs, TabContent, Button } from '../../../../components';
+
+    //传入个数,返回随机生成的颜色数组
+    const randomColorArr = num => {
+        //随机生成16进制颜色
+        const randomColor = () => '#' + ('00000' + ((Math.random() * 0x1000000) << 0).toString(16)).slice(-6);
+        let arr = [];
+        for (let i = 0; i < num; i++) {
+            arr.push(randomColor());
+        }
+        return arr;
+    };
+
+    const arr1 = new Array(22);
+    const arr2 = new Array(6);
+    const arr4 = new Array(4);
+    const labels = [{ text: '单色' }, { text: '双色' }, { text: '四色' }, { text: '其他' }];
+
+    const speedBtns = [0.5, 1, 2];
+    let speed = 1;
+</script>
+
+<div class="py-4">
+    <Tabs tab={{ labels, mx: '4' }}>
+        <TabContent>
+            <div class="py-4">
+                <div class="flex text-center font-bold text-sm">
+                    {#each ['默认色', '主题色', '自选色', '反差色', '反主色'] as item}
+                        <div class="flex-1 py-2 border border-black/5 dark:border-white/5">{item}</div>
+                    {/each}
+                </div>
+                <div class="grid grid-cols-5">
+                    {#each arr1 as item, i}
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'1_' + i} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'1_' + i}</div>
+                        </div>
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'1_' + i} theme bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'1_' + i}</div>
+                        </div>
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'1_' + i} theme customColor={randomColorArr(1)} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'1_' + i}</div>
+                        </div>
+                        <div
+                            class="py-6 w-full flex flex-col items-center border border-white/5 dark:border-black/5 bg-gray5 dark:bg-gray9 text-white dark:text-black"
+                        >
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'1_' + i} inverse bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'1_' + i}</div>
+                        </div>
+                        <div
+                            class="py-6 w-full flex flex-col items-center border border-white/5 dark:border-black/5 bg-gray5 dark:bg-gray9 text-white dark:text-black"
+                        >
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'1_' + i} theme inverse bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'1_' + i}</div>
+                        </div>
+                    {/each}
+                </div>
+            </div>
+            <div class="text-xs p-4">持续更新...</div>
+        </TabContent>
+        <TabContent>
+            <div class="py-4">
+                <div class="flex text-center font-bold text-sm">
+                    {#each ['默认色', '自选色', '反差色'] as item}
+                        <div class="flex-1 py-2 border border-black/5 dark:border-white/5">{item}</div>
+                    {/each}
+                </div>
+                <div class="grid grid-cols-3">
+                    {#each arr2 as item, i}
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'2_' + i} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'2_' + i}</div>
+                        </div>
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'2_' + i} customColor={randomColorArr(2)} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'2_' + i}</div>
+                        </div>
+                        <div
+                            class="py-6 w-full flex flex-col items-center border border-white/5 dark:border-black/5 bg-gray5 dark:bg-gray9 text-white dark:text-black"
+                        >
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'2_' + i} inverse bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'2_' + i}</div>
+                        </div>
+                    {/each}
+                </div>
+            </div>
+            <div class="text-xs p-4">持续更新...</div>
+        </TabContent>
+        <TabContent>
+            <div class="py-4">
+                <div class="flex text-center font-bold text-sm">
+                    {#each ['默认色', '自选色', '默认色', '自选色'] as item}
+                        <div class="flex-1 py-2 border border-black/5 dark:border-white/5">{item}</div>
+                    {/each}
+                </div>
+                <div class="grid grid-cols-4">
+                    {#each arr4 as item, i}
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'4_' + i} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'4_' + i}</div>
+                        </div>
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'4_' + i} customColor={randomColorArr(4)} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'4_' + i}</div>
+                        </div>
+                    {/each}
+                </div>
+            </div>
+            <div class="text-xs p-4">持续更新...</div>
+        </TabContent>
+        <TabContent>
+            <div class="py-4" />
+            <div class="text-xs p-4">持续更新...</div>
+        </TabContent>
+    </Tabs>
+</div>
+<!-- 固定在底部的按钮组,控制速度 -->
+<div class="sticky bottom-0 left-0 w-full flex gap-3 justify-between px-2 z-10 bg-white/90 dark:bg-black/90">
+    {#each speedBtns as item}
+        <div class="flex-1">
+            <Button fill={speed === item ? 'base' : 'lineTheme'} size="full" injClass="text-xs px-2" on:click={() => (speed = item)}>
+                {item} 倍速
+            </Button>
+        </div>
+    {/each}
+</div>

+ 150 - 0
demo/src/pages/loading/LoadingDemo_en.svelte

@@ -0,0 +1,150 @@
+<!--Loading Demo-->
+<script>
+    import { Loading, Tabs, TabContent, Button } from '../../../../components';
+
+    //Input the number and return an array of randomly generated colors
+    const randomColorArr = num => {
+        // Generate a random hexadecimal color
+        const randomColor = () => '#' + ('00000' + ((Math.random() * 0x1000000) << 0).toString(16)).slice(-6);
+        let arr = [];
+        for (let i = 0; i < num; i++) {
+            arr.push(randomColor());
+        }
+        return arr;
+    };
+
+    const arr1 = new Array(22);
+    const arr2 = new Array(6);
+    const arr4 = new Array(4);
+    const labels = [{ text: 'One color' }, { text: 'Two color' }, { text: 'Four color' }, { text: 'Other' }];
+
+    const speedBtns = [0.5, 1, 2];
+    let speed = 1;
+</script>
+
+<div class="py-4">
+    <Tabs tab={{ labels, mx: '4' }}>
+        <TabContent>
+            <div class="py-4">
+                <div class="flex text-center font-bold text-sm">
+                    {#each ['Default', 'Theme', 'Custom', 'Inverse', 'Inv theme'] as item}
+                        <div class="flex-1 py-2 border border-black/5 dark:border-white/5">{item}</div>
+                    {/each}
+                </div>
+                <div class="grid grid-cols-5">
+                    {#each arr1 as item, i}
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'1_' + i} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'1_' + i}</div>
+                        </div>
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'1_' + i} theme bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'1_' + i}</div>
+                        </div>
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'1_' + i} theme customColor={randomColorArr(1)} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'1_' + i}</div>
+                        </div>
+                        <div
+                            class="py-6 w-full flex flex-col items-center border border-white/5 dark:border-black/5 bg-gray5 dark:bg-gray9 text-white dark:text-black"
+                        >
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'1_' + i} inverse bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'1_' + i}</div>
+                        </div>
+                        <div
+                            class="py-6 w-full flex flex-col items-center border border-white/5 dark:border-black/5 bg-gray5 dark:bg-gray9 text-white dark:text-black"
+                        >
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'1_' + i} theme inverse bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'1_' + i}</div>
+                        </div>
+                    {/each}
+                </div>
+            </div>
+            <div class="text-xs p-4">Continually updated...</div>
+        </TabContent>
+        <TabContent>
+            <div class="py-4">
+                <div class="flex text-center font-bold text-sm">
+                    {#each ['Default', 'Custom', 'Inverse'] as item}
+                        <div class="flex-1 py-2 border border-black/5 dark:border-white/5">{item}</div>
+                    {/each}
+                </div>
+                <div class="grid grid-cols-3">
+                    {#each arr2 as item, i}
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'2_' + i} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'2_' + i}</div>
+                        </div>
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'2_' + i} customColor={randomColorArr(2)} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'2_' + i}</div>
+                        </div>
+                        <div
+                            class="py-6 w-full flex flex-col items-center border border-white/5 dark:border-black/5 bg-gray5 dark:bg-gray9 text-white dark:text-black"
+                        >
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'2_' + i} inverse bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'2_' + i}</div>
+                        </div>
+                    {/each}
+                </div>
+            </div>
+            <div class="text-xs p-4">Continually updated...</div>
+        </TabContent>
+        <TabContent>
+            <div class="py-4">
+                <div class="flex text-center font-bold text-sm">
+                    {#each ['Default', 'Custom', 'Default', 'Custom'] as item}
+                        <div class="flex-1 py-2 border border-black/5 dark:border-white/5">{item}</div>
+                    {/each}
+                </div>
+                <div class="grid grid-cols-4">
+                    {#each arr4 as item, i}
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'4_' + i} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'4_' + i}</div>
+                        </div>
+                        <div class="py-6 w-full flex flex-col items-center border border-black/5 dark:border-white/5">
+                            <div class="w-[30px] h-[30px]">
+                                <Loading type={'4_' + i} customColor={randomColorArr(4)} bind:speed />
+                            </div>
+                            <div class="text-xs text-center mt-4">{'4_' + i}</div>
+                        </div>
+                    {/each}
+                </div>
+            </div>
+            <div class="text-xs p-4">Continually updated...</div>
+        </TabContent>
+        <TabContent>
+            <div class="py-4" />
+            <div class="text-xs p-4">Continually updated...</div>
+        </TabContent>
+    </Tabs>
+</div>
+<!-- The button group fixed at the bottom, control speed -->
+<div class="sticky bottom-0 left-0 w-full flex gap-3 justify-between px-2 z-10 bg-white/90 dark:bg-black/90">
+    {#each speedBtns as item}
+        <div class="flex-1">
+            <Button fill={speed === item ? 'base' : 'lineTheme'} size="full" injClass="text-xs px-2" on:click={() => (speed = item)}>
+                {item} speed
+            </Button>
+        </div>
+    {/each}
+</div>

+ 61 - 0
demo/src/pages/mask/MaskDemo.svelte

@@ -0,0 +1,61 @@
+<!-- Mask Demo -->
+<script>
+    import { Mask, Toast, Cell, Button, Popup } from '../../../../components';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+
+    let isClick = false;
+</script>
+
+<div class="py-4">
+    <Cell title="基础用法" on:click={() => (visible1 = true)} />
+    <Mask visible={visible1} on:clickMask={() => (visible1 = false)} />
+
+    <Cell title="透明度为 0.1" on:click={() => (visible2 = true)} />
+    <Mask visible={visible2} opacity={0.1} on:clickMask={() => (visible2 = false)} />
+
+    <Cell title="透明度为 0.8" on:click={() => (visible3 = true)} />
+    <Mask visible={visible3} opacity={0.8} on:clickMask={() => (visible3 = false)} />
+
+    <Cell title="点击穿透" detail="请手动关闭" on:click={() => (visible4 = true)} />
+    <Mask visible={visible4} clickable />
+    <div class="flex">
+        <div class="flex-1">
+            <Button on:click={() => (isClick = !isClick)}>{isClick ? '已经点到我了' : '测试点击穿透'}</Button>
+        </div>
+        <div class="flex-1">
+            <Button on:click={() => (visible4 = false)}>手动关闭</Button>
+        </div>
+    </div>
+
+    <Cell title="反色遮罩" on:click={() => (visible5 = true)} />
+    <Mask visible={visible5} inverse on:clickMask={() => (visible5 = false)} />
+
+    <Cell title="模糊遮罩" on:click={() => (visible6 = true)} />
+    <Mask visible={visible6} backdropBlur="sm" opacity={0} on:clickMask={() => (visible6 = false)} />
+
+    <Cell title="加大模糊度" on:click={() => (visible7 = true)} />
+    <Mask visible={visible7} backdropBlur="xl" opacity={0} on:clickMask={() => (visible7 = false)} />
+
+    <Cell title="增加出现动画时长" on:click={() => (visible8 = true)} />
+    <Mask visible={visible8} duration={1000} on:clickMask={() => (visible8 = false)} />
+
+    <Cell title="增加消失动画时长" on:click={() => (visible9 = true)} />
+    <Mask visible={visible9} outDuration={1000} on:clickMask={() => (visible9 = false)} />
+
+    <Cell title="Toast 中使用" on:click={() => (visible10 = true)} />
+    <Toast bind:visible={visible10} message="透明度为 0" />
+
+    <Cell title="Popup 中使用" on:click={() => (visible11 = true)} />
+    <Popup bind:visible={visible11} />
+</div>

+ 61 - 0
demo/src/pages/mask/MaskDemo_en.svelte

@@ -0,0 +1,61 @@
+<!-- Mask Demo -->
+<script>
+    import { Mask, Toast, Cell, Button, Popup } from '../../../../components';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+
+    let isClick = false;
+</script>
+
+<div class="py-4">
+    <Cell title="Basic usage" on:click={() => (visible1 = true)} />
+    <Mask visible={visible1} on:clickMask={() => (visible1 = false)} />
+
+    <Cell title="Transparency is 0.1" on:click={() => (visible2 = true)} />
+    <Mask visible={visible2} opacity={0.1} on:clickMask={() => (visible2 = false)} />
+
+    <Cell title="Transparency is 0.8" on:click={() => (visible3 = true)} />
+    <Mask visible={visible3} opacity={0.8} on:clickMask={() => (visible3 = false)} />
+
+    <Cell title="Click through" detail="Please close manually" on:click={() => (visible4 = true)} />
+    <Mask visible={visible4} clickable />
+    <div class="flex">
+        <div class="flex-1">
+            <Button on:click={() => (isClick = !isClick)}>{isClick ? 'Click on me' : 'Click through'}</Button>
+        </div>
+        <div class="flex-1">
+            <Button on:click={() => (visible4 = false)}>Manual shutdown</Button>
+        </div>
+    </div>
+
+    <Cell title="Reverse color mask" on:click={() => (visible5 = true)} />
+    <Mask visible={visible5} inverse on:clickMask={() => (visible5 = false)} />
+
+    <Cell title="Blur mask" on:click={() => (visible6 = true)} />
+    <Mask visible={visible6} backdropBlur="sm" opacity={0} on:clickMask={() => (visible6 = false)} />
+
+    <Cell title="Increase ambiguity" on:click={() => (visible7 = true)} />
+    <Mask visible={visible7} backdropBlur="xl" opacity={0} on:clickMask={() => (visible7 = false)} />
+
+    <Cell title="Increased the animation time" on:click={() => (visible8 = true)} />
+    <Mask visible={visible8} duration={1000} on:clickMask={() => (visible8 = false)} />
+
+    <Cell title="Increased the duration of vanishing animation" on:click={() => (visible9 = true)} />
+    <Mask visible={visible9} outDuration={1000} on:clickMask={() => (visible9 = false)} />
+
+    <Cell title="Toast Use in" on:click={() => (visible10 = true)} />
+    <Toast bind:visible={visible10} message="Transparency is 0" />
+
+    <Cell title="Popup Use in" on:click={() => (visible11 = true)} />
+    <Popup bind:visible={visible11} />
+</div>

+ 112 - 0
demo/src/pages/modal/ModalDemo.svelte

@@ -0,0 +1,112 @@
+<!-- Modal Demo -->
+<script>
+    import { Modal, Cell, Toast } from '../../../../components';
+    import Aphorism from '../../components/Aphorism.svelte';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+    let visible12 = false;
+    let visible13 = false;
+    let visible14 = false;
+    let visible15 = false;
+
+    let toastVisible = false;
+
+    $: if (visible15) {
+        setTimeout(() => {
+            visible15 = false;
+        }, 3000);
+    }
+</script>
+
+<div class="py-4">
+    <Cell title="基础用法" on:click={() => (visible1 = true)} />
+    <Modal bind:visible={visible1} title="您明白吗?" content="留下来的人才是最痛苦的" btnText="我明白了" />
+
+    <Cell title="内容使用插槽" on:click={() => (visible2 = true)} />
+    <Modal bind:visible={visible2} contentSlot>
+        <Aphorism num={1} compact />
+    </Modal>
+
+    <Cell title="不显示标题" on:click={() => (visible3 = true)} />
+    <Modal bind:visible={visible3} title="" />
+
+    <Cell title="不显示按钮" on:click={() => (visible4 = true)} />
+    <Modal bind:visible={visible4} showBtn={false} contentSlot>
+        <Aphorism num={1} compact />
+    </Modal>
+
+    <Cell title="点击遮罩关闭" on:click={() => (visible5 = true)} />
+    <Modal bind:visible={visible5} popup={{ maskClosable: true }} />
+
+    <Cell title="自定义图标" on:click={() => (visible6 = true)} />
+    <Modal
+        bind:visible={visible6}
+        content="请佩戴口罩!"
+        showIcon
+        icon={{ name: 'ri-surgical-mask-fill', size: 40, injClass: 'text-[#48a1b4]' }}
+    />
+
+    <Cell title="错误状态按钮" on:click={() => (visible8 = true)} />
+    <Modal bind:visible={visible8} btnText="我错了" button={{ state: 'error' }} />
+
+    <Cell title="全圆角按钮" on:click={() => (visible9 = true)} />
+    <Modal bind:visible={visible9} button={{ radius: 'full' }} />
+
+    <Cell title="主题色纯文本按钮" on:click={() => (visible12 = true)} />
+    <Modal bind:visible={visible12} button={{ fill: 'textTheme' }} />
+
+    <Cell title="内容使用插槽且滚动" on:click={() => (visible10 = true)} />
+    <Modal bind:visible={visible10} contentSlot>
+        <div class="h-56 overflow-auto">
+            <Aphorism num={6} compact />
+        </div>
+    </Modal>
+
+    <Cell title="显示窄一点" on:click={() => (visible7 = true)} />
+    <Modal bind:visible={visible7} popup={{ px: '20' }} />
+
+    <Cell title="另一种动画效果" on:click={() => (visible11 = true)} />
+    <Modal bind:visible={visible11} content="回弹过渡" popup={{ easeType: 'backOut' }} />
+
+    <Cell title="监听关闭事件" on:click={() => (visible13 = true)} />
+    <Modal bind:visible={visible13} on:close={() => (toastVisible = true)} />
+    <Toast bind:visible={toastVisible} message="关闭了 Modal!" />
+
+    <Cell title="标题居左" on:click={() => (visible14 = true)} />
+    <Modal bind:visible={visible14} title="标题居左" titleAlign="left" />
+
+    <Cell title="自动关闭" on:click={() => (visible15 = true)} />
+    <Modal bind:visible={visible15} content="别动!3 秒后我立即消失!" />
+</div>
+
+<!-- Aphorism.svelte -->
+<!-- 
+<script>
+    import aphorisms from '../data/aphorisms'; //引入数据
+
+    export let num = 0; //显示条数
+    export let compact = false; //是否紧凑模式
+
+    //从 aphorisms 随机取出 num 条数据
+    const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
+</script>
+
+<div class={`${compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5`}>
+    {#each aphorismsList as item}
+        <div class:py-6={num > 1}>
+            <div class="text-sm text-justify">{item.text}</div>
+            <div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
+        </div>
+    {/each}
+</div>
+-->

+ 112 - 0
demo/src/pages/modal/ModalDemo_en.svelte

@@ -0,0 +1,112 @@
+<!-- Modal Demo -->
+<script>
+    import { Modal, Cell, Toast } from '../../../../components';
+    import Aphorism from '../../components/Aphorism.svelte';
+
+    let visible1 = false;
+    let visible2 = false;
+    let visible3 = false;
+    let visible4 = false;
+    let visible5 = false;
+    let visible6 = false;
+    let visible7 = false;
+    let visible8 = false;
+    let visible9 = false;
+    let visible10 = false;
+    let visible11 = false;
+    let visible12 = false;
+    let visible13 = false;
+    let visible14 = false;
+    let visible15 = false;
+
+    let toastVisible = false;
+
+    $: if (visible15) {
+        setTimeout(() => {
+            visible15 = false;
+        }, 3000);
+    }
+</script>
+
+<div class="py-4">
+    <Cell title="Basic usage" on:click={() => (visible1 = true)} />
+    <Modal bind:visible={visible1} title="Do you understand?" content="Those who stay will suffer the most" btnText="I see" />
+
+    <Cell title="Content usage slot" on:click={() => (visible2 = true)} />
+    <Modal bind:visible={visible2} contentSlot>
+        <Aphorism num={1} compact />
+    </Modal>
+
+    <Cell title="Do not show the title" on:click={() => (visible3 = true)} />
+    <Modal bind:visible={visible3} title="" />
+
+    <Cell title="Do not show button" on:click={() => (visible4 = true)} />
+    <Modal bind:visible={visible4} showBtn={false} contentSlot>
+        <Aphorism num={1} compact />
+    </Modal>
+
+    <Cell title="Click the mask to close" on:click={() => (visible5 = true)} />
+    <Modal bind:visible={visible5} popup={{ maskClosable: true }} />
+
+    <Cell title="Custom icon" on:click={() => (visible6 = true)} />
+    <Modal
+        bind:visible={visible6}
+        content="Please wear a mask!"
+        showIcon
+        icon={{ name: 'ri-surgical-mask-fill', size: 40, injClass: 'text-[#48a1b4]' }}
+    />
+
+    <Cell title="Error status button" on:click={() => (visible8 = true)} />
+    <Modal bind:visible={visible8} btnText="I was wrong." button={{ state: 'error' }} />
+
+    <Cell title="Full rounded corner button" on:click={() => (visible9 = true)} />
+    <Modal bind:visible={visible9} button={{ radius: 'full' }} />
+
+    <Cell title="Theme color plain text button" on:click={() => (visible12 = true)} />
+    <Modal bind:visible={visible12} button={{ fill: 'textTheme' }} />
+
+    <Cell title="Content uses slots and scrolls" on:click={() => (visible10 = true)} />
+    <Modal bind:visible={visible10} contentSlot>
+        <div class="h-56 overflow-auto">
+            <Aphorism num={6} compact />
+        </div>
+    </Modal>
+
+    <Cell title="Show narrow" on:click={() => (visible7 = true)} />
+    <Modal bind:visible={visible7} popup={{ px: '20' }} />
+
+    <Cell title="Another animation effect" on:click={() => (visible11 = true)} />
+    <Modal bind:visible={visible11} content="Rebound transition" popup={{ easeType: 'backOut' }} />
+
+    <Cell title="Listening shutdown event" on:click={() => (visible13 = true)} />
+    <Modal bind:visible={visible13} on:close={() => (toastVisible = true)} />
+    <Toast bind:visible={toastVisible} message="Shut down Modal!" />
+
+    <Cell title="Heading left" on:click={() => (visible14 = true)} />
+    <Modal bind:visible={visible14} title="Heading left" titleAlign="left" />
+
+    <Cell title="Automatic shutdown" on:click={() => (visible15 = true)} />
+    <Modal bind:visible={visible15} content="Don't move! I'll be gone in three seconds!" />
+</div>
+
+<!-- Aphorism.svelte -->
+<!-- 
+<script>
+    import aphorisms from '../data/aphorisms'; //Incoming data
+
+    export let num = 0; //Display number
+    export let compact = false; //Compact or not mode
+
+    //num bars were randomly extracted from aphorisms
+    const aphorismsList = aphorisms.sort(() => Math.random() - 0.5).slice(0, num);
+</script>
+
+<div class={`${compact ? '' : 'px-4 py-8 '}divide-y divide-black/5 dark:divide-white/5`}>
+    {#each aphorismsList as item}
+        <div class:py-6={num > 1}>
+            <div class="text-sm text-justify">{item.text}</div>
+            <div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
+        </div>
+    {/each}
+</div>
+-->

+ 68 - 0
demo/src/pages/navBar/NavBarDemo.svelte

@@ -0,0 +1,68 @@
+<!-- NavBar Demo -->
+<script>
+    import { NavBar, Icon, Toast } from '../../../../components';
+
+    const icons1 = [{ name: 'ri-paint-brush-line', theme: true }, { name: 'ri-share-line' }];
+    const icons2 = [{ name: 'ri-command-line' }, { name: 'ri-drag-move-line' }];
+    const icons3 = [{ name: 'ri-indent-decrease' }, { name: 'ri-service-line' }];
+    const icons4 = [{ name: 'ri-hand-heart-line', theme: true }, { name: 'ri-parent-line' }];
+
+    let visible1 = false;
+    let visible2 = false;
+    let rightIndex = 0;
+    let visible3 = false;
+</script>
+
+<div class="flex flex-col space-y-8 py-8">
+    <!-- 基础用法 -->
+    <NavBar title="基础用法" />
+    <!-- 右侧使用 Remix Icon -->
+    <NavBar title="右侧使用 Icon" rights={icons1} />
+    <!-- 点击左侧 -->
+    <NavBar title="点击左侧" on:clickleft={() => (visible1 = true)} />
+    <Toast bind:visible={visible1} message="点击了左侧!" />
+    <!-- 点击右侧 -->
+    <NavBar
+        title="点击右侧"
+        rights={icons2}
+        on:clickright={e => {
+            visible2 = true;
+            rightIndex = e.detail;
+        }}
+    />
+    <Toast bind:visible={visible2} message={`点击的右侧图标索引值是 ${rightIndex}。`} />
+    <!-- 无底部分割线,文字过长 -->
+    <NavBar title="无左侧与底分割线,文字过长长长长长长长" left="" line={false} rights={icons3} />
+    <!-- 自定义背景颜色 -->
+    <NavBar title="自定义背景颜色 by injClass" injClass="bg-[wheat] dark:bg-[purple]" />
+    <!-- 自定义文字颜色 -->
+    <NavBar titleSlot>
+        <div slot="title" class="text-[red] dark:text-[green]">自定义文字颜色 by slot</div>
+    </NavBar>
+    <!-- 插槽渲染标题区域 -->
+    <NavBar titleSlot rightSlot>
+        <div slot="title" class="flex flex-col justify-around text-xs h-12">
+            <div class="text-sm">title 插槽渲染标题区域</div>
+            <div>right 插槽渲染右侧且可点击</div>
+        </div>
+        <div slot="right">
+            <!-- svelte-ignore a11y-click-events-have-key-events -->
+            <div class="h-12 w-12 text-center text-primary dark:text-dark cursor-pointer" on:click={() => (visible3 = true)}>Hello</div>
+        </div>
+    </NavBar>
+    <Toast bind:visible={visible3} message="点击了右侧插槽内容!" />
+    <!-- 关爱版 -->
+    <NavBar title="关爱版导航栏" love rights={icons4} />
+    <!-- 灵活的自定义 -->
+    <NavBar titleSlot injClass="!bg-transparent" leftSlot line={false} rightSlot>
+        <div slot="left" class="h-8 w-8 m-2 leading-8 text-center bg-white dark:bg-black/50 rounded-full">
+            <Icon name="ri-home-7-line" size={18} top={-2} />
+        </div>
+        <div slot="title" class="px-3 h-8 my-2 leading-8 text-sm bg-white dark:bg-black/50 rounded-full">
+            injClass 与 slot 结合自定义样式
+        </div>
+        <div slot="right" class="h-8 w-8 m-2 leading-8 text-center bg-white dark:bg-black/50 rounded-full">
+            <Icon name="ri-customer-service-2-line" size={18} top={-2} />
+        </div>
+    </NavBar>
+</div>

+ 67 - 0
demo/src/pages/navBar/NavBarDemo_en.svelte

@@ -0,0 +1,67 @@
+<!-- NavBar Demo -->
+<script>
+    import { NavBar, Icon, Toast } from '../../../../components';
+
+    const icons1 = [{ name: 'ri-paint-brush-line', theme: true }, { name: 'ri-share-line' }];
+    const icons2 = [{ name: 'ri-command-line' }, { name: 'ri-drag-move-line' }];
+    const icons3 = [{ name: 'ri-indent-decrease' }, { name: 'ri-service-line' }];
+    const icons4 = [{ name: 'ri-hand-heart-line', theme: true }, { name: 'ri-parent-line' }];
+
+    let visible1 = false;
+    let visible2 = false;
+    let rightIndex = 0;
+    let visible3 = false;
+</script>
+
+<div class="flex flex-col space-y-8 py-8">
+    <NavBar title="Basic usage" />
+    
+    <NavBar title="Right-side use Icon" rights={icons1} />
+ 
+    <NavBar title="Click on the left" on:clickleft={() => (visible1 = true)} />
+    <Toast bind:visible={visible1} message="Click on the left!" />
+
+    <NavBar
+        title="Click right"
+        rights={icons2}
+        on:clickright={e => {
+            visible2 = true;
+            rightIndex = e.detail;
+        }}
+    />
+    <Toast bind:visible={visible2} message={`Click the right icon index value is ${rightIndex}。`} />
+
+    <NavBar title="There is no dividing line between the left side and the bottom, and the text is too long" left="" line={false} rights={icons3} />
+
+    <NavBar title="Customize the background color by injClass" injClass="bg-[wheat] dark:bg-[purple]" />
+
+    <NavBar titleSlot>
+        <div slot="title" class="text-[red] dark:text-[green]">Customize text colors by slot</div>
+    </NavBar>
+
+    <NavBar titleSlot rightSlot>
+        <div slot="title" class="flex flex-col justify-around text-xs h-12">
+            <div class="text-sm">title Slot render header area</div>
+            <div>right Slot render right and clickable</div>
+        </div>
+        <div slot="right">
+            <!-- svelte-ignore a11y-click-events-have-key-events -->
+            <div class="h-12 w-12 text-center text-primary dark:text-dark cursor-pointer" on:click={() => (visible3 = true)}>Hello</div>
+        </div>
+    </NavBar>
+    <Toast bind:visible={visible3} message="Click on the right slot content!" />
+
+    <NavBar title="Care edition navigation bar" love rights={icons4} />
+
+    <NavBar titleSlot injClass="!bg-transparent" leftSlot line={false} rightSlot>
+        <div slot="left" class="h-8 w-8 m-2 leading-8 text-center bg-white dark:bg-black/50 rounded-full">
+            <Icon name="ri-home-7-line" size={18} top={-2} />
+        </div>
+        <div slot="title" class="px-3 h-8 my-2 leading-8 text-sm bg-white dark:bg-black/50 rounded-full">
+            injClass and slot combine custom styles
+        </div>
+        <div slot="right" class="h-8 w-8 m-2 leading-8 text-center bg-white dark:bg-black/50 rounded-full">
+            <Icon name="ri-customer-service-2-line" size={18} top={-2} />
+        </div>
+    </NavBar>
+</div>

+ 61 - 0
demo/src/pages/noticeBar/NoticeBarDemo.svelte

@@ -0,0 +1,61 @@
+<!-- NoticeBar Demo -->
+<script>
+    import {NoticeBar, Toast} from '../../../../components';
+
+    let textList = ['1. 这是第一条通告内容!', '2. 这是第二条通告内容!'];
+    let textLongList = ['1. 这条通告超长长长长长长长长长长长长长长长长长长长长长!', '2. 这是第二条通告内容!'];
+
+    let visible = false;
+</script>
+
+<div class="m-4 mt-8 font-bold text-lg">基础用法</div>
+<NoticeBar {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">通告内容较短不滚动</div>
+<NoticeBar textList={['1. 短通告!','2. 短通告!']}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">设定通告间距</div>
+<NoticeBar space={200} {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">设定滚动速度</div>
+<NoticeBar speed={100} {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">右侧箭头(监听点击事件)</div>
+<NoticeBar rightIcon="arrow" {textList} on:clickright={()=>visible=true}></NoticeBar>
+<Toast bind:visible message='点击了右侧箭头!'></Toast>
+
+<div class="m-4 mt-8 font-bold text-lg">右侧无内容</div>
+<NoticeBar rightIcon="none" {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">左侧无内容</div>
+<NoticeBar leftIcon="none" {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">设定文字大小</div>
+<NoticeBar fontSize='lg' {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">自定义左侧</div>
+<NoticeBar leftIcon={{name:'ri-notification-2-line',size: 16, top:-1}} {textList}></NoticeBar>
+<NoticeBar leftIcon={{name:'ri-wireless-charging-line',size: 16, top:-1}} {textList}></NoticeBar>
+<NoticeBar leftIcon='slot' {textList}>🥳</NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">垂直滚动</div>
+<NoticeBar vertical {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">滚动过渡为 1 秒</div>
+<NoticeBar vertical duration="1000" {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">滚动间隔为 8 秒</div>
+<NoticeBar vertical interval="8" {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">文字过长</div>
+<NoticeBar vertical textList={textLongList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">单条不滚动</div>
+<NoticeBar vertical textList={[textLongList[0]]}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">自定义样式</div>
+<NoticeBar injClass="!text-error !bg-error/10" {textList}></NoticeBar>
+<NoticeBar leftIcon={{name:'ri-check-line',size: 16, top:-1}} injClass="!text-success !bg-success/10" {textList}></NoticeBar>
+<NoticeBar injClass="!text-purple !bg-purple/10" {textList}></NoticeBar>
+<div class="pb-8"></div>
+

+ 61 - 0
demo/src/pages/noticeBar/NoticeBarDemo_en.svelte

@@ -0,0 +1,61 @@
+<!-- NoticeBar Demo -->
+<script>
+    import {NoticeBar, Toast} from '../../../../components';
+
+    let textList = ['1. This is the first announcement!', '2. This is the second notice!'];
+    let textLongList = ['1. This message long, long, long, long, long, long, long, long, long, long, long, long, long!', '2. This is the second notice!'];
+
+    let visible = false;
+</script>
+
+<div class="m-4 mt-8 font-bold text-lg">Basic usage</div>
+<NoticeBar {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">The announcements are short and do not scroll</div>
+<NoticeBar textList={['1. Short notice!','2. Short notice!']}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Set notification spacing</div>
+<NoticeBar space={200} {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Set rolling speed</div>
+<NoticeBar speed={100} {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Right arrow (listen for click events)</div>
+<NoticeBar rightIcon="arrow" {textList} on:clickright={()=>visible=true}></NoticeBar>
+<Toast bind:visible message='Click the right arrow!'></Toast>
+
+<div class="m-4 mt-8 font-bold text-lg">No content on the right</div>
+<NoticeBar rightIcon="none" {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Nothing on the left</div>
+<NoticeBar leftIcon="none" {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Set text size</div>
+<NoticeBar fontSize='lg' {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Custom left</div>
+<NoticeBar leftIcon={{name:'ri-notification-2-line',size: 16, top:-1}} {textList}></NoticeBar>
+<NoticeBar leftIcon={{name:'ri-wireless-charging-line',size: 16, top:-1}} {textList}></NoticeBar>
+<NoticeBar leftIcon='slot' {textList}>🥳</NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Vertical rolling</div>
+<NoticeBar vertical {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Scroll transition to 1 second</div>
+<NoticeBar vertical duration="1000" {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">The scrolling interval is 8 seconds</div>
+<NoticeBar vertical interval="8" {textList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Excessively long text</div>
+<NoticeBar vertical textList={textLongList}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Single bar does not roll</div>
+<NoticeBar vertical textList={[textLongList[0]]}></NoticeBar>
+
+<div class="m-4 mt-8 font-bold text-lg">Custom style</div>
+<NoticeBar injClass="!text-error !bg-error/10" {textList}></NoticeBar>
+<NoticeBar leftIcon={{name:'ri-check-line',size: 16, top:-1}} injClass="!text-success !bg-success/10" {textList}></NoticeBar>
+<NoticeBar injClass="!text-purple !bg-purple/10" {textList}></NoticeBar>
+<div class="pb-8"></div>
+

+ 127 - 0
demo/src/pages/pagination/PaginationDemo.svelte

@@ -0,0 +1,127 @@
+<script>
+    import { onMount } from 'svelte';
+    import { Pagination, Loading } from '../../../../components';
+    import aphorisms from '../../data/aphorisms';
+
+    // 总数,一般是后端接口返回
+    const total = 200;
+
+    // 当前页码,演示事件监听
+    let current = 1;
+    const preFunc = e => {
+        current = e.detail;
+    };
+    const nextFunc = e => {
+        current = e.detail;
+    };
+    const changeFunc = e => {
+        current = e.detail;
+    };
+
+    // 模拟请求数据
+    let data = [];
+    let currentPage = 1;
+    let pageSize = 4;
+    let totalData = 0;
+    let loading = false;
+    const getData = current => {
+        loading = true;
+        // 使用 setTimeout 模拟请求
+        setTimeout(() => {
+            loading = false;
+            //从 aphorisms 随机取出 pageSize 条数据
+            data = aphorisms.sort(() => Math.random() - 0.5).slice(0, pageSize);
+            totalData = 64;
+        }, 2000);
+    };
+    const changePageFunc = e => {
+        currentPage = e.detail;
+        getData(currentPage);
+    };
+    // 初始请求第一页
+    onMount(() => {
+        getData(currentPage);
+    });
+</script>
+
+<div class="m-4 mt-24 font-bold text-lg">基础用法</div>
+<Pagination {total} />
+
+<div class="mx-4 mt-8 font-bold text-lg">事件监听</div>
+<div class="mx-4 mb-2 text-sm">当前页码:{current}</div>
+<Pagination {total} on:pre={preFunc} on:next={nextFunc} on:change={changeFunc} />
+
+<div class="mx-4 mt-24 font-bold text-lg">初始展示省略页码</div>
+<div class="mx-4 mb-4 text-xs">可用于引导用户</div>
+<Pagination {total} showNextOmitPage />
+
+<div class="m-4 mt-8 font-bold text-lg">设置初始页</div>
+<Pagination {total} current={10} />
+
+<div class="mx-4 mt-8 font-bold text-lg">最大显示 11 页</div>
+<div class="mx-4 mb-4 text-xs">同时显示较多页但页码较小</div>
+<Pagination maxShowPage={11} {total} />
+
+<div class="mx-4 mt-8 font-bold text-lg">最大显示 5 页</div>
+<div class="mx-4 mb-4 text-xs">适合分页区域较小的场景</div>
+<div class="flex items-center">
+    <div class="px-4">这是我的地盘</div>
+    <div class="flex-1">
+        <Pagination maxShowPage={5} {total} />
+    </div>
+</div>
+
+<div class="m-4 mt-8 font-bold text-lg">无数据</div>
+<Pagination total={0} />
+
+<div class="m-4 mt-8 font-bold text-lg">仅一页</div>
+<Pagination total={8} />
+
+<div class="mx-4 mt-8 font-bold text-lg">总页数未超过最大显示页数</div>
+<div class="mx-4 mb-4 text-xs">不会存在省略页码</div>
+<Pagination total={70} />
+
+<div class="mx-4 mt-8 font-bold text-lg">总页数超过最大显示页数但不算多</div>
+<div class="mx-4 mb-4 text-xs">不会同时存在前后两个省略页码</div>
+<Pagination total={90} maxShowPage={7} />
+
+<div class="mx-4 mt-8 font-bold text-lg">总页数很多</div>
+<div class="mx-4 mb-4 text-xs">会同时存在前后两个省略页码</div>
+<Pagination {total} />
+
+<div class="m-4 mt-8 font-bold text-lg">每页仅 3 项</div>
+<Pagination total={50} pageSize={3} />
+
+<div class="m-4 mt-8 font-bold text-lg">高亮页码为边框</div>
+<Pagination {total} type="border" />
+
+<div class="m-4 mt-8 font-bold text-lg">高亮页码为块状</div>
+<Pagination {total} type="block" />
+
+<div class="m-4 mt-8 font-bold text-lg">增加高亮页码圆角</div>
+<Pagination {total} type="block" radius="xl" />
+
+<div class="m-4 mt-8 font-bold text-lg">省略页码列数为 2</div>
+<Pagination {total} pageCol={2} />
+
+<div class="m-4 mt-8 font-bold text-lg">注入 injClass</div>
+<Pagination {total} injClass="mx-2 rounded-full shadow-md dark:shadow-white/10" />
+
+<div class="m-4 mt-8 font-bold text-lg">模拟请求</div>
+<div class="px-4 py-8 divide-y divide-black/5 dark:divide-white/5 min-h-[20rem] relative">
+    {#each data as item}
+        <div class:py-6={pageSize > 1}>
+            <div class="text-sm text-justify">{item.text}</div>
+            <div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
+        </div>
+    {/each}
+    {#if loading}
+        <div class="absolute inset-0 w-full h-full backdrop-blur flex flex-col justify-center gap-8 text-center">
+            <div>查询第 {currentPage} 页数据...</div>
+            <Loading />
+        </div>
+    {/if}
+</div>
+<Pagination {pageSize} total={totalData} on:change={changePageFunc} />
+
+<div class="pb-10" />

+ 127 - 0
demo/src/pages/pagination/PaginationDemo_en.svelte

@@ -0,0 +1,127 @@
+<script>
+    import { onMount } from 'svelte';
+    import { Pagination, Loading } from '../../../../components';
+    import aphorisms from '../../data/aphorisms';
+
+    // total data number, generally, the back-end interface returns
+    const total = 200;
+
+    // Current page number, demo event monitoring
+    let current = 1;
+    const preFunc = e => {
+        current = e.detail;
+    };
+    const nextFunc = e => {
+        current = e.detail;
+    };
+    const changeFunc = e => {
+        current = e.detail;
+    };
+
+    // Simulation request data
+    let data = [];
+    let currentPage = 1;
+    let pageSize = 4;
+    let totalData = 0;
+    let loading = false;
+    const getData = current => {
+        loading = true;
+        // Simulate a request using setTimeout
+        setTimeout(() => {
+            loading = false;
+            // Randomly extract pageSize pieces of data from aphorisms
+            data = aphorisms.sort(() => Math.random() - 0.5).slice(0, pageSize);
+            totalData = 64;
+        }, 2000);
+    };
+    const changePageFunc = e => {
+        currentPage = e.detail;
+        getData(currentPage);
+    };
+    // First page of the initial request
+    onMount(() => {
+        getData(currentPage);
+    });
+</script>
+
+<div class="m-4 mt-24 font-bold text-lg">Basic usage</div>
+<Pagination {total} />
+
+<div class="mx-4 mt-8 font-bold text-lg">Event monitoring</div>
+<div class="mx-4 mb-2 text-sm">Current page number: {current}</div>
+<Pagination {total} on:pre={preFunc} on:next={nextFunc} on:change={changeFunc} />
+
+<div class="mx-4 mt-24 font-bold text-lg">Initially omitting page number</div>
+<div class="mx-4 mb-4 text-xs">Can be used to guide users</div>
+<Pagination {total} showNextOmitPage />
+
+<div class="m-4 mt-8 font-bold text-lg">Set the initial page</div>
+<Pagination {total} current={10} />
+
+<div class="mx-4 mt-8 font-bold text-lg">Maximum display 11 pages</div>
+<div class="mx-4 mb-4 text-xs">At the same time display more pages but the page number is small</div>
+<Pagination maxShowPage={11} {total} />
+
+<div class="mx-4 mt-8 font-bold text-lg">Maximum display 5 pages</div>
+<div class="mx-4 mb-4 text-xs">Suitable for scenes with smaller paging area</div>
+<div class="flex items-center">
+    <div class="px-4">This is my site</div>
+    <div class="flex-1">
+        <Pagination maxShowPage={5} {total} />
+    </div>
+</div>
+
+<div class="m-4 mt-8 font-bold text-lg">no data</div>
+<Pagination total={0} />
+
+<div class="m-4 mt-8 font-bold text-lg">Only one page</div>
+<Pagination total={8} />
+
+<div class="mx-4 mt-8 font-bold text-lg">The total number of pages does not exceed the maximum display page</div>
+<div class="mx-4 mb-4 text-xs">There will be no omit -to -page number</div>
+<Pagination total={70} />
+
+<div class="mx-4 mt-8 font-bold text-lg">The total page number exceeds the maximum number of display pages, but not much</div>
+<div class="mx-4 mb-4 text-xs">There will not be two provinces to elaborate before and after the same existence</div>
+<Pagination total={90} maxShowPage={7} />
+
+<div class="mx-4 mt-8 font-bold text-lg">A lot of total pages</div>
+<div class="mx-4 mb-4 text-xs">There will be two provinces to omit the page number before and after at the same time</div>
+<Pagination {total} />
+
+<div class="m-4 mt-8 font-bold text-lg">Only 3 items per page</div>
+<Pagination total={50} pageSize={3} />
+
+<div class="m-4 mt-8 font-bold text-lg">Gao Liang Page Code is a border</div>
+<Pagination {total} type="border" />
+
+<div class="m-4 mt-8 font-bold text-lg">The highlight page number is block shape</div>
+<Pagination {total} type="block" />
+
+<div class="m-4 mt-8 font-bold text-lg">Increase high -bright pages round corners</div>
+<Pagination {total} type="block" radius="xl" />
+
+<div class="m-4 mt-8 font-bold text-lg">Number of omittings is 2</div>
+<Pagination {total} pageCol={2} />
+
+<div class="m-4 mt-8 font-bold text-lg">injection injClass</div>
+<Pagination {total} injClass="mx-2 rounded-full shadow-md dark:shadow-white/10" />
+
+<div class="m-4 mt-8 font-bold text-lg">Simulation request</div>
+<div class="px-4 py-8 divide-y divide-black/5 dark:divide-white/5 min-h-[20rem] relative">
+    {#each data as item}
+        <div class:py-6={pageSize > 1}>
+            <div class="text-sm text-justify">{item.text}</div>
+            <div class="text-right mt-1" class:italic={item.fromItalic}>{item.from}</div>
+        </div>
+    {/each}
+    {#if loading}
+        <div class="absolute inset-0 w-full h-full backdrop-blur flex flex-col justify-center gap-8 text-center">
+            <div>Query {currentPage} Page data...</div>
+            <Loading />
+        </div>
+    {/if}
+</div>
+<Pagination {pageSize} total={totalData} on:change={changePageFunc} />
+
+<div class="pb-10" />

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio