@hoci/core 0.5.0 → 0.5.2

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.
package/dist/index.cjs CHANGED
@@ -298,7 +298,7 @@ const useSelectionList = shared.defineHookComponent({
298
298
  }));
299
299
  const renderItem = () => {
300
300
  const children = options.filter((e) => actives.includes(e.value)).map((e) => e.render());
301
- return props.multiple ? children : children[0];
301
+ return props.multiple ? children : shared.getFirstChilld(children);
302
302
  };
303
303
  const slotData = {
304
304
  isActive,
@@ -362,12 +362,10 @@ const useSelectionItem = shared.defineHookComponent({
362
362
  return Array.isArray(label2) ? label2 : [label2];
363
363
  });
364
364
  function render() {
365
- return vue.renderSlot(slots, "default", {
365
+ return slots.default?.({
366
366
  active: context.isActive(props.value),
367
367
  activate
368
- }, () => {
369
- return label.value;
370
- });
368
+ }) ?? label.value.filter(Boolean);
371
369
  }
372
370
  let remove = () => {
373
371
  };
@@ -504,6 +502,7 @@ const iconProps = shared.defineHookProps({
504
502
  default: () => "auto"
505
503
  }
506
504
  });
505
+ const isSvg = (src) => src.endsWith(".svg") || src.startsWith("data:image/svg+xml");
507
506
  const useIcon = shared.defineHookComponent({
508
507
  props: iconProps,
509
508
  setup(props, context) {
@@ -522,7 +521,7 @@ const useIcon = shared.defineHookComponent({
522
521
  };
523
522
  });
524
523
  const dynamicStyle = vue.computed(() => {
525
- const mask = props.mask === "auto" ? props.src.endsWith(".svg") : props.mask;
524
+ const mask = props.mask === "auto" ? isSvg(props.src) : props.mask;
526
525
  if (!mask) {
527
526
  return {
528
527
  "background-image": "var(--icon-url)",
@@ -556,11 +555,256 @@ const useIcon = shared.defineHookComponent({
556
555
  }
557
556
  });
558
557
 
558
+ const configProviderProps = shared.defineHookProps({
559
+ icon: {
560
+ type: Object
561
+ },
562
+ activateEvent: {
563
+ type: String
564
+ }
565
+ });
566
+
567
+ const popoverProps = shared.defineHookProps({
568
+ popupClass: {
569
+ type: String
570
+ },
571
+ placement: {
572
+ type: String,
573
+ default: () => "auto"
574
+ },
575
+ triggerEvent: {
576
+ type: String,
577
+ default: () => "hover"
578
+ },
579
+ offset: {
580
+ type: Number,
581
+ default: () => 8
582
+ },
583
+ lazy: {
584
+ type: Boolean,
585
+ default: () => false
586
+ },
587
+ visible: {
588
+ type: Boolean,
589
+ default: () => false
590
+ },
591
+ disabled: {
592
+ type: Boolean,
593
+ default: () => false
594
+ },
595
+ teleport: {
596
+ type: [String, Object, Boolean],
597
+ default: () => true
598
+ }
599
+ });
600
+ const popoverEmits = shared.defineHookEmits(["update:visible", "change"]);
601
+ const usePopover = shared.defineHookComponent({
602
+ props: popoverProps,
603
+ emits: popoverEmits,
604
+ setup(props, context) {
605
+ const visible = core.useVModel(props, "visible", context.emit, {
606
+ passive: true
607
+ });
608
+ const triggerRef = vue.ref();
609
+ const popupRef = vue.ref();
610
+ const validate = (event) => {
611
+ const events2 = Array.isArray(event) ? event : [event];
612
+ return !props.disabled && events2.includes(props.triggerEvent);
613
+ };
614
+ let timer;
615
+ const toggle = (_value) => {
616
+ const value = _value ?? !visible.value;
617
+ visible.value = value;
618
+ context.emit("change", value);
619
+ };
620
+ function onMouseover() {
621
+ if (!validate("hover")) {
622
+ return;
623
+ }
624
+ timer = setTimeout(
625
+ () => {
626
+ toggle(true);
627
+ },
628
+ props.lazy ? 800 : 100
629
+ );
630
+ }
631
+ function onMouseout() {
632
+ if (!validate("hover")) {
633
+ return;
634
+ }
635
+ clearTimeout(timer);
636
+ toggle(false);
637
+ }
638
+ const onClick = (e) => {
639
+ if (!validate("click")) {
640
+ return;
641
+ }
642
+ e.preventDefault();
643
+ e.stopPropagation();
644
+ toggle();
645
+ };
646
+ core.onClickOutside(triggerRef, () => {
647
+ if (!validate(["click", "contextmenu", "touch", "dblclick", "mousedown"])) {
648
+ return;
649
+ }
650
+ toggle(false);
651
+ }, {
652
+ ignore: [popupRef]
653
+ });
654
+ const onContextmenu = (e) => {
655
+ if (!validate("contextmenu")) {
656
+ return;
657
+ }
658
+ e.preventDefault();
659
+ e.stopPropagation();
660
+ toggle();
661
+ };
662
+ const onFocusin = () => {
663
+ if (!validate("focus")) {
664
+ return;
665
+ }
666
+ toggle(true);
667
+ };
668
+ const onFocusout = () => {
669
+ if (!validate("focus")) {
670
+ return;
671
+ }
672
+ toggle(false);
673
+ };
674
+ const onTouchend = () => {
675
+ if (!validate("touch")) {
676
+ return;
677
+ }
678
+ toggle(true);
679
+ };
680
+ const onDblclick = () => {
681
+ if (!validate("dblclick")) {
682
+ return;
683
+ }
684
+ toggle(true);
685
+ };
686
+ const onMousedown = () => {
687
+ if (!validate("mousedown")) {
688
+ return;
689
+ }
690
+ toggle(true);
691
+ };
692
+ const onMouseup = () => {
693
+ if (!validate("mousedown")) {
694
+ return;
695
+ }
696
+ toggle(false);
697
+ };
698
+ const events = {
699
+ onMouseover,
700
+ onMouseout,
701
+ onMousedown,
702
+ onMouseup,
703
+ onContextmenu,
704
+ onClick,
705
+ onDblclick,
706
+ onFocusin,
707
+ onFocusout,
708
+ onTouchend
709
+ };
710
+ const dropdownPosition = vue.reactive({ x: 0, y: 0 });
711
+ const popupClass = vue.computed(() => {
712
+ return props.popupClass;
713
+ });
714
+ function resize() {
715
+ const trigger = triggerRef.value;
716
+ const popup = popupRef.value;
717
+ if (!!trigger && !!popup && visible.value) {
718
+ const { width, height, left, top } = trigger.getBoundingClientRect();
719
+ const { clientWidth: pWidth, clientHeight: pHeight } = popup;
720
+ let x = 0;
721
+ let y = 0;
722
+ const offset = props.offset;
723
+ switch (props.placement) {
724
+ case "auto":
725
+ case "bottom":
726
+ x = left - (pWidth - width) / 2;
727
+ y = top + height + offset;
728
+ break;
729
+ case "bottom-left":
730
+ x = left;
731
+ y = top + height + offset;
732
+ break;
733
+ case "bottom-right":
734
+ x = left + width - pWidth;
735
+ y = top + height + offset;
736
+ break;
737
+ case "top":
738
+ x = left - (pWidth - width) / 2;
739
+ y = top - pHeight - offset;
740
+ break;
741
+ case "top-left":
742
+ x = left;
743
+ y = top - pHeight - offset;
744
+ break;
745
+ case "top-right":
746
+ x = left + width - pWidth;
747
+ y = top - pHeight - offset;
748
+ break;
749
+ case "left":
750
+ x = left - pWidth - offset;
751
+ y = top - (pHeight - height) / 2;
752
+ break;
753
+ case "left-top":
754
+ x = left - pWidth - offset;
755
+ y = top;
756
+ break;
757
+ case "left-bottom":
758
+ x = left - pWidth - offset;
759
+ y = top + height - pHeight;
760
+ break;
761
+ case "right":
762
+ x = left + width + offset;
763
+ y = top - (pHeight - height) / 2;
764
+ break;
765
+ case "right-top":
766
+ x = left + width + offset;
767
+ y = top;
768
+ break;
769
+ case "right-bottom":
770
+ x = left + width + offset;
771
+ y = top + height - pHeight;
772
+ break;
773
+ }
774
+ dropdownPosition.x = x;
775
+ dropdownPosition.y = y;
776
+ }
777
+ }
778
+ vue.watch(visible, () => {
779
+ vue.nextTick(resize);
780
+ });
781
+ const popupStyle = vue.computed(() => {
782
+ return {
783
+ left: tslx.px(dropdownPosition.x),
784
+ top: tslx.px(dropdownPosition.y),
785
+ visibility: visible.value ? "visible" : "hidden",
786
+ position: "fixed"
787
+ };
788
+ });
789
+ return {
790
+ events,
791
+ dropdownPosition,
792
+ triggerRef,
793
+ popupRef,
794
+ popupClass,
795
+ popupStyle
796
+ };
797
+ }
798
+ });
799
+
559
800
  exports.AFFIX_TARGET_KEY = AFFIX_TARGET_KEY;
560
801
  exports.affixEmits = affixEmits;
561
802
  exports.affixProps = affixProps;
803
+ exports.configProviderProps = configProviderProps;
562
804
  exports.iconProps = iconProps;
563
805
  exports.itemProps = itemProps;
806
+ exports.popoverEmits = popoverEmits;
807
+ exports.popoverProps = popoverProps;
564
808
  exports.provideAffixTarget = provideAffixTarget;
565
809
  exports.selectionEmits = selectionEmits;
566
810
  exports.selectionProps = selectionProps;
@@ -568,6 +812,7 @@ exports.switchEmits = switchEmits;
568
812
  exports.switchProps = switchProps;
569
813
  exports.useAffix = useAffix;
570
814
  exports.useIcon = useIcon;
815
+ exports.usePopover = usePopover;
571
816
  exports.useSelectionContext = useSelectionContext;
572
817
  exports.useSelectionItem = useSelectionItem;
573
818
  exports.useSelectionList = useSelectionList;
package/dist/index.d.cts CHANGED
@@ -358,9 +358,7 @@ declare const itemProps: {
358
358
  };
359
359
  declare const useSelectionItem: _hoci_shared.HookComponent<{
360
360
  activate: () => void;
361
- render: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
362
- [key: string]: any;
363
- }>;
361
+ render: () => ElementLike;
364
362
  isActive: vue.ComputedRef<boolean>;
365
363
  isDisabled: vue.ComputedRef<boolean>;
366
364
  className: vue.ComputedRef<string>;
@@ -596,4 +594,152 @@ declare const useIcon: _hoci_shared.HookComponent<{
596
594
  color: string;
597
595
  }>;
598
596
 
599
- export { AFFIX_TARGET_KEY, type AffixProps, type HiIconProps, type HiItemSlotsData, type HiSelectionContext, type HiSelectionSlotData, type HiSwitchProps, type InitFunction, type Option, type SelectionProps, affixEmits, affixProps, iconProps, itemProps, provideAffixTarget, selectionEmits, selectionProps, switchEmits, switchProps, useAffix, useIcon, useSelectionContext, useSelectionItem, useSelectionList, useSwitch };
597
+ declare const configProviderProps: {
598
+ icon: {
599
+ type: PropType<Partial<{
600
+ size: number | undefined;
601
+ sizeUnit: string | undefined;
602
+ }>>;
603
+ };
604
+ activateEvent: {
605
+ type: PropType<Partial<_hoci_shared.ActivateEvent>>;
606
+ };
607
+ };
608
+
609
+ type Placement = "bottom" | "top" | "left" | "right" | "auto" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "left-top" | "left-bottom" | "right-top" | "right-bottom";
610
+ type TriggerEvent = "click" | "mousedown" | "dblclick" | "hover" | "contextmenu" | "focus" | "touch";
611
+ declare const popoverProps: {
612
+ popupClass: {
613
+ type: StringConstructor;
614
+ };
615
+ placement: {
616
+ type: PropType<Placement>;
617
+ default: () => "auto";
618
+ };
619
+ triggerEvent: {
620
+ type: PropType<TriggerEvent>;
621
+ default: () => "hover";
622
+ };
623
+ offset: {
624
+ type: NumberConstructor;
625
+ default: () => 8;
626
+ };
627
+ lazy: {
628
+ type: BooleanConstructor;
629
+ default: () => false;
630
+ };
631
+ visible: {
632
+ type: BooleanConstructor;
633
+ default: () => false;
634
+ };
635
+ disabled: {
636
+ type: BooleanConstructor;
637
+ default: () => false;
638
+ };
639
+ teleport: {
640
+ type: PropType<string | boolean | HTMLElement>;
641
+ default: () => true;
642
+ };
643
+ };
644
+ declare const popoverEmits: ("change" | "update:visible")[];
645
+ declare const usePopover: _hoci_shared.HookComponent<{
646
+ events: {
647
+ onMouseover: () => void;
648
+ onMouseout: () => void;
649
+ onMousedown: () => void;
650
+ onMouseup: () => void;
651
+ onContextmenu: (e: MouseEvent) => void;
652
+ onClick: (e: MouseEvent) => void;
653
+ onDblclick: () => void;
654
+ onFocusin: () => void;
655
+ onFocusout: () => void;
656
+ onTouchend: () => void;
657
+ };
658
+ dropdownPosition: {
659
+ x: number;
660
+ y: number;
661
+ };
662
+ triggerRef: vue.Ref<HTMLElement | undefined>;
663
+ popupRef: vue.Ref<HTMLElement | undefined>;
664
+ popupClass: vue.ComputedRef<string | undefined>;
665
+ popupStyle: vue.ComputedRef<{
666
+ left: string;
667
+ top: string;
668
+ visibility: string;
669
+ position: string;
670
+ }>;
671
+ }, ("change" | "update:visible")[], {
672
+ popupClass: {
673
+ type: StringConstructor;
674
+ };
675
+ placement: {
676
+ type: PropType<Placement>;
677
+ default: () => "auto";
678
+ };
679
+ triggerEvent: {
680
+ type: PropType<TriggerEvent>;
681
+ default: () => "hover";
682
+ };
683
+ offset: {
684
+ type: NumberConstructor;
685
+ default: () => 8;
686
+ };
687
+ lazy: {
688
+ type: BooleanConstructor;
689
+ default: () => false;
690
+ };
691
+ visible: {
692
+ type: BooleanConstructor;
693
+ default: () => false;
694
+ };
695
+ disabled: {
696
+ type: BooleanConstructor;
697
+ default: () => false;
698
+ };
699
+ teleport: {
700
+ type: PropType<string | boolean | HTMLElement>;
701
+ default: () => true;
702
+ };
703
+ }, vue.ExtractPropTypes<{
704
+ popupClass: {
705
+ type: StringConstructor;
706
+ };
707
+ placement: {
708
+ type: PropType<Placement>;
709
+ default: () => "auto";
710
+ };
711
+ triggerEvent: {
712
+ type: PropType<TriggerEvent>;
713
+ default: () => "hover";
714
+ };
715
+ offset: {
716
+ type: NumberConstructor;
717
+ default: () => 8;
718
+ };
719
+ lazy: {
720
+ type: BooleanConstructor;
721
+ default: () => false;
722
+ };
723
+ visible: {
724
+ type: BooleanConstructor;
725
+ default: () => false;
726
+ };
727
+ disabled: {
728
+ type: BooleanConstructor;
729
+ default: () => false;
730
+ };
731
+ teleport: {
732
+ type: PropType<string | boolean | HTMLElement>;
733
+ default: () => true;
734
+ };
735
+ }>, {
736
+ offset: number;
737
+ visible: boolean;
738
+ disabled: boolean;
739
+ placement: Placement;
740
+ triggerEvent: TriggerEvent;
741
+ lazy: boolean;
742
+ teleport: string | boolean | HTMLElement;
743
+ }>;
744
+
745
+ export { AFFIX_TARGET_KEY, type AffixProps, type HiIconProps, type HiItemSlotsData, type HiSelectionContext, type HiSelectionSlotData, type HiSwitchProps, type InitFunction, type Option, type Placement, type SelectionProps, type TriggerEvent, affixEmits, affixProps, configProviderProps, iconProps, itemProps, popoverEmits, popoverProps, provideAffixTarget, selectionEmits, selectionProps, switchEmits, switchProps, useAffix, useIcon, usePopover, useSelectionContext, useSelectionItem, useSelectionList, useSwitch };
package/dist/index.d.mts CHANGED
@@ -358,9 +358,7 @@ declare const itemProps: {
358
358
  };
359
359
  declare const useSelectionItem: _hoci_shared.HookComponent<{
360
360
  activate: () => void;
361
- render: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
362
- [key: string]: any;
363
- }>;
361
+ render: () => ElementLike;
364
362
  isActive: vue.ComputedRef<boolean>;
365
363
  isDisabled: vue.ComputedRef<boolean>;
366
364
  className: vue.ComputedRef<string>;
@@ -596,4 +594,152 @@ declare const useIcon: _hoci_shared.HookComponent<{
596
594
  color: string;
597
595
  }>;
598
596
 
599
- export { AFFIX_TARGET_KEY, type AffixProps, type HiIconProps, type HiItemSlotsData, type HiSelectionContext, type HiSelectionSlotData, type HiSwitchProps, type InitFunction, type Option, type SelectionProps, affixEmits, affixProps, iconProps, itemProps, provideAffixTarget, selectionEmits, selectionProps, switchEmits, switchProps, useAffix, useIcon, useSelectionContext, useSelectionItem, useSelectionList, useSwitch };
597
+ declare const configProviderProps: {
598
+ icon: {
599
+ type: PropType<Partial<{
600
+ size: number | undefined;
601
+ sizeUnit: string | undefined;
602
+ }>>;
603
+ };
604
+ activateEvent: {
605
+ type: PropType<Partial<_hoci_shared.ActivateEvent>>;
606
+ };
607
+ };
608
+
609
+ type Placement = "bottom" | "top" | "left" | "right" | "auto" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "left-top" | "left-bottom" | "right-top" | "right-bottom";
610
+ type TriggerEvent = "click" | "mousedown" | "dblclick" | "hover" | "contextmenu" | "focus" | "touch";
611
+ declare const popoverProps: {
612
+ popupClass: {
613
+ type: StringConstructor;
614
+ };
615
+ placement: {
616
+ type: PropType<Placement>;
617
+ default: () => "auto";
618
+ };
619
+ triggerEvent: {
620
+ type: PropType<TriggerEvent>;
621
+ default: () => "hover";
622
+ };
623
+ offset: {
624
+ type: NumberConstructor;
625
+ default: () => 8;
626
+ };
627
+ lazy: {
628
+ type: BooleanConstructor;
629
+ default: () => false;
630
+ };
631
+ visible: {
632
+ type: BooleanConstructor;
633
+ default: () => false;
634
+ };
635
+ disabled: {
636
+ type: BooleanConstructor;
637
+ default: () => false;
638
+ };
639
+ teleport: {
640
+ type: PropType<string | boolean | HTMLElement>;
641
+ default: () => true;
642
+ };
643
+ };
644
+ declare const popoverEmits: ("change" | "update:visible")[];
645
+ declare const usePopover: _hoci_shared.HookComponent<{
646
+ events: {
647
+ onMouseover: () => void;
648
+ onMouseout: () => void;
649
+ onMousedown: () => void;
650
+ onMouseup: () => void;
651
+ onContextmenu: (e: MouseEvent) => void;
652
+ onClick: (e: MouseEvent) => void;
653
+ onDblclick: () => void;
654
+ onFocusin: () => void;
655
+ onFocusout: () => void;
656
+ onTouchend: () => void;
657
+ };
658
+ dropdownPosition: {
659
+ x: number;
660
+ y: number;
661
+ };
662
+ triggerRef: vue.Ref<HTMLElement | undefined>;
663
+ popupRef: vue.Ref<HTMLElement | undefined>;
664
+ popupClass: vue.ComputedRef<string | undefined>;
665
+ popupStyle: vue.ComputedRef<{
666
+ left: string;
667
+ top: string;
668
+ visibility: string;
669
+ position: string;
670
+ }>;
671
+ }, ("change" | "update:visible")[], {
672
+ popupClass: {
673
+ type: StringConstructor;
674
+ };
675
+ placement: {
676
+ type: PropType<Placement>;
677
+ default: () => "auto";
678
+ };
679
+ triggerEvent: {
680
+ type: PropType<TriggerEvent>;
681
+ default: () => "hover";
682
+ };
683
+ offset: {
684
+ type: NumberConstructor;
685
+ default: () => 8;
686
+ };
687
+ lazy: {
688
+ type: BooleanConstructor;
689
+ default: () => false;
690
+ };
691
+ visible: {
692
+ type: BooleanConstructor;
693
+ default: () => false;
694
+ };
695
+ disabled: {
696
+ type: BooleanConstructor;
697
+ default: () => false;
698
+ };
699
+ teleport: {
700
+ type: PropType<string | boolean | HTMLElement>;
701
+ default: () => true;
702
+ };
703
+ }, vue.ExtractPropTypes<{
704
+ popupClass: {
705
+ type: StringConstructor;
706
+ };
707
+ placement: {
708
+ type: PropType<Placement>;
709
+ default: () => "auto";
710
+ };
711
+ triggerEvent: {
712
+ type: PropType<TriggerEvent>;
713
+ default: () => "hover";
714
+ };
715
+ offset: {
716
+ type: NumberConstructor;
717
+ default: () => 8;
718
+ };
719
+ lazy: {
720
+ type: BooleanConstructor;
721
+ default: () => false;
722
+ };
723
+ visible: {
724
+ type: BooleanConstructor;
725
+ default: () => false;
726
+ };
727
+ disabled: {
728
+ type: BooleanConstructor;
729
+ default: () => false;
730
+ };
731
+ teleport: {
732
+ type: PropType<string | boolean | HTMLElement>;
733
+ default: () => true;
734
+ };
735
+ }>, {
736
+ offset: number;
737
+ visible: boolean;
738
+ disabled: boolean;
739
+ placement: Placement;
740
+ triggerEvent: TriggerEvent;
741
+ lazy: boolean;
742
+ teleport: string | boolean | HTMLElement;
743
+ }>;
744
+
745
+ export { AFFIX_TARGET_KEY, type AffixProps, type HiIconProps, type HiItemSlotsData, type HiSelectionContext, type HiSelectionSlotData, type HiSwitchProps, type InitFunction, type Option, type Placement, type SelectionProps, type TriggerEvent, affixEmits, affixProps, configProviderProps, iconProps, itemProps, popoverEmits, popoverProps, provideAffixTarget, selectionEmits, selectionProps, switchEmits, switchProps, useAffix, useIcon, usePopover, useSelectionContext, useSelectionItem, useSelectionList, useSwitch };
package/dist/index.d.ts CHANGED
@@ -358,9 +358,7 @@ declare const itemProps: {
358
358
  };
359
359
  declare const useSelectionItem: _hoci_shared.HookComponent<{
360
360
  activate: () => void;
361
- render: () => vue.VNode<vue.RendererNode, vue.RendererElement, {
362
- [key: string]: any;
363
- }>;
361
+ render: () => ElementLike;
364
362
  isActive: vue.ComputedRef<boolean>;
365
363
  isDisabled: vue.ComputedRef<boolean>;
366
364
  className: vue.ComputedRef<string>;
@@ -596,4 +594,152 @@ declare const useIcon: _hoci_shared.HookComponent<{
596
594
  color: string;
597
595
  }>;
598
596
 
599
- export { AFFIX_TARGET_KEY, type AffixProps, type HiIconProps, type HiItemSlotsData, type HiSelectionContext, type HiSelectionSlotData, type HiSwitchProps, type InitFunction, type Option, type SelectionProps, affixEmits, affixProps, iconProps, itemProps, provideAffixTarget, selectionEmits, selectionProps, switchEmits, switchProps, useAffix, useIcon, useSelectionContext, useSelectionItem, useSelectionList, useSwitch };
597
+ declare const configProviderProps: {
598
+ icon: {
599
+ type: PropType<Partial<{
600
+ size: number | undefined;
601
+ sizeUnit: string | undefined;
602
+ }>>;
603
+ };
604
+ activateEvent: {
605
+ type: PropType<Partial<_hoci_shared.ActivateEvent>>;
606
+ };
607
+ };
608
+
609
+ type Placement = "bottom" | "top" | "left" | "right" | "auto" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "left-top" | "left-bottom" | "right-top" | "right-bottom";
610
+ type TriggerEvent = "click" | "mousedown" | "dblclick" | "hover" | "contextmenu" | "focus" | "touch";
611
+ declare const popoverProps: {
612
+ popupClass: {
613
+ type: StringConstructor;
614
+ };
615
+ placement: {
616
+ type: PropType<Placement>;
617
+ default: () => "auto";
618
+ };
619
+ triggerEvent: {
620
+ type: PropType<TriggerEvent>;
621
+ default: () => "hover";
622
+ };
623
+ offset: {
624
+ type: NumberConstructor;
625
+ default: () => 8;
626
+ };
627
+ lazy: {
628
+ type: BooleanConstructor;
629
+ default: () => false;
630
+ };
631
+ visible: {
632
+ type: BooleanConstructor;
633
+ default: () => false;
634
+ };
635
+ disabled: {
636
+ type: BooleanConstructor;
637
+ default: () => false;
638
+ };
639
+ teleport: {
640
+ type: PropType<string | boolean | HTMLElement>;
641
+ default: () => true;
642
+ };
643
+ };
644
+ declare const popoverEmits: ("change" | "update:visible")[];
645
+ declare const usePopover: _hoci_shared.HookComponent<{
646
+ events: {
647
+ onMouseover: () => void;
648
+ onMouseout: () => void;
649
+ onMousedown: () => void;
650
+ onMouseup: () => void;
651
+ onContextmenu: (e: MouseEvent) => void;
652
+ onClick: (e: MouseEvent) => void;
653
+ onDblclick: () => void;
654
+ onFocusin: () => void;
655
+ onFocusout: () => void;
656
+ onTouchend: () => void;
657
+ };
658
+ dropdownPosition: {
659
+ x: number;
660
+ y: number;
661
+ };
662
+ triggerRef: vue.Ref<HTMLElement | undefined>;
663
+ popupRef: vue.Ref<HTMLElement | undefined>;
664
+ popupClass: vue.ComputedRef<string | undefined>;
665
+ popupStyle: vue.ComputedRef<{
666
+ left: string;
667
+ top: string;
668
+ visibility: string;
669
+ position: string;
670
+ }>;
671
+ }, ("change" | "update:visible")[], {
672
+ popupClass: {
673
+ type: StringConstructor;
674
+ };
675
+ placement: {
676
+ type: PropType<Placement>;
677
+ default: () => "auto";
678
+ };
679
+ triggerEvent: {
680
+ type: PropType<TriggerEvent>;
681
+ default: () => "hover";
682
+ };
683
+ offset: {
684
+ type: NumberConstructor;
685
+ default: () => 8;
686
+ };
687
+ lazy: {
688
+ type: BooleanConstructor;
689
+ default: () => false;
690
+ };
691
+ visible: {
692
+ type: BooleanConstructor;
693
+ default: () => false;
694
+ };
695
+ disabled: {
696
+ type: BooleanConstructor;
697
+ default: () => false;
698
+ };
699
+ teleport: {
700
+ type: PropType<string | boolean | HTMLElement>;
701
+ default: () => true;
702
+ };
703
+ }, vue.ExtractPropTypes<{
704
+ popupClass: {
705
+ type: StringConstructor;
706
+ };
707
+ placement: {
708
+ type: PropType<Placement>;
709
+ default: () => "auto";
710
+ };
711
+ triggerEvent: {
712
+ type: PropType<TriggerEvent>;
713
+ default: () => "hover";
714
+ };
715
+ offset: {
716
+ type: NumberConstructor;
717
+ default: () => 8;
718
+ };
719
+ lazy: {
720
+ type: BooleanConstructor;
721
+ default: () => false;
722
+ };
723
+ visible: {
724
+ type: BooleanConstructor;
725
+ default: () => false;
726
+ };
727
+ disabled: {
728
+ type: BooleanConstructor;
729
+ default: () => false;
730
+ };
731
+ teleport: {
732
+ type: PropType<string | boolean | HTMLElement>;
733
+ default: () => true;
734
+ };
735
+ }>, {
736
+ offset: number;
737
+ visible: boolean;
738
+ disabled: boolean;
739
+ placement: Placement;
740
+ triggerEvent: TriggerEvent;
741
+ lazy: boolean;
742
+ teleport: string | boolean | HTMLElement;
743
+ }>;
744
+
745
+ export { AFFIX_TARGET_KEY, type AffixProps, type HiIconProps, type HiItemSlotsData, type HiSelectionContext, type HiSelectionSlotData, type HiSwitchProps, type InitFunction, type Option, type Placement, type SelectionProps, type TriggerEvent, affixEmits, affixProps, configProviderProps, iconProps, itemProps, popoverEmits, popoverProps, provideAffixTarget, selectionEmits, selectionProps, switchEmits, switchProps, useAffix, useIcon, usePopover, useSelectionContext, useSelectionItem, useSelectionList, useSwitch };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { ref, inject, computed, watchPostEffect, provide, reactive, renderSlot, watch } from 'vue';
2
- import { toReactive, useElementBounding, useElementVisibility, useEventListener, syncRef, isDefined, tryOnScopeDispose, useVModel } from '@vueuse/core';
3
- import { defineHookProps, defineHookEmits, defineHookComponent, useElement, throttleByRaf, isWindow, valuePropType, classPropType, labelPropType, useSharedConfig } from '@hoci/shared';
1
+ import { ref, inject, computed, watchPostEffect, provide, reactive, renderSlot, watch, nextTick } from 'vue';
2
+ import { toReactive, useElementBounding, useElementVisibility, useEventListener, syncRef, isDefined, tryOnScopeDispose, useVModel, onClickOutside } from '@vueuse/core';
3
+ import { defineHookProps, defineHookEmits, defineHookComponent, useElement, throttleByRaf, isWindow, valuePropType, classPropType, labelPropType, useSharedConfig, getFirstChilld } from '@hoci/shared';
4
4
  export * from '@hoci/shared';
5
5
  import { px, cls, createUnitFormat } from 'tslx';
6
6
 
@@ -297,7 +297,7 @@ const useSelectionList = defineHookComponent({
297
297
  }));
298
298
  const renderItem = () => {
299
299
  const children = options.filter((e) => actives.includes(e.value)).map((e) => e.render());
300
- return props.multiple ? children : children[0];
300
+ return props.multiple ? children : getFirstChilld(children);
301
301
  };
302
302
  const slotData = {
303
303
  isActive,
@@ -361,12 +361,10 @@ const useSelectionItem = defineHookComponent({
361
361
  return Array.isArray(label2) ? label2 : [label2];
362
362
  });
363
363
  function render() {
364
- return renderSlot(slots, "default", {
364
+ return slots.default?.({
365
365
  active: context.isActive(props.value),
366
366
  activate
367
- }, () => {
368
- return label.value;
369
- });
367
+ }) ?? label.value.filter(Boolean);
370
368
  }
371
369
  let remove = () => {
372
370
  };
@@ -503,6 +501,7 @@ const iconProps = defineHookProps({
503
501
  default: () => "auto"
504
502
  }
505
503
  });
504
+ const isSvg = (src) => src.endsWith(".svg") || src.startsWith("data:image/svg+xml");
506
505
  const useIcon = defineHookComponent({
507
506
  props: iconProps,
508
507
  setup(props, context) {
@@ -521,7 +520,7 @@ const useIcon = defineHookComponent({
521
520
  };
522
521
  });
523
522
  const dynamicStyle = computed(() => {
524
- const mask = props.mask === "auto" ? props.src.endsWith(".svg") : props.mask;
523
+ const mask = props.mask === "auto" ? isSvg(props.src) : props.mask;
525
524
  if (!mask) {
526
525
  return {
527
526
  "background-image": "var(--icon-url)",
@@ -555,4 +554,246 @@ const useIcon = defineHookComponent({
555
554
  }
556
555
  });
557
556
 
558
- export { AFFIX_TARGET_KEY, affixEmits, affixProps, iconProps, itemProps, provideAffixTarget, selectionEmits, selectionProps, switchEmits, switchProps, useAffix, useIcon, useSelectionContext, useSelectionItem, useSelectionList, useSwitch };
557
+ const configProviderProps = defineHookProps({
558
+ icon: {
559
+ type: Object
560
+ },
561
+ activateEvent: {
562
+ type: String
563
+ }
564
+ });
565
+
566
+ const popoverProps = defineHookProps({
567
+ popupClass: {
568
+ type: String
569
+ },
570
+ placement: {
571
+ type: String,
572
+ default: () => "auto"
573
+ },
574
+ triggerEvent: {
575
+ type: String,
576
+ default: () => "hover"
577
+ },
578
+ offset: {
579
+ type: Number,
580
+ default: () => 8
581
+ },
582
+ lazy: {
583
+ type: Boolean,
584
+ default: () => false
585
+ },
586
+ visible: {
587
+ type: Boolean,
588
+ default: () => false
589
+ },
590
+ disabled: {
591
+ type: Boolean,
592
+ default: () => false
593
+ },
594
+ teleport: {
595
+ type: [String, Object, Boolean],
596
+ default: () => true
597
+ }
598
+ });
599
+ const popoverEmits = defineHookEmits(["update:visible", "change"]);
600
+ const usePopover = defineHookComponent({
601
+ props: popoverProps,
602
+ emits: popoverEmits,
603
+ setup(props, context) {
604
+ const visible = useVModel(props, "visible", context.emit, {
605
+ passive: true
606
+ });
607
+ const triggerRef = ref();
608
+ const popupRef = ref();
609
+ const validate = (event) => {
610
+ const events2 = Array.isArray(event) ? event : [event];
611
+ return !props.disabled && events2.includes(props.triggerEvent);
612
+ };
613
+ let timer;
614
+ const toggle = (_value) => {
615
+ const value = _value ?? !visible.value;
616
+ visible.value = value;
617
+ context.emit("change", value);
618
+ };
619
+ function onMouseover() {
620
+ if (!validate("hover")) {
621
+ return;
622
+ }
623
+ timer = setTimeout(
624
+ () => {
625
+ toggle(true);
626
+ },
627
+ props.lazy ? 800 : 100
628
+ );
629
+ }
630
+ function onMouseout() {
631
+ if (!validate("hover")) {
632
+ return;
633
+ }
634
+ clearTimeout(timer);
635
+ toggle(false);
636
+ }
637
+ const onClick = (e) => {
638
+ if (!validate("click")) {
639
+ return;
640
+ }
641
+ e.preventDefault();
642
+ e.stopPropagation();
643
+ toggle();
644
+ };
645
+ onClickOutside(triggerRef, () => {
646
+ if (!validate(["click", "contextmenu", "touch", "dblclick", "mousedown"])) {
647
+ return;
648
+ }
649
+ toggle(false);
650
+ }, {
651
+ ignore: [popupRef]
652
+ });
653
+ const onContextmenu = (e) => {
654
+ if (!validate("contextmenu")) {
655
+ return;
656
+ }
657
+ e.preventDefault();
658
+ e.stopPropagation();
659
+ toggle();
660
+ };
661
+ const onFocusin = () => {
662
+ if (!validate("focus")) {
663
+ return;
664
+ }
665
+ toggle(true);
666
+ };
667
+ const onFocusout = () => {
668
+ if (!validate("focus")) {
669
+ return;
670
+ }
671
+ toggle(false);
672
+ };
673
+ const onTouchend = () => {
674
+ if (!validate("touch")) {
675
+ return;
676
+ }
677
+ toggle(true);
678
+ };
679
+ const onDblclick = () => {
680
+ if (!validate("dblclick")) {
681
+ return;
682
+ }
683
+ toggle(true);
684
+ };
685
+ const onMousedown = () => {
686
+ if (!validate("mousedown")) {
687
+ return;
688
+ }
689
+ toggle(true);
690
+ };
691
+ const onMouseup = () => {
692
+ if (!validate("mousedown")) {
693
+ return;
694
+ }
695
+ toggle(false);
696
+ };
697
+ const events = {
698
+ onMouseover,
699
+ onMouseout,
700
+ onMousedown,
701
+ onMouseup,
702
+ onContextmenu,
703
+ onClick,
704
+ onDblclick,
705
+ onFocusin,
706
+ onFocusout,
707
+ onTouchend
708
+ };
709
+ const dropdownPosition = reactive({ x: 0, y: 0 });
710
+ const popupClass = computed(() => {
711
+ return props.popupClass;
712
+ });
713
+ function resize() {
714
+ const trigger = triggerRef.value;
715
+ const popup = popupRef.value;
716
+ if (!!trigger && !!popup && visible.value) {
717
+ const { width, height, left, top } = trigger.getBoundingClientRect();
718
+ const { clientWidth: pWidth, clientHeight: pHeight } = popup;
719
+ let x = 0;
720
+ let y = 0;
721
+ const offset = props.offset;
722
+ switch (props.placement) {
723
+ case "auto":
724
+ case "bottom":
725
+ x = left - (pWidth - width) / 2;
726
+ y = top + height + offset;
727
+ break;
728
+ case "bottom-left":
729
+ x = left;
730
+ y = top + height + offset;
731
+ break;
732
+ case "bottom-right":
733
+ x = left + width - pWidth;
734
+ y = top + height + offset;
735
+ break;
736
+ case "top":
737
+ x = left - (pWidth - width) / 2;
738
+ y = top - pHeight - offset;
739
+ break;
740
+ case "top-left":
741
+ x = left;
742
+ y = top - pHeight - offset;
743
+ break;
744
+ case "top-right":
745
+ x = left + width - pWidth;
746
+ y = top - pHeight - offset;
747
+ break;
748
+ case "left":
749
+ x = left - pWidth - offset;
750
+ y = top - (pHeight - height) / 2;
751
+ break;
752
+ case "left-top":
753
+ x = left - pWidth - offset;
754
+ y = top;
755
+ break;
756
+ case "left-bottom":
757
+ x = left - pWidth - offset;
758
+ y = top + height - pHeight;
759
+ break;
760
+ case "right":
761
+ x = left + width + offset;
762
+ y = top - (pHeight - height) / 2;
763
+ break;
764
+ case "right-top":
765
+ x = left + width + offset;
766
+ y = top;
767
+ break;
768
+ case "right-bottom":
769
+ x = left + width + offset;
770
+ y = top + height - pHeight;
771
+ break;
772
+ }
773
+ dropdownPosition.x = x;
774
+ dropdownPosition.y = y;
775
+ }
776
+ }
777
+ watch(visible, () => {
778
+ nextTick(resize);
779
+ });
780
+ const popupStyle = computed(() => {
781
+ return {
782
+ left: px(dropdownPosition.x),
783
+ top: px(dropdownPosition.y),
784
+ visibility: visible.value ? "visible" : "hidden",
785
+ position: "fixed"
786
+ };
787
+ });
788
+ return {
789
+ events,
790
+ dropdownPosition,
791
+ triggerRef,
792
+ popupRef,
793
+ popupClass,
794
+ popupStyle
795
+ };
796
+ }
797
+ });
798
+
799
+ export { AFFIX_TARGET_KEY, affixEmits, affixProps, configProviderProps, iconProps, itemProps, popoverEmits, popoverProps, provideAffixTarget, selectionEmits, selectionProps, switchEmits, switchProps, useAffix, useIcon, usePopover, useSelectionContext, useSelectionItem, useSelectionList, useSwitch };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hoci/core",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "",
5
5
  "author": "chizuki",
6
6
  "license": "MIT",
@@ -19,14 +19,13 @@
19
19
  "dist/"
20
20
  ],
21
21
  "peerDependencies": {
22
- "@vueuse/core": ">=10",
23
- "vue": "^3.3.4"
22
+ "vue": "^3.0.0-0"
24
23
  },
25
24
  "dependencies": {
26
- "@vueuse/core": "^10.5.0",
25
+ "@vueuse/core": ">=10.5.0",
27
26
  "maybe-types": "^0.1.0",
28
27
  "tslx": "^0.1.1",
29
- "@hoci/shared": "0.5.0"
28
+ "@hoci/shared": "0.5.2"
30
29
  },
31
30
  "scripts": {
32
31
  "build": "unbuild",