snail.vue 1.0.40 → 1.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -399,15 +399,15 @@ type TreeNodeRenderOptions = {
399
399
  /**
400
400
  * 树节点 插槽配置选项
401
401
  */
402
- type TreeNodeSlotOptions<T> = {
402
+ type TreeNodeSlotOptions<Node> = {
403
403
  /**
404
404
  * 当前节点
405
405
  */
406
- node: TreeNodeModel<T>;
406
+ node: Node;
407
407
  /**
408
408
  * 父节点
409
409
  */
410
- parent?: TreeNodeModel<T>;
410
+ parent?: Node;
411
411
  /**
412
412
  * 所处层级
413
413
  */
@@ -444,23 +444,70 @@ type ScrollOptions = {
444
444
  */
445
445
  type ScrollEvents = {
446
446
  /**
447
- * 滚动条显示、隐藏事件
448
- * - x轴是否展示,y轴是否显示
447
+ * 【x轴方向】滚动条变化时
448
+ * @param show 是否显示。true 滚动条显示;false 滚动条隐藏
449
+ */
450
+ xbar: [show: boolean];
451
+ /**
452
+ * 【x轴方向】滚到【最左侧】了
449
453
  */
450
- bar: [x: boolean, y: boolean];
454
+ left: [];
451
455
  /**
452
- * 滚动条触碰事件,到顶了、到底了
456
+ * 【x轴方向】滚到【最右侧】了
453
457
  */
454
- touch: [type: ScrollTouchType];
458
+ right: [];
459
+ /**
460
+ * 【y轴方向】滚动条变化时
461
+ * @param show 是否显示。true 滚动条显示;false 滚动条隐藏
462
+ */
463
+ ybar: [show: boolean];
464
+ /**
465
+ * 【y轴方向】滚到【最顶部】了
466
+ */
467
+ top: [];
468
+ /**
469
+ * 【y轴方向】滚到【最底部】了
470
+ */
471
+ bottom: [];
455
472
  };
456
473
  /**
457
- * 滚动触碰类型
458
- * - left 最左侧
459
- * - right 最右侧
460
- * - top 最顶部
461
- * - bottom 最底部
474
+ * 滚动视图状态
475
+ * - 缓存起来 和下次滚动做比对,触发对应事件
462
476
  */
463
- type ScrollTouchType = "left" | "right" | "top" | "bottom";
477
+ type ScrollStatus = {
478
+ /**
479
+ * 水平滚动条是否显示
480
+ */
481
+ xbar: boolean;
482
+ /**
483
+ * 垂直滚动条是否显示
484
+ */
485
+ ybar: boolean;
486
+ /**
487
+ * 滚动到【左侧】了
488
+ */
489
+ left: boolean;
490
+ /**
491
+ * 滚动到【右侧】了
492
+ */
493
+ right: boolean;
494
+ /**
495
+ * 滚动到【顶部】了
496
+ */
497
+ top: boolean;
498
+ /**
499
+ * 滚动到【底部】了
500
+ */
501
+ bottom: boolean;
502
+ /**
503
+ * 滚动视图宽度
504
+ */
505
+ scrollwidth: number;
506
+ /**
507
+ * 滚动视图高度
508
+ */
509
+ scrollheight: number;
510
+ };
464
511
 
465
512
  /**
466
513
  * Table配置选项
@@ -544,6 +591,40 @@ type ComponentOptions = {
544
591
  */
545
592
  url?: string;
546
593
  };
594
+ /**
595
+ * 提取【组件事件】类型
596
+ * - 将【组件事件】中的key首字母小写,追加上on前缀;key对应的value为监听函数参数
597
+ * - T的类型约束:Record<string, unknown[]>
598
+ */
599
+ type ExtractComponentEvents<Events> = Events extends Record<string, unknown[]> ? ({
600
+ [key in keyof Events as `on${Capitalize<string & key>}`]?: (...args: Events[key]) => void;
601
+ }) : never;
602
+ /**
603
+ * 提取组件的props类型
604
+ * - 有效的 Props 类型:extends Record<string, any>
605
+ * - 有效类型则返回 Props 自身;否则无效,为undefined
606
+ */
607
+ type ExtractComponentProps<Props> = Props extends Record<string, any> ? Props : undefined;
608
+ /**
609
+ * 组件绑定 配置选项
610
+ * - Props、Events、Model 为可选泛型,分别约束 props、events、model 属性
611
+ * - 若泛型类型无效,则对应属性类型强制为undefined;详细参照对应属性说明
612
+ */
613
+ type ComponentBindOptions<Props = void, Model = void> = {
614
+ /**
615
+ * 传递给组件的属性值,执行 v-bind 绑定
616
+ * - key为属性名称,遵循vue解析规则;若绑定事件,则key为 on事件名称 ,事件名称首字母大写
617
+ * - 通过泛型类型 Props 约束,有效类型:Props extends Record<string, any>
618
+ * @see ExtractComponentEvents<Events> 获取组件事件类型
619
+ */
620
+ props?: ExtractComponentProps<Props>;
621
+ /**
622
+ * 传递给组件的双向绑定数据,执行 v-model 绑定
623
+ * - 使用 ShallowRef/Ref 包裹;推荐 ShallowRef,仅和组件进行.value值交互,避免深层双向影响性能
624
+ * - 通过泛型类型 Model 约束,有效类型: 非void、never、null、undefined等无效类型
625
+ */
626
+ model?: Model extends (void | never | null | undefined) ? undefined : (ShallowRef<Model> | Ref<Model>);
627
+ };
547
628
  /**
548
629
  *
549
630
  */
@@ -623,19 +704,13 @@ type SelectEvents<T> = SelectBaseEvents<T> & {};
623
704
  /**
624
705
  * 选项菜单 组件的Slot配置选项
625
706
  */
626
- type SelectSlotOptions<T> = {
707
+ type SelectSlotOptions = {
627
708
  /**
628
- * 关闭Follow弹窗
629
- * - 将隐藏已弹出的选项 follow 弹窗
630
- * @returns 已弹出则销毁成功返回true;未弹出则销毁失败返回false
709
+ * 清空已选【选择项】
710
+ * @param closeFollow 是否关闭【选择项】Follow弹窗
711
+ * @param stopPropagation 是否停止事件冒泡
631
712
  */
632
- closeFollow(): boolean;
633
- /**
634
- * 停止事件冒泡
635
- * - 解决问题:插槽内元素需要处理自定义click事件,此时不希望Select组件响应click事件
636
- * @param delay 在此延迟时间内,停止事件冒泡
637
- */
638
- stopPropagation(delay: number): any;
713
+ clear(closeFollow: boolean, stopPropagation: boolean): void;
639
714
  };
640
715
  /**
641
716
  * 【选项菜单】 组件上下文
@@ -1151,14 +1226,9 @@ type InputEvents = {
1151
1226
  * 弹窗配置选项
1152
1227
  * - 约束弹出组件信息
1153
1228
  * - 弹出组件时传递的参数信息
1229
+ * @see ComponentBindOptions 了解 Props、Model 泛型参数的含义
1154
1230
  */
1155
- type PopupOptions = ComponentOptions & {
1156
- /**
1157
- * 传递给组件的属性值,执行v-bind绑定到要显示的组件
1158
- * - key为属性名称,遵循vue解析规则
1159
- * - 若为事件监听,则使用onXXX
1160
- */
1161
- props?: Record<string, any>;
1231
+ type PopupOptions<Props = void, Model = void> = ComponentOptions & ComponentBindOptions<Props, Model> & {
1162
1232
  /**
1163
1233
  * 弹窗动画名
1164
1234
  * - 不传则默认“snail-fade”
@@ -1265,8 +1335,9 @@ type PopupDescriptor<Options extends PopupOptions, ExtOptions> = PopupStatusOpti
1265
1335
  /**
1266
1336
  * 模态弹窗 配置选项
1267
1337
  * - 继承 ComponentOptions ,动态加载组件
1338
+ * @see ComponentBindOptions 了解 Props、Model 泛型参数的含义
1268
1339
  */
1269
- type DialogOptions = PopupOptions & {
1340
+ type DialogOptions<Props = void, Model = void> = PopupOptions<Props, Model> & {
1270
1341
  /**
1271
1342
  * 禁用【遮罩层】
1272
1343
  * - 目前没实现,先忽略
@@ -1328,8 +1399,9 @@ type ToastOptions = {
1328
1399
  /**
1329
1400
  * 跟随弹窗 配置选项
1330
1401
  * - 传入的组件,根据配置跟随 target 位置和大小;
1402
+ * @see ComponentBindOptions 了解 Props、Model 泛型参数的含义
1331
1403
  */
1332
- type FollowOptions = PopupOptions & {
1404
+ type FollowOptions<Props = void, Model = void> = PopupOptions<Props, Model> & {
1333
1405
  /**
1334
1406
  * 启用【宽度】跟随
1335
1407
  * - 为true则和 target 宽度保持一致
@@ -1483,26 +1555,29 @@ interface IPopupManager {
1483
1555
  /**
1484
1556
  * 弹出
1485
1557
  * - 弹窗位置位置、大小、动画效果等由组件自己完成
1558
+ * @see ComponentBindOptions 了解 Props、Model 泛型参数的含义
1486
1559
  * @param options 弹窗配置选项
1487
1560
  * @returns 弹窗打开结果,外部可手动关闭弹窗
1488
1561
  */
1489
- popup<T>(options: PopupOptions): IAsyncScope<T>;
1562
+ popup<T, Props = void, Model = void>(options: PopupOptions<Props, Model>): IAsyncScope<T>;
1490
1563
  /**
1491
1564
  * 对话框
1492
1565
  * - 支持指定模态和非模态对话框
1493
1566
  * - 默认垂直水平居中展示
1567
+ * @see ComponentBindOptions 了解 Props、Model 泛型参数的含义
1494
1568
  * @param options 弹窗配置选项
1495
1569
  * @returns 弹窗打开结果,外部可手动关闭弹窗
1496
1570
  */
1497
- dialog<T>(options: DialogOptions): IAsyncScope<T>;
1571
+ dialog<T, Props = void, Model = void>(options: DialogOptions<Props, Model>): IAsyncScope<T>;
1498
1572
  /**
1499
1573
  * 跟随弹窗
1500
1574
  * - 跟随指定的target对象,可跟随位置、大小
1575
+ * @see ComponentBindOptions 了解 Props、Model 泛型参数的含义
1501
1576
  * @param target 跟随的目标元素
1502
1577
  * @param options 跟随配置选项
1503
1578
  * @returns 弹窗异步作用域,外部可手动关闭弹窗
1504
1579
  */
1505
- follow<T>(target: HTMLElement, options: FollowOptions): IAsyncScope<T>;
1580
+ follow<T, Props = void, Model = void>(target: HTMLElement, options: FollowOptions<Props, Model>): IAsyncScope<T>;
1506
1581
  /**
1507
1582
  * 打开【确认】弹窗
1508
1583
  * @param title 弹窗标题
@@ -1676,8 +1751,7 @@ declare const components: {
1676
1751
  }, string, {}, {}, string, {}, vue.GlobalComponents, vue.GlobalDirectives, string, vue.ComponentProvideOptions> & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & (new () => {
1677
1752
  $slots: {
1678
1753
  default?: (props: {
1679
- closeFollow: () => boolean;
1680
- stopPropagation: (delay: number) => any;
1754
+ clear: (closeFollow: boolean, stopPropagation: boolean) => void;
1681
1755
  }) => any;
1682
1756
  };
1683
1757
  });
@@ -1693,18 +1767,18 @@ declare const components: {
1693
1767
  "onUpdate:modelValue"?: (value: boolean) => any;
1694
1768
  }>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
1695
1769
  Dynamic: {
1696
- new (...args: any[]): vue.CreateComponentPublicInstanceWithMixins<Readonly<ComponentOptions> & Readonly<{}>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, vue.PublicProps, {}, true, {}, {}, vue.GlobalComponents, vue.GlobalDirectives, string, {}, any, vue.ComponentProvideOptions, {
1770
+ new (...args: any[]): vue.CreateComponentPublicInstanceWithMixins<Readonly<ComponentOptions & Pick<ComponentBindOptions<Record<string, any>>, "props">> & Readonly<{}>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, vue.PublicProps, {}, true, {}, {}, vue.GlobalComponents, vue.GlobalDirectives, string, {}, any, vue.ComponentProvideOptions, {
1697
1771
  P: {};
1698
1772
  B: {};
1699
1773
  D: {};
1700
1774
  C: {};
1701
1775
  M: {};
1702
1776
  Defaults: {};
1703
- }, Readonly<ComponentOptions> & Readonly<{}>, {}, {}, {}, {}, {}>;
1777
+ }, Readonly<ComponentOptions & Pick<ComponentBindOptions<Record<string, any>>, "props">> & Readonly<{}>, {}, {}, {}, {}, {}>;
1704
1778
  __isFragment?: never;
1705
1779
  __isTeleport?: never;
1706
1780
  __isSuspense?: never;
1707
- } & vue.ComponentOptionsBase<Readonly<ComponentOptions> & Readonly<{}>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, {}, {}, string, {}, vue.GlobalComponents, vue.GlobalDirectives, string, vue.ComponentProvideOptions> & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & (new () => {
1781
+ } & vue.ComponentOptionsBase<Readonly<ComponentOptions & Pick<ComponentBindOptions<Record<string, any>>, "props">> & Readonly<{}>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, {}, {}, string, {}, vue.GlobalComponents, vue.GlobalDirectives, string, vue.ComponentProvideOptions> & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & (new () => {
1708
1782
  $slots: {
1709
1783
  [x: string]: (props: any) => any;
1710
1784
  [x: number]: (props: any) => any;
@@ -1757,18 +1831,53 @@ declare const components: {
1757
1831
  };
1758
1832
  });
1759
1833
  Scroll: {
1760
- new (...args: any[]): vue.CreateComponentPublicInstanceWithMixins<Readonly<ScrollOptions> & Readonly<{}>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, vue.PublicProps, {}, true, {}, {}, vue.GlobalComponents, vue.GlobalDirectives, string, {}, any, vue.ComponentProvideOptions, {
1834
+ new (...args: any[]): vue.CreateComponentPublicInstanceWithMixins<Readonly<ScrollOptions> & Readonly<{
1835
+ onLeft?: () => any;
1836
+ onRight?: () => any;
1837
+ onBottom?: () => any;
1838
+ onTop?: () => any;
1839
+ onXbar?: (show: boolean) => any;
1840
+ onYbar?: (show: boolean) => any;
1841
+ }>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
1842
+ left: () => any;
1843
+ right: () => any;
1844
+ bottom: () => any;
1845
+ top: () => any;
1846
+ xbar: (show: boolean) => any;
1847
+ ybar: (show: boolean) => any;
1848
+ }, vue.PublicProps, {}, true, {}, {}, vue.GlobalComponents, vue.GlobalDirectives, string, {}, any, vue.ComponentProvideOptions, {
1761
1849
  P: {};
1762
1850
  B: {};
1763
1851
  D: {};
1764
1852
  C: {};
1765
1853
  M: {};
1766
1854
  Defaults: {};
1767
- }, Readonly<ScrollOptions> & Readonly<{}>, {}, {}, {}, {}, {}>;
1855
+ }, Readonly<ScrollOptions> & Readonly<{
1856
+ onLeft?: () => any;
1857
+ onRight?: () => any;
1858
+ onBottom?: () => any;
1859
+ onTop?: () => any;
1860
+ onXbar?: (show: boolean) => any;
1861
+ onYbar?: (show: boolean) => any;
1862
+ }>, {}, {}, {}, {}, {}>;
1768
1863
  __isFragment?: never;
1769
1864
  __isTeleport?: never;
1770
1865
  __isSuspense?: never;
1771
- } & vue.ComponentOptionsBase<Readonly<ScrollOptions> & Readonly<{}>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, {}, {}, string, {}, vue.GlobalComponents, vue.GlobalDirectives, string, vue.ComponentProvideOptions> & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & (new () => {
1866
+ } & vue.ComponentOptionsBase<Readonly<ScrollOptions> & Readonly<{
1867
+ onLeft?: () => any;
1868
+ onRight?: () => any;
1869
+ onBottom?: () => any;
1870
+ onTop?: () => any;
1871
+ onXbar?: (show: boolean) => any;
1872
+ onYbar?: (show: boolean) => any;
1873
+ }>, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
1874
+ left: () => any;
1875
+ right: () => any;
1876
+ bottom: () => any;
1877
+ top: () => any;
1878
+ xbar: (show: boolean) => any;
1879
+ ybar: (show: boolean) => any;
1880
+ }, string, {}, {}, string, {}, vue.GlobalComponents, vue.GlobalDirectives, string, vue.ComponentProvideOptions> & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & (new () => {
1772
1881
  $slots: {
1773
1882
  default?: (props: {}) => any;
1774
1883
  };
@@ -1927,8 +2036,8 @@ declare const components: {
1927
2036
  }, string, {}, {}, string, {}, vue.GlobalComponents, vue.GlobalDirectives, string, vue.ComponentProvideOptions> & vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps & (new () => {
1928
2037
  $slots: {
1929
2038
  default?: (props: {
1930
- node: TreeNodeModel<any>;
1931
- parent?: TreeNodeModel<any>;
2039
+ node: any;
2040
+ parent?: any;
1932
2041
  level: number;
1933
2042
  click(): void;
1934
2043
  toggle(): void;
@@ -1998,4 +2107,4 @@ declare const components: {
1998
2107
  };
1999
2108
 
2000
2109
  export { components, getSvgDraw, mount, onAppCreated, triggerAppCreated, usePopup, useReactive, useTreeContext };
2001
- export type { ButtonOptions, ChooseEvents, ChooseItem, ChooseOptions, ComponentMountOptions, ComponentOptions, ConfirmAreaOptions, ConfirmOptions, DialogHandle, DialogOptions, DisabledOptions, DragVerifyInfo, DragVerifyOptions, EmptyOptions, FoldEvents, FoldOptions, FoldStatus, FollowElectResult, FollowExtend, FollowHandle, FollowOptions, FollowStrategy, FollowStrategyOptions, FooterEvents, FooterOptions, HeaderEvents, HeaderOptions, IPopupManager, IReactiveManager, ISelectContext, ITreeBaseContext, IconOptions, IconType, InputEvents, InputOptions, LoadingOptions, MessageOptions, PlaceholderOptions, PopupDescriptor, PopupHandle, PopupOptions, PopupStatus, PopupStatusOptions, ReactiveVar, ReadonlyOptions, ScrollEvents, ScrollOptions, ScrollTouchType, SearchEvents, SearchOptions, SelectBaseEvents, SelectBaseOptions, SelectEvents, SelectItem, SelectNodeEvents, SelectNodeOptions, SelectOptions, SelectPopupExtend, SelectPopupOptions, SelectSlotOptions, SortEvents, SortOptions, SwitchEvents, SwitchOptions, TableColOptions, TableOptions, TableRowOptions, TitleOptions, ToastOptions, TreeEvents, TreeNode, TreeNodeEvents, TreeNodeExtend, TreeNodeModel, TreeNodeOptions, TreeNodeRenderOptions, TreeNodeSlotOptions, TreeOptions, TreeSearchResult };
2110
+ export type { ButtonOptions, ChooseEvents, ChooseItem, ChooseOptions, ComponentBindOptions, ComponentMountOptions, ComponentOptions, ConfirmAreaOptions, ConfirmOptions, DialogHandle, DialogOptions, DisabledOptions, DragVerifyInfo, DragVerifyOptions, EmptyOptions, ExtractComponentEvents, ExtractComponentProps, FoldEvents, FoldOptions, FoldStatus, FollowElectResult, FollowExtend, FollowHandle, FollowOptions, FollowStrategy, FollowStrategyOptions, FooterEvents, FooterOptions, HeaderEvents, HeaderOptions, IPopupManager, IReactiveManager, ISelectContext, ITreeBaseContext, IconOptions, IconType, InputEvents, InputOptions, LoadingOptions, MessageOptions, PlaceholderOptions, PopupDescriptor, PopupHandle, PopupOptions, PopupStatus, PopupStatusOptions, ReactiveVar, ReadonlyOptions, ScrollEvents, ScrollOptions, ScrollStatus, SearchEvents, SearchOptions, SelectBaseEvents, SelectBaseOptions, SelectEvents, SelectItem, SelectNodeEvents, SelectNodeOptions, SelectOptions, SelectPopupExtend, SelectPopupOptions, SelectSlotOptions, SortEvents, SortOptions, SwitchEvents, SwitchOptions, TableColOptions, TableOptions, TableRowOptions, TitleOptions, ToastOptions, TreeEvents, TreeNode, TreeNodeEvents, TreeNodeExtend, TreeNodeModel, TreeNodeOptions, TreeNodeRenderOptions, TreeNodeSlotOptions, TreeOptions, TreeSearchResult };
package/dist/snail.vue.js CHANGED
@@ -1,7 +1,7 @@
1
1
  //@ sourceURL=/snail.vue.js
2
- import { defineComponent, createElementBlock, openBlock, normalizeClass, renderSlot, createTextVNode, mergeModels, useModel, computed, Fragment, renderList, normalizeStyle, unref, createElementVNode, createCommentVNode, toDisplayString, createBlock, shallowRef, withDirectives, vModelText, createVNode, createApp, Transition, withCtx, normalizeProps, guardReactiveProps, watch, ref, onErrorCaptured, resolveDynamicComponent, mergeProps, createSlots, onMounted, withModifiers, getCurrentInstance, nextTick, useTemplateRef, resolveComponent, onActivated, onDeactivated, onBeforeUnmount, getCurrentScope, onScopeDispose } from 'vue';
3
- import { isArray, newId, throwError, isArrayNotEmpty, isStringNotEmpty, mustFunction, useScope, removeFromArray, mustObject, throwIfFalse, isObject, isNumberNotNaN, mountScope, useScopes, isPromise, wait, script, delay, useTimer, defer, useAsyncScope, useHook, hasAny, throwIfTrue, isFunction, onMountScope, getType } from 'snail.core';
4
- import { css, link, useObserver, useAnimation } from 'snail.view';
2
+ import { defineComponent, createElementBlock, openBlock, normalizeClass, renderSlot, createTextVNode, mergeModels, useModel, computed, Fragment, renderList, normalizeStyle, unref, createElementVNode, createCommentVNode, toDisplayString, createBlock, shallowRef, withDirectives, vModelText, createVNode, createApp, Transition, withCtx, normalizeProps, guardReactiveProps, watch, ref, onErrorCaptured, resolveDynamicComponent, mergeProps, createSlots, onMounted, withModifiers, isRef, getCurrentInstance, nextTick, useTemplateRef, resolveComponent, onBeforeUnmount, getCurrentScope, onScopeDispose } from 'vue';
3
+ import { isArray, newId, throwError, isArrayNotEmpty, isStringNotEmpty, mustFunction, useScope, removeFromArray, mustObject, throwIfFalse, isObject, isNumberNotNaN, mountScope, useScopes, isPromise, wait, script, delay, useTimer, defer, useAsyncScope, useHook, hasAny, throwIfTrue, isFunction, onMountScope } from 'snail.core';
4
+ import { link, css, useObserver, useAnimation } from 'snail.view';
5
5
 
6
6
  var _sfc_main$r = defineComponent({
7
7
  ...{
@@ -23,6 +23,10 @@ var _sfc_main$r = defineComponent({
23
23
  }
24
24
  });
25
25
 
26
+ var addLink = href => setTimeout(link.register, 0, href);
27
+
28
+ addLink("/styles/snail.vue.vue.css");
29
+
26
30
  const _hoisted_1$e = ["onClick"];
27
31
  const _hoisted_2$9 = ["type", "checked"];
28
32
  const _hoisted_3$6 = ["textContent"];
@@ -96,10 +100,6 @@ var _sfc_main$q = defineComponent({
96
100
  }
97
101
  });
98
102
 
99
- var addLink = href => setTimeout(link.register, 0, href);
100
-
101
- addLink("/styles/snail.vue.vue.css");
102
-
103
103
  var _sfc_main$p = defineComponent({
104
104
  ...{
105
105
  name: "Footer",
@@ -688,7 +688,10 @@ var _sfc_main$j = defineComponent({
688
688
  props: {
689
689
  name: {},
690
690
  component: {},
691
- url: {}
691
+ url: {},
692
+ props: {
693
+ default: () => ({})
694
+ }
692
695
  },
693
696
  setup(__props) {
694
697
  const {
@@ -735,10 +738,10 @@ var _sfc_main$j = defineComponent({
735
738
  }
736
739
  });
737
740
  return (_ctx, _cache) => {
738
- return openBlock(), createElementBlock(Fragment, null, [(openBlock(), createBlock(resolveDynamicComponent(dynamicComponentRef.value), mergeProps(_ctx.$attrs, {
741
+ return openBlock(), createElementBlock(Fragment, null, [(openBlock(), createBlock(resolveDynamicComponent(dynamicComponentRef.value), mergeProps({
739
742
  ref_key: "componentRef",
740
743
  ref: componentRef
741
- }), createSlots({
744
+ }, _ctx.props, _ctx.$attrs), createSlots({
742
745
  _: 2
743
746
  }, [renderList(_ctx.$slots, (_, name) => {
744
747
  return {
@@ -751,7 +754,7 @@ var _sfc_main$j = defineComponent({
751
754
  }, _ctx.$attrs), [_cache[0] || (_cache[0] = createTextVNode(" load component error:")), createElementVNode("span", null, toDisplayString(dynamicErrorRef.value), 1)], 16)) : dynamicComponentRef.value == void 0 ? (openBlock(), createBlock(_sfc_main$k, {
752
755
  key: 1,
753
756
  show: true,
754
- "disabled-mask": true
757
+ "mask-disabled": true
755
758
  })) : createCommentVNode("", true)], 64);
756
759
  };
757
760
  }
@@ -772,6 +775,10 @@ var _sfc_main$i = defineComponent({
772
775
  popupTransition: {}
773
776
  },
774
777
  setup(__props) {
778
+ const {
779
+ props,
780
+ model = shallowRef(void 0)
781
+ } = __props.options;
775
782
  const {
776
783
  closePopup,
777
784
  onBeforeClose
@@ -795,15 +802,19 @@ var _sfc_main$i = defineComponent({
795
802
  style: normalizeStyle({
796
803
  "z-index": _ctx.zIndex
797
804
  }),
798
- onClick: _cache[0] || (_cache[0] = withModifiers($event => {
805
+ onClick: _cache[1] || (_cache[1] = withModifiers($event => {
799
806
  _ctx.options.closeOnMask && unref(closePopup)();
800
807
  }, ["self"]))
801
808
  }, [createVNode(_sfc_main$j, mergeProps({
802
809
  class: "dialog-body",
803
810
  name: _ctx.options.name,
804
811
  component: _ctx.options.component,
805
- url: _ctx.options.url
806
- }, _ctx.options.props, unref(dialogExtend)), null, 16, ["name", "component", "url"])], 6);
812
+ url: _ctx.options.url,
813
+ props: unref(props)
814
+ }, unref(dialogExtend), {
815
+ modelValue: unref(model),
816
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => isRef(model) ? model.value = $event : null)
817
+ }), null, 16, ["name", "component", "url", "props", "modelValue"])], 6);
807
818
  };
808
819
  }
809
820
  });
@@ -823,6 +834,10 @@ var _sfc_main$h = defineComponent({
823
834
  popupTransition: {}
824
835
  },
825
836
  setup(__props) {
837
+ const {
838
+ props,
839
+ model = shallowRef(void 0)
840
+ } = __props.options;
826
841
  const {
827
842
  closePopup
828
843
  } = __props.extOptions;
@@ -921,8 +936,12 @@ var _sfc_main$h = defineComponent({
921
936
  },
922
937
  name: _ctx.options.name,
923
938
  component: _ctx.options.component,
924
- url: _ctx.options.url
925
- }, _ctx.options.props, unref(followExt)), null, 16, ["class", "style", "name", "component", "url"]);
939
+ url: _ctx.options.url,
940
+ props: unref(props)
941
+ }, unref(followExt), {
942
+ modelValue: unref(model),
943
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => isRef(model) ? model.value = $event : null)
944
+ }), null, 16, ["class", "style", "name", "component", "url", "props", "modelValue"]);
926
945
  };
927
946
  }
928
947
  });
@@ -942,8 +961,10 @@ var _sfc_main$g = defineComponent({
942
961
  popupTransition: {}
943
962
  },
944
963
  setup(__props) {
945
- const loadingRef = shallowRef(false);
946
- onMounted(() => loadingRef.value = true);
964
+ const {
965
+ props,
966
+ model = shallowRef(void 0)
967
+ } = __props.options;
947
968
  return (_ctx, _cache) => {
948
969
  return openBlock(), createBlock(_sfc_main$j, mergeProps({
949
970
  class: ["snail-popup", [_ctx.popupStatus.value, _ctx.popupTransition.value]],
@@ -952,11 +973,12 @@ var _sfc_main$g = defineComponent({
952
973
  },
953
974
  name: _ctx.options.name,
954
975
  component: _ctx.options.component,
955
- url: _ctx.options.url
956
- }, _ctx.options.props, {
957
- "in-popup": true,
958
- "close-popup": _ctx.extOptions.closePopup
959
- }), null, 16, ["class", "style", "name", "component", "url", "close-popup"]);
976
+ url: _ctx.options.url,
977
+ props: unref(props)
978
+ }, _ctx.extOptions, {
979
+ modelValue: unref(model),
980
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => isRef(model) ? model.value = $event : null)
981
+ }), null, 16, ["class", "style", "name", "component", "url", "props", "modelValue"]);
960
982
  };
961
983
  }
962
984
  });
@@ -1279,7 +1301,7 @@ var _sfc_main$c = defineComponent({
1279
1301
  followY: {},
1280
1302
  pinned: {}
1281
1303
  },
1282
- emits: ["change", "search"],
1304
+ emits: ["change"],
1283
1305
  setup(__props, _ref) {
1284
1306
  let {
1285
1307
  emit: __emit
@@ -1495,7 +1517,6 @@ function searchPath(nodes, target) {
1495
1517
  }
1496
1518
 
1497
1519
  function useSelectContext(items, selectsRef) {
1498
- const treeContxt = useTreeContext(items);
1499
1520
  function selected(multiple, item) {
1500
1521
  if (selectsRef.value) {
1501
1522
  return multiple == true ? selectsRef.value.includes(item) : selectsRef.value[selectsRef.value.length - 1] == item;
@@ -1508,11 +1529,18 @@ function useSelectContext(items, selectsRef) {
1508
1529
  }
1509
1530
  return "";
1510
1531
  }
1511
- return Object.freeze({
1512
- ...treeContxt,
1513
- selected,
1514
- selectedText
1515
- });
1532
+ const context = Object.create(null);
1533
+ {
1534
+ const treeContxt = useTreeContext(items);
1535
+ Object.assign(context, treeContxt, {
1536
+ selected,
1537
+ selectedText
1538
+ });
1539
+ mountScope(context, "ISelectContext");
1540
+ treeContxt.onDestroy(() => context.destroyed || context.destroy());
1541
+ context.onDestroy(() => treeContxt.destroyed || treeContxt.destroy());
1542
+ }
1543
+ return Object.freeze(context);
1516
1544
  }
1517
1545
 
1518
1546
  const _hoisted_1$6 = {
@@ -1572,12 +1600,11 @@ var _sfc_main$b = defineComponent({
1572
1600
  const context = useSelectContext(props.items, valuesModel);
1573
1601
  const selectTextRef = computed(() => context.selectedText(props.multiple, props.showPath));
1574
1602
  const slotOptions = Object.freeze({
1575
- closeFollow,
1576
- stopPropagation
1603
+ clear
1577
1604
  });
1578
1605
  var followScope = void 0;
1579
1606
  var stopPropagationScope = void 0;
1580
- function closeFollow() {
1607
+ function destroyFollow() {
1581
1608
  if (followScope != void 0) {
1582
1609
  followScope.destroy();
1583
1610
  followScope = void 0;
@@ -1585,15 +1612,17 @@ var _sfc_main$b = defineComponent({
1585
1612
  }
1586
1613
  return false;
1587
1614
  }
1588
- function stopPropagation(delay) {
1615
+ function clear(closeFollow, stopPropagation) {
1616
+ valuesModel.value = [];
1617
+ closeFollow && destroyFollow();
1589
1618
  stopPropagationScope && stopPropagationScope.destroy();
1590
- stopPropagationScope = onTimeout(() => stopPropagationScope = void 0, delay);
1619
+ stopPropagationScope = stopPropagation ? onTimeout(() => stopPropagationScope = void 0, 200) : void 0;
1591
1620
  }
1592
1621
  async function onClick() {
1593
1622
  if (props.readonly == true || rootDom.value == void 0) {
1594
1623
  return;
1595
1624
  }
1596
- if (closeFollow() == true || stopPropagationScope != void 0) {
1625
+ if (destroyFollow() == true || stopPropagationScope != void 0) {
1597
1626
  return;
1598
1627
  }
1599
1628
  const values = valuesModel.value && valuesModel.value.length > 0 ? [...valuesModel.value] : [];
@@ -1608,16 +1637,15 @@ var _sfc_main$b = defineComponent({
1608
1637
  closeOnMask: true,
1609
1638
  closeOnResize: true,
1610
1639
  closeOnTarget: true,
1611
- props: Object.freeze(Object.assign({
1640
+ props: {
1612
1641
  items: props.items,
1613
1642
  context,
1614
1643
  level: 1,
1615
1644
  search: props.search,
1616
1645
  multiple: props.multiple,
1617
- popupStyle: props.popupStyle
1618
- }, {
1646
+ popupStyle: props.popupStyle,
1619
1647
  onChange: onSelectItemChange
1620
- }))
1648
+ }
1621
1649
  });
1622
1650
  await followScope;
1623
1651
  followScope = void 0;
@@ -1634,16 +1662,16 @@ var _sfc_main$b = defineComponent({
1634
1662
  }]),
1635
1663
  onClick: _cache[0] || (_cache[0] = $event => onClick()),
1636
1664
  ref: "select"
1637
- }, [unref(hasAny)(props.items) == true ? (openBlock(), createElementBlock(Fragment, {
1665
+ }, [props.items && props.items.length > 0 ? (openBlock(), createElementBlock(Fragment, {
1638
1666
  key: 0
1639
- }, [unref(hasAny)(valuesModel.value) ? (openBlock(), createElementBlock("div", _hoisted_1$6, [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(slotOptions))), () => [createElementVNode("div", {
1667
+ }, [valuesModel.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_1$6, [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(unref(slotOptions))), () => [createElementVNode("div", {
1640
1668
  class: "select-text",
1641
1669
  title: selectTextRef.value,
1642
1670
  textContent: toDisplayString(selectTextRef.value)
1643
1671
  }, null, 8, _hoisted_2$3)])])) : (openBlock(), createElementBlock("div", {
1644
1672
  key: 1,
1645
1673
  class: "select-result text-tips",
1646
- textContent: toDisplayString(props.placeholder || "请选择")
1674
+ textContent: toDisplayString(props.readonly ? "" : props.placeholder || "请选择")
1647
1675
  }, null, 8, _hoisted_3$3)), createVNode(_sfc_main$o, {
1648
1676
  type: "arrow",
1649
1677
  size: 24,
@@ -1818,18 +1846,81 @@ var _sfc_main$8 = defineComponent({
1818
1846
  type: Boolean
1819
1847
  }
1820
1848
  },
1821
- setup(__props) {
1849
+ emits: ["xbar", "left", "right", "ybar", "top", "bottom"],
1850
+ setup(__props, _ref) {
1851
+ let {
1852
+ emit: __emit
1853
+ } = _ref;
1822
1854
  const props = __props;
1823
- console.warn("scroll 的事件还没实现");
1824
- onActivated(() => console.log("onActivated"));
1825
- onDeactivated(() => console.log("onDeactivated"));
1855
+ const emits = __emit;
1856
+ const rootDom = useTemplateRef("scroll-root");
1857
+ const {
1858
+ onSize
1859
+ } = useObserver();
1860
+ const {
1861
+ onInterval
1862
+ } = useTimer();
1863
+ const classRef = computed(() => ({
1864
+ "scroll-x": props.scrollX == true,
1865
+ "scroll-y": props.scrollY == true
1866
+ }));
1867
+ var preStatus = void 0;
1868
+ function refreshScrollInfo() {
1869
+ const status = {
1870
+ xbar: rootDom.value.scrollWidth > rootDom.value.clientWidth,
1871
+ ybar: rootDom.value.scrollHeight > rootDom.value.clientHeight,
1872
+ left: false,
1873
+ right: false,
1874
+ top: false,
1875
+ bottom: false,
1876
+ scrollwidth: rootDom.value.scrollWidth,
1877
+ scrollheight: rootDom.value.scrollHeight
1878
+ };
1879
+ if (status.xbar == true) {
1880
+ status.left = rootDom.value.scrollLeft == 0;
1881
+ status.right = rootDom.value.scrollLeft + rootDom.value.clientWidth == rootDom.value.scrollWidth;
1882
+ }
1883
+ if (status.ybar == true) {
1884
+ status.top = rootDom.value.scrollTop == 0;
1885
+ status.bottom = rootDom.value.scrollTop + rootDom.value.clientHeight == rootDom.value.scrollHeight;
1886
+ }
1887
+ Object.freeze(status);
1888
+ const events = Object.create(null);
1889
+ if (preStatus != void 0) {
1890
+ preStatus.xbar != status.xbar && (events.xbar = [status.xbar]);
1891
+ preStatus.ybar != status.ybar && (events.ybar = [status.ybar]);
1892
+ if (preStatus.xbar == true && status.xbar == true) {
1893
+ status.left && preStatus.left !== status.left && (events.left = []);
1894
+ status.right && preStatus.right !== status.right && (events.right = []);
1895
+ }
1896
+ if (preStatus.ybar == true && status.ybar == true) {
1897
+ status.top && preStatus.top !== status.top && (events.top = []);
1898
+ status.bottom && preStatus.bottom !== status.bottom && (events.bottom = []);
1899
+ }
1900
+ }
1901
+ preStatus = status;
1902
+ preStatus = Object.freeze(status);
1903
+ events.xbar && emits("xbar", ...events.xbar);
1904
+ events.left && emits("left");
1905
+ events.right && emits("right");
1906
+ events.ybar && emits("ybar", ...events.ybar);
1907
+ events.top && emits("top");
1908
+ events.bottom && emits("bottom");
1909
+ }
1910
+ onMounted(() => {
1911
+ refreshScrollInfo();
1912
+ onSize(rootDom.value, refreshScrollInfo);
1913
+ onInterval(() => {
1914
+ const isChange = preStatus.scrollwidth != rootDom.value.scrollWidth || preStatus.scrollheight != rootDom.value.scrollHeight;
1915
+ isChange && refreshScrollInfo();
1916
+ }, 100);
1917
+ });
1826
1918
  return (_ctx, _cache) => {
1827
1919
  return openBlock(), createElementBlock("div", {
1828
- class: normalizeClass(["snail-scroll", {
1829
- "scroll-x": props.scrollX == true,
1830
- "scroll-y": props.scrollY == true
1831
- }])
1832
- }, [renderSlot(_ctx.$slots, "default")], 2);
1920
+ class: normalizeClass(["snail-scroll", classRef.value]),
1921
+ ref: "scroll-root",
1922
+ onScroll: refreshScrollInfo
1923
+ }, [renderSlot(_ctx.$slots, "default")], 34);
1833
1924
  };
1834
1925
  }
1835
1926
  });
@@ -2441,12 +2532,7 @@ const components = {
2441
2532
  };
2442
2533
 
2443
2534
  onMountScope(scope => {
2444
- const type = getType(scope);
2445
- console.log(`%c${type}:`, "color:green", "scope mounted");
2446
- getCurrentScope() && onScopeDispose(() => {
2447
- console.log(`%c${type}:`, "color:blue", "scope auto destroyed");
2448
- scope.destroy();
2449
- });
2535
+ getCurrentScope() && onScopeDispose(scope.destroy);
2450
2536
  });
2451
2537
 
2452
2538
  export { components, getSvgDraw, mount, onAppCreated, triggerAppCreated, usePopup, useReactive, useTreeContext };
@@ -25,6 +25,10 @@
25
25
  }
26
26
  });
27
27
 
28
+ var addLink = href => setTimeout(snail_view.link.register, 0, href);
29
+
30
+ addLink("/styles/snail.vue.vue.css");
31
+
28
32
  const _hoisted_1$e = ["onClick"];
29
33
  const _hoisted_2$9 = ["type", "checked"];
30
34
  const _hoisted_3$6 = ["textContent"];
@@ -98,10 +102,6 @@
98
102
  }
99
103
  });
100
104
 
101
- var addLink = href => setTimeout(snail_view.link.register, 0, href);
102
-
103
- addLink("/styles/snail.vue.vue.css");
104
-
105
105
  var _sfc_main$p = vue.defineComponent({
106
106
  ...{
107
107
  name: "Footer",
@@ -690,7 +690,10 @@
690
690
  props: {
691
691
  name: {},
692
692
  component: {},
693
- url: {}
693
+ url: {},
694
+ props: {
695
+ default: () => ({})
696
+ }
694
697
  },
695
698
  setup(__props) {
696
699
  const {
@@ -737,10 +740,10 @@
737
740
  }
738
741
  });
739
742
  return (_ctx, _cache) => {
740
- return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [(vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(dynamicComponentRef.value), vue.mergeProps(_ctx.$attrs, {
743
+ return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [(vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(dynamicComponentRef.value), vue.mergeProps({
741
744
  ref_key: "componentRef",
742
745
  ref: componentRef
743
- }), vue.createSlots({
746
+ }, _ctx.props, _ctx.$attrs), vue.createSlots({
744
747
  _: 2
745
748
  }, [vue.renderList(_ctx.$slots, (_, name) => {
746
749
  return {
@@ -753,7 +756,7 @@
753
756
  }, _ctx.$attrs), [_cache[0] || (_cache[0] = vue.createTextVNode(" load component error:")), vue.createElementVNode("span", null, vue.toDisplayString(dynamicErrorRef.value), 1)], 16)) : dynamicComponentRef.value == void 0 ? (vue.openBlock(), vue.createBlock(_sfc_main$k, {
754
757
  key: 1,
755
758
  show: true,
756
- "disabled-mask": true
759
+ "mask-disabled": true
757
760
  })) : vue.createCommentVNode("", true)], 64);
758
761
  };
759
762
  }
@@ -774,6 +777,10 @@
774
777
  popupTransition: {}
775
778
  },
776
779
  setup(__props) {
780
+ const {
781
+ props,
782
+ model = vue.shallowRef(void 0)
783
+ } = __props.options;
777
784
  const {
778
785
  closePopup,
779
786
  onBeforeClose
@@ -797,15 +804,19 @@
797
804
  style: vue.normalizeStyle({
798
805
  "z-index": _ctx.zIndex
799
806
  }),
800
- onClick: _cache[0] || (_cache[0] = vue.withModifiers($event => {
807
+ onClick: _cache[1] || (_cache[1] = vue.withModifiers($event => {
801
808
  _ctx.options.closeOnMask && vue.unref(closePopup)();
802
809
  }, ["self"]))
803
810
  }, [vue.createVNode(_sfc_main$j, vue.mergeProps({
804
811
  class: "dialog-body",
805
812
  name: _ctx.options.name,
806
813
  component: _ctx.options.component,
807
- url: _ctx.options.url
808
- }, _ctx.options.props, vue.unref(dialogExtend)), null, 16, ["name", "component", "url"])], 6);
814
+ url: _ctx.options.url,
815
+ props: vue.unref(props)
816
+ }, vue.unref(dialogExtend), {
817
+ modelValue: vue.unref(model),
818
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => vue.isRef(model) ? model.value = $event : null)
819
+ }), null, 16, ["name", "component", "url", "props", "modelValue"])], 6);
809
820
  };
810
821
  }
811
822
  });
@@ -825,6 +836,10 @@
825
836
  popupTransition: {}
826
837
  },
827
838
  setup(__props) {
839
+ const {
840
+ props,
841
+ model = vue.shallowRef(void 0)
842
+ } = __props.options;
828
843
  const {
829
844
  closePopup
830
845
  } = __props.extOptions;
@@ -923,8 +938,12 @@
923
938
  },
924
939
  name: _ctx.options.name,
925
940
  component: _ctx.options.component,
926
- url: _ctx.options.url
927
- }, _ctx.options.props, vue.unref(followExt)), null, 16, ["class", "style", "name", "component", "url"]);
941
+ url: _ctx.options.url,
942
+ props: vue.unref(props)
943
+ }, vue.unref(followExt), {
944
+ modelValue: vue.unref(model),
945
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => vue.isRef(model) ? model.value = $event : null)
946
+ }), null, 16, ["class", "style", "name", "component", "url", "props", "modelValue"]);
928
947
  };
929
948
  }
930
949
  });
@@ -944,8 +963,10 @@
944
963
  popupTransition: {}
945
964
  },
946
965
  setup(__props) {
947
- const loadingRef = vue.shallowRef(false);
948
- vue.onMounted(() => loadingRef.value = true);
966
+ const {
967
+ props,
968
+ model = vue.shallowRef(void 0)
969
+ } = __props.options;
949
970
  return (_ctx, _cache) => {
950
971
  return vue.openBlock(), vue.createBlock(_sfc_main$j, vue.mergeProps({
951
972
  class: ["snail-popup", [_ctx.popupStatus.value, _ctx.popupTransition.value]],
@@ -954,11 +975,12 @@
954
975
  },
955
976
  name: _ctx.options.name,
956
977
  component: _ctx.options.component,
957
- url: _ctx.options.url
958
- }, _ctx.options.props, {
959
- "in-popup": true,
960
- "close-popup": _ctx.extOptions.closePopup
961
- }), null, 16, ["class", "style", "name", "component", "url", "close-popup"]);
978
+ url: _ctx.options.url,
979
+ props: vue.unref(props)
980
+ }, _ctx.extOptions, {
981
+ modelValue: vue.unref(model),
982
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => vue.isRef(model) ? model.value = $event : null)
983
+ }), null, 16, ["class", "style", "name", "component", "url", "props", "modelValue"]);
962
984
  };
963
985
  }
964
986
  });
@@ -1281,7 +1303,7 @@
1281
1303
  followY: {},
1282
1304
  pinned: {}
1283
1305
  },
1284
- emits: ["change", "search"],
1306
+ emits: ["change"],
1285
1307
  setup(__props, _ref) {
1286
1308
  let {
1287
1309
  emit: __emit
@@ -1497,7 +1519,6 @@
1497
1519
  }
1498
1520
 
1499
1521
  function useSelectContext(items, selectsRef) {
1500
- const treeContxt = useTreeContext(items);
1501
1522
  function selected(multiple, item) {
1502
1523
  if (selectsRef.value) {
1503
1524
  return multiple == true ? selectsRef.value.includes(item) : selectsRef.value[selectsRef.value.length - 1] == item;
@@ -1510,11 +1531,18 @@
1510
1531
  }
1511
1532
  return "";
1512
1533
  }
1513
- return Object.freeze({
1514
- ...treeContxt,
1515
- selected,
1516
- selectedText
1517
- });
1534
+ const context = Object.create(null);
1535
+ {
1536
+ const treeContxt = useTreeContext(items);
1537
+ Object.assign(context, treeContxt, {
1538
+ selected,
1539
+ selectedText
1540
+ });
1541
+ snail_core.mountScope(context, "ISelectContext");
1542
+ treeContxt.onDestroy(() => context.destroyed || context.destroy());
1543
+ context.onDestroy(() => treeContxt.destroyed || treeContxt.destroy());
1544
+ }
1545
+ return Object.freeze(context);
1518
1546
  }
1519
1547
 
1520
1548
  const _hoisted_1$6 = {
@@ -1574,12 +1602,11 @@
1574
1602
  const context = useSelectContext(props.items, valuesModel);
1575
1603
  const selectTextRef = vue.computed(() => context.selectedText(props.multiple, props.showPath));
1576
1604
  const slotOptions = Object.freeze({
1577
- closeFollow,
1578
- stopPropagation
1605
+ clear
1579
1606
  });
1580
1607
  var followScope = void 0;
1581
1608
  var stopPropagationScope = void 0;
1582
- function closeFollow() {
1609
+ function destroyFollow() {
1583
1610
  if (followScope != void 0) {
1584
1611
  followScope.destroy();
1585
1612
  followScope = void 0;
@@ -1587,15 +1614,17 @@
1587
1614
  }
1588
1615
  return false;
1589
1616
  }
1590
- function stopPropagation(delay) {
1617
+ function clear(closeFollow, stopPropagation) {
1618
+ valuesModel.value = [];
1619
+ closeFollow && destroyFollow();
1591
1620
  stopPropagationScope && stopPropagationScope.destroy();
1592
- stopPropagationScope = onTimeout(() => stopPropagationScope = void 0, delay);
1621
+ stopPropagationScope = stopPropagation ? onTimeout(() => stopPropagationScope = void 0, 200) : void 0;
1593
1622
  }
1594
1623
  async function onClick() {
1595
1624
  if (props.readonly == true || rootDom.value == void 0) {
1596
1625
  return;
1597
1626
  }
1598
- if (closeFollow() == true || stopPropagationScope != void 0) {
1627
+ if (destroyFollow() == true || stopPropagationScope != void 0) {
1599
1628
  return;
1600
1629
  }
1601
1630
  const values = valuesModel.value && valuesModel.value.length > 0 ? [...valuesModel.value] : [];
@@ -1610,16 +1639,15 @@
1610
1639
  closeOnMask: true,
1611
1640
  closeOnResize: true,
1612
1641
  closeOnTarget: true,
1613
- props: Object.freeze(Object.assign({
1642
+ props: {
1614
1643
  items: props.items,
1615
1644
  context,
1616
1645
  level: 1,
1617
1646
  search: props.search,
1618
1647
  multiple: props.multiple,
1619
- popupStyle: props.popupStyle
1620
- }, {
1648
+ popupStyle: props.popupStyle,
1621
1649
  onChange: onSelectItemChange
1622
- }))
1650
+ }
1623
1651
  });
1624
1652
  await followScope;
1625
1653
  followScope = void 0;
@@ -1636,16 +1664,16 @@
1636
1664
  }]),
1637
1665
  onClick: _cache[0] || (_cache[0] = $event => onClick()),
1638
1666
  ref: "select"
1639
- }, [vue.unref(snail_core.hasAny)(props.items) == true ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, {
1667
+ }, [props.items && props.items.length > 0 ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, {
1640
1668
  key: 0
1641
- }, [vue.unref(snail_core.hasAny)(valuesModel.value) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [vue.renderSlot(_ctx.$slots, "default", vue.normalizeProps(vue.guardReactiveProps(vue.unref(slotOptions))), () => [vue.createElementVNode("div", {
1669
+ }, [valuesModel.value.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [vue.renderSlot(_ctx.$slots, "default", vue.normalizeProps(vue.guardReactiveProps(vue.unref(slotOptions))), () => [vue.createElementVNode("div", {
1642
1670
  class: "select-text",
1643
1671
  title: selectTextRef.value,
1644
1672
  textContent: vue.toDisplayString(selectTextRef.value)
1645
1673
  }, null, 8, _hoisted_2$3)])])) : (vue.openBlock(), vue.createElementBlock("div", {
1646
1674
  key: 1,
1647
1675
  class: "select-result text-tips",
1648
- textContent: vue.toDisplayString(props.placeholder || "请选择")
1676
+ textContent: vue.toDisplayString(props.readonly ? "" : props.placeholder || "请选择")
1649
1677
  }, null, 8, _hoisted_3$3)), vue.createVNode(_sfc_main$o, {
1650
1678
  type: "arrow",
1651
1679
  size: 24,
@@ -1820,18 +1848,81 @@
1820
1848
  type: Boolean
1821
1849
  }
1822
1850
  },
1823
- setup(__props) {
1851
+ emits: ["xbar", "left", "right", "ybar", "top", "bottom"],
1852
+ setup(__props, _ref) {
1853
+ let {
1854
+ emit: __emit
1855
+ } = _ref;
1824
1856
  const props = __props;
1825
- console.warn("scroll 的事件还没实现");
1826
- vue.onActivated(() => console.log("onActivated"));
1827
- vue.onDeactivated(() => console.log("onDeactivated"));
1857
+ const emits = __emit;
1858
+ const rootDom = vue.useTemplateRef("scroll-root");
1859
+ const {
1860
+ onSize
1861
+ } = snail_view.useObserver();
1862
+ const {
1863
+ onInterval
1864
+ } = snail_core.useTimer();
1865
+ const classRef = vue.computed(() => ({
1866
+ "scroll-x": props.scrollX == true,
1867
+ "scroll-y": props.scrollY == true
1868
+ }));
1869
+ var preStatus = void 0;
1870
+ function refreshScrollInfo() {
1871
+ const status = {
1872
+ xbar: rootDom.value.scrollWidth > rootDom.value.clientWidth,
1873
+ ybar: rootDom.value.scrollHeight > rootDom.value.clientHeight,
1874
+ left: false,
1875
+ right: false,
1876
+ top: false,
1877
+ bottom: false,
1878
+ scrollwidth: rootDom.value.scrollWidth,
1879
+ scrollheight: rootDom.value.scrollHeight
1880
+ };
1881
+ if (status.xbar == true) {
1882
+ status.left = rootDom.value.scrollLeft == 0;
1883
+ status.right = rootDom.value.scrollLeft + rootDom.value.clientWidth == rootDom.value.scrollWidth;
1884
+ }
1885
+ if (status.ybar == true) {
1886
+ status.top = rootDom.value.scrollTop == 0;
1887
+ status.bottom = rootDom.value.scrollTop + rootDom.value.clientHeight == rootDom.value.scrollHeight;
1888
+ }
1889
+ Object.freeze(status);
1890
+ const events = Object.create(null);
1891
+ if (preStatus != void 0) {
1892
+ preStatus.xbar != status.xbar && (events.xbar = [status.xbar]);
1893
+ preStatus.ybar != status.ybar && (events.ybar = [status.ybar]);
1894
+ if (preStatus.xbar == true && status.xbar == true) {
1895
+ status.left && preStatus.left !== status.left && (events.left = []);
1896
+ status.right && preStatus.right !== status.right && (events.right = []);
1897
+ }
1898
+ if (preStatus.ybar == true && status.ybar == true) {
1899
+ status.top && preStatus.top !== status.top && (events.top = []);
1900
+ status.bottom && preStatus.bottom !== status.bottom && (events.bottom = []);
1901
+ }
1902
+ }
1903
+ preStatus = status;
1904
+ preStatus = Object.freeze(status);
1905
+ events.xbar && emits("xbar", ...events.xbar);
1906
+ events.left && emits("left");
1907
+ events.right && emits("right");
1908
+ events.ybar && emits("ybar", ...events.ybar);
1909
+ events.top && emits("top");
1910
+ events.bottom && emits("bottom");
1911
+ }
1912
+ vue.onMounted(() => {
1913
+ refreshScrollInfo();
1914
+ onSize(rootDom.value, refreshScrollInfo);
1915
+ onInterval(() => {
1916
+ const isChange = preStatus.scrollwidth != rootDom.value.scrollWidth || preStatus.scrollheight != rootDom.value.scrollHeight;
1917
+ isChange && refreshScrollInfo();
1918
+ }, 100);
1919
+ });
1828
1920
  return (_ctx, _cache) => {
1829
1921
  return vue.openBlock(), vue.createElementBlock("div", {
1830
- class: vue.normalizeClass(["snail-scroll", {
1831
- "scroll-x": props.scrollX == true,
1832
- "scroll-y": props.scrollY == true
1833
- }])
1834
- }, [vue.renderSlot(_ctx.$slots, "default")], 2);
1922
+ class: vue.normalizeClass(["snail-scroll", classRef.value]),
1923
+ ref: "scroll-root",
1924
+ onScroll: refreshScrollInfo
1925
+ }, [vue.renderSlot(_ctx.$slots, "default")], 34);
1835
1926
  };
1836
1927
  }
1837
1928
  });
@@ -2443,12 +2534,7 @@
2443
2534
  };
2444
2535
 
2445
2536
  snail_core.onMountScope(scope => {
2446
- const type = snail_core.getType(scope);
2447
- console.log(`%c${type}:`, "color:green", "scope mounted");
2448
- vue.getCurrentScope() && vue.onScopeDispose(() => {
2449
- console.log(`%c${type}:`, "color:blue", "scope auto destroyed");
2450
- scope.destroy();
2451
- });
2537
+ vue.getCurrentScope() && vue.onScopeDispose(scope.destroy);
2452
2538
  });
2453
2539
 
2454
2540
  exports.components = components;
@@ -1,9 +1,9 @@
1
- /* src:base\choose.vue index:0 */
2
- .snail-choose{align-items:center;display:flex;flex-wrap:wrap;overflow-x:hidden}.snail-choose>div.choose-item{align-items:center;cursor:pointer;display:flex;flex-shrink:0;margin:0 8px;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none}.snail-choose>div.choose-item:after{content:"";height:100%;left:0;overflow:hidden;position:absolute;top:0;width:100%}.snail-choose>div.choose-item>input::checkmark{background-color:#2196f3;border-color:#2196f3}.snail-choose>div.choose-item>span{margin-left:4px}.snail-choose.readonly>div.choose-item{cursor:not-allowed}
3
1
  /* src:base\button.vue index:0 */
4
2
  .snail-button{align-items:center;border-radius:2px;cursor:pointer;display:flex;display:inline-flex;justify-content:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;white-space:nowrap}.snail-button.max{height:40px;width:120px}.snail-button.middle{height:32px;width:90px}.snail-button.normal{height:28px;width:54px}.snail-button.small{height:20px;width:30px}.snail-button.primary{background-color:#5ca3ff;color:#fff}.snail-button.default{background-color:#fff;border:1px solid #dddfed;color:#2e2f33}.snail-button.link{color:#4c9aff}
5
3
  /* src:base\footer.vue index:0 */
6
4
  .snail-footer{align-items:center;background-color:#fff;display:flex;flex-shrink:0;height:72px;padding:0 40px;width:100%}.snail-footer>.snail-button:nth-child(n+2){margin-left:20px}.snail-footer.start-divider{border-top:1px solid #dddfed}.snail-footer.left{justify-content:left}.snail-footer.center{justify-content:center}.snail-footer.right{justify-content:right}
5
+ /* src:base\choose.vue index:0 */
6
+ .snail-choose{align-items:center;display:flex;flex-wrap:wrap;overflow-x:hidden}.snail-choose>div.choose-item{align-items:center;cursor:pointer;display:flex;flex-shrink:0;margin:0 8px;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none}.snail-choose>div.choose-item:after{content:"";height:100%;left:0;overflow:hidden;position:absolute;top:0;width:100%}.snail-choose>div.choose-item>input::checkmark{background-color:#2196f3;border-color:#2196f3}.snail-choose>div.choose-item>span{margin-left:4px}.snail-choose.readonly>div.choose-item{cursor:not-allowed}
7
7
  /* src:base\icon.vue index:0 */
8
8
  .snail-icon{cursor:pointer;opacity:1}
9
9
  /* src:base\header.vue index:0 */
@@ -13,7 +13,7 @@
13
13
  /* src:base\select.vue index:0 */
14
14
  .snail-select{align-items:center;background-color:#fff;border:1px solid #dddfed;border-radius:4px;color:#2e3033;cursor:pointer;display:flex;height:32px;width:100%}.snail-select>div.select-result{align-items:center;display:flex;flex:1;flex-wrap:nowrap;height:30px;overflow:hidden;padding:0 10px 0 6px}.snail-select>div.select-result>div.select-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.snail-select>svg.snail-icon{flex-shrink:0;margin-right:4px}.snail-select>div.no-items{cursor:text;padding:0 8px}.snail-select.readonly{cursor:auto}.snail-select.readonly>svg.snail-icon{display:none}
15
15
  /* src:base\switch.vue index:0 */
16
- .snail-switch{border-radius:10px 10px 10px 10px;cursor:pointer;height:20px!important;overflow:hidden;position:relative;width:36px!important}.snail-switch>div{height:100%;width:100%}.snail-switch>div.on{background-color:#5ca3ff}.snail-switch>div.off{background-color:#c4c8cc;position:absolute;transition:left .2s ease}.snail-switch>div.status{background:#fff;border-radius:10px 10px 10px 10px;height:16px;position:absolute;top:2px;transition:left .2s ease;width:16px}.snail-switch.on>div.off{left:100%;top:0}.snail-switch.on>div.status{left:calc(100% - 18px)}.snail-switch.off>div.off{left:0;top:0}.snail-switch.off>div.status{left:2px}.snail-switch.readonly{cursor:default}
16
+ .snail-switch{border-radius:10px 10px 10px 10px;cursor:pointer;height:20px!important;overflow:hidden;position:relative;width:36px!important}.snail-switch>div{height:100%;width:100%}.snail-switch>div.on{background-color:#5ca3ff}.snail-switch>div.off{background-color:#c4c8cc;position:absolute;transition:left .2s ease}.snail-switch>div.status{background:#fff;border-radius:10px 10px 10px 10px;height:16px;position:absolute;top:2px;transition:left .2s ease;width:16px}.snail-switch.on>div.off{left:100%;top:0}.snail-switch.on>div.status{left:calc(100% - 18px)}.snail-switch.off>div.off{left:0;top:0}.snail-switch.off>div.status{left:2px}.snail-switch.readonly{cursor:not-allowed}
17
17
  /* src:container\dynamic.vue index:0 */
18
18
  .snail-dynamic-error{color:red}.snail-dynamic-error>span{color:gray}
19
19
  /* src:container\fold.vue index:0 */
@@ -40,10 +40,10 @@
40
40
  .snail-loading{height:100%;left:0;position:absolute;top:0;width:100%;z-index:10000}.snail-loading.show-mask{background-color:rgba(0,0,0,.15)}.snail-loading:after,.snail-loading:before{animation:snail-loading-stretch 1s ease-in-out infinite;border-radius:50%;content:"";display:block;display:inline-block;height:10px;left:50%;margin-left:-18px;margin-top:-6px;position:absolute;top:50%;width:10px}.snail-loading:before{background-color:#279bf1}.snail-loading:after{animation-delay:-.5s;background:#64d214;margin-left:0;margin-right:-18px}@keyframes snail-loading-stretch{0%,to{transform:scale(1)}50%{transform:scale(2)}}.snail-loading-enter-active,.snail-loading-leave-active{transition:opacity .5s ease-in-out}.snail-loading-enter-from,.snail-loading-leave-to{opacity:0}
41
41
  /* src:popup\components\confirm-container.vue index:0 */
42
42
  .snail-confirm{background-color:#fff;border-radius:4px;color:#2e2f33;display:flex;flex-direction:column;max-height:350px;max-width:548px;min-width:348px}.snail-confirm>div.confirm-body{flex:1;margin:20px 40px;overflow:auto;word-wrap:break-word}
43
- /* src:popup\components\follow-container.vue index:0 */
44
- .snail-follow{background-color:#fff;display:inline-block;max-height:100%;max-width:100%;position:fixed;transition-duration:.5s;transition-property:left,top;transition-timing-function:ease}
45
43
  /* src:popup\components\dialog-container.vue index:0 */
46
44
  .snail-dialog{align-items:center;display:flex;height:100%;justify-content:center;left:0;position:fixed;top:0;width:100%}.snail-dialog:before{background-color:rgba(24,27,33,.45);content:"";height:100%;opacity:1;position:absolute;transition:opacity .4s ease-in-out;width:100%}.snail-dialog>.dialog-body{background-color:#fff;border-radius:4px;box-shadow:0 0 15px rgba(0,0,0,.3);position:relative}.snail-dialog.unactive:before{opacity:0}.snail-dialog.unactive>.dialog-body{box-shadow:0 0 4px rgba(0,0,0,.3)}
45
+ /* src:popup\components\follow-container.vue index:0 */
46
+ .snail-follow{background-color:#fff;display:inline-block;max-height:100%;max-width:100%;position:fixed;transition-duration:.5s;transition-property:left,top;transition-timing-function:ease}
47
47
  /* src:popup\components\popup-container.vue index:0 */
48
48
  .snail-popup{left:0;position:fixed;top:0}
49
49
  /* src:popup\components\toast-container.vue index:0 */
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "依赖【snail】,基于vue封装常用UI组件",
4
4
  "author": "snail_dev@163.com",
5
5
  "license": "MIT",
6
- "version": "1.0.40",
6
+ "version": "1.0.42",
7
7
  "type": "module",
8
8
  "main": "dist/snail.vue.js",
9
9
  "module": "dist/snail.vue.js",