Explorar el Código

Add C++ template test: Framework7 Demo

xcbosa-itx hace 2 años
padre
commit
c08b061370
Se han modificado 100 ficheros con 5567 adiciones y 20 borrados
  1. BIN
      .DS_Store
  2. 1 0
      .gitignore
  3. 2 1
      CMakeLists.txt
  4. 4 19
      controller/StaticWebPageController.cpp
  5. BIN
      data/.DS_Store
  6. BIN
      data/html/.DS_Store
  7. BIN
      data/html/framework7/.DS_Store
  8. 20 0
      data/html/framework7/LICENSE
  9. 32 0
      data/html/framework7/README.md
  10. BIN
      data/html/framework7/components/.DS_Store
  11. 2 0
      data/html/framework7/components/accordion/accordion-aurora.less
  12. 2 0
      data/html/framework7/components/accordion/accordion-ios.less
  13. 2 0
      data/html/framework7/components/accordion/accordion-md.less
  14. 0 0
      data/html/framework7/components/accordion/accordion-rtl.css
  15. 0 0
      data/html/framework7/components/accordion/accordion-vars.less
  16. 0 0
      data/html/framework7/components/accordion/accordion.css
  17. 55 0
      data/html/framework7/components/accordion/accordion.d.ts
  18. 132 0
      data/html/framework7/components/accordion/accordion.js
  19. 0 0
      data/html/framework7/components/accordion/accordion.lazy.js
  20. 218 0
      data/html/framework7/components/accordion/accordion.less
  21. 9 0
      data/html/framework7/components/actions/actions-aurora.less
  22. 370 0
      data/html/framework7/components/actions/actions-class.js
  23. 9 0
      data/html/framework7/components/actions/actions-ios.less
  24. 11 0
      data/html/framework7/components/actions/actions-md.less
  25. 0 0
      data/html/framework7/components/actions/actions-rtl.css
  26. 97 0
      data/html/framework7/components/actions/actions-vars.less
  27. 0 0
      data/html/framework7/components/actions/actions.css
  28. 164 0
      data/html/framework7/components/actions/actions.d.ts
  29. 51 0
      data/html/framework7/components/actions/actions.js
  30. 0 0
      data/html/framework7/components/actions/actions.lazy.js
  31. 209 0
      data/html/framework7/components/actions/actions.less
  32. 10 0
      data/html/framework7/components/app/app-aurora.less
  33. 199 0
      data/html/framework7/components/app/app-class.d.ts
  34. 337 0
      data/html/framework7/components/app/app-class.js
  35. 25 0
      data/html/framework7/components/app/app-ios.less
  36. 10 0
      data/html/framework7/components/app/app-md.less
  37. 205 0
      data/html/framework7/components/app/app-vars.less
  38. 3 0
      data/html/framework7/components/app/app.less
  39. 144 0
      data/html/framework7/components/app/load-module.js
  40. 2 0
      data/html/framework7/components/appbar/appbar-aurora.less
  41. 2 0
      data/html/framework7/components/appbar/appbar-ios.less
  42. 2 0
      data/html/framework7/components/appbar/appbar-md.less
  43. 0 0
      data/html/framework7/components/appbar/appbar-rtl.css
  44. 28 0
      data/html/framework7/components/appbar/appbar-vars.less
  45. 0 0
      data/html/framework7/components/appbar/appbar.css
  46. 14 0
      data/html/framework7/components/appbar/appbar.d.ts
  47. 3 0
      data/html/framework7/components/appbar/appbar.js
  48. 1 0
      data/html/framework7/components/appbar/appbar.lazy.js
  49. 106 0
      data/html/framework7/components/appbar/appbar.less
  50. 2 0
      data/html/framework7/components/area-chart/area-chart-aurora.less
  51. 523 0
      data/html/framework7/components/area-chart/area-chart-class.js
  52. 2 0
      data/html/framework7/components/area-chart/area-chart-ios.less
  53. 2 0
      data/html/framework7/components/area-chart/area-chart-md.less
  54. 0 0
      data/html/framework7/components/area-chart/area-chart-rtl.css
  55. 29 0
      data/html/framework7/components/area-chart/area-chart-vars.less
  56. 0 0
      data/html/framework7/components/area-chart/area-chart.css
  57. 128 0
      data/html/framework7/components/area-chart/area-chart.d.ts
  58. 47 0
      data/html/framework7/components/area-chart/area-chart.js
  59. 0 0
      data/html/framework7/components/area-chart/area-chart.lazy.js
  60. 134 0
      data/html/framework7/components/area-chart/area-chart.less
  61. 17 0
      data/html/framework7/components/autocomplete/autocomplete-aurora.less
  62. 958 0
      data/html/framework7/components/autocomplete/autocomplete-class.js
  63. 17 0
      data/html/framework7/components/autocomplete/autocomplete-ios.less
  64. 30 0
      data/html/framework7/components/autocomplete/autocomplete-md.less
  65. 0 0
      data/html/framework7/components/autocomplete/autocomplete-rtl.css
  66. 50 0
      data/html/framework7/components/autocomplete/autocomplete-vars.less
  67. 0 0
      data/html/framework7/components/autocomplete/autocomplete.css
  68. 195 0
      data/html/framework7/components/autocomplete/autocomplete.d.ts
  69. 86 0
      data/html/framework7/components/autocomplete/autocomplete.js
  70. 0 0
      data/html/framework7/components/autocomplete/autocomplete.lazy.js
  71. 114 0
      data/html/framework7/components/autocomplete/autocomplete.less
  72. 2 0
      data/html/framework7/components/badge/badge-aurora.less
  73. 2 0
      data/html/framework7/components/badge/badge-ios.less
  74. 2 0
      data/html/framework7/components/badge/badge-md.less
  75. 21 0
      data/html/framework7/components/badge/badge-vars.less
  76. 14 0
      data/html/framework7/components/badge/badge.d.ts
  77. 3 0
      data/html/framework7/components/badge/badge.js
  78. 47 0
      data/html/framework7/components/badge/badge.less
  79. 2 0
      data/html/framework7/components/block/block-aurora.less
  80. 2 0
      data/html/framework7/components/block/block-ios.less
  81. 2 0
      data/html/framework7/components/block/block-md.less
  82. 104 0
      data/html/framework7/components/block/block-vars.less
  83. 14 0
      data/html/framework7/components/block/block.d.ts
  84. 3 0
      data/html/framework7/components/block/block.js
  85. 184 0
      data/html/framework7/components/block/block.less
  86. 2 0
      data/html/framework7/components/breadcrumbs/breadcrumbs-aurora.less
  87. 2 0
      data/html/framework7/components/breadcrumbs/breadcrumbs-ios.less
  88. 2 0
      data/html/framework7/components/breadcrumbs/breadcrumbs-md.less
  89. 0 0
      data/html/framework7/components/breadcrumbs/breadcrumbs-rtl.css
  90. 36 0
      data/html/framework7/components/breadcrumbs/breadcrumbs-vars.less
  91. 0 0
      data/html/framework7/components/breadcrumbs/breadcrumbs.css
  92. 15 0
      data/html/framework7/components/breadcrumbs/breadcrumbs.d.ts
  93. 13 0
      data/html/framework7/components/breadcrumbs/breadcrumbs.js
  94. 1 0
      data/html/framework7/components/breadcrumbs/breadcrumbs.lazy.js
  95. 100 0
      data/html/framework7/components/breadcrumbs/breadcrumbs.less
  96. 25 0
      data/html/framework7/components/button/button-aurora.less
  97. 18 0
      data/html/framework7/components/button/button-ios.less
  98. 14 0
      data/html/framework7/components/button/button-md.less
  99. 108 0
      data/html/framework7/components/button/button-vars.less
  100. 14 0
      data/html/framework7/components/button/button.d.ts

BIN
.DS_Store


+ 1 - 0
.gitignore

@@ -1 +1,2 @@
 cmake-build-debug
 cmake-build-debug
+node_modules

+ 2 - 1
CMakeLists.txt

@@ -5,12 +5,13 @@ set(CMAKE_CXX_STANDARD 17)
 
 
 aux_source_directory(. DIR_SRCS)
 aux_source_directory(. DIR_SRCS)
 aux_source_directory(controller DIR_CONTROLLERS)
 aux_source_directory(controller DIR_CONTROLLERS)
+aux_source_directory(view DIR_VIEW)
 
 
 add_subdirectory(utils)
 add_subdirectory(utils)
 add_subdirectory(httpserver)
 add_subdirectory(httpserver)
 add_subdirectory(processor)
 add_subdirectory(processor)
 
 
-add_executable(FRPCWebUI ${DIR_SRCS} ${DIR_CONTROLLERS})
+add_executable(FRPCWebUI ${DIR_SRCS} ${DIR_CONTROLLERS} ${DIR_VIEW})
 
 
 find_package(Threads)
 find_package(Threads)
 target_link_libraries(FRPCWebUI PRIVATE HttpServerUtils HttpServer Processor ${CMAKE_THREAD_LIBS_INIT})
 target_link_libraries(FRPCWebUI PRIVATE HttpServerUtils HttpServer Processor ${CMAKE_THREAD_LIBS_INIT})

+ 4 - 19
controller/StaticWebPageController.cpp

@@ -4,6 +4,9 @@
 
 
 #include "../processor/processor.h"
 #include "../processor/processor.h"
 #include "../webuiconf.h"
 #include "../webuiconf.h"
+
+#include "../processor/templates/framework7/Framework7Document.hpp"
+
 #include <sys/stat.h>
 #include <sys/stat.h>
 
 
 using namespace std;
 using namespace std;
@@ -77,26 +80,8 @@ namespace xc::controller {
                            })
                            })
 
 
     ResponseData *test1(RequestData request) {
     ResponseData *test1(RequestData request) {
-        vector<map<string, string>> model = {
-                {
-                        { "name", "user1" },
-                        { "pwd", "123456" }
-                },
-                {
-                        { "name", "user2" },
-                        { "pwd", "234567" }
-                }
-        };
         return new TemplateResponseData({
         return new TemplateResponseData({
-            p("Hello world"),
-            Foreach(model, [](map<string, string> it) {
-                return p({
-                    "Hello ",
-                    b(it["name"]),
-                    ", You password is ",
-                    it["pwd"]
-                }).style("text-align", "center");
-            })
+            framework7::Framework7Document()
         });
         });
     }
     }
 
 

BIN
data/.DS_Store


BIN
data/html/.DS_Store


BIN
data/html/framework7/.DS_Store


+ 20 - 0
data/html/framework7/LICENSE

@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Vladimir Kharlampidi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 32 - 0
data/html/framework7/README.md

@@ -0,0 +1,32 @@
+<a href="https://www.patreon.com/framework7"><img src="https://framework7.io/i/support-badge.png" height="20"></a>
+
+# Framework7
+
+Full Featured Mobile HTML Framework For Building iOS & Android Apps
+
+## Supporting Framework7
+
+Framework7 is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome [backers](https://github.com/framework7io/framework7/blob/master/BACKERS.md). If you'd like to join them, please consider [becoming a backer or sponsor on Patreon.](https://www.patreon.com/framework7)
+
+
+## Getting Started
+  * [Getting Started Guide](https://framework7.io/docs/introduction.html)
+  * [Installation Guide](https://framework7.io/docs/installation.html)
+  * [App Layout](https://framework7.io/docs/app-layout.html)
+  * [Initialize App](https://framework7.io/docs/init-app.html)
+
+## Forum
+
+If you have questions about Framework7 or want to help others you are welcome to special forum at https://forum.framework7.io/
+
+## Docs
+
+Documentation available at https://framework7.io/docs/
+
+## Tutorials
+
+Tutorials available at https://framework7.io/tutorials/
+
+## Showcase
+
+Appstore apps made with Framework7: https://framework7.io/showcase/

BIN
data/html/framework7/components/.DS_Store


+ 2 - 0
data/html/framework7/components/accordion/accordion-aurora.less

@@ -0,0 +1,2 @@
+.aurora {
+}

+ 2 - 0
data/html/framework7/components/accordion/accordion-ios.less

@@ -0,0 +1,2 @@
+.ios {
+}

+ 2 - 0
data/html/framework7/components/accordion/accordion-md.less

@@ -0,0 +1,2 @@
+.md {
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/accordion/accordion-rtl.css


+ 0 - 0
data/html/framework7/components/accordion/accordion-vars.less


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/accordion/accordion.css


+ 55 - 0
data/html/framework7/components/accordion/accordion.d.ts

@@ -0,0 +1,55 @@
+import Framework7 from '../app/app-class.js';
+import { CSSSelector, Framework7Plugin } from '../app/app-class.js';
+
+export namespace Accordion {
+  interface AppMethods {
+    accordion: {
+      /** open specified accordion item */
+      open(el: HTMLElement | CSSSelector): void;
+
+      /** close specified accordion item */
+      close(el: HTMLElement | CSSSelector): void;
+
+      /** toggle specified accordion item */
+      toggle(el: HTMLElement | CSSSelector): void;
+    };
+  }
+  interface AppParams {}
+  interface DomEvents {
+    /** Event will be triggered right before accordion content starts its opening animation. event.detail.prevent contains function that will prevent accordion from opening when called */
+    'accordion:beforeopen': () => void;
+    /** Event will be triggered when accordion content starts its opening animation */
+    'accordion:open': () => void;
+    /** Event will be triggered after accordion content completes its opening animation */
+    'accordion:opened': () => void;
+    /** Event will be triggered right before accordion content starts its closing animation. event.detail.prevent contains function that will prevent accordion from closing when called */
+    'accordion:beforeclose': () => void;
+    /** Event will be triggered when accordion content starts its closing animation */
+    'accordion:close': () => void;
+    /** Event will be triggered after accordion content completes its closing animation */
+    'accordion:closed': () => void;
+  }
+  interface AppEvents {
+    /** Event will be triggered before accordion content starts its opening animation */
+    accordionBeforeOpen: (el: HTMLElement | CSSSelector, prevent: () => void) => void;
+
+    /** Event will be triggered when accordion content starts its opening animation */
+    accordionOpen: (el: HTMLElement | CSSSelector) => void;
+
+    /** Event will be triggered after accordion content completes its opening animation */
+    accordionOpened: (el: HTMLElement | CSSSelector) => void;
+
+    /** Event will be triggered before accordion content starts its closing animation */
+    accordionBeforeClose: (el: HTMLElement | CSSSelector, prevent: () => void) => void;
+
+    /** Event will be triggered when accordion content starts its closing animation */
+    accordionClose: (el: HTMLElement | CSSSelector) => void;
+
+    /** Event will be triggered after accordion content completes its closing animation */
+    accordionClosed: (el: HTMLElement | CSSSelector) => void;
+  }
+}
+
+declare const AccordionComponent: Framework7Plugin;
+
+export default AccordionComponent;

+ 132 - 0
data/html/framework7/components/accordion/accordion.js

@@ -0,0 +1,132 @@
+import $ from '../../shared/dom7.js';
+import { nextFrame, bindMethods } from '../../shared/utils.js';
+const Accordion = {
+  toggleClicked($clickedEl) {
+    const app = this;
+    let $accordionItemEl = $clickedEl.closest('.accordion-item').eq(0);
+    if (!$accordionItemEl.length) $accordionItemEl = $clickedEl.parents('li').eq(0);
+    const $accordionContent = $clickedEl.parents('.accordion-item-content').eq(0);
+
+    if ($accordionContent.length) {
+      if ($accordionContent.parents($accordionItemEl).length) return;
+    }
+
+    if ($clickedEl.parents('li').length > 1 && $clickedEl.parents('li')[0] !== $accordionItemEl[0]) return;
+    app.accordion.toggle($accordionItemEl);
+  },
+
+  open(el) {
+    const app = this;
+    const $el = $(el);
+    let prevented = false;
+
+    function prevent() {
+      prevented = true;
+    }
+
+    $el.trigger('accordion:beforeopen', {
+      prevent
+    }, prevent);
+    app.emit('accordionBeforeOpen', $el[0], prevent);
+    if (prevented) return;
+    const $list = $el.parents('.accordion-list').eq(0);
+    let $contentEl = $el.children('.accordion-item-content');
+    $contentEl.removeAttr('aria-hidden');
+    if ($contentEl.length === 0) $contentEl = $el.find('.accordion-item-content');
+    if ($contentEl.length === 0) return;
+    const $openedItem = $list.length > 0 && $el.parent().children('.accordion-item-opened');
+
+    if ($openedItem.length > 0) {
+      app.accordion.close($openedItem);
+    }
+
+    $contentEl.transitionEnd(() => {
+      if ($el.hasClass('accordion-item-opened')) {
+        $contentEl.transition(0);
+        $contentEl.css('height', 'auto');
+        nextFrame(() => {
+          $contentEl.transition('');
+          $el.trigger('accordion:opened');
+          app.emit('accordionOpened', $el[0]);
+        });
+      } else {
+        $contentEl.css('height', '');
+        $el.trigger('accordion:closed');
+        app.emit('accordionClosed', $el[0]);
+      }
+    });
+    $contentEl.css('height', `${$contentEl[0].scrollHeight}px`);
+    $el.trigger('accordion:open');
+    $el.addClass('accordion-item-opened');
+    app.emit('accordionOpen', $el[0]);
+  },
+
+  close(el) {
+    const app = this;
+    const $el = $(el);
+    let prevented = false;
+
+    function prevent() {
+      prevented = true;
+    }
+
+    $el.trigger('accordion:beforeclose', {
+      prevent
+    }, prevent);
+    app.emit('accordionBeforeClose', $el[0], prevent);
+    if (prevented) return;
+    let $contentEl = $el.children('.accordion-item-content');
+    if ($contentEl.length === 0) $contentEl = $el.find('.accordion-item-content');
+    $el.removeClass('accordion-item-opened');
+    $contentEl.attr('aria-hidden', true);
+    $contentEl.transition(0);
+    $contentEl.css('height', `${$contentEl[0].scrollHeight}px`); // Close
+
+    $contentEl.transitionEnd(() => {
+      if ($el.hasClass('accordion-item-opened')) {
+        $contentEl.transition(0);
+        $contentEl.css('height', 'auto');
+        nextFrame(() => {
+          $contentEl.transition('');
+          $el.trigger('accordion:opened');
+          app.emit('accordionOpened', $el[0]);
+        });
+      } else {
+        $contentEl.css('height', '');
+        $el.trigger('accordion:closed');
+        app.emit('accordionClosed', $el[0]);
+      }
+    });
+    nextFrame(() => {
+      $contentEl.transition('');
+      $contentEl.css('height', '');
+      $el.trigger('accordion:close');
+      app.emit('accordionClose', $el[0]);
+    });
+  },
+
+  toggle(el) {
+    const app = this;
+    const $el = $(el);
+    if ($el.length === 0) return;
+    if ($el.hasClass('accordion-item-opened')) app.accordion.close(el);else app.accordion.open(el);
+  }
+
+};
+export default {
+  name: 'accordion',
+
+  create() {
+    const app = this;
+    bindMethods(app, {
+      accordion: Accordion
+    });
+  },
+
+  clicks: {
+    '.accordion-item .item-link, .accordion-item-toggle, .links-list.accordion-list > ul > li > a': function open($clickedEl) {
+      const app = this;
+      Accordion.toggleClicked.call(app, $clickedEl);
+    }
+  }
+};

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/accordion/accordion.lazy.js


+ 218 - 0
data/html/framework7/components/accordion/accordion.less

@@ -0,0 +1,218 @@
+/* === Accordion === */
+@import './accordion-vars.less';
+
+:root {
+  --f7-accordion-chevron-icon-down: 'chevron_down';
+  --f7-accordion-chevron-icon-up: 'chevron_up';
+}
+.accordion-item-toggle {
+  cursor: pointer;
+}
+.list.accordion-list .accordion-item-toggle {
+  transition-duration: 300ms;
+  position: relative;
+  overflow: hidden;
+  &.active-state {
+    transition-duration: 300ms;
+    background-color: var(--f7-list-link-pressed-bg-color);
+    > .item-inner {
+      .hairline-color(bottom, transparent);
+    }
+  }
+  .item-inner {
+    transition-duration: 300ms;
+    transition-property: background-color;
+    &:after {
+      transition-duration: 300ms;
+    }
+  }
+  .ripple-wave {
+    z-index: 0;
+  }
+}
+
+.accordion-item {
+  .item-link .item-inner:after {
+    transition-duration: 300ms;
+  }
+  .list,
+  .block {
+    margin-top: 0;
+    margin-bottom: 0;
+  }
+  .block {
+    > h1,
+    > h2,
+    > h3,
+    > h4,
+    > p {
+      &:first-child {
+        margin-top: 10px;
+      }
+      &:last-child {
+        margin-bottom: 10px;
+      }
+    }
+  }
+}
+.accordion-item-opened {
+  .accordion-item-toggle .item-inner,
+  > .item-link .item-inner {
+    .hairline-color(bottom, transparent);
+  }
+}
+
+.list li.accordion-item ul {
+  .ltr({
+    padding-left: 0;
+  });
+  .rtl({
+    padding-right: 0;
+  });
+}
+.accordion-item-content {
+  position: relative;
+  overflow: hidden;
+  height: 0;
+  font-size: 14px;
+  transition-duration: 300ms;
+  .accordion-item-opened > & {
+    height: auto;
+  }
+  html.device-android-4 & {
+    transform: none;
+  }
+}
+.list .accordion-item-toggle .item-inner {
+  &:before {
+    .core-icons-font();
+    position: absolute;
+    top: 50%;
+    font-size: var(--f7-list-chevron-icon-font-size);
+    color: var(--f7-list-chevron-icon-color);
+    pointer-events: none;
+    .ltr({
+      right: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
+    });
+    .rtl({
+      left: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
+    });
+  }
+}
+.list:not(.accordion-opposite) .accordion-item-toggle .item-inner {
+  .ltr({
+    padding-right: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
+  });
+  .rtl({
+    padding-left: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
+  });
+}
+.accordion-opposite {
+  .accordion-item-toggle.item-link .item-inner,
+  .accordion-item-toggle .item-inner,
+  .accordion-item > .item-link > .item-inner,
+  .accordion-item > .item-link > .item-content > .item-inner {
+    .ltr({
+      padding-right: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
+    });
+    .rtl({
+      padding-left: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
+    });
+  }
+  .accordion-item > .item-link > .item-title-row {
+    padding-right: 0;
+  }
+  .accordion-item-toggle.item-link .item-inner,
+  .accordion-item-toggle .item-inner,
+  .accordion-item > .item-link > .item-inner,
+  .accordion-item > .item-link > .item-content > .item-inner,
+  .accordion-item > .item-link .item-title-row {
+    &:before {
+      display: none;
+    }
+  }
+  .accordion-item-toggle > .item-content,
+  .accordion-item-toggle.item-content,
+  .accordion-item > .item-content,
+  .accordion-item > .item-link > .item-content,
+  &.links-list .accordion-item > a {
+    position: relative;
+    .ltr({
+      padding-left: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
+    });
+    .rtl({
+      padding-right: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
+    });
+    &:before {
+      .core-icons-font();
+      position: absolute;
+      top: 50%;
+      font-size: var(--f7-list-chevron-icon-font-size);
+      color: var(--f7-list-chevron-icon-color);
+      pointer-events: none;
+      content: var(--f7-accordion-chevron-icon-down);
+      width: 14px;
+      height: 8px;
+      margin-top: -4px;
+      line-height: 8px;
+      transform: translateX(-50%);
+      .ltr({
+        left: calc((var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal)) / 2 + var(--f7-safe-area-left));
+      });
+      .rtl({
+        right: calc((var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal)) / 2 + var(--f7-safe-area-right));
+      });
+    }
+  }
+}
+.list .accordion-item-toggle.active-state {
+  background-color: var(--f7-list-link-pressed-bg-color);
+}
+
+.list .accordion-item-toggle .item-inner,
+.list:not(.media-list) .accordion-item:not(.media-item) .accordion-item-toggle .item-inner,
+.list:not(.media-list) .accordion-item:not(.media-item) > .item-link .item-inner,
+.media-list .accordion-item .accordion-item-toggle .item-title-row,
+.media-list .accordion-item > .item-link .item-title-row,
+.accordion-item.media-item .accordion-item-toggle .item-title-row,
+.accordion-item.media-item > .item-link .item-title-row,
+.links-list .accordion-item > a {
+  &:before {
+    content: var(--f7-accordion-chevron-icon-down);
+    width: 14px;
+    height: 8px;
+    margin-top: -4px;
+    line-height: 8px;
+  }
+}
+.list .accordion-item-toggle.accordion-item-opened .item-inner,
+.list:not(.media-list) .accordion-item-opened:not(.media-item) .accordion-item-toggle .item-inner,
+.list:not(.media-list) .accordion-item-opened:not(.media-item) > .item-link .item-inner,
+.media-list .accordion-item-opened .accordion-item-toggle .item-title-row,
+.media-list .accordion-item-opened > .item-link .item-title-row,
+.accordion-item-opened.media-item .accordion-item-toggle .item-title-row,
+.accordion-item-opened.media-item > .item-link .item-title-row,
+.links-list .accordion-item-opened > a,
+.accordion-opposite .accordion-item-opened .accordion-item-toggle > .item-content,
+.accordion-opposite .accordion-item-opened .accordion-item-toggle.item-content,
+.accordion-opposite .accordion-item-opened > .item-content,
+.accordion-opposite .accordion-item-opened > .item-link > .item-content,
+.accordion-opposite &.links-list .accordion-item-opened > a {
+  &:before {
+    content: var(--f7-accordion-chevron-icon-up);
+    width: 14px;
+    height: 8px;
+    margin-top: -4px;
+    line-height: 8px;
+  }
+}
+
+.if-ios-theme({
+  @import './accordion-ios.less';
+});
+.if-md-theme({
+  @import './accordion-md.less';
+});
+.if-aurora-theme({
+  @import './accordion-aurora.less';
+});

+ 9 - 0
data/html/framework7/components/actions/actions-aurora.less

@@ -0,0 +1,9 @@
+.aurora {
+  .actions-button-media {
+    margin-left: 16px;
+    + .actions-button-text {
+      text-align: left;
+      margin-left: 16px;
+    }
+  }
+}

+ 370 - 0
data/html/framework7/components/actions/actions-class.js

@@ -0,0 +1,370 @@
+/* eslint indent: ["off"] */
+import { getWindow, getDocument } from 'ssr-window';
+import { getDevice } from '../../shared/get-device.js';
+import { extend, nextTick } from '../../shared/utils.js';
+import Modal from '../modal/modal-class.js';
+import $ from '../../shared/dom7.js';
+/** @jsx $jsx */
+
+import $jsx from '../../shared/$jsx.js';
+
+class Actions extends Modal {
+  constructor(app, params) {
+    const extendedParams = extend({
+      on: {}
+    }, app.params.actions, params); // Extends with open/close Modal methods;
+
+    super(app, extendedParams);
+    const actions = this;
+    const device = getDevice();
+    const window = getWindow();
+    const document = getDocument();
+    actions.params = extendedParams; // Buttons
+
+    let groups;
+
+    if (actions.params.buttons) {
+      groups = actions.params.buttons;
+      if (!Array.isArray(groups[0])) groups = [groups];
+    }
+
+    actions.groups = groups; // Find Element
+
+    let $el;
+
+    if (actions.params.el) {
+      $el = $(actions.params.el).eq(0);
+    } else if (actions.params.content) {
+      $el = $(actions.params.content).filter(node => node.nodeType === 1).eq(0);
+    } else if (actions.params.buttons) {
+      if (actions.params.convertToPopover) {
+        actions.popoverHtml = actions.renderPopover();
+      }
+
+      actions.actionsHtml = actions.render();
+    }
+
+    if ($el && $el.length > 0 && $el[0].f7Modal) {
+      return $el[0].f7Modal;
+    }
+
+    if ($el && $el.length === 0 && !(actions.actionsHtml || actions.popoverHtml)) {
+      return actions.destroy();
+    } // Backdrop
+
+
+    let $backdropEl;
+
+    if (actions.params.backdrop && actions.params.backdropEl) {
+      $backdropEl = $(actions.params.backdropEl);
+    } else if (actions.params.backdrop) {
+      if (actions.params.backdropUnique) {
+        $backdropEl = $('<div class="popup-backdrop popup-backdrop-unique"></div>');
+        actions.$containerEl.append($backdropEl);
+      } else {
+        $backdropEl = actions.$containerEl.children('.actions-backdrop');
+      }
+
+      if ($backdropEl.length === 0) {
+        $backdropEl = $('<div class="actions-backdrop"></div>');
+        actions.$containerEl.append($backdropEl);
+      }
+    }
+
+    const originalOpen = actions.open;
+    const originalClose = actions.close;
+    let popover;
+
+    function buttonOnClick(e) {
+      const $buttonEl = $(this);
+      let buttonIndex;
+      let groupIndex;
+
+      if ($buttonEl.hasClass('list-button') || $buttonEl.hasClass('item-link')) {
+        buttonIndex = $buttonEl.parents('li').index();
+        groupIndex = $buttonEl.parents('.list').index();
+      } else {
+        buttonIndex = $buttonEl.index();
+        groupIndex = $buttonEl.parents('.actions-group').index();
+      }
+
+      if (typeof groups !== 'undefined') {
+        const button = groups[groupIndex][buttonIndex];
+        if (button.onClick) button.onClick(actions, e);
+        if (actions.params.onClick) actions.params.onClick(actions, e);
+        if (button.close !== false) actions.close();
+      }
+    }
+
+    actions.open = function open(animate) {
+      let convertToPopover = false;
+      const {
+        targetEl,
+        targetX,
+        targetY,
+        targetWidth,
+        targetHeight
+      } = actions.params;
+
+      if (actions.params.convertToPopover && (targetEl || targetX !== undefined && targetY !== undefined)) {
+        // Popover
+        if (actions.params.forceToPopover || device.ios && device.ipad || app.width >= 768 || device.desktop && app.theme === 'aurora') {
+          convertToPopover = true;
+        }
+      }
+
+      if (convertToPopover && actions.popoverHtml) {
+        popover = app.popover.create({
+          containerEl: actions.params.containerEl,
+          content: actions.popoverHtml,
+          backdrop: actions.params.backdrop,
+          targetEl,
+          targetX,
+          targetY,
+          targetWidth,
+          targetHeight,
+          on: {
+            open() {
+              if (!actions.$el) {
+                actions.$el = popover.$el;
+              }
+
+              actions.$el.trigger(`modal:open ${actions.type.toLowerCase()}:open`);
+              actions.emit(`local::open modalOpen ${actions.type}Open`, actions);
+            },
+
+            opened() {
+              if (!actions.$el) {
+                actions.$el = popover.$el;
+              }
+
+              actions.$el.trigger(`modal:opened ${actions.type.toLowerCase()}:opened`);
+              actions.emit(`local::opened modalOpened ${actions.type}Opened`, actions);
+            },
+
+            close() {
+              if (!actions.$el) {
+                actions.$el = popover.$el;
+              }
+
+              actions.$el.trigger(`modal:close ${actions.type.toLowerCase()}:close`);
+              actions.emit(`local::close modalClose ${actions.type}Close`, actions);
+            },
+
+            closed() {
+              if (!actions.$el) {
+                actions.$el = popover.$el;
+              }
+
+              actions.$el.trigger(`modal:closed ${actions.type.toLowerCase()}:closed`);
+              actions.emit(`local::closed modalClosed ${actions.type}Closed`, actions);
+            }
+
+          }
+        });
+        popover.open(animate);
+        popover.once('popoverOpened', () => {
+          popover.$el.find('.list-button, .item-link').each(buttonEl => {
+            $(buttonEl).on('click', buttonOnClick);
+          });
+        });
+        popover.once('popoverClosed', () => {
+          popover.$el.find('.list-button, .item-link').each(buttonEl => {
+            $(buttonEl).off('click', buttonOnClick);
+          });
+          nextTick(() => {
+            popover.destroy();
+            popover = undefined;
+          });
+        });
+      } else {
+        actions.$el = actions.actionsHtml ? $(actions.actionsHtml) : actions.$el;
+        actions.$el[0].f7Modal = actions;
+
+        if (actions.groups) {
+          actions.$el.find('.actions-button').each(buttonEl => {
+            $(buttonEl).on('click', buttonOnClick);
+          });
+          actions.once('actionsClosed', () => {
+            actions.$el.find('.actions-button').each(buttonEl => {
+              $(buttonEl).off('click', buttonOnClick);
+            });
+          });
+        }
+
+        actions.el = actions.$el[0];
+        originalOpen.call(actions, animate);
+      }
+
+      return actions;
+    };
+
+    actions.close = function close(animate) {
+      if (popover) {
+        popover.close(animate);
+      } else {
+        originalClose.call(actions, animate);
+      }
+
+      return actions;
+    };
+
+    extend(actions, {
+      app,
+      $el,
+      el: $el ? $el[0] : undefined,
+      $backdropEl,
+      backdropEl: $backdropEl && $backdropEl[0],
+      type: 'actions'
+    });
+
+    function handleClick(e) {
+      const target = e.target;
+      const $target = $(target);
+      const keyboardOpened = !device.desktop && device.cordova && (window.Keyboard && window.Keyboard.isVisible || window.cordova.plugins && window.cordova.plugins.Keyboard && window.cordova.plugins.Keyboard.isVisible);
+      if (keyboardOpened) return;
+
+      if ($target.closest(actions.el).length === 0) {
+        if (actions.params.closeByBackdropClick && actions.params.backdrop && actions.backdropEl && actions.backdropEl === target) {
+          actions.close();
+        } else if (actions.params.closeByOutsideClick) {
+          actions.close();
+        }
+      }
+    }
+
+    function onKeyDown(e) {
+      const keyCode = e.keyCode;
+
+      if (keyCode === 27 && actions.params.closeOnEscape) {
+        actions.close();
+      }
+    }
+
+    if (actions.params.closeOnEscape) {
+      actions.on('open', () => {
+        $(document).on('keydown', onKeyDown);
+      });
+      actions.on('close', () => {
+        $(document).off('keydown', onKeyDown);
+      });
+    }
+
+    actions.on('opened', () => {
+      if (actions.params.closeByBackdropClick || actions.params.closeByOutsideClick) {
+        app.on('click', handleClick);
+      }
+    });
+    actions.on('close', () => {
+      if (actions.params.closeByBackdropClick || actions.params.closeByOutsideClick) {
+        app.off('click', handleClick);
+      }
+    });
+
+    if ($el) {
+      $el[0].f7Modal = actions;
+    }
+
+    return actions;
+  }
+
+  render() {
+    const actions = this;
+    if (actions.params.render) return actions.params.render.call(actions, actions);
+    const {
+      groups
+    } = actions;
+    const cssClass = actions.params.cssClass;
+    return $jsx("div", {
+      class: `actions-modal${actions.params.grid ? ' actions-grid' : ''} ${cssClass || ''}`
+    }, groups.map(group => $jsx("div", {
+      class: "actions-group"
+    }, group.map(button => {
+      const buttonClasses = [`actions-${button.label ? 'label' : 'button'}`];
+      const {
+        color,
+        bg,
+        bold,
+        disabled,
+        label,
+        text,
+        icon
+      } = button;
+      if (color) buttonClasses.push(`color-${color}`);
+      if (bg) buttonClasses.push(`bg-color-${bg}`);
+      if (bold) buttonClasses.push('actions-button-bold');
+      if (disabled) buttonClasses.push('disabled');
+
+      if (label) {
+        return $jsx("div", {
+          class: buttonClasses.join(' ')
+        }, text);
+      }
+
+      return $jsx("div", {
+        class: buttonClasses.join(' ')
+      }, icon && $jsx("div", {
+        class: "actions-button-media"
+      }, icon), $jsx("div", {
+        class: "actions-button-text"
+      }, text));
+    }))));
+  }
+
+  renderPopover() {
+    const actions = this;
+    if (actions.params.renderPopover) return actions.params.renderPopover.call(actions, actions);
+    const {
+      groups
+    } = actions;
+    const cssClass = actions.params.cssClass;
+    return $jsx("div", {
+      class: `popover popover-from-actions ${cssClass || ''}`
+    }, $jsx("div", {
+      class: "popover-inner"
+    }, groups.map(group => $jsx("div", {
+      class: "list"
+    }, $jsx("ul", null, group.map(button => {
+      const itemClasses = [];
+      const {
+        color,
+        bg,
+        bold,
+        disabled,
+        label,
+        text,
+        icon
+      } = button;
+      if (color) itemClasses.push(`color-${color}`);
+      if (bg) itemClasses.push(`bg-color-${bg}`);
+      if (bold) itemClasses.push('popover-from-actions-bold');
+      if (disabled) itemClasses.push('disabled');
+
+      if (label) {
+        itemClasses.push('popover-from-actions-label');
+        return `<li class="${itemClasses.join(' ')}">${text}</li>`;
+      }
+
+      if (icon) {
+        itemClasses.push('item-link item-content');
+        return $jsx("li", null, $jsx("a", {
+          class: itemClasses.join(' ')
+        }, $jsx("div", {
+          class: "item-media"
+        }, icon), $jsx("div", {
+          class: "item-inner"
+        }, $jsx("div", {
+          class: "item-title"
+        }, text))));
+      }
+
+      itemClasses.push('list-button');
+      return $jsx("li", null, $jsx("a", {
+        class: itemClasses.join(' ')
+      }, text));
+    }))))));
+  }
+
+}
+
+export default Actions;

+ 9 - 0
data/html/framework7/components/actions/actions-ios.less

@@ -0,0 +1,9 @@
+.ios {
+  .actions-button-media {
+    margin-left: 16px;
+    + .actions-button-text {
+      text-align: left;
+      margin-left: 16px;
+    }
+  }
+}

+ 11 - 0
data/html/framework7/components/actions/actions-md.less

@@ -0,0 +1,11 @@
+.md {
+  .actions-button {
+    transition-duration: 300ms;
+  }
+  .actions-button-media {
+    min-width: 40px;
+    + .actions-button-text {
+      margin-left: 16px;
+    }
+  }
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/actions/actions-rtl.css


+ 97 - 0
data/html/framework7/components/actions/actions-vars.less

@@ -0,0 +1,97 @@
+:root {
+  /*
+  --f7-actions-button-text-color: var(--f7-theme-color);
+  */
+  --f7-actions-grid-button-font-size: 12px;
+  --f7-actions-grid-button-text-color: #757575;
+  --f7-actions-grid-button-icon-size: 48px;
+  .dark-vars({
+    --f7-actions-label-text-color:rgba(255,255,255,0.55);
+  });
+}
+.ios-vars({
+  --f7-actions-border-radius: 13px;
+
+  --f7-actions-button-padding: 0px;
+  --f7-actions-button-text-align: center;
+  --f7-actions-button-height: 57px;
+  --f7-actions-button-height-landscape: 44px;
+  --f7-actions-button-font-size: 20px;
+  --f7-actions-button-icon-size: 28px;
+  --f7-actions-button-justify-content: center;
+  --f7-actions-label-padding: 8px 10px;
+
+  --f7-actions-label-font-size: 13px;
+  --f7-actions-label-justify-content: center;
+  --f7-actions-group-border-color: transparent;
+  --f7-actions-group-margin: 8px;
+  .light-vars({
+    --f7-actions-bg-color: rgba(255,255,255,0.95);
+    --f7-actions-bg-color-rgb: 255, 255, 255;
+    --f7-actions-button-border-color: rgba(0,0,0,0.2);
+    --f7-actions-button-pressed-bg-color: rgba(230,230,230,0.9);
+    --f7-actions-button-pressed-bg-color-rgb: 230, 230, 230;
+    --f7-actions-label-text-color: #8a8a8a;
+  });
+  .dark-vars({
+    --f7-actions-bg-color: rgba(45,45,45,0.95);
+    --f7-actions-bg-color-rgb: 45, 45, 45;
+    --f7-actions-button-border-color: rgba(255, 255, 255, 0.15);
+    --f7-actions-button-pressed-bg-color: rgba(50,50,50,0.9);
+    --f7-actions-button-pressed-bg-color-rgb: 50, 50, 50;
+
+  })
+});
+.md-vars({
+  --f7-actions-border-radius: 0px;
+  --f7-actions-button-border-color: transparent;
+  --f7-actions-button-padding: 0 16px;
+  --f7-actions-button-text-align: left;
+  --f7-actions-button-height: 48px;
+  --f7-actions-button-height-landscape: 48px;
+  --f7-actions-button-font-size: 16px;
+  --f7-actions-button-icon-size: 24px;
+  --f7-actions-button-justify-content: space-between;
+  --f7-actions-label-padding: 12px 16px;
+  --f7-actions-label-font-size: 16px;
+  --f7-actions-label-justify-content: flex-start;
+  --f7-actions-group-margin: 0px;
+  .light-vars({
+    --f7-actions-bg-color: #fff;
+    --f7-actions-button-pressed-bg-color: #e5e5e5;
+    --f7-actions-label-text-color: rgba(0,0,0,0.54);
+    --f7-actions-group-border-color: rgba(0,0,0,0.12);
+  });
+  .dark-vars({
+    --f7-actions-bg-color: #202020;
+    --f7-actions-button-pressed-bg-color: #2e2e2e;
+    --f7-actions-group-border-color: rgba(255,255,255,0.15);
+  });
+});
+.aurora-vars({
+  --f7-actions-border-radius: 8px;
+  --f7-actions-button-padding: 0 16px;
+  --f7-actions-button-text-align: center;
+  --f7-actions-button-height: 48px;
+  --f7-actions-button-height-landscape: 48px;
+  --f7-actions-button-font-size: 16px;
+  --f7-actions-button-icon-size: 24px;
+  --f7-actions-button-justify-content: space-between;
+  --f7-actions-label-padding: 10px 16px;
+  --f7-actions-label-font-size: 14px;
+  --f7-actions-label-justify-content: center;
+  --f7-actions-group-margin: 16px;
+  .light-vars({
+    --f7-actions-bg-color: #fff;
+    --f7-actions-button-border-color: rgba(0,0,0,0.12);
+    --f7-actions-button-pressed-bg-color: #e5e5e5;
+    --f7-actions-label-text-color: rgba(0,0,0,0.5);
+    --f7-actions-group-border-color: rgba(0,0,0,0.1);
+  });
+  .dark-vars({
+    --f7-actions-bg-color: #202020;
+    --f7-actions-button-border-color: rgba(255, 255, 255, 0.15);
+    --f7-actions-button-pressed-bg-color: #2e2e2e;
+    --f7-actions-group-border-color: rgba(255,255,255,0.15);
+  });
+});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/actions/actions.css


+ 164 - 0
data/html/framework7/components/actions/actions.d.ts

@@ -0,0 +1,164 @@
+import { Dom7Array } from 'dom7';
+import Framework7, {
+  CSSSelector,
+  Framework7EventsClass,
+  Framework7Plugin,
+} from '../app/app-class.js';
+
+export namespace Actions {
+  interface Actions extends Framework7EventsClass<Events> {
+    /** Link to global app instance */
+    app: Framework7;
+    /** Action sheet HTML element */
+    el: HTMLElement;
+    /** Dom7 instance with action sheet HTML element */
+    $el: Dom7Array;
+    /** Backdrop HTML element */
+    backdropEl: HTMLElement;
+    /** Dom7 instance with backdrop HTML element */
+    $backdropEl: Dom7Array;
+    /** Action sheet instance parameters */
+    params: Parameters;
+    /** Boolean prop indicating whether action sheet is opened or not */
+    opened: boolean;
+
+    /** Open action sheet. Where animate - boolean (by default true) - defines whether it should be opened with animation */
+    open(animate?: boolean): void;
+    /** Close action sheet. Where animate - boolean (by default true) - defines whether it should be closed with animation */
+    close(animate?: boolean): void;
+    /** Destroy action sheet */
+    destroy(): void;
+  }
+
+  interface Button {
+    /** String with Button's text (could be HTML string) */
+    text: string;
+    /** HTML string of icon */
+    icon?: string;
+    /** Enables bold button text */
+    bold?: boolean;
+    /** Button color, one of default colors */
+    color?: string;
+    /** Button background color, one of default colors */
+    bg?: string;
+    /** If enabled then it will be rendered as label instead of button */
+    label?: boolean;
+    /** Defines whether the button is disabled or not. */
+    disabled?: boolean;
+    /** If enabled then button click will close Action Sheet */
+    close?: boolean;
+    /** Callback function that will be executed after click on this button */
+    onClick?: (actions: Actions, e: unknown) => void;
+  }
+
+  interface Parameters {
+    /** Action Sheet element. Can be useful if you already have Action Sheet element in your HTML and want to create new instance using this element*/
+    el?: HTMLElement | CSSSelector;
+    /** Full Action Sheet HTML content string. Can be useful if you want to create Action Sheet element with custom HTML*/
+    content?: string;
+    /** Enables Action Sheet backdrop (dark semi transparent layer behind)*/
+    backdrop?: boolean;
+    /** Backdrop element to share across instances */
+    backdropEl?: HTMLElement | CSSSelector;
+    /** If enabled it creates unique backdrop element exclusively for this modal (default false) */
+    backdropUnique?: boolean;
+    /** Custom css class added to Actions Sheet element */
+    cssClass?: string;
+    /** When enabled, action sheet will be closed on backdrop click*/
+    closeByBackdropClick?: boolean;
+    /** When enabled, action sheet will be closed on when click outside of it*/
+    closeByOutsideClick?: boolean;
+    /** When enabled, action sheet will be closed on ESC keyboard key press (default false) */
+    closeOnEscape?: boolean;
+    /** Whether the Action Sheet should be opened/closed with animation or not. Can be overwritten in .open() and .close() methods*/
+    animate?: boolean;
+    /** Action sheet groups/buttons. In this case Actions layout will be generated dynamically based on passed groups and buttons. In case of groups it should array where each item represent array with buttons for group.*/
+    buttons?: Button[] | Button[][];
+    /** Enables grid buttons layout*/
+    grid?: boolean;
+    /** When enabled, action sheet will be converted to Popover on large screens.*/
+    convertToPopover?: boolean;
+    /** When enabled, action sheet will be always converted to Popover.*/
+    forceToPopover?: boolean;
+    /** HTML element or string CSS selector of target element. Required when conversion to popover is in use*/
+    targetEl?: HTMLElement | CSSSelector;
+    /** Virtual target element horizontal offset from left side of the screen. Required when conversion to popover is in use without using real target element (targetEl)*/
+    targetX?: number;
+    /** Virtual target element vertical offset from top of the screen. Required when conversion to popover is in use without using real target element (targetEl)*/
+    targetY?: number;
+    /** Virtual target element width (in px). Required when conversion to popover is in use without using real target element (targetEl)*/
+    targetWidth?: number;
+    /** Virtual target element height (in px). Required when conversion to popover is in use without using real target element (targetEl)*/
+    targetHeight?: number;
+    /** Element to mount modal to. (default app.el) */
+    containerEl?: HTMLElement | CSSSelector;
+    /** Callback function that will be executed after click on the Action Sheet button*/
+    onClick?: (actions: Actions, e: unknown) => void;
+    /** Custom function to render Action Sheet. Must return Action Sheet html*/
+    render?: () => string;
+    /** Custom function to render Popover when conversion to popover is in use. Must return Popover html*/
+    renderPopover?: () => string;
+    /** Object with event handlers */
+    on?: {
+      [event in keyof Events]?: Events[event];
+    };
+  }
+
+  interface Events {
+    /** Event will be triggered when Action Sheet starts its opening animation. As an argument event handler receives action sheet instance */
+    open: (actions: Actions) => void;
+    /** Event will be triggered after Action Sheet completes its opening animation. As an argument event handler receives action sheet instance */
+    opened: (actions: Actions) => void;
+    /** Event will be triggered when Action Sheet starts its closing animation. As an argument event handler receives action sheet instance */
+    close: (actions: Actions) => void;
+    /** Event will be triggered after Action Sheet completes its closing animation. As an argument event handler receives action sheet instance */
+    closed: (actions: Actions) => void;
+    /** Event will be triggered right before Action Sheet instance will be destroyed. As an argument event handler receives action sheet instance */
+    beforeDestroy: (actions: Actions) => void;
+  }
+
+  interface DomEvents {
+    /** Event will be triggered when Action Sheet starts its opening animation */
+    'actions:open': (actions: Actions) => void;
+    /** Event will be triggered after Action Sheet completes its opening animation */
+    'actions:opened': (actions: Actions) => void;
+    /** Event will be triggered when Action Sheet starts its closing animation */
+    'actions:close': (actions: Actions) => void;
+    /** Event will be triggered after Action Sheet completes its closing animation */
+    'actions:closed': (actions: Actions) => void;
+  }
+
+  interface AppMethods {
+    actions: {
+      /** create Action Sheet instance */
+      create(parameters: Parameters): Actions;
+      /** destroy Action Sheet instance */
+      destroy(el: HTMLElement | CSSSelector | Actions): void;
+      /** get Action Sheet instance by HTML element */
+      get(el?: HTMLElement | CSSSelector): Actions;
+      /** opens Action Sheet */
+      open(el?: HTMLElement | CSSSelector, animate?: boolean): Actions;
+      /** closes Action Sheet */
+      close(el?: HTMLElement | CSSSelector, animate?: boolean): Actions;
+    };
+  }
+  interface AppParams {
+    actions?: Parameters | undefined;
+  }
+  interface AppEvents {
+    /** Event will be triggered when Action Sheet starts its opening animation. As an argument event handler receives action sheet instance */
+    actionsOpen: (actions: Actions) => void;
+    /** Event will be triggered after Action Sheet completes its opening animation. As an argument event handler receives action sheet instance */
+    actionsOpened: (actions: Actions) => void;
+    /** Event will be triggered when Action Sheet starts its closing animation. As an argument event handler receives action sheet instance */
+    actionsClose: (actions: Actions) => void;
+    /** Event will be triggered after Action Sheet completes its closing animation. As an argument event handler receives action sheet instance */
+    actionsClosed: (actions: Actions) => void;
+    /** Event will be triggered right before Action Sheet instance will be destroyed. As an argument event handler receives action sheet instance */
+    actionsBeforeDestroy: (actions: Actions) => void;
+  }
+}
+
+declare const ActionsComponent: Framework7Plugin;
+
+export default ActionsComponent;

+ 51 - 0
data/html/framework7/components/actions/actions.js

@@ -0,0 +1,51 @@
+import Actions from './actions-class.js';
+import ModalMethods from '../../shared/modal-methods.js';
+export default {
+  name: 'actions',
+  params: {
+    actions: {
+      convertToPopover: true,
+      forceToPopover: false,
+      backdrop: true,
+      backdropEl: undefined,
+      backdropUnique: false,
+      cssClass: null,
+      closeByBackdropClick: true,
+      closeOnEscape: false,
+      render: null,
+      renderPopover: null,
+      containerEl: null
+    }
+  },
+  static: {
+    Actions
+  },
+
+  create() {
+    const app = this;
+    app.actions = ModalMethods({
+      app,
+      constructor: Actions,
+      defaultSelector: '.actions-modal.modal-in'
+    });
+  },
+
+  clicks: {
+    '.actions-open': function openActions($clickedEl, data) {
+      if (data === void 0) {
+        data = {};
+      }
+
+      const app = this;
+      app.actions.open(data.actions, data.animate, $clickedEl);
+    },
+    '.actions-close': function closeActions($clickedEl, data) {
+      if (data === void 0) {
+        data = {};
+      }
+
+      const app = this;
+      app.actions.close(data.actions, data.animate, $clickedEl);
+    }
+  }
+};

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/actions/actions.lazy.js


+ 209 - 0
data/html/framework7/components/actions/actions.less

@@ -0,0 +1,209 @@
+/* === Actions === */
+@import './actions-vars.less';
+.actions-backdrop {
+  &-unique {
+    z-index: 13500;
+  }
+}
+.actions-modal {
+  position: absolute;
+  left: 0;
+  bottom: 0;
+  z-index: 13500;
+  width: 100%;
+  transform: translate3d(0, 100%, 0);
+  display: none;
+  max-height: 100%;
+  .scrollable();
+  transition-property: transform;
+  will-change: transform;
+  &.modal-in,
+  &.modal-out {
+    transition-duration: 300ms;
+  }
+  &.not-animated {
+    transition-duration: 0ms;
+  }
+  &.modal-in {
+    transform: translate3d(0, calc(-1 * var(--f7-safe-area-bottom)), 0);
+  }
+  &.modal-out {
+    z-index: 13500 - 1;
+    transform: translate3d(0, 100%, 0);
+  }
+  @media (min-width: 496px) {
+    width: 480px;
+    left: 50%;
+    margin-left: -240px;
+  }
+  @media (orientation: landscape) {
+    --f7-actions-button-height: var(--f7-actions-button-height-landscape);
+  }
+}
+.actions-group {
+  overflow: hidden;
+  position: relative;
+  margin: var(--f7-actions-group-margin);
+  border-radius: var(--f7-actions-border-radius);
+  .hairline(bottom, var(--f7-actions-group-border-color));
+  transform: translate3d(0, 0, 0);
+  &:last-child {
+    .hairline-remove(bottom);
+  }
+}
+.actions-button,
+.actions-label {
+  width: 100%;
+  font-weight: normal;
+  margin: 0;
+  box-sizing: border-box;
+  display: block;
+  position: relative;
+  overflow: hidden;
+  text-align: var(--f7-actions-button-text-align);
+  background: var(--f7-actions-bg-color);
+  .ios-translucent-modals(var(--f7-actions-bg-color-rgb));
+  .hairline(bottom, var(--f7-actions-button-border-color));
+  &:first-child {
+    border-radius: var(--f7-actions-border-radius) var(--f7-actions-border-radius) 0 0;
+  }
+  &:last-child {
+    .hairline-remove(bottom);
+    border-radius: 0 0 var(--f7-actions-border-radius) var(--f7-actions-border-radius);
+  }
+  &:first-child:last-child {
+    border-radius: var(--f7-actions-border-radius);
+  }
+  a {
+    text-decoration: none;
+    color: inherit;
+    display: block;
+  }
+  b,
+  &.actions-button-bold {
+    font-weight: 600;
+  }
+}
+.actions-button {
+  cursor: pointer;
+  display: flex;
+  color: var(--f7-actions-button-text-color, var(--f7-theme-color));
+  font-size: var(--f7-actions-button-font-size);
+  height: var(--f7-actions-button-height);
+  line-height: var(--f7-actions-button-height);
+  padding: var(--f7-actions-button-padding);
+  justify-content: var(--f7-actions-button-justify-content);
+  z-index: 10;
+  &.active-state {
+    background-color: var(--f7-actions-button-pressed-bg-color) !important;
+  }
+  &[class*='color-'] {
+    color: var(--f7-theme-color);
+  }
+}
+.actions-button.active-state {
+  .ios-translucent-modals(var(--f7-actions-button-pressed-bg-color-rgb));
+}
+
+.actions-button-media {
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  i.icon {
+    width: var(--f7-actions-button-icon-size);
+    height: var(--f7-actions-button-icon-size);
+    font-size: var(--f7-actions-button-icon-size);
+  }
+}
+.actions-button a,
+.actions-button-text {
+  position: relative;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.actions-button-text {
+  width: 100%;
+  flex-shrink: 1;
+  text-align: var(--f7-actions-button-text-align);
+}
+.actions-label {
+  line-height: 1.3;
+  display: flex;
+  align-items: center;
+  font-size: var(--f7-actions-label-font-size);
+  color: var(--f7-actions-label-text-color);
+  padding: var(--f7-actions-label-padding);
+  justify-content: var(--f7-actions-label-justify-content);
+  min-height: var(--f7-actions-label-min-height, var(--f7-actions-button-height));
+}
+.actions-label[class*=' color-'] {
+  --f7-actions-label-text-color: var(--f7-theme-color);
+}
+.actions-grid {
+  .actions-group {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: flex-start;
+    border-radius: 0;
+    background: var(--f7-actions-bg-color);
+    margin-top: 0;
+    &:first-child {
+      border-radius: var(--f7-actions-border-radius) var(--f7-actions-border-radius) 0 0;
+    }
+    &:last-child {
+      border-radius: 0 0 var(--f7-actions-border-radius) var(--f7-actions-border-radius);
+    }
+    &:first-child:last-child {
+      border-radius: var(--f7-actions-border-radius);
+    }
+    &:not(:last-child) {
+      margin-bottom: 0;
+    }
+  }
+  .actions-button,
+  .actions-label {
+    border-radius: 0 !important;
+    background: none;
+  }
+  .actions-button {
+    width: (100% / 3);
+    display: block;
+    color: var(--f7-actions-grid-button-text-color);
+    height: auto;
+    line-height: 1;
+    .hairline-remove(bottom);
+    padding: 16px;
+  }
+  .actions-button-media {
+    margin-left: auto !important;
+    margin-right: auto !important;
+    width: var(--f7-actions-grid-button-icon-size);
+    height: var(--f7-actions-grid-button-icon-size);
+    i.icon {
+      width: var(--f7-actions-grid-button-icon-size);
+      height: var(--f7-actions-grid-button-icon-size);
+      font-size: var(--f7-actions-grid-button-icon-size);
+    }
+  }
+  .actions-button-text {
+    margin-left: 0 !important;
+    text-align: center !important;
+    margin-top: 8px;
+    line-height: 1.33em;
+    height: 1.33em;
+    font-size: var(--f7-actions-grid-button-font-size);
+  }
+}
+.actions-grid .actions-group {
+  .ios-translucent-modals(var(--f7-actions-bg-color-rgb));
+}
+.if-ios-theme({
+  @import './actions-ios.less';
+});
+.if-md-theme({
+  @import './actions-md.less';
+});
+.if-aurora-theme({
+  @import './actions-aurora.less';
+});

+ 10 - 0
data/html/framework7/components/app/app-aurora.less

@@ -0,0 +1,10 @@
+.aurora {
+  .ios-only,
+  .if-ios,
+  .md-only,
+  .if-md,
+  .if-not-aurora,
+  .not-aurora {
+    display: none !important;
+  }
+}

+ 199 - 0
data/html/framework7/components/app/app-class.d.ts

@@ -0,0 +1,199 @@
+import { Dom7, Dom7Array } from 'dom7';
+import { Router } from '../../modules/router/router.js';
+import { DeviceParams, Device } from '../../shared/get-device.js';
+import { Support } from '../../shared/get-support.js';
+import { Request } from '../../shared/request.js';
+import { Utils } from '../../shared/utils.js';
+import {
+  ComponentClass,
+  ComponentFunction as Component,
+} from '../../modules/component/component.js';
+import { StoreObject, StoreParameters } from '../../modules/store/store.js';
+
+// Css Selector string is an option on many F7 methods
+// Giving this alias makes the typename show in the intellisense
+// instead of just `string`.
+export interface CSSSelector extends String {}
+
+export interface Framework7Class<Events> {
+  /** Add event handler */
+  on<E extends keyof Events>(event: E, handler: Events[E]): void;
+  /** Add event handler that will be removed after it was fired */
+  once<E extends keyof Events>(event: E, handler: Events[E]): void;
+  /** Remove event handler */
+  off<E extends keyof Events>(event: E, handler: Events[E]): void;
+  /** Remove all handlers for specified event */
+  off<E extends keyof Events>(event: E): void;
+  /** Fire event on instance */
+  emit<E extends keyof Events>(event: E, ...args: any[]): void;
+}
+
+export interface Framework7EventsClass<Events> {
+  /** Add event handler */
+  on<E extends keyof Events>(event: E, handler: Events[E]): void;
+  /** Add event handler that will be removed after it was fired */
+  once<E extends keyof Events>(event: E, handler: Events[E]): void;
+  /** Remove event handler */
+  off<E extends keyof Events>(event: E, handler: Events[E]): void;
+  /** Remove all handlers for specified event */
+  off<E extends keyof Events>(event: E): void;
+  /** Fire event on instance */
+  emit<E extends keyof Events>(event: E, ...args: any[]): void;
+}
+
+export interface Framework7Parameters {
+  /** App root element. If you main app layout is not a direct child of the <body> then it is required to specify root element here. (default body) */
+  el?: string;
+  /** App bundle id.. (default io.framework7.testapp) */
+  id?: string | 'io.framework7.testapp';
+  /** App name. Can be used by other components, e.g. as the default title for Dialog component.. (default Framework7) */
+  name?: string;
+  /** App version. Can be used by other components.. (default 1.0.0) */
+  version?: string;
+  /** App theme. Can be ios, md, aurora or auto. In case of auto it will use iOS theme for iOS devices, Aurora theme for desktop device running in Electron environment, and MD theme for all other devices.. (default auto) */
+  theme?: string;
+  /** App language. Can be used by other components. By default equal to the current browser/webview language (i.e. navigator.language).. */
+  language?: string;
+  /** Array with default routes to all views.. (default []) */
+  routes?: Router.RouteParameters[];
+  /** Enables auto dark mode */
+  autoDarkMode?: boolean;
+  /** Lazy modules path */
+  lazyModulesPath?: string;
+  /** By default Framework7 will be initialized automatically when you call new Framework7(). If you want to prevent this behavior you can disable it with this option and then initialize it manually with init() when you need it.. (default true) */
+  init?: boolean;
+  /** If automatic initialization is enabled with init: true parameter and app is running under cordova environment then it will be initialized on deviceready event.. (default true) */
+  initOnDeviceReady?: boolean;
+  /** Enable translucent effect (blur background) on navigation bars for iOS theme (on iOS devices) (by default enabled) */
+  iosTranslucentBars?: boolean;
+  /** Enable translucent effect (blur background) on modals (Dialog, Popover, Actions) for iOS theme (on iOS devices) (by default enabled) */
+  iosTranslucentModals?: boolean;
+  /** userAgent string. Required for browser/device detection when rendered on server-side */
+  userAgent?: string;
+  /** Required for current route detection when rendered on server-side */
+  url?: string;
+  /** Object with events handlers.. (default {}) */
+  on?: {
+    [event in keyof Framework7Events]?: Framework7Events[event];
+  };
+}
+
+export interface Framework7Plugin {
+  /** Module Name */
+  name: string;
+  /** Install callback
+  It will be executed right after component is installed
+  Context of this callback points to Class where it was installed */
+  install: () => void;
+  /** Create callback
+  It will be executed in the very beginning of class initilization (when we create new instance of the class) */
+  create(instance: Framework7): () => void;
+  /** Object with default class/plugin parameters */
+  params?: {
+    [plugin_name: string]: {
+      [param: string]: any;
+    };
+  };
+  /** proto object extends Class prototype */
+  proto?: {
+    [name: string]: any;
+  };
+  /** Extend Class with static props and methods, e.g. Class.myMethod */
+  static?: {
+    [name: string]: any;
+  };
+  /** Initialized instance Props & Methods */
+  instance?: {
+    [name: string]: any;
+  };
+  /** Event handlers */
+  on?: {
+    [event: string]: (...params: any[]) => void;
+  };
+  /** Handle clicks - prop name means CSS selector of element to add click handler */
+  clicks?: {
+    [selector: string]: ($clickedEl: HTMLElement, data: any) => void;
+  };
+}
+
+export interface Framework7Events {
+  /** Event will be fired on app initialization. Automatically after new Framework7() or after app.init() if you disabled auto init. */
+  init: () => void;
+  /** Event will be fired on device preferred color scheme change. It has effect only when `autoDarkMode` enabled */
+  darkModeChange: (isDark: boolean) => void;
+  /** Event will be fired when app goes online */
+  online: () => void;
+  /** Event will be fired when app goes offline */
+  offline: () => void;
+  /** Event will be fired on network state change */
+  connection: (isOnline: boolean) => void;
+}
+
+interface Framework7 extends Framework7Class<Framework7Events> {
+  /** App ID passed in parameters */
+  id: string;
+  /** App name passed in parameters */
+  name: string;
+  /** App version */
+  version: string;
+  /** App routes */
+  routes: Router.RouteParameters[];
+  /** App language */
+  language: string;
+  /** App root HTML element */
+  el: HTMLElement;
+  /** Dom7 instance with app root element */
+  $el: Dom7Array;
+  /** Boolean property indicating app is in RTL layout or not */
+  rtl: boolean;
+  /** Current app theme. Can be md, ios or aurora */
+  theme: string;
+  /** Indicates whether the dark mode active or not. This property has effect only when `autoDarkMode` enabled */
+  darkMode: boolean;
+  /** Object with app root data passed on intialization */
+  data: any;
+  /** Object with app root methods */
+  methods: { [name: string]: () => any };
+  /** Boolean property indicating app is initialized or not */
+  initialized: boolean;
+  /** Boolean property indication app connection state. (`true` if online) */
+  online: boolean;
+  /** Dom7 alias */
+  $: Dom7;
+  /** App parameters */
+  params: Framework7Parameters;
+  /** Enables auto dark mode detection */
+  enableAutoDarkMode(): void;
+  /** Disables auto dark mode detection */
+  disableAutoDarkMode(): void;
+  /** Initialize app. In case you disabled auto initialization with init: false parameter */
+  init(): void;
+  /** Load module */
+  loadModule(module: string | Function | Framework7Plugin): Promise<any>;
+  /** Load modules */
+  loadModules(modules: any[]): Promise<any>;
+}
+interface Events extends Framework7EventsClass<Framework7Events> {}
+
+declare class Framework7 implements Framework7 {
+  constructor(parameters?: Framework7Parameters);
+
+  static use(plugin: Framework7Plugin): void;
+  static use(plugins: Framework7Plugin[]): void;
+  static getDevice: (overrides?: DeviceParams) => Device;
+  static getSupport: () => Support;
+  static device: Device;
+  static support: Support;
+  static request: Request;
+  static utils: Utils;
+  static Events: Events;
+  static Component: ComponentClass;
+  /** Register custom component */
+  static registerComponent(tagName: string, component: Component): void;
+  /** Unregister custom component */
+  static unregisterComponent(tagName: string): void;
+  /** Create new store */
+  createStore: (storeParameters: StoreParameters) => StoreObject;
+}
+
+export default Framework7;

+ 337 - 0
data/html/framework7/components/app/app-class.js

@@ -0,0 +1,337 @@
+/* eslint-disable no-underscore-dangle */
+import { getWindow, getDocument } from 'ssr-window';
+import { extend, nextFrame } from '../../shared/utils.js';
+import { getDevice } from '../../shared/get-device.js';
+import { getSupport } from '../../shared/get-support.js';
+import Framework7Class from '../../shared/class.js';
+import EventsClass from '../../shared/events-class.js';
+import ConstructorMethods from '../../shared/constructor-methods.js';
+import ModalMethods from '../../shared/modal-methods.js';
+import $ from '../../shared/dom7.js';
+import loadModule from './load-module.js';
+import $jsx from '../../shared/$jsx.js';
+
+class Framework7 extends Framework7Class {
+  constructor(params) {
+    if (params === void 0) {
+      params = {};
+    }
+
+    super(params); // eslint-disable-next-line
+
+    if (Framework7.instance && typeof window !== 'undefined') {
+      throw new Error("Framework7 is already initialized and can't be initialized more than once");
+    }
+
+    const device = getDevice({
+      userAgent: params.userAgent || undefined
+    });
+    const support = getSupport();
+    const passedParams = extend({}, params); // App Instance
+
+    const app = this;
+    app.device = device;
+    app.support = support;
+    const w = getWindow();
+    const d = getDocument();
+    Framework7.instance = app; // Default
+
+    const defaults = {
+      version: '1.0.0',
+      id: 'io.framework7.myapp',
+      el: 'body',
+      theme: 'auto',
+      language: w.navigator.language,
+      routes: [],
+      name: 'Framework7',
+      lazyModulesPath: null,
+      initOnDeviceReady: true,
+      init: true,
+      autoDarkMode: false,
+      iosTranslucentBars: true,
+      iosTranslucentModals: true,
+      component: undefined,
+      componentUrl: undefined,
+      userAgent: null,
+      url: null
+    }; // Extend defaults with modules params
+
+    app.useModulesParams(defaults); // Extend defaults with passed params
+
+    app.params = extend(defaults, params);
+    extend(app, {
+      // App Id
+      id: app.params.id,
+      // App Name
+      name: app.params.name,
+      // App version
+      version: app.params.version,
+      // Routes
+      routes: app.params.routes,
+      // Lang
+      language: app.params.language,
+      // Theme
+      theme: function getTheme() {
+        if (app.params.theme === 'auto') {
+          if (device.ios) return 'ios';
+          if (device.desktop && device.electron) return 'aurora';
+          return 'md';
+        }
+
+        return app.params.theme;
+      }(),
+      // Initially passed parameters
+      passedParams,
+      online: w.navigator.onLine
+    });
+    if (params.store) app.params.store = params.store; // Save Root
+
+    if (app.$el && app.$el[0]) {
+      app.$el[0].f7 = app;
+    } // Install Modules
+
+
+    app.useModules(); // Init Store
+
+    app.initStore(); // Init
+
+    if (app.params.init) {
+      if (device.cordova && app.params.initOnDeviceReady) {
+        $(d).on('deviceready', () => {
+          app.init();
+        });
+      } else {
+        app.init();
+      }
+    } // Return app instance
+
+
+    return app;
+  }
+
+  mount(rootEl) {
+    const app = this;
+    const window = getWindow();
+    const document = getDocument();
+    const $rootEl = $(rootEl || app.params.el).eq(0);
+    app.$el = $rootEl;
+
+    if (app.$el && app.$el[0]) {
+      app.el = app.$el[0];
+      app.el.f7 = app;
+      app.rtl = $rootEl.css('direction') === 'rtl';
+    } // Auto Dark Mode
+
+
+    const DARK = '(prefers-color-scheme: dark)';
+    const LIGHT = '(prefers-color-scheme: light)';
+    app.mq = {};
+
+    if (window.matchMedia) {
+      app.mq.dark = window.matchMedia(DARK);
+      app.mq.light = window.matchMedia(LIGHT);
+    }
+
+    app.colorSchemeListener = function colorSchemeListener(_ref) {
+      let {
+        matches,
+        media
+      } = _ref;
+
+      if (!matches) {
+        return;
+      }
+
+      const html = document.querySelector('html');
+
+      if (media === DARK) {
+        html.classList.add('dark');
+        app.darkMode = true;
+        app.emit('darkModeChange', true);
+      } else if (media === LIGHT) {
+        html.classList.remove('dark');
+        app.darkMode = false;
+        app.emit('darkModeChange', false);
+      }
+    };
+
+    app.emit('mount');
+  }
+
+  initStore() {
+    const app = this;
+
+    if (typeof app.params.store !== 'undefined' && app.params.store.__store) {
+      app.store = app.params.store;
+    } else {
+      app.store = app.createStore(app.params.store);
+    }
+  }
+
+  enableAutoDarkMode() {
+    const window = getWindow();
+    const document = getDocument();
+    if (!window.matchMedia) return;
+    const app = this;
+    const html = document.querySelector('html');
+
+    if (app.mq.dark && app.mq.light) {
+      app.mq.dark.addListener(app.colorSchemeListener);
+      app.mq.light.addListener(app.colorSchemeListener);
+    }
+
+    if (app.mq.dark && app.mq.dark.matches) {
+      html.classList.add('dark');
+      app.darkMode = true;
+      app.emit('darkModeChange', true);
+    } else if (app.mq.light && app.mq.light.matches) {
+      html.classList.remove('dark');
+      app.darkMode = false;
+      app.emit('darkModeChange', false);
+    }
+  }
+
+  disableAutoDarkMode() {
+    const window = getWindow();
+    if (!window.matchMedia) return;
+    const app = this;
+    if (app.mq.dark) app.mq.dark.removeListener(app.colorSchemeListener);
+    if (app.mq.light) app.mq.light.removeListener(app.colorSchemeListener);
+  }
+
+  initAppComponent(callback) {
+    const app = this;
+    app.router.componentLoader(app.params.component, app.params.componentUrl, {
+      componentOptions: {
+        el: app.$el[0]
+      }
+    }, el => {
+      app.$el = $(el);
+      app.$el[0].f7 = app;
+      app.$elComponent = el.f7Component;
+      app.el = app.$el[0];
+      if (callback) callback();
+    }, () => {});
+  }
+
+  init(rootEl) {
+    const app = this;
+    app.mount(rootEl);
+
+    const init = () => {
+      if (app.initialized) return;
+      app.$el.addClass('framework7-initializing'); // RTL attr
+
+      if (app.rtl) {
+        $('html').attr('dir', 'rtl');
+      } // Auto Dark Mode
+
+
+      if (app.params.autoDarkMode) {
+        app.enableAutoDarkMode();
+      } // Watch for online/offline state
+
+
+      const window = getWindow();
+      window.addEventListener('offline', () => {
+        app.online = false;
+        app.emit('offline');
+        app.emit('connection', false);
+      });
+      window.addEventListener('online', () => {
+        app.online = true;
+        app.emit('online');
+        app.emit('connection', true);
+      }); // Root class
+
+      app.$el.addClass('framework7-root'); // Theme class
+
+      $('html').removeClass('ios md aurora').addClass(app.theme); // iOS Translucent
+
+      const device = app.device;
+
+      if (app.params.iosTranslucentBars && app.theme === 'ios' && device.ios) {
+        $('html').addClass('ios-translucent-bars');
+      }
+
+      if (app.params.iosTranslucentModals && app.theme === 'ios' && device.ios) {
+        $('html').addClass('ios-translucent-modals');
+      } // Init class
+
+
+      nextFrame(() => {
+        app.$el.removeClass('framework7-initializing');
+      }); // Emit, init other modules
+
+      app.initialized = true;
+      app.emit('init');
+    };
+
+    if (app.params.component || app.params.componentUrl) {
+      app.initAppComponent(() => {
+        init();
+      });
+    } else {
+      init();
+    }
+
+    return app;
+  } // eslint-disable-next-line
+
+
+  loadModule() {
+    return Framework7.loadModule(...arguments);
+  } // eslint-disable-next-line
+
+
+  loadModules() {
+    return Framework7.loadModules(...arguments);
+  }
+
+  getVnodeHooks(hook, id) {
+    const app = this;
+    if (!app.vnodeHooks || !app.vnodeHooks[hook]) return [];
+    return app.vnodeHooks[hook][id] || [];
+  } // eslint-disable-next-line
+
+
+  get $() {
+    return $;
+  }
+
+  static get Dom7() {
+    return $;
+  }
+
+  static get $() {
+    return $;
+  }
+
+  static get device() {
+    return getDevice();
+  }
+
+  static get support() {
+    return getSupport();
+  }
+
+  static get Class() {
+    return Framework7Class;
+  }
+
+  static get Events() {
+    return EventsClass;
+  }
+
+}
+
+Framework7.$jsx = $jsx;
+Framework7.ModalMethods = ModalMethods;
+Framework7.ConstructorMethods = ConstructorMethods;
+Framework7.loadModule = loadModule;
+
+Framework7.loadModules = function loadModules(modules) {
+  return Promise.all(modules.map(module => Framework7.loadModule(module)));
+};
+
+export default Framework7;

+ 25 - 0
data/html/framework7/components/app/app-ios.less

@@ -0,0 +1,25 @@
+.ios {
+  .md-only,
+  .if-md,
+  .aurora-only,
+  .if-aurora,
+  .if-not-ios,
+  .not-ios {
+    display: none !important;
+  }
+  // Fix for iPad in Safari in Lanscape mode
+  @media (width: 1024px) and (height: 691px) and (orientation: landscape) {
+    &,
+    & body,
+    & .framework7-root {
+      height: 671px;
+    }
+  }
+  @media (width: 1024px) and (height: 692px) and (orientation: landscape) {
+    &,
+    & body,
+    & .framework7-root {
+      height: 672px;
+    }
+  }
+}

+ 10 - 0
data/html/framework7/components/app/app-md.less

@@ -0,0 +1,10 @@
+.md {
+  .ios-only,
+  .if-ios,
+  .aurora-only,
+  .if-aurora,
+  .if-not-md,
+  .not-md {
+    display: none !important;
+  }
+}

+ 205 - 0
data/html/framework7/components/app/app-vars.less

@@ -0,0 +1,205 @@
+/*====================
+  Core
+  ==================== */
+:root {
+  @themeColorRed: red(@themeColor);
+  @themeColorGreen: green(@themeColor);
+  @themeColorBlue: blue(@themeColor);
+  --f7-theme-color: @themeColor;
+  --f7-theme-color-rgb: @themeColorRed, @themeColorGreen, @themeColorBlue;
+  --f7-theme-color-shade: darken(@themeColor, 8%);
+  --f7-theme-color-tint: lighten(@themeColor, 8%);
+
+  --f7-safe-area-left: 0px;
+  --f7-safe-area-right: 0px;
+  --f7-safe-area-top: 0px;
+  --f7-safe-area-bottom: 0px;
+
+  --f7-safe-area-outer-left: 0px;
+  --f7-safe-area-outer-right: 0px;
+
+  @supports (left: env(safe-area-inset-left)) {
+    --f7-safe-area-top: env(safe-area-inset-top);
+    --f7-safe-area-bottom: env(safe-area-inset-bottom);
+    .ios-left-edge,
+    .ios-edges,
+    .safe-area-left,
+    .safe-areas,
+    .popup,
+    .sheet-modal,
+    .panel-left {
+      --f7-safe-area-left: env(safe-area-inset-left);
+      --f7-safe-area-outer-left: env(safe-area-inset-left);
+    }
+    .ios-right-edge,
+    .ios-edges,
+    .safe-area-right,
+    .safe-areas,
+    .popup,
+    .sheet-modal,
+    .panel-right {
+      --f7-safe-area-right: env(safe-area-inset-right);
+      --f7-safe-area-outer-right: env(safe-area-inset-right);
+    }
+    .no-safe-areas,
+    .no-safe-area-left,
+    .no-ios-edges,
+    .no-ios-left-edge {
+      --f7-safe-area-left: 0px;
+      --f7-safe-area-outer-left: 0px;
+    }
+    .no-safe-areas,
+    .no-safe-area-right,
+    .no-ios-edges,
+    .no-ios-right-edge {
+      --f7-safe-area-right: 0px;
+      --f7-safe-area-outer-right: 0px;
+    }
+  }
+
+  --f7-device-pixel-ratio: 1;
+  @media (min-resolution: 2dppx) {
+    --f7-device-pixel-ratio: 2;
+  }
+  @media (min-resolution: 3dppx) {
+    --f7-device-pixel-ratio: 3;
+  }
+}
+/*====================
+  Fonts & Bars
+  ==================== */
+:root {
+  --f7-font-size: 14px;
+  /*
+  --f7-bars-link-color: var(--f7-theme-color);
+  */
+  --f7-bars-bg-image: none;
+  --f7-bars-translucent-opacity: 0.8;
+  --f7-bars-translucent-blur: 20px;
+  --f7-bars-shadow-bottom-image: linear-gradient(
+    to bottom,
+    rgba(0, 0, 0, 0.25) 0%,
+    rgba(0, 0, 0, 0.08) 40%,
+    rgba(0, 0, 0, 0.04) 50%,
+    rgba(0, 0, 0, 0) 90%,
+    rgba(0, 0, 0, 0) 100%
+  );
+  --f7-bars-shadow-top-image: linear-gradient(
+    to top,
+    rgba(0, 0, 0, 0.25) 0%,
+    rgba(0, 0, 0, 0.08) 40%,
+    rgba(0, 0, 0, 0.04) 50%,
+    rgba(0, 0, 0, 0) 90%,
+    rgba(0, 0, 0, 0) 100%
+  );
+  .light-vars({
+    --f7-bars-text-color: #000;
+    --f7-bars-bg-color: #f7f7f8;
+    --f7-bars-bg-color-rgb: 247, 247, 248;
+  });
+  .dark-vars({
+    --f7-bars-text-color: #fff;
+  });
+}
+.ios-vars({
+  --f7-font-family: -apple-system, SF Pro Text, SF UI Text, system-ui, Helvetica Neue, Helvetica, Arial, sans-serif;
+  --f7-line-height: 1.4;
+  .light-vars({
+    --f7-text-color: #000;
+    --f7-bars-border-color: rgba(0,0,0,0.25);
+  });
+  .dark-vars({
+    --f7-text-color: #fff;
+    --f7-bars-bg-color: #121212;
+    --f7-bars-bg-color-rgb: 22, 22, 22;
+    --f7-bars-border-color: rgba(255,255,255,0.16);
+  });
+});
+.md-vars({
+  --f7-font-family: Roboto, system-ui, Noto, Helvetica, Arial, sans-serif;
+  --f7-line-height: 1.5;
+  --f7-bars-border-color: transparent;
+  .light-vars({
+    --f7-text-color: #212121;
+  });
+  .dark-vars({
+    --f7-text-color: rgba(255,255,255,0.87);
+    --f7-bars-bg-color: #202020;
+  });
+});
+.aurora-vars({
+  --f7-font-family: -apple-system, system-ui, Helvetica, Arial, sans-serif;
+  --f7-line-height: 1.5;
+  .light-vars({
+    --f7-text-color: #000;
+    --f7-bars-border-color: rgba(0,0,0,0.2);
+  });
+  .dark-vars({
+    --f7-text-color: #fff;
+    --f7-bars-bg-color: #202020;
+    --f7-bars-border-color: rgba(255, 255, 255, 0.1);
+  });
+});
+
+/*====================
+  Color Themes
+  ==================== */
+.color-primary {
+}
+.text-color-primary {
+  --f7-theme-color-text-color: var(--f7-theme-color);
+}
+.bg-color-primary {
+  --f7-theme-color-bg-color: var(--f7-theme-color);
+}
+.border-color-primary {
+  --f7-theme-color-border-color: var(--f7-theme-color);
+}
+.ripple-color-primary {
+  --f7-theme-color-ripple-color: rgba(var(--f7-theme-color-rgb), 0.3);
+}
+:root {
+  each(@colors, {
+    @themeColorRed: red(@value);
+    @themeColorGreen: green(@value);
+    @themeColorBlue: blue(@value);
+    --f7-color-@{key}: @value;
+    --f7-color-@{key}-rgb: @themeColorRed, @themeColorGreen, @themeColorBlue;
+    --f7-color-@{key}-shade: darken(@value, 8%);
+    --f7-color-@{key}-tint: lighten(@value, 8%);
+  });
+}
+each(@colors, {
+  .color-theme-@{key} {
+    @themeColorRed: red(@value);
+    @themeColorGreen: green(@value);
+    @themeColorBlue: blue(@value);
+    --f7-theme-color: @value;
+    --f7-theme-color-rgb: @themeColorRed, @themeColorGreen, @themeColorBlue;
+    --f7-theme-color-shade: darken(@value, 8%);
+    --f7-theme-color-tint: lighten(@value, 8%);
+  }
+});
+each(@colors, {
+  @themeColorRed: red(@value);
+  @themeColorGreen: green(@value);
+  @themeColorBlue: blue(@value);
+  .color-@{key} {
+    --f7-theme-color: @value;
+    --f7-theme-color-rgb: @themeColorRed, @themeColorGreen, @themeColorBlue;
+    --f7-theme-color-shade: darken(@value, 8%);
+    --f7-theme-color-tint: lighten(@value, 8%);
+  }
+  .text-color-@{key} {
+    --f7-theme-color-text-color: @value;
+  }
+  .bg-color-@{key} {
+    --f7-theme-color-bg-color: @value;
+  }
+  .border-color-@{key} {
+    --f7-theme-color-border-color: @value;
+  }
+  .ripple-color-@{key}, .ripple-@{key} {
+    --f7-theme-color-ripple-color: rgba(@themeColorRed, @themeColorGreen, @themeColorBlue, 0.3);
+  }
+});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3 - 0
data/html/framework7/components/app/app.less


+ 144 - 0
data/html/framework7/components/app/load-module.js

@@ -0,0 +1,144 @@
+import { getWindow, getDocument } from 'ssr-window';
+import { id } from '../../shared/utils.js';
+import $ from '../../shared/dom7.js';
+const fetchedModules = [];
+
+function loadModule(moduleToLoad) {
+  const Framework7 = this;
+  const window = getWindow();
+  const document = getDocument();
+  return new Promise((resolve, reject) => {
+    const app = Framework7.instance;
+    let modulePath;
+    let moduleObj;
+    let moduleFunc;
+
+    if (!moduleToLoad) {
+      reject(new Error('Framework7: Lazy module must be specified'));
+      return;
+    }
+
+    function install(module) {
+      Framework7.use(module);
+
+      if (app) {
+        app.useModuleParams(module, app.params);
+        app.useModule(module);
+      }
+    }
+
+    if (typeof moduleToLoad === 'string') {
+      const matchNamePattern = moduleToLoad.match(/([a-z0-9-]*)/i);
+
+      if (moduleToLoad.indexOf('.') < 0 && matchNamePattern && matchNamePattern[0].length === moduleToLoad.length) {
+        if (!app || app && !app.params.lazyModulesPath) {
+          reject(new Error('Framework7: "lazyModulesPath" app parameter must be specified to fetch module by name'));
+          return;
+        }
+
+        modulePath = `${app.params.lazyModulesPath}/${moduleToLoad}/${moduleToLoad}.lazy.js`;
+      } else {
+        modulePath = moduleToLoad;
+      }
+    } else if (typeof moduleToLoad === 'function') {
+      moduleFunc = moduleToLoad;
+    } else {
+      // considering F7-Plugin object
+      moduleObj = moduleToLoad;
+    }
+
+    if (moduleFunc) {
+      const module = moduleFunc(Framework7, false);
+
+      if (!module) {
+        reject(new Error("Framework7: Can't find Framework7 component in specified component function"));
+        return;
+      } // Check if it was added
+
+
+      if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
+        resolve();
+        return;
+      } // Install It
+
+
+      install(module);
+      resolve();
+    }
+
+    if (moduleObj) {
+      const module = moduleObj;
+
+      if (!module) {
+        reject(new Error("Framework7: Can't find Framework7 component in specified component"));
+        return;
+      } // Check if it was added
+
+
+      if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
+        resolve();
+        return;
+      } // Install It
+
+
+      install(module);
+      resolve();
+    }
+
+    if (modulePath) {
+      if (fetchedModules.indexOf(modulePath) >= 0) {
+        resolve();
+        return;
+      }
+
+      fetchedModules.push(modulePath);
+      const scriptLoad = new Promise((resolveScript, rejectScript) => {
+        Framework7.request.get(modulePath, scriptContent => {
+          const callbackId = id();
+          const callbackLoadName = `f7_component_loader_callback_${callbackId}`;
+          const scriptEl = document.createElement('script');
+          scriptEl.innerHTML = `window.${callbackLoadName} = function (Framework7, Framework7AutoInstallComponent) {return ${scriptContent.trim()}}`;
+          $('head').append(scriptEl);
+          const componentLoader = window[callbackLoadName];
+          delete window[callbackLoadName];
+          $(scriptEl).remove();
+          const module = componentLoader(Framework7, false);
+
+          if (!module) {
+            rejectScript(new Error(`Framework7: Can't find Framework7 component in ${modulePath} file`));
+            return;
+          } // Check if it was added
+
+
+          if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
+            resolveScript();
+            return;
+          } // Install It
+
+
+          install(module);
+          resolveScript();
+        }, (xhr, status) => {
+          rejectScript(xhr, status);
+        });
+      });
+      const styleLoad = new Promise(resolveStyle => {
+        Framework7.request.get(modulePath.replace('.lazy.js', app.rtl ? '.rtl.css' : '.css').replace('.js', app.rtl ? '.rtl.css' : '.css'), styleContent => {
+          const styleEl = document.createElement('style');
+          styleEl.innerHTML = styleContent;
+          $('head').append(styleEl);
+          resolveStyle();
+        }, () => {
+          resolveStyle();
+        });
+      });
+      Promise.all([scriptLoad, styleLoad]).then(() => {
+        resolve();
+      }).catch(err => {
+        reject(err);
+      });
+    }
+  });
+}
+
+export default loadModule;

+ 2 - 0
data/html/framework7/components/appbar/appbar-aurora.less

@@ -0,0 +1,2 @@
+.aurora {
+}

+ 2 - 0
data/html/framework7/components/appbar/appbar-ios.less

@@ -0,0 +1,2 @@
+.ios {
+}

+ 2 - 0
data/html/framework7/components/appbar/appbar-md.less

@@ -0,0 +1,2 @@
+.md {
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/appbar/appbar-rtl.css


+ 28 - 0
data/html/framework7/components/appbar/appbar-vars.less

@@ -0,0 +1,28 @@
+:root {
+  /*
+  --f7-appbar-offset: var(--f7-appbar-height);
+  --f7-appbar-extra-offset: 0px;
+  --f7-appbar-bg-color: var(--f7-bars-bg-color);
+  --f7-appbar-bg-color-rgb: var(--f7-bars-bg-color-rgb);
+  --f7-appbar-bg-image: var(--f7-bars-bg-image);
+  --f7-appbar-border-color: var(--f7-bars-border-color);
+  --f7-appbar-link-color: var(--f7-bars-link-color);
+  --f7-appbar-text-color: var(--f7-bars-text-color);
+  */
+  --f7-appbar-shadow-image: none;
+}
+.ios-vars({
+  --f7-appbar-height: 44px;
+  --f7-appbar-inner-padding-left: 8px;
+  --f7-appbar-inner-padding-right: 8px;
+});
+.md-vars({
+  --f7-appbar-height: 48px;
+  --f7-appbar-inner-padding-left: 16px;
+  --f7-appbar-inner-padding-right: 16px;
+});
+.aurora-vars({
+  --f7-appbar-height: 64px;
+  --f7-appbar-inner-padding-left: 16px;
+  --f7-appbar-inner-padding-right: 16px;
+});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/appbar/appbar.css


+ 14 - 0
data/html/framework7/components/appbar/appbar.d.ts

@@ -0,0 +1,14 @@
+import Framework7, {
+  CSSSelector,
+  Framework7EventsClass,
+  Framework7Plugin,
+} from '../app/app-class.js';
+
+export namespace Appbar {
+  interface AppMethods {}
+  interface AppParams {}
+  interface AppEvents {}
+}
+
+declare const AppbarComponent: Framework7Plugin;
+export default AppbarComponent;

+ 3 - 0
data/html/framework7/components/appbar/appbar.js

@@ -0,0 +1,3 @@
+export default {
+  name: 'appbar'
+};

+ 1 - 0
data/html/framework7/components/appbar/appbar.lazy.js

@@ -0,0 +1 @@
+(function framework7ComponentLoader(e,o){void 0===o&&(o=!0);e.$,e.utils,e.getDevice,e.getSupport,e.Class,e.Modal,e.ConstructorMethods,e.ModalMethods,e.$jsx;var t={name:"appbar"};if(o){if(e.prototype.modules&&e.prototype.modules[t.name])return;e.use(t),e.instance&&(e.instance.useModuleParams(t,e.instance.params),e.instance.useModule(t))}return t}(Framework7, typeof Framework7AutoInstallComponent === 'undefined' ? undefined : Framework7AutoInstallComponent))

+ 106 - 0
data/html/framework7/components/appbar/appbar.less

@@ -0,0 +1,106 @@
+/* === Appbar === */
+@import './appbar-vars.less';
+
+.appbar {
+  position: relative;
+  left: 0;
+  top: 0;
+  width: 100%;
+  z-index: 500;
+  backface-visibility: hidden;
+  box-sizing: border-box;
+  margin: 0;
+  transform: translate3d(0, 0, 0);
+  height: calc(var(--f7-appbar-height) + var(--f7-safe-area-top));
+  background-image: var(--f7-appbar-bg-image, var(--f7-bars-bg-image));
+  background-color: var(--f7-appbar-bg-color, var(--f7-bars-bg-color));
+  color: var(--f7-appbar-text-color, var(--f7-bars-text-color));
+  font-size: var(--f7-appbar-font-size);
+  z-index: 7000;
+  .ios-translucent-bars(var(--f7-appbar-bg-color-rgb, var(--f7-bars-bg-color-rgb)));
+  .panel ~ .appbar {
+    z-index: 5500;
+  }
+  a {
+    color: var(--f7-appbar-link-color, var(--f7-bars-link-color, var(--f7-theme-color)));
+  }
+  a.link {
+    display: flex;
+    justify-content: flex-start;
+    line-height: var(--f7-appbar-link-line-height, var(--f7-appbar-height));
+    height: var(--f7-appbar-link-height, var(--f7-appbar-height));
+  }
+  .left,
+  .center,
+  .right {
+    display: flex;
+    align-items: center;
+  }
+  &.no-hairline,
+  &.no-border {
+    &:after {
+      display: none !important;
+    }
+    .title-large:after {
+      display: none !important;
+    }
+  }
+  &.no-shadow {
+    &:before {
+      display: none !important;
+    }
+  }
+  &:after,
+  &:before {
+    backface-visibility: hidden;
+  }
+  .hairline(bottom, var(--f7-appbar-border-color, var(--f7-bars-border-color)));
+  .bar-shadow-bottom(var(--f7-appbar-shadow-image));
+  &:after {
+    z-index: 1;
+  }
+  & ~ * {
+    --f7-appbar-app-offset: calc(
+      var(--f7-appbar-height) + var(--f7-appbar-extra-offset, 0px) + var(--f7-safe-area-top)
+    );
+  }
+  & ~ .views,
+  & ~ .view,
+  & ~ .appbar {
+    --f7-safe-area-top: 0px;
+  }
+  & ~ .panel {
+    .view,
+    .page,
+    .page-content {
+      --f7-safe-area-top: 0px;
+    }
+  }
+}
+.appbar-inner {
+  position: absolute;
+  left: 0;
+  top: var(--f7-safe-area-top);
+  width: 100%;
+  height: var(--f7-appbar-height);
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  box-sizing: border-box;
+  padding: 0 calc(var(--f7-appbar-inner-padding-right) + var(--f7-safe-area-right)) 0
+    calc(var(--f7-appbar-inner-padding-left) + var(--f7-safe-area-left));
+
+  &.stacked {
+    display: none;
+  }
+}
+
+.if-ios-theme({
+  @import './appbar-ios.less';
+});
+.if-md-theme({
+  @import './appbar-md.less';
+});
+.if-aurora-theme({
+  @import './appbar-aurora.less';
+});

+ 2 - 0
data/html/framework7/components/area-chart/area-chart-aurora.less

@@ -0,0 +1,2 @@
+.aurora {
+}

+ 523 - 0
data/html/framework7/components/area-chart/area-chart-class.js

@@ -0,0 +1,523 @@
+import $ from '../../shared/dom7.js';
+import { extend, deleteProps } from '../../shared/utils.js';
+import Framework7Class from '../../shared/class.js';
+/** @jsx $jsx */
+
+import $jsx from '../../shared/$jsx.js';
+
+class AreaChart extends Framework7Class {
+  constructor(app, params) {
+    if (params === void 0) {
+      params = {};
+    }
+
+    super(params, [app]);
+    const self = this;
+    const defaults = extend({}, app.params.areaChart); // Extend defaults with modules params
+
+    self.useModulesParams(defaults);
+    self.params = extend(defaults, params);
+    const {
+      el
+    } = self.params;
+    if (!el) return self;
+    const $el = $(el);
+    if ($el.length === 0) return self;
+    if ($el[0].f7AreaChart) return $el[0].f7AreaChart;
+    extend(self, {
+      app,
+      $el,
+      el: $el && $el[0],
+      currentIndex: null,
+      hiddenDatasets: [],
+      f7Tooltip: null,
+      linesOffsets: null
+    });
+    $el[0].f7AreaChart = self; // Install Modules
+
+    self.useModules();
+    self.onMouseEnter = self.onMouseEnter.bind(self);
+    self.onMouseMove = self.onMouseMove.bind(self);
+    self.onMouseLeave = self.onMouseLeave.bind(self);
+    self.onLegendClick = self.onLegendClick.bind(self);
+    self.init();
+    return self;
+  }
+
+  getVisibleLabels() {
+    const {
+      maxAxisLabels,
+      axisLabels
+    } = this.params;
+    if (!maxAxisLabels || axisLabels.length <= maxAxisLabels) return axisLabels;
+    const skipStep = Math.ceil(axisLabels.length / maxAxisLabels);
+    const filtered = axisLabels.filter((label, index) => index % skipStep === 0);
+    return filtered;
+  }
+
+  getSummValues() {
+    const {
+      datasets
+    } = this.params;
+    const {
+      hiddenDatasets
+    } = this;
+    const summValues = [];
+    datasets.filter((dataset, index) => !hiddenDatasets.includes(index)).forEach(_ref => {
+      let {
+        values
+      } = _ref;
+      values.forEach((value, valueIndex) => {
+        if (!summValues[valueIndex]) summValues[valueIndex] = 0;
+        summValues[valueIndex] += value;
+      });
+    });
+    return summValues;
+  }
+
+  getChartData() {
+    const {
+      datasets,
+      lineChart,
+      width,
+      height
+    } = this.params;
+    const {
+      hiddenDatasets
+    } = this;
+    const data = [];
+
+    if (!datasets.length) {
+      return data;
+    }
+
+    const lastValues = datasets[0].values.map(() => 0);
+    let maxValue = 0;
+
+    if (lineChart) {
+      datasets.filter((dataset, index) => !hiddenDatasets.includes(index)).forEach(_ref2 => {
+        let {
+          values
+        } = _ref2;
+        const datasetMaxValue = Math.max(...values);
+        if (datasetMaxValue > maxValue) maxValue = datasetMaxValue;
+      });
+    } else {
+      maxValue = Math.max(...this.getSummValues());
+    }
+
+    datasets.filter((dataset, index) => !hiddenDatasets.includes(index)).forEach(_ref3 => {
+      let {
+        label,
+        values,
+        color
+      } = _ref3;
+      const points = values.map((originalValue, valueIndex) => {
+        lastValues[valueIndex] += originalValue;
+        const value = lineChart ? originalValue : lastValues[valueIndex];
+        const x = valueIndex / (values.length - 1) * width;
+        const y = height - value / maxValue * height;
+
+        if (lineChart) {
+          return `${valueIndex === 0 ? 'M' : 'L'}${x},${y}`;
+        }
+
+        return `${x} ${y}`;
+      });
+
+      if (!lineChart) {
+        points.push(`${width} ${height} 0 ${height}`);
+      }
+
+      data.push({
+        label,
+        points: points.join(' '),
+        color
+      });
+    });
+    return data.reverse();
+  }
+
+  getVerticalLines() {
+    const {
+      datasets,
+      width
+    } = this.params;
+    const lines = [];
+
+    if (!datasets.length) {
+      return lines;
+    }
+
+    const values = datasets[0].values;
+    values.forEach((value, valueIndex) => {
+      const x = valueIndex / (values.length - 1) * width;
+      lines.push(x);
+    });
+    return lines;
+  }
+
+  toggleDataset(index) {
+    const {
+      hiddenDatasets,
+      params: {
+        toggleDatasets
+      }
+    } = this;
+    if (!toggleDatasets) return;
+
+    if (hiddenDatasets.includes(index)) {
+      hiddenDatasets.splice(hiddenDatasets.indexOf(index), 1);
+    } else {
+      hiddenDatasets.push(index);
+    }
+
+    if (this.$legendEl) {
+      this.$legendEl.find('.area-chart-legend-item').removeClass('area-chart-legend-item-hidden');
+      hiddenDatasets.forEach(i => {
+        this.$legendEl.find(`.area-chart-legend-item[data-index="${i}"]`).addClass('area-chart-legend-item-hidden');
+      });
+    }
+
+    this.update({}, true);
+  }
+
+  formatAxisLabel(label) {
+    const {
+      formatAxisLabel
+    } = this.params;
+    if (formatAxisLabel) return formatAxisLabel.call(this, label);
+    return label;
+  }
+
+  formatLegendLabel(label) {
+    const {
+      formatLegendLabel
+    } = this.params;
+    if (formatLegendLabel) return formatLegendLabel.call(this, label);
+    return label;
+  }
+
+  calcLinesOffsets() {
+    const lines = this.svgEl.querySelectorAll('line');
+    this.linesOffsets = [];
+
+    for (let i = 0; i < lines.length; i += 1) {
+      this.linesOffsets.push(lines[i].getBoundingClientRect().left);
+    }
+  }
+
+  formatTooltip() {
+    const self = this;
+    const {
+      currentIndex,
+      hiddenDatasets,
+      params: {
+        datasets,
+        axisLabels,
+        formatTooltip,
+        formatTooltipTotal,
+        formatTooltipAxisLabel,
+        formatTooltipDataset
+      }
+    } = self;
+    if (currentIndex === null) return '';
+    let total = 0;
+    const currentValues = datasets.filter((dataset, index) => !hiddenDatasets.includes(index)).map(dataset => ({
+      color: dataset.color,
+      label: dataset.label,
+      value: dataset.values[currentIndex]
+    }));
+    currentValues.forEach(dataset => {
+      total += dataset.value;
+    });
+
+    if (formatTooltip) {
+      return formatTooltip({
+        index: currentIndex,
+        total,
+        datasets: currentValues
+      });
+    }
+
+    let labelText = formatTooltipAxisLabel ? formatTooltipAxisLabel.call(self, axisLabels[currentIndex]) : this.formatAxisLabel(axisLabels[currentIndex]);
+    if (!labelText) labelText = '';
+    const totalText = formatTooltipTotal ? formatTooltipTotal.call(self, total) : total; // prettier-ignore
+
+    const datasetsText = currentValues.length > 0 ? `
+      <ul class="area-chart-tooltip-list">
+        ${currentValues.map(_ref4 => {
+      let {
+        label,
+        color,
+        value
+      } = _ref4;
+      const valueText = formatTooltipDataset ? formatTooltipDataset.call(self, label, value, color) : `${label ? `${label}: ` : ''}${value}`;
+      return `
+              <li><span style="background-color: ${color};"></span>${valueText}</li>
+            `;
+    }).join('')}
+      </ul>` : ''; // prettier-ignore
+
+    return `
+      <div class="area-chart-tooltip-label">${labelText}</div>
+      <div class="area-chart-tooltip-total">${totalText}</div>
+      ${datasetsText}
+    `;
+  }
+
+  setTooltip() {
+    const self = this;
+    const {
+      app,
+      el,
+      svgEl,
+      hiddenDatasets,
+      currentIndex,
+      params: {
+        tooltip,
+        datasets
+      }
+    } = self;
+    if (!tooltip) return;
+    const hasVisibleDataSets = datasets.filter((dataset, index) => !hiddenDatasets.includes(index)).length > 0;
+
+    if (!hasVisibleDataSets) {
+      if (self.f7Tooltip && self.f7Tooltip.hide) self.f7Tooltip.hide();
+      return;
+    }
+
+    if (currentIndex !== null && !self.f7Tooltip) {
+      self.f7Tooltip = app.tooltip.create({
+        trigger: 'manual',
+        containerEl: el,
+        targetEl: svgEl.querySelector(`line[data-index="${currentIndex}"]`),
+        text: self.formatTooltip(),
+        cssClass: 'area-chart-tooltip'
+      });
+
+      if (self.f7Tooltip && self.f7Tooltip.show) {
+        self.f7Tooltip.show();
+      }
+
+      return;
+    }
+
+    if (!self.f7Tooltip || !self.f7Tooltip.hide || !self.f7Tooltip.show) {
+      return;
+    }
+
+    if (currentIndex !== null) {
+      self.f7Tooltip.setText(self.formatTooltip());
+      self.f7Tooltip.setTargetEl(svgEl.querySelector(`line[data-index="${currentIndex}"]`));
+      self.f7Tooltip.show();
+    } else {
+      self.f7Tooltip.hide();
+    }
+  }
+
+  setCurrentIndex(index) {
+    if (index === this.currentIndex) return;
+    this.currentIndex = index;
+    this.$el.trigger('areachart:select', {
+      index
+    });
+    this.emit('local::select areaChartSelect', this, index);
+    this.$svgEl.find('line').removeClass('area-chart-current-line');
+    this.$svgEl.find(`line[data-index="${index}"]`).addClass('area-chart-current-line');
+    this.setTooltip();
+  }
+
+  onLegendClick(e) {
+    const index = parseInt($(e.target).closest('.area-chart-legend-item').attr('data-index'), 10);
+    this.toggleDataset(index);
+  }
+
+  onMouseEnter() {
+    this.calcLinesOffsets();
+  }
+
+  onMouseMove(e) {
+    const self = this;
+
+    if (!self.linesOffsets) {
+      self.calcLinesOffsets();
+    }
+
+    let currentLeft = e.pageX;
+    if (typeof currentLeft === 'undefined') currentLeft = 0;
+    const distances = self.linesOffsets.map(left => Math.abs(currentLeft - left));
+    const minDistance = Math.min(...distances);
+    const closestIndex = distances.indexOf(minDistance);
+    self.setCurrentIndex(closestIndex);
+  }
+
+  onMouseLeave() {
+    this.setCurrentIndex(null);
+  }
+
+  attachEvents() {
+    const {
+      svgEl,
+      $el
+    } = this;
+    if (!svgEl) return;
+    svgEl.addEventListener('mouseenter', this.onMouseEnter);
+    svgEl.addEventListener('mousemove', this.onMouseMove);
+    svgEl.addEventListener('mouseleave', this.onMouseLeave);
+    $el.on('click', '.area-chart-legend-item', this.onLegendClick);
+  }
+
+  detachEvents() {
+    const {
+      svgEl,
+      $el
+    } = this;
+    if (!svgEl) return;
+    svgEl.removeEventListener('mouseenter', this.onMouseEnter);
+    svgEl.removeEventListener('mousemove', this.onMouseMove);
+    svgEl.removeEventListener('mouseleave', this.onMouseLeave);
+    $el.off('click', '.area-chart-legend-item', this.onLegendClick);
+  }
+
+  render() {
+    const self = this;
+    const {
+      lineChart,
+      toggleDatasets,
+      width,
+      height,
+      axis,
+      axisLabels,
+      legend,
+      datasets
+    } = self.params;
+    const chartData = self.getChartData();
+    const verticalLines = self.getVerticalLines();
+    const visibleLegends = self.getVisibleLabels();
+    const LegendItemTag = toggleDatasets ? 'button' : 'span';
+    return $jsx("div", null, $jsx("svg", {
+      xmlns: "http://www.w3.org/2000/svg",
+      width: width,
+      height: height,
+      viewBox: `0 0 ${width} ${height}`,
+      preserveAspectRatio: "none"
+    }, chartData.map(data => lineChart ? $jsx("path", {
+      stroke: data.color,
+      "fill-rule": "evenodd",
+      d: data.points
+    }) : $jsx("polygon", {
+      fill: data.color,
+      "fill-rule": "evenodd",
+      points: data.points
+    })), verticalLines.map((line, index) => $jsx("line", {
+      "data-index": index,
+      fill: "#000",
+      x1: line,
+      y1: 0,
+      x2: line,
+      y2: height
+    }))), axis && $jsx("div", {
+      class: "area-chart-axis"
+    }, axisLabels.map(label => $jsx("span", null, visibleLegends.includes(label) && $jsx("span", null, self.formatAxisLabel(label))))), legend && $jsx("div", {
+      class: "area-chart-legend"
+    }, datasets.map((dataset, index) => $jsx(LegendItemTag, {
+      "data-index": index,
+      class: `area-chart-legend-item ${toggleDatasets ? 'area-chart-legend-button' : ''}`,
+      _type: toggleDatasets ? 'button' : undefined
+    }, $jsx("span", {
+      style: `background-color: ${dataset.color}`
+    }), self.formatLegendLabel(dataset.label)))));
+  }
+
+  update(newParams, onlySvg) {
+    if (newParams === void 0) {
+      newParams = {};
+    }
+
+    if (onlySvg === void 0) {
+      onlySvg = false;
+    }
+
+    const self = this;
+    const {
+      params
+    } = self;
+    Object.keys(newParams).forEach(param => {
+      if (typeof newParams[param] !== 'undefined') {
+        params[param] = newParams[param];
+      }
+    });
+    if (self.$svgEl.length === 0) return self;
+    self.detachEvents();
+    self.$svgEl.remove();
+
+    if (!onlySvg) {
+      self.$axisEl.remove();
+      self.$legendEl.remove();
+    }
+
+    const $rendered = $(self.render());
+    const $svgEl = $rendered.find('svg');
+    extend(self, {
+      svgEl: $svgEl && $svgEl[0],
+      $svgEl
+    });
+
+    if (!onlySvg) {
+      const $axisEl = $rendered.find('.area-chart-axis');
+      const $legendEl = $rendered.find('.area-chart-legend');
+      extend(self, {
+        $axisEl,
+        $legendEl
+      });
+      self.$el.append($axisEl);
+      self.$el.append($legendEl);
+    }
+
+    self.$el.prepend($svgEl);
+    self.attachEvents();
+    return self;
+  }
+
+  init() {
+    const self = this;
+    const $rendered = $(self.render());
+    const $svgEl = $rendered.find('svg');
+    const $axisEl = $rendered.find('.area-chart-axis');
+    const $legendEl = $rendered.find('.area-chart-legend');
+    extend(self, {
+      svgEl: $svgEl && $svgEl[0],
+      $svgEl,
+      $axisEl,
+      $legendEl
+    });
+    self.$el.append($svgEl);
+    self.$el.append($axisEl);
+    self.$el.append($legendEl);
+    self.attachEvents();
+    return self;
+  }
+
+  destroy() {
+    const self = this;
+    if (!self.$el || self.destroyed) return;
+    self.$el.trigger('piechart:beforedestroy');
+    self.emit('local::beforeDestroy areaChartBeforeDestroy', self);
+    self.detachEvents();
+    self.$svgEl.remove();
+    self.$axisEl.remove();
+    self.$legendEl.remove();
+
+    if (self.f7Tooltip && self.f7Tooltip.destroy) {
+      self.f7Tooltip.destroy();
+    }
+
+    delete self.$el[0].f7AreaChart;
+    deleteProps(self);
+    self.destroyed = true;
+  }
+
+}
+
+export default AreaChart;

+ 2 - 0
data/html/framework7/components/area-chart/area-chart-ios.less

@@ -0,0 +1,2 @@
+.ios {
+}

+ 2 - 0
data/html/framework7/components/area-chart/area-chart-md.less

@@ -0,0 +1,2 @@
+.md {
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/area-chart/area-chart-rtl.css


+ 29 - 0
data/html/framework7/components/area-chart/area-chart-vars.less

@@ -0,0 +1,29 @@
+:root {
+  --f7-area-chart-current-line-stroke-width: 2px;
+  --f7-area-chart-current-line-stroke: rgba(0, 0, 0, 0.15);
+  --f7-area-chart-axis-text-color: inherit;
+  --f7-area-chart-axis-height: 1px;
+  --f7-area-chart-axis-font-size: 10px;
+  --f7-area-chart-axis-font-weight: 500;
+  --f7-area-chart-tooltip-font-size: 12px;
+  --f7-area-chart-tooltip-total-label-text-color: rgba(255, 255, 255, 0.75);
+  --f7-area-chart-tooltip-total-font-size: 16px;
+  --f7-area-chart-tooltip-total-font-weight: bold;
+  --f7-area-chart-tooltip-color-size: 10px;
+  --f7-area-chart-legend-font-size: 14px;
+  --f7-area-chart-legend-font-weight: 500;
+  --f7-area-chart-legend-text-color: inherit;
+  --f7-area-chart-legend-padding: 4px 8px;
+  --f7-area-chart-legend-border-radius: 4px;
+  --f7-area-chart-legend-color-size: 14px;
+  --f7-area-chart-line-stroke-width: 2px;
+
+  .light-vars({
+    --f7-area-chart-axis-bg-color: rgba(0, 0, 0, 0.15);
+    --f7-area-chart-legend-disabled-text-color: rgba(0,0,0,0.22);
+  });
+  .dark-vars({
+    --f7-area-chart-axis-bg-color: rgba(255, 255, 255, 0.15);
+    --f7-area-chart-legend-disabled-text-color: rgba(255, 255, 255, 0.22);
+  });
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/area-chart/area-chart.css


+ 128 - 0
data/html/framework7/components/area-chart/area-chart.d.ts

@@ -0,0 +1,128 @@
+import { Dom7Array } from 'dom7';
+import Framework7, {
+  CSSSelector,
+  Framework7EventsClass,
+  Framework7Plugin,
+} from '../app/app-class.js';
+
+export namespace AreaChart {
+  interface AreaChart extends Framework7EventsClass<Events> {
+    /** Link to global app instance */
+    app: Framework7;
+    /** Area chart HTML element */
+    el: HTMLElement;
+    /** Dom7 instance with chart HTML element */
+    $el: Dom7Array;
+    /** Area chart generated SVH HTML element */
+    svgEl: HTMLElement;
+    /** Dom7 instance with generated SVH HTML element */
+    $svgEl: Dom7Array;
+    /** Area chart parameters */
+    params: Parameters;
+
+    /** Update/rerender chart SVG element according to passed parameters. It accepts object with same parameters required for chart initialization. You can pass only parameters that needs to be updated */
+    update(parameters: Parameters): AreaChart;
+    /** Destroys chart instance */
+    destroy(): void;
+  }
+
+  interface Dataset {
+    /** Dataset value */
+    values: number[];
+    /** Dataset HEX color */
+    color?: string;
+    /** Dataset label */
+    label?: any;
+  }
+
+  interface Parameters {
+    /** Area chart element. HTMLElement or string with CSS selector of chart element. Generated SVG will be inserted into this element. */
+    el: HTMLElement | CSSSelector;
+    /** Enables lines chart (instead of area chart) */
+    lineChart: boolean;
+    /** Chart data sets */
+    datasets: Dataset[];
+    /** Enables chart horizontal (X) axis */
+    axis: boolean;
+    /** Chart horizontal (X) axis labels. Should have same amount of items as dataset values */
+    axisLabels: any[];
+    /** Enables tooltip on hover */
+    tooltip: boolean;
+    /** Enables chart legend */
+    legend: boolean;
+    /** When enabled it will toggle data sets on legend items click */
+    toggleDatasets: boolean;
+    /** Generated SVG image width (in px). (default 640) */
+    width: number;
+    /** Generated SVG image height (in px). (default 320) */
+    height: number;
+    /** Max numbers of axis labels (ticks) to be visible on axis. (default 8) */
+    maxAxisLabels: number;
+    /** Custom render function to format axis label text */
+    formatAxisLabel: (this: AreaChart, label: any) => string;
+    /** Custom render function to format legend label text */
+    formatLegendLabel: (this: AreaChart, label: any) => string;
+    /** Custom render function that must return tooltip's HTML content */
+    formatTooltip?: (
+      this: AreaChart,
+      data: {
+        index: number;
+        total: number;
+        datasets: {
+          color?: string;
+          label: any;
+          value: number;
+        }[];
+      },
+    ) => string;
+    /** Custom render function to format axis label text in Tooltip */
+    formatTooltipAxisLabel: (this: AreaChart, label: any) => string;
+    /** Custom render function to format total value text in Tooltip */
+    formatTooltipTotal: (this: AreaChart, total: number) => string;
+    /** Custom render function to format dataset text in Tooltip */
+    formatTooltipDataset: (this: AreaChart, label: string, value: number, color: string) => string;
+    /** Object with events handlers.. */
+    on?: {
+      [event in keyof Events]?: Events[event];
+    };
+  }
+
+  interface Events {
+    /** Event will be triggered (when tooltip enabled) on chart hover */
+    select: (areaChart: AreaChart, index: number | null) => void;
+    /** Event will be triggered right before Area chart instance will be destroyed. As an argument event handler receives Area chart instance */
+    beforeDestroy: (areaChart: AreaChart) => void;
+  }
+
+  interface DomEvents {
+    /** Event will be triggered (when tooltip enabled) on chart hover */
+    'areachart:select': () => void;
+    /** Event will be triggered right before Area chart instance will be destroyed */
+    'areachart:beforedestroy': () => void;
+  }
+  interface AppMethods {
+    areaChart: {
+      /** create Area chart instance */
+      create(parameters: Parameters): AreaChart;
+      /** destroy Area chart instance */
+      destroy(el: HTMLElement | CSSSelector | AreaChart): void;
+      /** get Area chart instance by HTML element */
+      get(el: HTMLElement | CSSSelector): AreaChart;
+      /** update/rerender Area chart SVG according to passed parameters */
+      update(parameters: Parameters): AreaChart;
+    };
+  }
+  interface AppParams {
+    areaChart?: Parameters | undefined;
+  }
+  interface AppEvents {
+    /** Event will be triggered (when tooltip enabled) on chart hover */
+    areaChartSelect: (areaChart: AreaChart, index: number | null) => void;
+    /** Event will be triggered right before AreaChart instance will be destroyed. As an argument event handler receives Area chart instance */
+    areaChartBeforeDestroy: (areaChart: AreaChart) => void;
+  }
+}
+
+declare const AreaChartComponent: Framework7Plugin;
+
+export default AreaChartComponent;

+ 47 - 0
data/html/framework7/components/area-chart/area-chart.js

@@ -0,0 +1,47 @@
+import $ from '../../shared/dom7.js';
+import AreaChart from './area-chart-class.js';
+import ConstructorMethods from '../../shared/constructor-methods.js';
+export default {
+  name: 'areaChart',
+  params: {
+    areaChart: {
+      el: null,
+      lineChart: false,
+      datasets: [],
+      axis: false,
+      axisLabels: [],
+      tooltip: false,
+      legend: false,
+      toggleDatasets: false,
+      width: 640,
+      height: 320,
+      maxAxisLabels: 8,
+      formatAxisLabel: null,
+      formatLegendLabel: null,
+      formatTooltip: null,
+      formatTooltipAxisLabel: null,
+      formatTooltipTotal: null,
+      formatTooltipDataset: null
+    }
+  },
+
+  create() {
+    const app = this;
+    app.areaChart = ConstructorMethods({
+      defaultSelector: '.area-chart',
+      constructor: AreaChart,
+      app,
+      domProp: 'f7AreaChart'
+    });
+
+    app.areaChart.update = function update(el, newParams) {
+      const $el = $(el);
+      if ($el.length === 0) return undefined;
+      const areaChart = app.areaChart.get(el);
+      if (!areaChart) return undefined;
+      areaChart.update(newParams);
+      return areaChart;
+    };
+  }
+
+};

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/area-chart/area-chart.lazy.js


+ 134 - 0
data/html/framework7/components/area-chart/area-chart.less

@@ -0,0 +1,134 @@
+@import './area-chart-vars.less';
+.area-chart {
+  position: relative;
+  svg {
+    display: block;
+    width: 100%;
+    font-size: 0;
+    height: auto;
+    margin: 0 auto;
+  }
+
+  path {
+    fill: none;
+    stroke-width: var(--f7-area-chart-line-stroke-width);
+  }
+  &-current-line {
+    stroke: var(--f7-area-chart-current-line-stroke);
+    stroke-width: var(--f7-area-chart-current-line-stroke-width);
+  }
+  &-axis {
+    height: var(--f7-area-chart-axis-height);
+    background: var(--f7-area-chart-axis-bg-color);
+    color: var(--f7-area-chart-axis-text-color);
+    display: flex;
+    font-size: var(--f7-area-chart-axis-font-size);
+    font-weight: var(--f7-area-chart-axis-font-weight);
+    justify-content: space-between;
+    line-height: 1;
+    margin-bottom: 2em;
+    > span {
+      padding-top: 10px;
+      width: 0;
+      display: flex;
+      align-items: flex-start;
+      justify-content: center;
+      white-space: nowrap;
+      &:first-child {
+        justify-content: flex-start;
+      }
+      &:last-child {
+        justify-content: flex-end;
+      }
+    }
+  }
+  &-tooltip {
+    pointer-events: none;
+    text-align: left;
+    font-size: var(--f7-area-chart-tooltip-font-size);
+    line-height: 1.4;
+
+    &-label {
+      color: var(--f7-area-chart-tooltip-total-label-text-color);
+    }
+    &-total {
+      font-size: var(--f7-area-chart-tooltip-total-font-size);
+      font-weight: var(--f7-area-chart-tooltip-total-font-weight);
+    }
+    &-list {
+      list-style: none;
+      margin: 0;
+      padding: 0;
+      li {
+        white-space: nowrap;
+      }
+      span {
+        display: inline-block;
+        width: var(--f7-area-chart-tooltip-color-size);
+        height: var(--f7-area-chart-tooltip-color-size);
+        border-radius: 50%;
+        margin-right: 4px;
+      }
+    }
+  }
+  &-axis ~ &-legend {
+    margin-top: 2em;
+  }
+  &-legend {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+    justify-content: center;
+    font-size: var(--f7-area-chart-legend-font-size);
+    width: 100%;
+    margin-top: 1em;
+    &-button {
+      -webkit-appearance: none !important;
+      appearance: none !important;
+      background-color: transparent;
+      border-radius: 0;
+      border: none;
+      outline: 0 !important;
+      cursor: pointer;
+      font-family: inherit;
+      font-size: inherit;
+      box-shadow: none !important;
+    }
+    &-item {
+      position: relative;
+      color: var(--f7-area-chart-legend-text-color);
+      width: auto;
+      display: flex;
+      align-items: center;
+      font-weight: var(--f7-area-chart-legend-font-weight);
+      transition-duration: 200ms;
+      padding: var(--f7-area-chart-legend-padding);
+      border-radius: var(--f7-area-chart-legend-border-radius);
+      overflow: hidden;
+      span {
+        width: var(--f7-area-chart-legend-color-size);
+        height: var(--f7-area-chart-legend-color-size);
+        margin-right: 4px;
+        border-radius: 50%;
+        transition-duration: 200ms;
+      }
+
+      &-hidden {
+        color: var(--f7-area-chart-legend-disabled-text-color);
+        span {
+          background-color: var(--f7-area-chart-legend-disabled-text-color) !important;
+        }
+      }
+    }
+  }
+}
+
+.if-ios-theme({
+  @import './area-chart-ios.less';
+});
+.if-md-theme({
+  @import './area-chart-md.less';
+});
+.if-aurora-theme({
+  @import './area-chart-aurora.less';
+});

+ 17 - 0
data/html/framework7/components/autocomplete/autocomplete-aurora.less

@@ -0,0 +1,17 @@
+.aurora {
+  .autocomplete-dropdown {
+    .autocomplete-preloader {
+      .ltr({ right: 16px; });
+      .rtl({ left: 16px; });
+      margin-bottom: 2px;
+    }
+  }
+  .searchbar-input-wrap .autocomplete-dropdown {
+    margin-top: calc(-1 * var(--f7-searchbar-input-height));
+    top: 100%;
+    z-index: 20;
+    .autocomplete-dropdown-inner {
+      padding-top: var(--f7-searchbar-input-height);
+    }
+  }
+}

+ 958 - 0
data/html/framework7/components/autocomplete/autocomplete-class.js

@@ -0,0 +1,958 @@
+/* eslint "no-useless-escape": "off" */
+import $ from '../../shared/dom7.js';
+import { extend, id, nextTick, deleteProps, iosPreloaderContent, mdPreloaderContent, auroraPreloaderContent } from '../../shared/utils.js';
+import { getDevice } from '../../shared/get-device.js';
+import Framework7Class from '../../shared/class.js';
+/** @jsx $jsx */
+
+import $jsx from '../../shared/$jsx.js';
+
+class Autocomplete extends Framework7Class {
+  constructor(app, params) {
+    if (params === void 0) {
+      params = {};
+    }
+
+    super(params, [app]);
+    const ac = this;
+    ac.app = app;
+    const device = getDevice();
+    const defaults = extend({
+      on: {}
+    }, app.params.autocomplete);
+
+    if (typeof defaults.searchbarDisableButton === 'undefined') {
+      defaults.searchbarDisableButton = app.theme !== 'aurora';
+    } // Extend defaults with modules params
+
+
+    ac.useModulesParams(defaults);
+    ac.params = extend(defaults, params);
+    let $openerEl;
+
+    if (ac.params.openerEl) {
+      $openerEl = $(ac.params.openerEl);
+      if ($openerEl.length) $openerEl[0].f7Autocomplete = ac;
+    }
+
+    let $inputEl;
+
+    if (ac.params.inputEl) {
+      $inputEl = $(ac.params.inputEl);
+      if ($inputEl.length) $inputEl[0].f7Autocomplete = ac;
+    }
+
+    const uniqueId = id();
+    let url = params.url;
+
+    if (!url && $openerEl && $openerEl.length) {
+      if ($openerEl.attr('href')) url = $openerEl.attr('href');else if ($openerEl.find('a').length > 0) {
+        url = $openerEl.find('a').attr('href');
+      }
+    }
+
+    if (!url || url === '#' || url === '') url = ac.params.url;
+    const inputType = ac.params.multiple ? 'checkbox' : 'radio';
+    extend(ac, {
+      $openerEl,
+      openerEl: $openerEl && $openerEl[0],
+      $inputEl,
+      inputEl: $inputEl && $inputEl[0],
+      id: uniqueId,
+      url,
+      value: ac.params.value || [],
+      inputType,
+      inputName: `${inputType}-${uniqueId}`,
+      $modalEl: undefined,
+      $dropdownEl: undefined
+    });
+    let previousQuery = '';
+
+    function onInputChange() {
+      let query = ac.$inputEl.val().trim();
+      if (!ac.params.source) return;
+      ac.params.source.call(ac, query, items => {
+        let itemsHTML = '';
+        const limit = ac.params.limit ? Math.min(ac.params.limit, items.length) : items.length;
+        ac.items = items;
+        let regExp;
+
+        if (ac.params.highlightMatches) {
+          query = query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
+          regExp = new RegExp(`(${query})`, 'i');
+        }
+
+        let firstValue;
+        let firstItem;
+
+        for (let i = 0; i < limit; i += 1) {
+          const itemValue = typeof items[i] === 'object' ? items[i][ac.params.valueProperty] : items[i];
+          const itemText = typeof items[i] === 'object' ? items[i][ac.params.textProperty] : items[i];
+
+          if (i === 0) {
+            firstValue = itemValue;
+            firstItem = ac.items[i];
+          }
+
+          itemsHTML += ac.renderItem({
+            value: itemValue,
+            text: ac.params.highlightMatches ? itemText.replace(regExp, '<b>$1</b>') : itemText
+          }, i);
+        }
+
+        if (itemsHTML === '' && query === '' && ac.params.dropdownPlaceholderText) {
+          itemsHTML += ac.renderItem({
+            placeholder: true,
+            text: ac.params.dropdownPlaceholderText
+          });
+        }
+
+        ac.$dropdownEl.find('ul').html(itemsHTML);
+
+        if (ac.params.typeahead) {
+          if (!firstValue || !firstItem) {
+            return;
+          }
+
+          if (firstValue.toLowerCase().indexOf(query.toLowerCase()) !== 0) {
+            return;
+          }
+
+          if (previousQuery.toLowerCase() === query.toLowerCase()) {
+            ac.value = [];
+            return;
+          }
+
+          if (previousQuery.toLowerCase().indexOf(query.toLowerCase()) === 0) {
+            previousQuery = query;
+            ac.value = [];
+            return;
+          }
+
+          $inputEl.val(firstValue);
+          $inputEl[0].setSelectionRange(query.length, firstValue.length);
+          const previousValue = typeof ac.value[0] === 'object' ? ac.value[0][ac.params.valueProperty] : ac.value[0];
+
+          if (!previousValue || firstValue.toLowerCase() !== previousValue.toLowerCase()) {
+            ac.value = [firstItem];
+            ac.emit('local::change autocompleteChange', [firstItem]);
+          }
+        }
+
+        previousQuery = query;
+      });
+    }
+
+    function onPageInputChange() {
+      const inputEl = this;
+      const value = inputEl.value;
+      const isValues = $(inputEl).parents('.autocomplete-values').length > 0;
+      let item;
+      let itemValue;
+      let aValue;
+
+      if (isValues) {
+        if (ac.inputType === 'checkbox' && !inputEl.checked) {
+          for (let i = 0; i < ac.value.length; i += 1) {
+            aValue = typeof ac.value[i] === 'string' ? ac.value[i] : ac.value[i][ac.params.valueProperty];
+
+            if (aValue === value || aValue * 1 === value * 1) {
+              ac.value.splice(i, 1);
+            }
+          }
+
+          ac.updateValues();
+          ac.emit('local::change autocompleteChange', ac.value);
+        }
+
+        return;
+      } // Find Related Item
+
+
+      for (let i = 0; i < ac.items.length; i += 1) {
+        itemValue = typeof ac.items[i] === 'object' ? ac.items[i][ac.params.valueProperty] : ac.items[i];
+        if (itemValue === value || itemValue * 1 === value * 1) item = ac.items[i];
+      }
+
+      if (ac.inputType === 'radio') {
+        ac.value = [item];
+      } else if (inputEl.checked) {
+        ac.value.push(item);
+      } else {
+        for (let i = 0; i < ac.value.length; i += 1) {
+          aValue = typeof ac.value[i] === 'object' ? ac.value[i][ac.params.valueProperty] : ac.value[i];
+
+          if (aValue === value || aValue * 1 === value * 1) {
+            ac.value.splice(i, 1);
+          }
+        }
+      } // Update Values Block
+
+
+      ac.updateValues(); // On Select Callback
+
+      if (ac.inputType === 'radio' && inputEl.checked || ac.inputType === 'checkbox') {
+        ac.emit('local::change autocompleteChange', ac.value);
+      }
+    }
+
+    function onHtmlClick(e) {
+      const $targetEl = $(e.target);
+      if ($targetEl.is(ac.$inputEl[0]) || ac.$dropdownEl && $targetEl.closest(ac.$dropdownEl[0]).length) return;
+      ac.close();
+    }
+
+    function onOpenerClick() {
+      ac.open();
+    }
+
+    function onInputFocus() {
+      ac.open();
+    }
+
+    function onInputBlur() {
+      if (ac.$dropdownEl.find('label.active-state').length > 0) return;
+      setTimeout(() => {
+        ac.close();
+      }, 0);
+    }
+
+    function onResize() {
+      ac.positionDropdown();
+    }
+
+    function onKeyDown(e) {
+      if (!ac.opened) return;
+
+      if (e.keyCode === 27) {
+        // ESC
+        e.preventDefault();
+        ac.$inputEl.blur();
+        return;
+      }
+
+      if (e.keyCode === 13) {
+        // Enter
+        const $selectedItemLabel = ac.$dropdownEl.find('.autocomplete-dropdown-selected label');
+
+        if ($selectedItemLabel.length) {
+          e.preventDefault();
+          $selectedItemLabel.trigger('click');
+          ac.$inputEl.blur();
+          return;
+        }
+
+        if (ac.params.typeahead) {
+          e.preventDefault();
+          ac.$inputEl.blur();
+        }
+
+        return;
+      }
+
+      if (e.keyCode !== 40 && e.keyCode !== 38) return;
+      e.preventDefault();
+      const $selectedItem = ac.$dropdownEl.find('.autocomplete-dropdown-selected');
+      let $newItem;
+
+      if ($selectedItem.length) {
+        $newItem = $selectedItem[e.keyCode === 40 ? 'next' : 'prev']('li');
+
+        if (!$newItem.length) {
+          $newItem = ac.$dropdownEl.find('li').eq(e.keyCode === 40 ? 0 : ac.$dropdownEl.find('li').length - 1);
+        }
+      } else {
+        $newItem = ac.$dropdownEl.find('li').eq(e.keyCode === 40 ? 0 : ac.$dropdownEl.find('li').length - 1);
+      }
+
+      if ($newItem.hasClass('autocomplete-dropdown-placeholder')) return;
+      $selectedItem.removeClass('autocomplete-dropdown-selected');
+      $newItem.addClass('autocomplete-dropdown-selected');
+    }
+
+    function onDropdownClick() {
+      const $clickedEl = $(this);
+      let clickedItem;
+
+      for (let i = 0; i < ac.items.length; i += 1) {
+        const itemValue = typeof ac.items[i] === 'object' ? ac.items[i][ac.params.valueProperty] : ac.items[i];
+        const value = $clickedEl.attr('data-value');
+
+        if (itemValue === value || itemValue * 1 === value * 1) {
+          clickedItem = ac.items[i];
+        }
+      }
+
+      if (ac.params.updateInputValueOnSelect) {
+        ac.$inputEl.val(typeof clickedItem === 'object' ? clickedItem[ac.params.valueProperty] : clickedItem);
+        ac.$inputEl.trigger('input change');
+      }
+
+      ac.value = [clickedItem];
+      ac.emit('local::change autocompleteChange', [clickedItem]);
+      ac.close();
+    }
+
+    ac.attachEvents = function attachEvents() {
+      if (ac.params.openIn !== 'dropdown' && ac.$openerEl) {
+        ac.$openerEl.on('click', onOpenerClick);
+      }
+
+      if (ac.params.openIn === 'dropdown' && ac.$inputEl) {
+        ac.$inputEl.on('focus', onInputFocus);
+        ac.$inputEl.on(ac.params.inputEvents, onInputChange);
+
+        if (device.android) {
+          $('html').on('click', onHtmlClick);
+        } else {
+          ac.$inputEl.on('blur', onInputBlur);
+        }
+
+        ac.$inputEl.on('keydown', onKeyDown);
+      }
+    };
+
+    ac.detachEvents = function attachEvents() {
+      if (ac.params.openIn !== 'dropdown' && ac.$openerEl) {
+        ac.$openerEl.off('click', onOpenerClick);
+      }
+
+      if (ac.params.openIn === 'dropdown' && ac.$inputEl) {
+        ac.$inputEl.off('focus', onInputFocus);
+        ac.$inputEl.off(ac.params.inputEvents, onInputChange);
+
+        if (device.android) {
+          $('html').off('click', onHtmlClick);
+        } else {
+          ac.$inputEl.off('blur', onInputBlur);
+        }
+
+        ac.$inputEl.off('keydown', onKeyDown);
+      }
+    };
+
+    ac.attachDropdownEvents = function attachDropdownEvents() {
+      ac.$dropdownEl.on('click', 'label', onDropdownClick);
+      app.on('resize', onResize);
+    };
+
+    ac.detachDropdownEvents = function detachDropdownEvents() {
+      ac.$dropdownEl.off('click', 'label', onDropdownClick);
+      app.off('resize', onResize);
+    };
+
+    ac.attachPageEvents = function attachPageEvents() {
+      ac.$el.on('change', 'input[type="radio"], input[type="checkbox"]', onPageInputChange);
+
+      if (ac.params.closeOnSelect && !ac.params.multiple) {
+        ac.$el.once('click', '.list label', () => {
+          nextTick(() => {
+            ac.close();
+          });
+        });
+      }
+    };
+
+    ac.detachPageEvents = function detachPageEvents() {
+      ac.$el.off('change', 'input[type="radio"], input[type="checkbox"]', onPageInputChange);
+    }; // Install Modules
+
+
+    ac.useModules(); // Init
+
+    ac.init();
+    return ac;
+  }
+
+  get view() {
+    const ac = this;
+    const {
+      $openerEl,
+      $inputEl,
+      app
+    } = ac;
+    let view;
+
+    if (ac.params.view) {
+      view = ac.params.view;
+    } else if ($openerEl || $inputEl) {
+      const $el = $openerEl || $inputEl;
+      view = $el.closest('.view').length && $el.closest('.view')[0].f7View;
+    }
+
+    if (!view) view = app.views.main;
+    return view;
+  }
+
+  positionDropdown() {
+    const ac = this;
+    const {
+      $inputEl,
+      app,
+      $dropdownEl
+    } = ac;
+    const $pageContentEl = $inputEl.parents('.page-content');
+    if ($pageContentEl.length === 0) return;
+    const inputOffset = $inputEl.offset();
+    const inputOffsetWidth = $inputEl[0].offsetWidth;
+    const inputOffsetHeight = $inputEl[0].offsetHeight;
+    const $listEl = $inputEl.parents('.list');
+    let $listParent;
+    $listEl.parents().each(parentEl => {
+      if ($listParent) return;
+      const $parentEl = $(parentEl);
+      if ($parentEl.parent($pageContentEl).length) $listParent = $parentEl;
+    });
+    const listOffset = $listEl.offset();
+    const paddingBottom = parseInt($pageContentEl.css('padding-bottom'), 10);
+    const listOffsetLeft = $listEl.length > 0 ? listOffset.left - $pageContentEl.offset().left : 0;
+    const inputOffsetLeft = inputOffset.left - ($listEl.length > 0 ? listOffset.left : 0) - (app.rtl ? 0 : 0);
+    const inputOffsetTop = inputOffset.top - ($pageContentEl.offset().top - $pageContentEl[0].scrollTop);
+    const maxHeight = $pageContentEl[0].scrollHeight - paddingBottom - (inputOffsetTop + $pageContentEl[0].scrollTop) - $inputEl[0].offsetHeight;
+    const paddingProp = app.rtl ? 'padding-right' : 'padding-left';
+    let paddingValue;
+
+    if ($listEl.length && !ac.params.expandInput) {
+      paddingValue = (app.rtl ? $listEl[0].offsetWidth - inputOffsetLeft - inputOffsetWidth : inputOffsetLeft) - (app.theme === 'md' ? 16 : 15);
+    }
+
+    $dropdownEl.css({
+      left: `${$listEl.length > 0 ? listOffsetLeft : inputOffsetLeft}px`,
+      top: `${inputOffsetTop + $pageContentEl[0].scrollTop + inputOffsetHeight}px`,
+      width: `${$listEl.length > 0 ? $listEl[0].offsetWidth : inputOffsetWidth}px`
+    });
+    $dropdownEl.children('.autocomplete-dropdown-inner').css({
+      maxHeight: `${maxHeight}px`,
+      [paddingProp]: $listEl.length > 0 && !ac.params.expandInput ? `${paddingValue}px` : ''
+    });
+  }
+
+  focus() {
+    const ac = this;
+    ac.$el.find('input[type=search]').focus();
+  }
+
+  source(query) {
+    const ac = this;
+    if (!ac.params.source) return;
+    const {
+      $el
+    } = ac;
+    ac.params.source.call(ac, query, items => {
+      let itemsHTML = '';
+      const limit = ac.params.limit ? Math.min(ac.params.limit, items.length) : items.length;
+      ac.items = items;
+
+      for (let i = 0; i < limit; i += 1) {
+        let selected = false;
+        const itemValue = typeof items[i] === 'object' ? items[i][ac.params.valueProperty] : items[i];
+
+        for (let j = 0; j < ac.value.length; j += 1) {
+          const aValue = typeof ac.value[j] === 'object' ? ac.value[j][ac.params.valueProperty] : ac.value[j];
+          if (aValue === itemValue || aValue * 1 === itemValue * 1) selected = true;
+        }
+
+        itemsHTML += ac.renderItem({
+          value: itemValue,
+          text: typeof items[i] === 'object' ? items[i][ac.params.textProperty] : items[i],
+          inputType: ac.inputType,
+          id: ac.id,
+          inputName: ac.inputName,
+          selected
+        }, i);
+      }
+
+      $el.find('.autocomplete-found ul').html(itemsHTML);
+
+      if (items.length === 0) {
+        if (query.length !== 0) {
+          $el.find('.autocomplete-not-found').show();
+          $el.find('.autocomplete-found, .autocomplete-values').hide();
+        } else {
+          $el.find('.autocomplete-values').show();
+          $el.find('.autocomplete-found, .autocomplete-not-found').hide();
+        }
+      } else {
+        $el.find('.autocomplete-found').show();
+        $el.find('.autocomplete-not-found, .autocomplete-values').hide();
+      }
+    });
+  }
+
+  updateValues() {
+    const ac = this;
+    let valuesHTML = '';
+
+    for (let i = 0; i < ac.value.length; i += 1) {
+      valuesHTML += ac.renderItem({
+        value: typeof ac.value[i] === 'object' ? ac.value[i][ac.params.valueProperty] : ac.value[i],
+        text: typeof ac.value[i] === 'object' ? ac.value[i][ac.params.textProperty] : ac.value[i],
+        inputType: ac.inputType,
+        id: ac.id,
+        inputName: `${ac.inputName}-checked}`,
+        selected: true
+      }, i);
+    }
+
+    ac.$el.find('.autocomplete-values ul').html(valuesHTML);
+  }
+
+  preloaderHide() {
+    const ac = this;
+
+    if (ac.params.openIn === 'dropdown' && ac.$dropdownEl) {
+      ac.$dropdownEl.find('.autocomplete-preloader').removeClass('autocomplete-preloader-visible');
+    } else {
+      $('.autocomplete-preloader').removeClass('autocomplete-preloader-visible');
+    }
+  }
+
+  preloaderShow() {
+    const ac = this;
+
+    if (ac.params.openIn === 'dropdown' && ac.$dropdownEl) {
+      ac.$dropdownEl.find('.autocomplete-preloader').addClass('autocomplete-preloader-visible');
+    } else {
+      $('.autocomplete-preloader').addClass('autocomplete-preloader-visible');
+    }
+  }
+
+  renderPreloader() {
+    const ac = this;
+    const preloaders = {
+      iosPreloaderContent,
+      mdPreloaderContent,
+      auroraPreloaderContent
+    };
+    return $jsx("div", {
+      class: `autocomplete-preloader preloader ${ac.params.preloaderColor ? `color-${ac.params.preloaderColor}` : ''}`
+    }, preloaders[`${ac.app.theme}PreloaderContent`] || '');
+  }
+
+  renderSearchbar() {
+    const ac = this;
+    if (ac.params.renderSearchbar) return ac.params.renderSearchbar.call(ac);
+    return $jsx("form", {
+      class: "searchbar"
+    }, $jsx("div", {
+      class: "searchbar-inner"
+    }, $jsx("div", {
+      class: "searchbar-input-wrap"
+    }, $jsx("input", {
+      type: "search",
+      spellcheck: ac.params.searchbarSpellcheck || 'false',
+      placeholder: ac.params.searchbarPlaceholder
+    }), $jsx("i", {
+      class: "searchbar-icon"
+    }), $jsx("span", {
+      class: "input-clear-button"
+    })), ac.params.searchbarDisableButton && $jsx("span", {
+      class: "searchbar-disable-button"
+    }, ac.params.searchbarDisableText)));
+  }
+
+  renderItem(item, index) {
+    const ac = this;
+    if (ac.params.renderItem) return ac.params.renderItem.call(ac, item, index);
+    const itemValue = item.value && typeof item.value === 'string' ? item.value.replace(/"/g, '&quot;') : item.value;
+
+    if (ac.params.openIn !== 'dropdown') {
+      return $jsx("li", null, $jsx("label", {
+        class: `item-${item.inputType} item-content`
+      }, $jsx("input", {
+        type: item.inputType,
+        name: item.inputName,
+        value: itemValue,
+        _checked: item.selected
+      }), $jsx("i", {
+        class: `icon icon-${item.inputType}`
+      }), $jsx("div", {
+        class: "item-inner"
+      }, $jsx("div", {
+        class: "item-title"
+      }, item.text))));
+    } // Dropdown
+
+
+    if (!item.placeholder) {
+      return $jsx("li", null, $jsx("label", {
+        class: "item-radio item-content",
+        "data-value": itemValue
+      }, $jsx("div", {
+        class: "item-inner"
+      }, $jsx("div", {
+        class: "item-title"
+      }, item.text))));
+    } // Dropwdown placeholder
+
+
+    return $jsx("li", {
+      class: "autocomplete-dropdown-placeholder"
+    }, $jsx("label", {
+      class: "item-content"
+    }, $jsx("div", {
+      class: "item-inner"
+    }, $jsx("div", {
+      class: "item-title"
+    }, item.text))));
+  }
+
+  renderNavbar() {
+    const ac = this;
+    if (ac.params.renderNavbar) return ac.params.renderNavbar.call(ac);
+    let pageTitle = ac.params.pageTitle;
+
+    if (typeof pageTitle === 'undefined' && ac.$openerEl && ac.$openerEl.length) {
+      pageTitle = ac.$openerEl.find('.item-title').text().trim();
+    }
+
+    const inPopup = ac.params.openIn === 'popup'; // eslint-disable-next-line
+
+    const navbarLeft = inPopup ? ac.params.preloader && $jsx("div", {
+      class: "left"
+    }, ac.renderPreloader()) : $jsx("div", {
+      class: "left sliding"
+    }, $jsx("a", {
+      class: "link back"
+    }, $jsx("i", {
+      class: "icon icon-back"
+    }), $jsx("span", {
+      class: "if-not-md"
+    }, ac.params.pageBackLinkText)));
+    const navbarRight = inPopup ? $jsx("div", {
+      class: "right"
+    }, $jsx("a", {
+      class: "link popup-close",
+      "data-popup": ".autocomplete-popup"
+    }, ac.params.popupCloseLinkText)) : ac.params.preloader && $jsx("div", {
+      class: "right"
+    }, ac.renderPreloader());
+    return $jsx("div", {
+      class: `navbar ${ac.params.navbarColorTheme ? `color-${ac.params.navbarColorTheme}` : ''}`
+    }, $jsx("div", {
+      class: "navbar-bg"
+    }), $jsx("div", {
+      class: `navbar-inner ${ac.params.navbarColorTheme ? `color-${ac.params.navbarColorTheme}` : ''}`
+    }, navbarLeft, pageTitle && $jsx("div", {
+      class: "title sliding"
+    }, pageTitle), navbarRight, $jsx("div", {
+      class: "subnavbar sliding"
+    }, ac.renderSearchbar())));
+  }
+
+  renderDropdown() {
+    const ac = this;
+    if (ac.params.renderDropdown) return ac.params.renderDropdown.call(ac, ac.items);
+    return $jsx("div", {
+      class: "autocomplete-dropdown"
+    }, $jsx("div", {
+      class: "autocomplete-dropdown-inner"
+    }, $jsx("div", {
+      class: `list ${!ac.params.expandInput ? 'no-safe-areas' : ''}`
+    }, $jsx("ul", null))), ac.params.preloader && ac.renderPreloader());
+  }
+
+  renderPage(inPopup) {
+    const ac = this;
+    if (ac.params.renderPage) return ac.params.renderPage.call(ac, ac.items);
+    return $jsx("div", {
+      class: "page page-with-subnavbar autocomplete-page",
+      "data-name": "autocomplete-page"
+    }, ac.renderNavbar(inPopup), $jsx("div", {
+      class: "searchbar-backdrop"
+    }), $jsx("div", {
+      class: "page-content"
+    }, $jsx("div", {
+      class: `list autocomplete-list autocomplete-found autocomplete-list-${ac.id} ${ac.params.formColorTheme ? `color-${ac.params.formColorTheme}` : ''}`
+    }, $jsx("ul", null)), $jsx("div", {
+      class: "list autocomplete-not-found"
+    }, $jsx("ul", null, $jsx("li", {
+      class: "item-content"
+    }, $jsx("div", {
+      class: "item-inner"
+    }, $jsx("div", {
+      class: "item-title"
+    }, ac.params.notFoundText))))), $jsx("div", {
+      class: "list autocomplete-values"
+    }, $jsx("ul", null))));
+  }
+
+  renderPopup() {
+    const ac = this;
+    if (ac.params.renderPopup) return ac.params.renderPopup.call(ac, ac.items);
+    return $jsx("div", {
+      class: "popup autocomplete-popup"
+    }, $jsx("div", {
+      class: "view"
+    }, ac.renderPage(true), ";"));
+  }
+
+  onOpen(type, el) {
+    const ac = this;
+    const app = ac.app;
+    const $el = $(el);
+    ac.$el = $el;
+    ac.el = $el[0];
+    ac.openedIn = type;
+    ac.opened = true;
+
+    if (ac.params.openIn === 'dropdown') {
+      ac.attachDropdownEvents();
+      ac.$dropdownEl.addClass('autocomplete-dropdown-in');
+      ac.$inputEl.trigger('input');
+    } else {
+      // Init SB
+      let $searchbarEl = $el.find('.searchbar');
+
+      if (ac.params.openIn === 'page' && app.theme === 'ios' && $searchbarEl.length === 0) {
+        $searchbarEl = $(app.navbar.getElByPage($el)).find('.searchbar');
+      }
+
+      ac.searchbar = app.searchbar.create({
+        el: $searchbarEl,
+        backdropEl: $el.find('.searchbar-backdrop'),
+        customSearch: true,
+        on: {
+          search(sb, query) {
+            if (query.length === 0 && ac.searchbar.enabled) {
+              ac.searchbar.backdropShow();
+            } else {
+              ac.searchbar.backdropHide();
+            }
+
+            ac.source(query);
+          }
+
+        }
+      }); // Attach page events
+
+      ac.attachPageEvents(); // Update Values On Page Init
+
+      ac.updateValues(); // Source on load
+
+      if (ac.params.requestSourceOnOpen) ac.source('');
+    }
+
+    ac.emit('local::open autocompleteOpen', ac);
+  }
+
+  autoFocus() {
+    const ac = this;
+
+    if (ac.searchbar && ac.searchbar.$inputEl) {
+      ac.searchbar.$inputEl.focus();
+    }
+
+    return ac;
+  }
+
+  onOpened() {
+    const ac = this;
+
+    if (ac.params.openIn !== 'dropdown' && ac.params.autoFocus) {
+      ac.autoFocus();
+    }
+
+    ac.emit('local::opened autocompleteOpened', ac);
+  }
+
+  onClose() {
+    const ac = this;
+    if (ac.destroyed) return; // Destroy SB
+
+    if (ac.searchbar && ac.searchbar.destroy) {
+      ac.searchbar.destroy();
+      ac.searchbar = null;
+      delete ac.searchbar;
+    }
+
+    if (ac.params.openIn === 'dropdown') {
+      ac.detachDropdownEvents();
+      ac.$dropdownEl.removeClass('autocomplete-dropdown-in').remove();
+      ac.$inputEl.parents('.item-content-dropdown-expanded').removeClass('item-content-dropdown-expanded');
+    } else {
+      ac.detachPageEvents();
+    }
+
+    ac.emit('local::close autocompleteClose', ac);
+  }
+
+  onClosed() {
+    const ac = this;
+    if (ac.destroyed) return;
+    ac.opened = false;
+    ac.$el = null;
+    ac.el = null;
+    delete ac.$el;
+    delete ac.el;
+    ac.emit('local::closed autocompleteClosed', ac);
+  }
+
+  openPage() {
+    const ac = this;
+    if (ac.opened) return ac;
+    const pageHtml = ac.renderPage();
+    ac.view.router.navigate({
+      url: ac.url,
+      route: {
+        content: pageHtml,
+        path: ac.url,
+        on: {
+          pageBeforeIn(e, page) {
+            ac.onOpen('page', page.el);
+          },
+
+          pageAfterIn(e, page) {
+            ac.onOpened('page', page.el);
+          },
+
+          pageBeforeOut(e, page) {
+            ac.onClose('page', page.el);
+          },
+
+          pageAfterOut(e, page) {
+            ac.onClosed('page', page.el);
+          }
+
+        },
+        options: {
+          animate: ac.params.animate
+        }
+      }
+    });
+    return ac;
+  }
+
+  openPopup() {
+    const ac = this;
+    if (ac.opened) return ac;
+    const popupHtml = ac.renderPopup();
+    const popupParams = {
+      content: popupHtml,
+      animate: ac.params.animate,
+      push: ac.params.popupPush,
+      swipeToClose: ac.params.popupSwipeToClose,
+      on: {
+        popupOpen(popup) {
+          ac.onOpen('popup', popup.el);
+        },
+
+        popupOpened(popup) {
+          ac.onOpened('popup', popup.el);
+        },
+
+        popupClose(popup) {
+          ac.onClose('popup', popup.el);
+        },
+
+        popupClosed(popup) {
+          ac.onClosed('popup', popup.el);
+        }
+
+      }
+    };
+
+    if (ac.params.routableModals && ac.view) {
+      ac.view.router.navigate({
+        url: ac.url,
+        route: {
+          path: ac.url,
+          popup: popupParams
+        }
+      });
+    } else {
+      ac.modal = ac.app.popup.create(popupParams).open(ac.params.animate);
+    }
+
+    return ac;
+  }
+
+  openDropdown() {
+    const ac = this;
+
+    if (!ac.$dropdownEl) {
+      ac.$dropdownEl = $(ac.renderDropdown());
+    }
+
+    const $listEl = ac.$inputEl.parents('.list');
+
+    if ($listEl.length && ac.$inputEl.parents('.item-content').length > 0 && ac.params.expandInput) {
+      ac.$inputEl.parents('.item-content').addClass('item-content-dropdown-expanded');
+    }
+
+    const $pageContentEl = ac.$inputEl.parents('.page-content');
+
+    if (ac.params.dropdownContainerEl) {
+      $(ac.params.dropdownContainerEl).append(ac.$dropdownEl);
+    } else if ($pageContentEl.length === 0) {
+      ac.$dropdownEl.insertAfter(ac.$inputEl);
+    } else {
+      ac.positionDropdown();
+      $pageContentEl.append(ac.$dropdownEl);
+    }
+
+    ac.onOpen('dropdown', ac.$dropdownEl);
+    ac.onOpened('dropdown', ac.$dropdownEl);
+  }
+
+  open() {
+    const ac = this;
+    if (ac.opened) return ac;
+    const openIn = ac.params.openIn;
+    ac[`open${openIn.split('').map((el, index) => {
+      if (index === 0) return el.toUpperCase();
+      return el;
+    }).join('')}`]();
+    return ac;
+  }
+
+  close() {
+    const ac = this;
+    if (!ac.opened) return ac;
+
+    if (ac.params.openIn === 'dropdown') {
+      ac.onClose();
+      ac.onClosed();
+    } else if (ac.params.routableModals && ac.view || ac.openedIn === 'page') {
+      ac.view.router.back({
+        animate: ac.params.animate
+      });
+    } else {
+      ac.modal.once('modalClosed', () => {
+        nextTick(() => {
+          if (ac.destroyed) return;
+          ac.modal.destroy();
+          delete ac.modal;
+        });
+      });
+      ac.modal.close();
+    }
+
+    return ac;
+  }
+
+  init() {
+    const ac = this;
+    ac.attachEvents();
+  }
+
+  destroy() {
+    const ac = this;
+    ac.emit('local::beforeDestroy autocompleteBeforeDestroy', ac);
+    ac.detachEvents();
+
+    if (ac.$inputEl && ac.$inputEl[0]) {
+      delete ac.$inputEl[0].f7Autocomplete;
+    }
+
+    if (ac.$openerEl && ac.$openerEl[0]) {
+      delete ac.$openerEl[0].f7Autocomplete;
+    }
+
+    deleteProps(ac);
+    ac.destroyed = true;
+  }
+
+}
+
+export default Autocomplete;

+ 17 - 0
data/html/framework7/components/autocomplete/autocomplete-ios.less

@@ -0,0 +1,17 @@
+.ios {
+  .autocomplete-dropdown {
+    .autocomplete-preloader {
+      .ltr({ right: 16px; });
+      .rtl({ left: 16px; });
+      margin-bottom: 12px;
+    }
+  }
+  .searchbar-input-wrap .autocomplete-dropdown {
+    margin-top: calc(-1 * var(--f7-searchbar-input-height));
+    top: 100%;
+    z-index: 20;
+    .autocomplete-dropdown-inner {
+      padding-top: var(--f7-searchbar-input-height);
+    }
+  }
+}

+ 30 - 0
data/html/framework7/components/autocomplete/autocomplete-md.less

@@ -0,0 +1,30 @@
+.md {
+  .autocomplete-page {
+    .navbar .autocomplete-preloader {
+      .ltr({ margin-right: 8px; });
+      .rtl({ margin-left: 8px; });
+    }
+  }
+  .autocomplete-popup {
+    .navbar .autocomplete-preloader {
+      .ltr({
+        margin-left: 8px;
+        margin-right: 16px;
+      });
+      .rtl({
+        margin-right: 8px;
+        margin-left: 16px;
+      });
+    }
+  }
+  .autocomplete-dropdown {
+    .autocomplete-preloader {
+      .ltr({ right: 16px; });
+      .rtl({ left: 16px; });
+      margin-bottom: 8px;
+      circle {
+        stroke-width: 3;
+      }
+    }
+  }
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/autocomplete/autocomplete-rtl.css


+ 50 - 0
data/html/framework7/components/autocomplete/autocomplete-vars.less

@@ -0,0 +1,50 @@
+:root {
+  --f7-autocomplete-dropdown-placeholder-color: #a9a9a9;
+  --f7-autocomplete-dropdown-preloader-size: 20px;
+  --f7-autocomplete-dropdown-font-size: var(--f7-list-font-size);
+  /*
+  --f7-autocomplete-dropdown-selected-bg-color: rgba(var(--f7-theme-color-rgb), 0.2);
+  */
+  .light-vars({
+    --f7-autocomplete-dropdown-bg-color: #fff;
+  });
+  .dark-vars({
+    --f7-autocomplete-dropdown-bg-color: #1c1c1d;
+  });
+}
+.ios-vars({
+  --f7-autocomplete-dropdown-box-shadow: 0px 3px 3px rgba(0,0,0,0.2);
+  --f7-autocomplete-dropdown-text-matching-font-weight: 600;
+  .light-vars({
+    --f7-autocomplete-dropdown-text-color: #000;
+    --f7-autocomplete-dropdown-text-matching-color: #000;
+  });
+  .dark-vars({
+    --f7-autocomplete-dropdown-text-color: #fff;
+    --f7-autocomplete-dropdown-text-matching-color: #fff;
+  });
+});
+.md-vars({
+  --f7-autocomplete-dropdown-box-shadow: 0 2px 2px rgba(0,0,0,0.25);
+  --f7-autocomplete-dropdown-text-matching-font-weight: 400;
+  .light-vars({
+    --f7-autocomplete-dropdown-text-color: rgba(0,0,0,0.54);
+    --f7-autocomplete-dropdown-text-matching-color: #212121;
+  });
+  .dark-vars({
+    --f7-autocomplete-dropdown-text-color: rgba(255,255,255,0.54);
+    --f7-autocomplete-dropdown-text-matching-color: rgba(255,255,255,0.87);
+  });
+});
+.aurora-vars({
+  --f7-autocomplete-dropdown-box-shadow: 0px 1px 2px rgba(0,0,0,0.2);
+  --f7-autocomplete-dropdown-text-matching-font-weight: 700;
+  .light-vars({
+    --f7-autocomplete-dropdown-text-color: #000;
+    --f7-autocomplete-dropdown-text-matching-color: #000;
+  });
+  .dark-vars({
+    --f7-autocomplete-dropdown-text-color: #fff;
+    --f7-autocomplete-dropdown-text-matching-color: #fff;
+  });
+});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/autocomplete/autocomplete.css


+ 195 - 0
data/html/framework7/components/autocomplete/autocomplete.d.ts

@@ -0,0 +1,195 @@
+import { Dom7Array } from 'dom7';
+import Framework7, {
+  CSSSelector,
+  Framework7EventsClass,
+  Framework7Plugin,
+} from '../app/app-class.js';
+import { Searchbar } from '../searchbar/searchbar.js';
+import { View } from '../view/view.js';
+
+export namespace Autocomplete {
+  interface Autocomplete extends Framework7EventsClass<Events> {
+    /** Link to global app instance */
+    app: Framework7;
+    /** Object with passed initialization parameters */
+    params: Parameters;
+    /** Array with selected items */
+    value: unknown[];
+    /** true if Autocomplete is currently opened */
+    opened: boolean;
+    /** HTML element of Autocomplete opener element (if passed on init) */
+    openerEl: HTMLElement | undefined;
+    /** Dom7 instance of of Autocomplete opener element (if passed on init) */
+    $openerEl: Dom7Array | undefined;
+    /** HTML element of Autocomplete input (if passed on init) */
+    inputEl: HTMLElement | undefined;
+    /** Dom7 instance of of Autocomplete input (if passed on init) */
+    $inputEl: Dom7Array | undefined;
+    /** Dom7 instance of Autocomplete dropdown */
+    $dropdownEl: Dom7Array | undefined;
+    /** Autocomplete URL (that was passed in url parameter) */
+    url: string;
+    /** Autocomplete View (that was passed in view parameter) or found parent view */
+    view: View.View;
+    /** HTML element of Autocomplete container: dropdown element, or popup element, or page element. Available when Autocomplete opened */
+    el: HTMLElement | undefined;
+    /** Dom7 instance of Autocomplete container: dropdown element, or popup element, or page element. Available when Autocomplete opened */
+    $el: Dom7Array | undefined;
+    /** Autocomplete page Searchbar instance */
+    searchbar: Searchbar.Searchbar;
+
+    /** Open Autocomplete (Dropdown, Page or Popup) */
+    open(): void;
+    /** Close Autocomplete */
+    close(): void;
+    /** Show autocomplete preloader */
+    preloaderShow(): void;
+    /** Hide autocomplete preloader */
+    preloaderHide(): void;
+    /** Destroy Autocomplete instance and remove all events */
+    destroy(): void;
+  }
+
+  interface Parameters {
+    /** Defines how to open Autocomplete, can be page or popup (for Standalone) or dropdown. (default page) */
+    openIn?: string;
+    /** Function which accepts search query and render function where you need to pass array with matched items. */
+    source: (query: string, render: (items: any[]) => void) => void;
+    /** Limit number of maximum displayed items in autocomplete per query. */
+    limit?: number;
+    /** Set to true to include Preloader to autocomplete layout. (default false) */
+    preloader?: boolean;
+    /** Preloader color, one of the default colors. */
+    preloaderColor?: string;
+    /** Array with default selected values. */
+    value?: unknown[];
+    /** Name of matched item object's key that represents item value. (default id) */
+    valueProperty?: string;
+    /** Name of matched item object's key that represents item display value which is used as title of displayed options. (default text) */
+    textProperty?: string;
+    /** If enabled, then it will request passed to source function on autocomplete open. (default false) */
+    requestSourceOnOpen?: boolean;
+    /** String with CSS selector or HTMLElement of link which will open standalone autocomplete page or popup on click. */
+    openerEl?: HTMLElement | CSSSelector;
+    /** Default text for "Close" button when opened as Popup. (default Close) */
+    popupCloseLinkText?: string;
+    /** Default text for "Back" link when opened as Page. (default Back) */
+    pageBackLinkText?: string;
+    /** Autocomplete page title. If nothing is specified and passed openerEl is an item of List View, then text value of item-title element will be used. */
+    pageTitle?: string;
+    /** Searchbar placeholder text. (default Search...) */
+    searchbarPlaceholder?: string;
+    /** Searchbar "Cancel" button text. (default Cancel) */
+    searchbarDisableText?: string;
+    /** Enables searchbar disable button. By default, disabled for Aurora theme */
+    searchbarDisableButton?: boolean;
+    /** Value of "spellcheck" attribute on searchbar input (default false) */
+    searchbarSpellcheck?: boolean;
+    /** Enables Autocomplete popup to push view/s behind on open (default false)*/
+    popupPush?: boolean;
+    /** Enables ability to close Autocomplete popup with swipe (default undefined) */
+    popupSwipeToClose?: boolean | undefined;
+    /** Text which is displayed when no matches found. (default Nothing found) */
+    notFoundText?: string;
+    /** Set to true to allow multiple selections. (default false) */
+    multiple?: boolean;
+    /** Set to true and autocomplete will be closed when user picks value. Not available if multiple is enabled. (default false) */
+    closeOnSelect?: boolean;
+    /** Set to true to auto focus search field on autocomplete open. (default false) */
+    autoFocus?: boolean;
+    /** Set to false to open standalone autocomplete without animation. (default true) */
+    animate?: boolean;
+    /** Navbar color theme. One of the default color themes. */
+    navbarColorTheme?: string;
+    /** Form (checkboxes or radios) color theme. One of the default color themes. */
+    formColorTheme?: string;
+    /** Will add opened autocomplete modal (when openIn: 'popup') to router history which gives ability to close autocomplete by going back in router history and set current route to the autocomplete modal. (default false) */
+    routableModals?: boolean;
+    /** Standalone autocomplete URL that will be set as a current route. (default select/) */
+    url?: string;
+    /** Link to initialized View instance if you want use standalone Autocomplete. By default, if not specified, it will be opened in Main View.. */
+    view?: View.View;
+    /** String with CSS selector or HTMLElement of related text input. */
+    inputEl?: HTMLElement | CSSSelector;
+    /** Allows to configure input events used to handle Autocomplete actions and source request. Can be changed for example to change keyup compositionend if you use keyboard with composition of Chinese characters. (default input) */
+    inputEvents?: string;
+    /** Highlight matches in autocomplete results. (default true) */
+    highlightMatches?: boolean;
+    /** Enables type ahead, will prefill input value with first item in match. (default false) */
+    typeahead?: boolean;
+    /** Specify dropdown placeholder text. */
+    dropdownPlaceholderText?: string;
+    /** If true then value of related input will be update as well. (default true) */
+    updateInputValueOnSelect?: boolean;
+    /** If true then input which is used as item-input in List View will be expanded to full screen wide during dropdown visible.. (default false) */
+    expandInput?: boolean;
+    /** By default dropdown will be added to parent page-content element. You can specify here different element where to add dropdown element. */
+    dropdownContainerEl?: HTMLElement | CSSSelector;
+    /** Function to render autocomplete dropdown, must return dropdown HTML string. */
+    renderDropdown?: (items: any[]) => string;
+    /** Function to render autocomplete page, must return page HTML string. */
+    renderPage?: (items: any[]) => string;
+    /** Function to render autocomplete popup, must return popup HTML string. */
+    renderPopup?: (items: any[]) => string;
+    /** Function to render single autocomplete, must return item HTML string. */
+    renderItem?: (item: any, index: number) => string;
+    /** Function to render searchbar, must return searchbar HTML string. */
+    renderSearchbar?: () => string;
+    /** Function to render navbar, must return navbar HTML string. */
+    renderNavbar?: () => string;
+
+    on?: {
+      [event in keyof Events]?: Events[event];
+    };
+  }
+
+  interface Events {
+    /** Event will be triggered when Autocomplete value changed. Returned value is an array with selected items */
+    change: (values: any[]) => void;
+    /** Event will be triggered when Autocomplete starts its opening animation. As an argument event handler receives autocomplete instance */
+    open: (autocomplete: Autocomplete) => void;
+    /** Event will be triggered after Autocomplete completes its opening animation. As an argument event handler receives autocomplete instance */
+    opened: (autocomplete: Autocomplete) => void;
+    /** Event will be triggered when Autocomplete starts its closing animation. As an argument event handler receives autocomplete instance */
+    close: (autocomplete: Autocomplete) => void;
+    /** Event will be triggered after Autocomplete completes its closing animation. As an argument event handler receives autocomplete instance */
+    closed: (autocomplete: Autocomplete) => void;
+    /** Event will be triggered right before Autocomplete instance will be destroyed. As an argument event handler receives autocomplete instance */
+    beforeDestroy: (autocomplete: Autocomplete) => void;
+  }
+
+  interface AppMethods {
+    autocomplete: {
+      /** create Autocomplete instance */
+      create(parameters: Parameters): Autocomplete;
+      /** destroy Autocomplete instance */
+      destroy(el: HTMLElement | CSSSelector): void;
+      /** get Autocomplete instance by HTML element */
+      get(el: HTMLElement | CSSSelector): Autocomplete;
+      /** open Autocomplete */
+      open(el: HTMLElement | CSSSelector): Autocomplete;
+      /** closes Autocomplete */
+      close(el: HTMLElement | CSSSelector): Autocomplete;
+    };
+  }
+  interface AppParams {
+    autocomplete?: Parameters | undefined;
+  }
+  interface AppEvents {
+    /** Event will be triggered when Autocomplete value changed. Returned value is an array with selected items */
+    autocompleteChange: (autocomplete: Autocomplete, value: unknown) => void;
+    /** Event will be triggered when Autocomplete starts its opening animation. As an argument event handler receives autocomplete instance */
+    autocompleteOpen: (autocomplete: Autocomplete) => void;
+    /** Event will be triggered after Autocomplete completes its opening animation. As an argument event handler receives autocomplete instance */
+    autocompleteOpened: (autocomplete: Autocomplete) => void;
+    /** Event will be triggered when Autocomplete starts its closing animation. As an argument event handler receives autocomplete instance */
+    autocompleteClose: (autocomplete: Autocomplete) => void;
+    /** Event will be triggered after Autocomplete completes its closing animation. As an argument event handler receives autocomplete instance */
+    autocompleteClosed: (autocomplete: Autocomplete) => void;
+    /** Event will be triggered right before Autocomplete instance will be destroyed. As an argument event handler receives autocomplete instance */
+    autocompleteBeforeDestroy: (autocomplete: Autocomplete) => void;
+  }
+}
+declare const AutocompleteComponent: Framework7Plugin;
+
+export default AutocompleteComponent;

+ 86 - 0
data/html/framework7/components/autocomplete/autocomplete.js

@@ -0,0 +1,86 @@
+import { extend } from '../../shared/utils.js';
+import Autocomplete from './autocomplete-class.js';
+import ConstructorMethods from '../../shared/constructor-methods.js';
+export default {
+  name: 'autocomplete',
+  params: {
+    autocomplete: {
+      openerEl: undefined,
+      inputEl: undefined,
+      view: undefined,
+      // DropDown
+      dropdownContainerEl: undefined,
+      dropdownPlaceholderText: undefined,
+      typeahead: false,
+      highlightMatches: true,
+      expandInput: false,
+      updateInputValueOnSelect: true,
+      inputEvents: 'input',
+      value: undefined,
+      multiple: false,
+      source: undefined,
+      limit: undefined,
+      valueProperty: 'id',
+      textProperty: 'text',
+      openIn: 'page',
+      // or 'popup' or 'dropdown'
+      pageBackLinkText: 'Back',
+      popupCloseLinkText: 'Close',
+      pageTitle: undefined,
+      searchbarPlaceholder: 'Search...',
+      searchbarDisableText: 'Cancel',
+      searchbarDisableButton: undefined,
+      searchbarSpellcheck: false,
+      popupPush: false,
+      popupSwipeToClose: undefined,
+      animate: true,
+      autoFocus: false,
+      closeOnSelect: false,
+      notFoundText: 'Nothing found',
+      requestSourceOnOpen: false,
+      // Preloader
+      preloaderColor: undefined,
+      preloader: false,
+      // Colors
+      formColorTheme: undefined,
+      navbarColorTheme: undefined,
+      // Routing
+      routableModals: false,
+      url: 'select/',
+      // Custom render functions
+      renderDropdown: undefined,
+      renderPage: undefined,
+      renderPopup: undefined,
+      renderItem: undefined,
+      renderSearchbar: undefined,
+      renderNavbar: undefined
+    }
+  },
+  static: {
+    Autocomplete
+  },
+
+  create() {
+    const app = this;
+    app.autocomplete = extend(ConstructorMethods({
+      defaultSelector: undefined,
+      constructor: Autocomplete,
+      app,
+      domProp: 'f7Autocomplete'
+    }), {
+      open(autocompleteEl) {
+        const ac = app.autocomplete.get(autocompleteEl);
+        if (ac && ac.open) return ac.open();
+        return undefined;
+      },
+
+      close(autocompleteEl) {
+        const ac = app.autocomplete.get(autocompleteEl);
+        if (ac && ac.close) return ac.close();
+        return undefined;
+      }
+
+    });
+  }
+
+};

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/autocomplete/autocomplete.lazy.js


+ 114 - 0
data/html/framework7/components/autocomplete/autocomplete.less

@@ -0,0 +1,114 @@
+/* === Autocomplete === */
+@import './autocomplete-vars.less';
+
+.autocomplete-page {
+  .autocomplete-found {
+    display: block;
+  }
+  .autocomplete-not-found {
+    display: none;
+  }
+  .autocomplete-values {
+    display: block;
+  }
+  .list ul:empty {
+    display: none;
+  }
+}
+.autocomplete-preloader:not(.autocomplete-preloader-visible) {
+  visibility: hidden;
+  &,
+  * {
+    animation: none;
+  }
+}
+.autocomplete-dropdown {
+  background: var(--f7-autocomplete-dropdown-bg-color);
+  box-shadow: var(--f7-autocomplete-dropdown-box-shadow);
+  box-sizing: border-box;
+  position: absolute;
+  z-index: 500;
+  width: 100%;
+  .ltr({ left: 0; });
+  .rtl({ right: 0; });
+  .autocomplete-dropdown-inner {
+    position: relative;
+    .scrollable();
+    height: 100%;
+    z-index: 1;
+  }
+  .autocomplete-preloader {
+    display: none;
+    position: absolute;
+    bottom: 100%;
+    width: var(--f7-autocomplete-dropdown-preloader-size);
+    height: var(--f7-autocomplete-dropdown-preloader-size);
+  }
+  .autocomplete-preloader-visible {
+    display: block;
+  }
+  .autocomplete-dropdown-placeholder {
+    color: var(--f7-autocomplete-dropdown-placeholder-color);
+  }
+  .list {
+    margin: 0;
+    color: var(--f7-autocomplete-dropdown-text-color);
+    font-size: var(--f7-autocomplete-dropdown-font-size);
+    b {
+      color: var(--f7-autocomplete-dropdown-text-matching-color);
+      font-weight: var(--f7-autocomplete-dropdown-text-matching-font-weight);
+    }
+    ul {
+      .hairline-remove-top-bottom();
+      background: none !important;
+    }
+  }
+  .autocomplete-dropdown-selected {
+    background: var(
+      --f7-autocomplete-dropdown-selected-bg-color,
+      rgba(var(--f7-theme-color-rgb), 0.2)
+    );
+  }
+}
+.searchbar-input-wrap .autocomplete-dropdown {
+  background-color: var(--f7-searchbar-input-bg-color, var(--f7-searchbar-bg-color));
+  border-radius: var(--f7-searchbar-input-border-radius);
+  .autocomplete-dropdown-placeholder {
+    color: var(--f7-searchbar-placeholder-color);
+  }
+  li:last-child {
+    border-radius: 0 0 var(--f7-searchbar-input-border-radius)
+      var(--f7-searchbar-input-border-radius);
+    position: relative;
+    overflow: hidden;
+  }
+  .item-content {
+    .ltr({ padding-left: calc(var(--f7-searchbar-input-padding-horizontal) + var(--f7-searchbar-input-extra-padding-left, 0px)); });
+    .rtl({ padding-right: calc(var(--f7-searchbar-input-padding-horizontal) + var(--f7-searchbar-input-extra-padding-left, 0px)); });
+  }
+}
+
+.list .item-content-dropdown-expanded {
+  .item-title.item-label {
+    width: 0;
+    flex-shrink: 10;
+    overflow: hidden;
+    + .item-input-wrap {
+      .ltr({ margin-left: 0; });
+      .rtl({ margin-right: 0; });
+    }
+  }
+  .item-input-wrap {
+    width: 100%;
+  }
+}
+
+.if-ios-theme({
+  @import './autocomplete-ios.less';
+});
+.if-md-theme({
+  @import './autocomplete-md.less';
+});
+.if-aurora-theme({
+  @import './autocomplete-aurora.less';
+});

+ 2 - 0
data/html/framework7/components/badge/badge-aurora.less

@@ -0,0 +1,2 @@
+.aurora {
+}

+ 2 - 0
data/html/framework7/components/badge/badge-ios.less

@@ -0,0 +1,2 @@
+.ios {
+}

+ 2 - 0
data/html/framework7/components/badge/badge-md.less

@@ -0,0 +1,2 @@
+.md {
+}

+ 21 - 0
data/html/framework7/components/badge/badge-vars.less

@@ -0,0 +1,21 @@
+:root {
+  --f7-badge-text-color: #fff;
+  --f7-badge-bg-color: #8e8e93;
+  --f7-badge-padding: 0 4px;
+  --f7-badge-in-icon-size: 16px;
+  --f7-badge-in-icon-font-size: 10px;
+  --f7-badge-font-weight: normal;
+  --f7-badge-font-size: 12px;
+}
+.ios-vars({
+  --f7-badge-size: 20px;
+  --f7-badge-font-weight: 600;
+});
+.md-vars({
+  --f7-badge-size: 18px;
+  --f7-badge-font-weight: 500;
+});
+.aurora-vars({
+  --f7-badge-size: 18px;
+  --f7-badge-font-weight: 600;
+});

+ 14 - 0
data/html/framework7/components/badge/badge.d.ts

@@ -0,0 +1,14 @@
+import Framework7, {
+  CSSSelector,
+  Framework7EventsClass,
+  Framework7Plugin,
+} from '../app/app-class.js';
+
+export namespace Badge {
+  interface AppMethods {}
+  interface AppParams {}
+  interface AppEvents {}
+}
+
+declare const BadgeComponent: Framework7Plugin;
+export default BadgeComponent;

+ 3 - 0
data/html/framework7/components/badge/badge.js

@@ -0,0 +1,3 @@
+export default {
+  name: 'badge'
+};

+ 47 - 0
data/html/framework7/components/badge/badge.less

@@ -0,0 +1,47 @@
+/* === Badge === */
+@import './badge-vars.less';
+
+.badge {
+  display: inline-flex;
+  align-items: center;
+  align-content: center;
+  justify-content: center;
+  color: var(--f7-badge-text-color);
+  background: var(--f7-badge-bg-color);
+  position: relative;
+  box-sizing: border-box;
+  text-align: center;
+  vertical-align: middle;
+  font-weight: var(--f7-badge-font-weight);
+  font-size: var(--f7-badge-font-size);
+  border-radius: var(--f7-badge-size);
+  padding: var(--f7-badge-padding);
+  height: var(--f7-badge-size);
+  min-width: var(--f7-badge-size);
+
+  .icon &,
+  .f7-icons &,
+  .framework7-icons &,
+  .material-icons & {
+    position: absolute;
+    left: 100%;
+    margin-left: -10px;
+    top: -2px;
+    font-family: var(--f7-font-family);
+    --f7-badge-font-size: var(--f7-badge-in-icon-font-size);
+    --f7-badge-size: var(--f7-badge-in-icon-size);
+  }
+}
+.badge[class*='color-'] {
+  --f7-badge-bg-color: var(--f7-theme-color);
+}
+
+.if-ios-theme({
+  @import './badge-ios.less';
+});
+.if-md-theme({
+  @import './badge-md.less';
+});
+.if-aurora-theme({
+  @import './badge-aurora.less';
+});

+ 2 - 0
data/html/framework7/components/block/block-aurora.less

@@ -0,0 +1,2 @@
+.aurora {
+}

+ 2 - 0
data/html/framework7/components/block/block-ios.less

@@ -0,0 +1,2 @@
+.ios {
+}

+ 2 - 0
data/html/framework7/components/block/block-md.less

@@ -0,0 +1,2 @@
+.md {
+}

+ 104 - 0
data/html/framework7/components/block/block-vars.less

@@ -0,0 +1,104 @@
+:root {
+  --f7-block-padding-horizontal: 16px;
+  --f7-block-padding-vertical: 16px;
+  --f7-block-font-size: inherit;
+  --f7-block-text-color: inherit;
+  --f7-block-header-margin: 10px;
+  --f7-block-footer-margin: 10px;
+  --f7-block-header-font-size: 14px;
+  --f7-block-footer-font-size: 14px;
+  --f7-block-title-text-transform: none;
+  --f7-block-title-white-space: nowrap;
+  --f7-block-title-medium-text-transform: none;
+  --f7-block-title-large-text-transform: none;
+  --f7-block-inset-side-margin: 16px;
+  .light-vars({
+    --f7-block-title-medium-text-color: #000;
+    --f7-block-title-large-text-color: #000;
+    --f7-block-strong-bg-color: #fff;
+  });
+  .dark-vars({
+    --f7-block-title-text-color: #fff;
+    --f7-block-strong-border-color: rgba(255, 255, 255, 0.15);
+    --f7-block-title-medium-text-color: #fff;
+    --f7-block-title-large-text-color: #fff;
+    --f7-block-strong-bg-color: #1c1c1d;
+  });
+}
+.ios-vars({
+  --f7-block-margin-vertical: 35px;
+  --f7-block-strong-border-color: rgba(0,0,0,0.22);
+  --f7-block-title-text-color: #000;
+  --f7-block-title-font-size: 16px;
+  --f7-block-title-font-weight: 600;
+  --f7-block-title-line-height: 20px;
+  --f7-block-title-margin-bottom: 10px;
+  --f7-block-title-medium-font-size: 22px;
+  --f7-block-title-medium-font-weight: bold;
+  --f7-block-title-medium-line-height: 1.4;
+  --f7-block-title-large-font-size: 30px;
+  --f7-block-title-large-font-weight: bold;
+  --f7-block-title-large-line-height: 1.3;
+  --f7-block-inset-border-radius: 8px;
+  .light-vars({
+    --f7-block-strong-text-color: #000;
+    --f7-block-header-text-color: rgba(0, 0, 0, 0.45);
+    --f7-block-footer-text-color: rgba(0, 0, 0, 0.45);
+  });
+  .dark-vars({
+    --f7-block-header-text-color: rgba(255,255,255,0.55);
+    --f7-block-footer-text-color: rgba(255,255,255,0.55);
+    --f7-block-strong-text-color: #fff;
+  });
+});
+.md-vars({
+  --f7-block-margin-vertical: 32px;
+  --f7-block-strong-text-color: inherit;
+  --f7-block-strong-border-color: rgba(0,0,0,0.12);
+  --f7-block-title-font-size: inherit;
+  --f7-block-title-text-color: rgba(0,0,0,0.54);
+  --f7-block-title-font-weight: 500;
+  --f7-block-title-line-height: 16px;
+  --f7-block-title-margin-bottom: 16px;
+  --f7-block-title-medium-font-size: 24px;
+  --f7-block-title-medium-font-weight: 500;
+  --f7-block-title-medium-line-height: 1.3;
+  --f7-block-title-large-font-size: 34px;
+  --f7-block-title-large-font-weight: 500;
+  --f7-block-title-large-line-height: 1.2;
+  --f7-block-inset-border-radius: 4px;
+  .light-vars({
+    --f7-block-header-text-color: rgba(0,0,0,0.54);
+    --f7-block-footer-text-color: rgba(0,0,0,0.54);
+  });
+  .dark-vars({
+    --f7-block-header-text-color: rgba(255,255,255,0.54);
+    --f7-block-footer-text-color: rgba(255,255,255,0.54);
+  });
+});
+.aurora-vars({
+  --f7-block-margin-vertical: 32px;
+  --f7-block-strong-border-color: rgba(0,0,0,0.12);
+  --f7-block-title-font-size: 16px;
+  --f7-block-title-text-color: #000;
+  --f7-block-title-font-weight: 600;
+  --f7-block-title-line-height: 1.5;
+  --f7-block-title-margin-bottom: 10px;
+  --f7-block-title-medium-font-size: 22px;
+  --f7-block-title-medium-font-weight: bold;
+  --f7-block-title-medium-line-height: 1.4;
+  --f7-block-title-large-font-size: 28px;
+  --f7-block-title-large-font-weight: bold;
+  --f7-block-title-large-line-height: 1.3;
+  --f7-block-inset-border-radius: 8px;
+  .light-vars({
+    --f7-block-strong-text-color: inherit;
+    --f7-block-header-text-color: rgba(0,0,0,0.6);
+    --f7-block-footer-text-color: rgba(0,0,0,0.6);
+  });
+  .dark-vars({
+    --f7-block-header-text-color: rgba(255,255,255,0.54);
+    --f7-block-footer-text-color: rgba(255,255,255,0.54);
+    --f7-block-strong-text-color: #fff;
+  });
+});

+ 14 - 0
data/html/framework7/components/block/block.d.ts

@@ -0,0 +1,14 @@
+import Framework7, {
+  CSSSelector,
+  Framework7EventsClass,
+  Framework7Plugin,
+} from '../app/app-class.js';
+
+export namespace Block {
+  interface AppMethods {}
+  interface AppParams {}
+  interface AppEvents {}
+}
+
+declare const BlockComponent: Framework7Plugin;
+export default BlockComponent;

+ 3 - 0
data/html/framework7/components/block/block.js

@@ -0,0 +1,3 @@
+export default {
+  name: 'block'
+};

+ 184 - 0
data/html/framework7/components/block/block.less

@@ -0,0 +1,184 @@
+/* === Content Block === */
+@import './block-vars.less';
+
+.block {
+  box-sizing: border-box;
+  position: relative;
+  z-index: 1;
+  color: var(--f7-block-text-color);
+  margin: var(--f7-block-margin-vertical) 0;
+  padding-top: 0;
+  padding-bottom: 0;
+  padding-left: calc(var(--f7-block-padding-horizontal) + var(--f7-safe-area-left));
+  padding-right: calc(var(--f7-block-padding-horizontal) + var(--f7-safe-area-right));
+  font-size: var(--f7-block-font-size);
+  .no-hairlines();
+  > h1,
+  > h2,
+  > h3,
+  > h4,
+  > p {
+    &:first-child {
+      margin-top: 0;
+    }
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+}
+.block-strong {
+  color: var(--f7-block-strong-text-color);
+  padding-top: var(--f7-block-padding-vertical);
+  padding-bottom: var(--f7-block-padding-vertical);
+  background-color: var(--f7-block-strong-bg-color);
+  .hairline(top, var(--f7-block-strong-border-color));
+  .hairline(bottom, var(--f7-block-strong-border-color));
+}
+.block-title {
+  position: relative;
+  overflow: hidden;
+  margin: 0;
+  white-space: var(--f7-block-title-white-space);
+  text-overflow: ellipsis;
+  text-transform: var(--f7-block-title-text-transform);
+  color: var(--f7-block-title-text-color);
+  font-size: var(--f7-block-title-font-size, inherit);
+  font-weight: var(--f7-block-title-font-weight);
+  line-height: var(--f7-block-title-line-height);
+  margin-top: var(--f7-block-margin-vertical);
+  margin-bottom: var(--f7-block-title-margin-bottom);
+  margin-left: calc(var(--f7-block-padding-horizontal) + var(--f7-safe-area-left));
+  margin-right: calc(var(--f7-block-padding-horizontal) + var(--f7-safe-area-right));
+  + .list,
+  + .block,
+  + .card,
+  + .timeline,
+  + .block-header {
+    margin-top: 0px;
+  }
+}
+.block-title-medium {
+  font-size: var(--f7-block-title-medium-font-size);
+  text-transform: var(--f7-block-title-medium-text-transform);
+  color: var(--f7-block-title-medium-text-color);
+  font-weight: var(--f7-block-title-medium-font-weight);
+  line-height: var(--f7-block-title-medium-line-height);
+}
+.block-title-large {
+  font-size: var(--f7-block-title-large-font-size);
+  text-transform: var(--f7-block-title-large-text-transform);
+  color: var(--f7-block-title-large-text-color);
+  font-weight: var(--f7-block-title-large-font-weight);
+  line-height: var(--f7-block-title-large-line-height);
+}
+.block,
+.list {
+  > .block-title:first-child {
+    margin-top: 0;
+    margin-left: 0;
+    margin-right: 0;
+  }
+}
+// Header/Footer
+.block-header {
+  color: var(--f7-block-header-text-color);
+  font-size: var(--f7-block-header-font-size);
+  margin-bottom: var(--f7-block-header-margin);
+  margin-top: var(--f7-block-margin-vertical);
+  + .list,
+  + .block,
+  + .card,
+  + .timeline {
+    margin-top: var(--f7-block-header-margin);
+  }
+}
+.block-footer {
+  color: var(--f7-block-footer-text-color);
+  font-size: var(--f7-block-footer-font-size);
+  margin-top: var(--f7-block-footer-margin);
+  margin-bottom: var(--f7-block-margin-vertical);
+}
+.block-footer,
+.block-header {
+  padding-top: 0;
+  padding-bottom: 0;
+  padding-left: calc(var(--f7-block-padding-horizontal) + var(--f7-safe-area-left));
+  padding-right: calc(var(--f7-block-padding-horizontal) + var(--f7-safe-area-right));
+  ul,
+  p,
+  h1,
+  h2,
+  h3,
+  h4 {
+    &:first-child {
+      margin-top: 0;
+    }
+    &:last-child {
+      margin-bottom: 0;
+    }
+    &:first-child:last-child {
+      margin-top: 0;
+      margin-bottom: 0;
+    }
+  }
+}
+.list,
+.block,
+.card,
+.timeline {
+  .block-header {
+    margin-top: 0;
+  }
+  .block-footer {
+    margin-bottom: 0;
+  }
+  + .block-footer {
+    margin-top: calc(-1 * (var(--f7-block-margin-vertical) - var(--f7-block-footer-margin)));
+  }
+}
+.block + .block-footer {
+  margin-top: calc(-1 * (var(--f7-block-margin-vertical) - var(--f7-block-footer-margin)));
+  margin-bottom: var(--f7-block-margin-vertical);
+}
+.block {
+  .block-header,
+  .block-footer {
+    padding: 0;
+  }
+}
+// Inset
+.block.inset {
+  border-radius: var(--f7-block-inset-border-radius);
+  margin-left: calc(var(--f7-block-inset-side-margin) + var(--f7-safe-area-outer-left));
+  margin-right: calc(var(--f7-block-inset-side-margin) + var(--f7-safe-area-outer-right));
+  --f7-safe-area-left: 0px;
+  --f7-safe-area-right: 0px;
+}
+.block-strong.inset {
+  .hairline-remove-top-bottom();
+}
+
+each(@breakpoints, {
+  @media (min-width:@value) {
+    .block.@{key}-inset {
+      border-radius: var(--f7-block-inset-border-radius);
+      margin-left: calc(var(--f7-block-inset-side-margin) + var(--f7-safe-area-outer-left));
+      margin-right: calc(var(--f7-block-inset-side-margin) + var(--f7-safe-area-outer-right));
+      --f7-safe-area-left: 0px;
+      --f7-safe-area-right: 0px;
+    }
+    .block-strong.@{key}-inset {
+      .hairline-remove-top-bottom();
+    }
+  }
+});
+
+.if-ios-theme({
+  @import './block-ios.less';
+});
+.if-md-theme({
+  @import './block-md.less';
+});
+.if-aurora-theme({
+  @import './block-aurora.less';
+});

+ 2 - 0
data/html/framework7/components/breadcrumbs/breadcrumbs-aurora.less

@@ -0,0 +1,2 @@
+.aurora {
+}

+ 2 - 0
data/html/framework7/components/breadcrumbs/breadcrumbs-ios.less

@@ -0,0 +1,2 @@
+.ios {
+}

+ 2 - 0
data/html/framework7/components/breadcrumbs/breadcrumbs-md.less

@@ -0,0 +1,2 @@
+.md {
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/breadcrumbs/breadcrumbs-rtl.css


+ 36 - 0
data/html/framework7/components/breadcrumbs/breadcrumbs-vars.less

@@ -0,0 +1,36 @@
+:root {
+  --f7-breadcrumbs-spacing: 12px;
+  --f7-breadcrumbs-padding: 2px 0;
+  --f7-breadcrumbs-item-padding: 0px;
+  --f7-breadcrumbs-item-bg-color: 0px;
+  --f7-breadcrumbs-item-font-weight: normal;
+  --f7-breadcrumbs-item-active-font-weight: 600;
+  --f7-breadcrumbs-icon-size: 24px;
+
+  .light-vars({
+    --f7-breadcrumbs-item-color: rgba(0,0,0,0.55);
+    --f7-breadcrumbs-separator-color: rgba(0,0,0,0.35);
+    --f7-breadcrumbs-item-active-color: #000;
+    --f7-breadcrumbs-collapsed-color: rgba(0,0,0,0.75);
+    --f7-breadcrumbs-collapsed-bg-color: rgba(0, 0, 0, 0.15);
+  });
+  .dark-vars({
+    --f7-breadcrumbs-item-color: rgba(255,255,255,0.75);
+    --f7-breadcrumbs-separator-color: rgba(255,255,255,0.35);
+    --f7-breadcrumbs-item-active-color: #fff;
+    --f7-breadcrumbs-collapsed-color: rgba(255,255,255,0.75);
+    --f7-breadcrumbs-collapsed-bg-color: rgba(255, 255, 255, 0.15);
+  });
+}
+.ios-vars({
+  --f7-breadcrumbs-separator-icon: 'chevron_right_ios';
+  --f7-breadcrumbs-font-size: 17px;
+});
+.md-vars({
+  --f7-breadcrumbs-separator-icon: 'chevron_right_md';
+  --f7-breadcrumbs-font-size: 16px;
+});
+.aurora-vars({
+  --f7-breadcrumbs-separator-icon: 'chevron_right_ios';
+  --f7-breadcrumbs-font-size: 16px;
+});

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
data/html/framework7/components/breadcrumbs/breadcrumbs.css


+ 15 - 0
data/html/framework7/components/breadcrumbs/breadcrumbs.d.ts

@@ -0,0 +1,15 @@
+import Framework7 from '../app/app-class.js';
+import { CSSSelector, Framework7Plugin } from '../app/app-class.js';
+
+export namespace Breadcrumbs {
+  interface AppMethods {
+    breadcrumbs: {};
+  }
+  interface AppParams {}
+  interface DomEvents {}
+  interface AppEvents {}
+}
+
+declare const BreadcrumbsComponent: Framework7Plugin;
+
+export default BreadcrumbsComponent;

+ 13 - 0
data/html/framework7/components/breadcrumbs/breadcrumbs.js

@@ -0,0 +1,13 @@
+import { bindMethods } from '../../shared/utils.js';
+const Breadcrumbs = {};
+export default {
+  name: 'breadrumbs',
+
+  create() {
+    const app = this;
+    bindMethods(app, {
+      breadrumbs: Breadcrumbs
+    });
+  }
+
+};

+ 1 - 0
data/html/framework7/components/breadcrumbs/breadcrumbs.lazy.js

@@ -0,0 +1 @@
+(function framework7ComponentLoader(e,t){void 0===t&&(t=!0);e.$;var o=e.utils,s=(e.getDevice,e.getSupport,e.Class,e.Modal,e.ConstructorMethods,e.ModalMethods,e.$jsx,o.bindMethods);const r={};var a={name:"breadrumbs",create(){s(this,{breadrumbs:r})}};if(t){if(e.prototype.modules&&e.prototype.modules[a.name])return;e.use(a),e.instance&&(e.instance.useModuleParams(a,e.instance.params),e.instance.useModule(a))}return a}(Framework7, typeof Framework7AutoInstallComponent === 'undefined' ? undefined : Framework7AutoInstallComponent))

+ 100 - 0
data/html/framework7/components/breadcrumbs/breadcrumbs.less

@@ -0,0 +1,100 @@
+/* === Breadcrumbs === */
+@import './breadcrumbs-vars.less';
+
+.breadcrumbs {
+  display: flex;
+  align-items: center;
+  justify-content: flex-start;
+  font-size: var(--f7-breadcrumbs-font-size);
+  overflow: auto;
+  white-space: nowrap;
+  padding: var(--f7-breadcrumbs-padding);
+  &::-webkit-scrollbar {
+    display: none;
+    opacity: 0;
+  }
+}
+.breadcrumbs-separator,
+.breadcrumbs-item,
+.breadcrumbs-collapsed {
+  flex-shrink: 0;
+  --f7-touch-ripple-color: transparent !important;
+  & + & {
+    margin-left: var(--f7-breadcrumbs-spacing);
+  }
+}
+.breadcrumbs-item {
+  color: var(--f7-breadcrumbs-item-color);
+  font-weight: var(--f7-breadcrumbs-item-font-weight);
+  padding: var(--f7-breadcrumbs-item-padding);
+  background-color: var(--f7-breadcrumbs-item-bg-color);
+  display: flex;
+  align-items: center;
+  .icon {
+    font-size: var(--f7-breadcrumbs-icon-size);
+    width: var(--f7-breadcrumbs-icon-size);
+    height: var(--f7-breadcrumbs-icon-size);
+  }
+  a {
+    color: inherit;
+    --f7-touch-ripple-color: transparent !important;
+  }
+  &-active {
+    color: var(--f7-breadcrumbs-item-active-color, var(--f7-breadcrumbs-item-color));
+    font-weight: var(--f7-breadcrumbs-item-active-font-weight);
+  }
+}
+.breadcrumbs-separator {
+  color: var(--f7-breadcrumbs-separator-color);
+  height: 24px;
+  overflow: hidden;
+  display: flex;
+  align-items: center;
+  &::after {
+    .core-icons-font();
+    content: var(--f7-breadcrumbs-separator-icon);
+    width: 12px;
+  }
+  .ios &::after {
+    font-size: 12px;
+    height: 11px;
+  }
+  .md &::after {
+    font-size: 18px;
+    height: 18px;
+  }
+  .aurora &::after {
+    font-size: 12px;
+    height: 11px;
+  }
+}
+.breadcrumbs-collapsed {
+  display: flex;
+  align-items: center;
+  padding: 0 6px;
+  background: var(--f7-breadcrumbs-collapsed-bg-color);
+  height: 1em;
+  border-radius: 4px;
+  cursor: pointer;
+  &::before,
+  &::after,
+  span {
+    content: '';
+    width: 4px;
+    height: 4px;
+    background: var(--f7-breadcrumbs-collapsed-color);
+    border-radius: 50%;
+  }
+  span {
+    margin: 0 3px;
+  }
+}
+.if-ios-theme({
+  @import './breadcrumbs-ios.less';
+});
+.if-md-theme({
+  @import './breadcrumbs-md.less';
+});
+.if-aurora-theme({
+  @import './breadcrumbs-aurora.less';
+});

+ 25 - 0
data/html/framework7/components/button/button-aurora.less

@@ -0,0 +1,25 @@
+.aurora {
+  // Buttons
+  .button {
+    transition-duration: 100ms;
+    transform: translate3d(0, 0, 0);
+  }
+  &.device-desktop {
+    .button:not(.active-state):not(.no-hover):hover {
+      background-color: var(--f7-button-hover-bg-color, rgba(var(--f7-theme-color-rgb), 0.07));
+    }
+  }
+  .button-fill,
+  .button-fill-aurora {
+    --f7-button-pressed-bg-color: var(
+      --f7-button-fill-pressed-bg-color,
+      var(--f7-theme-color-shade)
+    );
+  }
+  .button-fill,
+  .button-active,
+  .button.tab-link-active,
+  .button-fill-aurora {
+    --f7-button-hover-bg-color: var(--f7-button-fill-hover-bg-color, var(--f7-theme-color-tint));
+  }
+}

+ 18 - 0
data/html/framework7/components/button/button-ios.less

@@ -0,0 +1,18 @@
+.ios {
+  // Buttons
+  .button {
+    transition-duration: 100ms;
+  }
+  .button-fill,
+  .button-fill-ios {
+    --f7-button-pressed-bg-color: var(
+      --f7-button-fill-pressed-bg-color,
+      var(--f7-theme-color-tint)
+    );
+  }
+
+  .button-small,
+  .button-small-ios {
+    transition-duration: 200ms;
+  }
+}

+ 14 - 0
data/html/framework7/components/button/button-md.less

@@ -0,0 +1,14 @@
+.md {
+  // Buttons
+  .button {
+    transition-duration: 300ms;
+    transform: translate3d(0, 0, 0);
+  }
+  .button-fill,
+  .button-fill-md {
+    --f7-button-pressed-bg-color: var(
+      --f7-button-fill-pressed-bg-color,
+      var(--f7-theme-color-shade)
+    );
+  }
+}

+ 108 - 0
data/html/framework7/components/button/button-vars.less

@@ -0,0 +1,108 @@
+:root {
+  --f7-button-font-size: 14px;
+  --f7-button-min-width: 32px;
+  --f7-button-bg-color: transparent;
+  --f7-button-border-width: 0px;
+  --f7-button-text-transform: uppercase;
+  --f7-button-large-text-transform: uppercase;
+  --f7-button-small-text-transform: uppercase;
+  --f7-button-small-outline-border-width: 2px;
+  /*
+  --f7-button-text-color: var(--f7-theme-color);
+  --f7-button-pressed-bg-color: rgba(var(--f7-theme-color-rgb), .15);
+  --f7-button-pressed-text-color: var(--f7-button-text-color, var(--f7-theme-color));
+  --f7-button-border-color: var(--f7-theme-color);
+  --f7-button-fill-text-color: #fff;
+  --f7-button-fill-bg-color: var(--f7-theme-color);
+  --f7-button-outline-border-color: var(--f7-theme-color);
+  --f7-button-padding-vertical: 0px;
+  */
+  --f7-button-outline-border-width: 2px;
+  --f7-button-raised-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
+  --f7-button-raised-pressed-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16),
+    0 3px 6px rgba(0, 0, 0, 0.23);
+  --f7-segmented-raised-divider-color: rgba(0, 0, 0, 0.1);
+  --f7-segmented-strong-padding: 2px;
+  --f7-segmented-strong-between-buttons: 4px;
+  --f7-segmented-strong-button-font-weight: 500;
+  --f7-segmented-strong-button-active-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.25);
+  .light-vars({
+    --f7-segmented-strong-bg-color: rgba(0,0,0,0.07);
+    --f7-segmented-strong-button-text-color: #000;
+    --f7-segmented-strong-button-pressed-bg-color: rgba(0,0,0,0.07);
+    --f7-segmented-strong-button-hover-bg-color: rgba(0,0,0,0.04);
+    --f7-segmented-strong-button-active-text-color: #000;
+    --f7-segmented-strong-button-active-bg-color: #fff;
+  });
+  .dark-vars({
+    --f7-segmented-strong-bg-color: rgba(255, 255, 255, 0.1);
+    --f7-segmented-strong-button-pressed-bg-color: rgba(255,255,255,0.04);
+    --f7-segmented-strong-button-hover-bg-color: rgba(255,255,255,0.02);
+    --f7-segmented-strong-button-active-bg-color: rgba(255, 255, 255, 0.14);
+    --f7-segmented-strong-button-text-color: #fff;
+    --f7-segmented-strong-button-active-text-color: #fff;
+  });
+}
+.ios-vars({
+
+  --f7-button-height: 28px;
+  --f7-button-padding-horizontal: 10px;
+  --f7-button-border-radius: 5px;
+  --f7-button-font-weight: 600;
+  --f7-button-letter-spacing: 0;
+  /*
+  --f7-button-fill-pressed-bg-color: var(--f7-theme-color-tint);
+  */
+  --f7-button-large-height: 44px;
+  --f7-button-large-font-size: 17px;
+  --f7-button-large-font-weight: 500;
+  --f7-button-small-height: 26px;
+  --f7-button-small-font-size: 13px;
+  --f7-button-small-font-weight: 600;
+
+  --f7-segmented-strong-button-text-transform: none;
+  --f7-segmented-strong-button-active-font-weight: 600;
+});
+.md-vars({
+  --f7-button-height: 36px;
+  --f7-button-padding-horizontal: 8px;
+  --f7-button-border-radius: 4px;
+  --f7-button-font-weight: 500;
+  --f7-button-letter-spacing: 0.05em;
+  /*
+  --f7-button-fill-pressed-bg-color: var(--f7-theme-color-shade);
+  */
+  --f7-button-large-height: 48px;
+  --f7-button-large-font-size: 14px;
+  --f7-button-large-font-weight: 500;
+  --f7-button-small-height: 28px;
+  --f7-button-small-font-size: 14px;
+  --f7-button-small-font-weight: 500;
+
+  --f7-segmented-strong-button-text-transform: uppercase;
+  --f7-segmented-strong-button-active-font-weight: 500;
+
+});
+.aurora-vars({
+  /*
+  --f7-button-hover-bg-color: rgba(var(--f7-theme-color-rgb), .07);
+  --f7-button-fill-hover-bg-color: var(--f7-theme-color-tint);
+  */
+  --f7-button-height: 36px;
+  --f7-button-min-width: 24px;
+  --f7-button-padding-horizontal: 10px;
+  --f7-button-border-radius: 8px;
+  --f7-button-font-weight: 600;
+  --f7-button-letter-spacing: 0em;
+  /*
+  --f7-button-fill-pressed-bg-color: var(--f7-theme-color-shade);
+  */
+  --f7-button-large-height: 48px;
+  --f7-button-large-font-size: 16px;
+  --f7-button-large-font-weight: 600;
+  --f7-button-small-height: 28px;
+  --f7-button-small-font-size: 14px;
+  --f7-button-small-font-weight: 600;
+  --f7-segmented-strong-button-text-transform: uppercase;
+  --f7-segmented-strong-button-active-font-weight: 600;
+});

+ 14 - 0
data/html/framework7/components/button/button.d.ts

@@ -0,0 +1,14 @@
+import Framework7, {
+  CSSSelector,
+  Framework7EventsClass,
+  Framework7Plugin,
+} from '../app/app-class.js';
+
+export namespace Button {
+  interface AppMethods {}
+  interface AppParams {}
+  interface AppEvents {}
+}
+
+declare const ButtonComponent: Framework7Plugin;
+export default ButtonComponent;

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio