@v-c/resize-observer 0.0.1

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.
Files changed (48) hide show
  1. package/dist/Collection.cjs +1 -0
  2. package/dist/Collection.d.ts +15 -0
  3. package/dist/Collection.js +36 -0
  4. package/dist/SingleObserver/DomWrapper.cjs +1 -0
  5. package/dist/SingleObserver/DomWrapper.d.ts +4 -0
  6. package/dist/SingleObserver/DomWrapper.js +14 -0
  7. package/dist/SingleObserver/index.cjs +1 -0
  8. package/dist/SingleObserver/index.d.ts +3 -0
  9. package/dist/SingleObserver/index.js +84 -0
  10. package/dist/index.cjs +1 -0
  11. package/dist/index.d.ts +24 -0
  12. package/dist/index.js +46 -0
  13. package/dist/utils/observerUtil.cjs +1 -0
  14. package/dist/utils/observerUtil.d.ts +7 -0
  15. package/dist/utils/observerUtil.js +24 -0
  16. package/package/dist/Collection.cjs +1 -0
  17. package/package/dist/Collection.d.ts +15 -0
  18. package/package/dist/Collection.js +36 -0
  19. package/package/dist/SingleObserver/DomWrapper.cjs +1 -0
  20. package/package/dist/SingleObserver/DomWrapper.d.ts +4 -0
  21. package/package/dist/SingleObserver/DomWrapper.js +14 -0
  22. package/package/dist/SingleObserver/index.cjs +1 -0
  23. package/package/dist/SingleObserver/index.d.ts +3 -0
  24. package/package/dist/SingleObserver/index.js +84 -0
  25. package/package/dist/index.cjs +1 -0
  26. package/package/dist/index.d.ts +24 -0
  27. package/package/dist/index.js +46 -0
  28. package/package/dist/utils/observerUtil.cjs +1 -0
  29. package/package/dist/utils/observerUtil.d.ts +7 -0
  30. package/package/dist/utils/observerUtil.js +24 -0
  31. package/package/package.json +26 -0
  32. package/package/src/Collection.tsx +44 -0
  33. package/package/src/SingleObserver/DomWrapper.tsx +7 -0
  34. package/package/src/SingleObserver/index.tsx +92 -0
  35. package/package/src/index.tsx +62 -0
  36. package/package/src/utils/observerUtil.ts +41 -0
  37. package/package/tsconfig.json +7 -0
  38. package/package/vite.config.ts +18 -0
  39. package/package/vitest.config.ts +9 -0
  40. package/package.json +26 -0
  41. package/src/Collection.tsx +44 -0
  42. package/src/SingleObserver/DomWrapper.tsx +7 -0
  43. package/src/SingleObserver/index.tsx +92 -0
  44. package/src/index.tsx +62 -0
  45. package/src/utils/observerUtil.ts +41 -0
  46. package/tsconfig.json +7 -0
  47. package/vite.config.ts +18 -0
  48. package/vitest.config.ts +9 -0
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("vue"),u=Symbol("CollectionContext"),d=n.defineComponent({props:{onBatchResize:{type:Function,required:!1}},setup(o,{slots:t}){const i=n.shallowRef(0),l=n.shallowRef([]),c=n.inject(u,()=>{}),v=(e,r,s)=>{const a=i.value+1;i.value=a,l.value.push({size:e,element:r,data:s}),Promise.resolve().then(()=>{var f;if(i.value===a){const C=l.value;l.value=[],(f=o.onBatchResize)==null||f.call(o,C)}}),c==null||c(e,r,s)};return n.provide(u,v),()=>{var e;return(e=t.default)==null?void 0:e.call(t)}}});exports.Collection=d;exports.CollectionContext=u;
@@ -0,0 +1,15 @@
1
+ import { InjectionKey } from 'vue';
2
+ import { SizeInfo } from '.';
3
+ type onCollectionResize = (size: SizeInfo, element: HTMLElement, data: any) => void;
4
+ export declare const CollectionContext: InjectionKey<onCollectionResize>;
5
+ export interface ResizeInfo {
6
+ size: SizeInfo;
7
+ element: HTMLElement;
8
+ data: any;
9
+ }
10
+ export interface CollectionProps {
11
+ /** Trigger when some children ResizeObserver changed. Collect by frame render level */
12
+ onBatchResize?: (resizeInfo: ResizeInfo[]) => void;
13
+ }
14
+ export declare const Collection: import('vue').DefineComponent<CollectionProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<CollectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
15
+ export {};
@@ -0,0 +1,36 @@
1
+ import { defineComponent as z, shallowRef as f, inject as R, provide as d } from "vue";
2
+ const a = Symbol("CollectionContext"), m = /* @__PURE__ */ z({
3
+ props: {
4
+ onBatchResize: {
5
+ type: Function,
6
+ required: !1
7
+ }
8
+ },
9
+ setup(n, {
10
+ slots: o
11
+ }) {
12
+ const t = f(0), i = f([]), c = R(a, () => {
13
+ });
14
+ return d(a, (e, r, u) => {
15
+ const l = t.value + 1;
16
+ t.value = l, i.value.push({
17
+ size: e,
18
+ element: r,
19
+ data: u
20
+ }), Promise.resolve().then(() => {
21
+ var s;
22
+ if (t.value === l) {
23
+ const v = i.value;
24
+ i.value = [], (s = n.onBatchResize) == null || s.call(n, v);
25
+ }
26
+ }), c == null || c(e, r, u);
27
+ }), () => {
28
+ var e;
29
+ return (e = o.default) == null ? void 0 : e.call(o);
30
+ };
31
+ }
32
+ });
33
+ export {
34
+ m as Collection,
35
+ a as CollectionContext
36
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const r=require("vue"),t=r.defineComponent({setup(n,{slots:e}){return()=>{var u;return(u=e.default)==null?void 0:u.call(e)}}});exports.default=t;
@@ -0,0 +1,4 @@
1
+ declare const _default: import('vue').DefineComponent<{}, () => import('vue').VNode<import('vue').RendererNode, import('vue').RendererElement, {
2
+ [key: string]: any;
3
+ }>[] | undefined, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
4
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { defineComponent as p } from "vue";
2
+ const f = /* @__PURE__ */ p({
3
+ setup(n, {
4
+ slots: e
5
+ }) {
6
+ return () => {
7
+ var r;
8
+ return (r = e.default) == null ? void 0 : r.call(e);
9
+ };
10
+ }
11
+ });
12
+ export {
13
+ f as default
14
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue"),a=require("@v-c/util/dist/Dom/findDOMNode"),O=require("../Collection.cjs"),w=require("../utils/observerUtil.cjs"),S=require("./DomWrapper.cjs"),x=t.defineComponent({props:{data:{type:null,required:!1},disabled:{type:Boolean,required:!1},onResize:{type:Function,required:!1}},name:"SingleObserver",inheritAttrs:!1,setup(h,{expose:M,slots:f}){const i=t.shallowRef(),c=t.shallowRef(),l=t.inject(O.CollectionContext,()=>{}),n=t.shallowRef({width:-1,height:-1,offsetWidth:-1,offsetHeight:-1}),v=()=>{const e=a(i)||(i.value&&typeof i.value=="object"?a(i.value.nativeElement):null)||a(c.value);return e&&e.nodeType===3&&e.nextElementSibling?e.nextElementSibling:e},g=e=>{const{onResize:m,data:W}=h,{width:u,height:d}=e.getBoundingClientRect(),{offsetHeight:r,offsetWidth:s}=e,b=Math.floor(u),p=Math.floor(d);if(n.value.width!==b||n.value.height!==p||n.value.offsetWidth!==s||n.value.offsetHeight!==r){const R={width:b,height:p,offsetWidth:s,offsetHeight:r};n.value=R;const y=s===Math.round(u)?u:s,H=r===Math.round(d)?d:r,q={...R,offsetWidth:y,offsetHeight:H};l==null||l(q,e,W),m&&Promise.resolve().then(()=>{m(q,e)})}};let o;return t.onMounted(()=>{o=v(),o&&!h.disabled&&w.observe(o,g)}),t.onBeforeUnmount(()=>{o&&w.unobserve(o,g)}),M({getDom:v}),()=>t.createVNode(S.default,{ref:c},{default:()=>{var e;return[(e=f.default)==null?void 0:e.call(f)]}})}});exports.default=x;
@@ -0,0 +1,3 @@
1
+ import { ResizeObserverProps } from '../index.tsx';
2
+ declare const SingleObserver: import('vue').DefineComponent<ResizeObserverProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<ResizeObserverProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
3
+ export default SingleObserver;
@@ -0,0 +1,84 @@
1
+ import { defineComponent as y, shallowRef as a, inject as z, onMounted as O, onBeforeUnmount as E, createVNode as S } from "vue";
2
+ import h from "@v-c/util/dist/Dom/findDOMNode";
3
+ import { CollectionContext as q } from "../Collection.js";
4
+ import { observe as B, unobserve as C } from "../utils/observerUtil.js";
5
+ import D from "./DomWrapper.js";
6
+ const P = /* @__PURE__ */ y({
7
+ props: {
8
+ data: {
9
+ type: null,
10
+ required: !1
11
+ },
12
+ disabled: {
13
+ type: Boolean,
14
+ required: !1
15
+ },
16
+ onResize: {
17
+ type: Function,
18
+ required: !1
19
+ }
20
+ },
21
+ name: "SingleObserver",
22
+ inheritAttrs: !1,
23
+ setup(u, {
24
+ expose: w,
25
+ slots: r
26
+ }) {
27
+ const n = a(), m = a(), s = z(q, () => {
28
+ }), t = a({
29
+ width: -1,
30
+ height: -1,
31
+ offsetWidth: -1,
32
+ offsetHeight: -1
33
+ }), c = () => {
34
+ const e = h(n) || (n.value && typeof n.value == "object" ? h(n.value.nativeElement) : null) || h(m.value);
35
+ return e && e.nodeType === 3 && e.nextElementSibling ? e.nextElementSibling : e;
36
+ }, p = (e) => {
37
+ const {
38
+ onResize: g,
39
+ data: x
40
+ } = u, {
41
+ width: d,
42
+ height: l
43
+ } = e.getBoundingClientRect(), {
44
+ offsetHeight: i,
45
+ offsetWidth: f
46
+ } = e, v = Math.floor(d), b = Math.floor(l);
47
+ if (t.value.width !== v || t.value.height !== b || t.value.offsetWidth !== f || t.value.offsetHeight !== i) {
48
+ const R = {
49
+ width: v,
50
+ height: b,
51
+ offsetWidth: f,
52
+ offsetHeight: i
53
+ };
54
+ t.value = R;
55
+ const H = f === Math.round(d) ? d : f, M = i === Math.round(l) ? l : i, W = {
56
+ ...R,
57
+ offsetWidth: H,
58
+ offsetHeight: M
59
+ };
60
+ s == null || s(W, e, x), g && Promise.resolve().then(() => {
61
+ g(W, e);
62
+ });
63
+ }
64
+ };
65
+ let o;
66
+ return O(() => {
67
+ o = c(), o && !u.disabled && B(o, p);
68
+ }), E(() => {
69
+ o && C(o, p);
70
+ }), w({
71
+ getDom: c
72
+ }), () => S(D, {
73
+ ref: m
74
+ }, {
75
+ default: () => {
76
+ var e;
77
+ return [(e = r.default) == null ? void 0 : e.call(r)];
78
+ }
79
+ });
80
+ }
81
+ });
82
+ export {
83
+ P as default
84
+ };
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue"),s=require("@v-c/util"),c=require("@v-c/util/dist/Children/toArray"),d=require("./Collection.cjs"),f=require("./SingleObserver/index.cjs"),p=require("./utils/observerUtil.cjs");function b(r){return typeof r=="function"||Object.prototype.toString.call(r)==="[object Object]"&&!t.isVNode(r)}const y="vc-observer-key",u=t.defineComponent({props:{data:{type:null,required:!1},disabled:{type:Boolean,required:!1},onResize:{type:Function,required:!1}},setup(r,{slots:n}){return()=>{var i;const o=c.toArray((i=n.default)==null?void 0:i.call(n));return process.env.NODE_ENV!=="production"&&(o.length>1?s.warning(!1,"Find more than one child node with `children` in ResizeObserver. Please use ResizeObserver.Collection instead."):o.length===0&&s.warning(!1,"`children` of ResizeObserver is empty. Nothing is in observe.")),o.map((e,l)=>{const a=(e==null?void 0:e.key)||`${y}-${l}`;return t.createVNode(f.default,t.mergeProps(r,{key:a}),b(e)?e:{default:()=>[e]})})}}});u.Collection=d.Collection;exports._rs=p._rs;exports.default=u;
@@ -0,0 +1,24 @@
1
+ import { Collection } from './Collection.tsx';
2
+ import { _rs } from './utils/observerUtil';
3
+ export {
4
+ /** @private Test only for mock trigger resize event */
5
+ _rs, };
6
+ export interface SizeInfo {
7
+ width: number;
8
+ height: number;
9
+ offsetWidth: number;
10
+ offsetHeight: number;
11
+ }
12
+ export type OnResize = (size: SizeInfo, element: HTMLElement) => void;
13
+ export interface ResizeObserverProps {
14
+ /** Pass to ResizeObserver.Collection with additional data */
15
+ data?: any;
16
+ disabled?: boolean;
17
+ /** Trigger if element resized. Will always trigger when first time render. */
18
+ onResize?: OnResize;
19
+ }
20
+ declare const ResizeObserver: import('vue').DefineComponent<ResizeObserverProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<ResizeObserverProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
21
+ declare const _default: typeof ResizeObserver & {
22
+ Collection: typeof Collection;
23
+ };
24
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,46 @@
1
+ import { defineComponent as p, createVNode as a, mergeProps as l, isVNode as u } from "vue";
2
+ import { warning as i } from "@v-c/util";
3
+ import { toArray as m } from "@v-c/util/dist/Children/toArray";
4
+ import { Collection as c } from "./Collection.js";
5
+ import d from "./SingleObserver/index.js";
6
+ import { _rs as k } from "./utils/observerUtil.js";
7
+ function b(r) {
8
+ return typeof r == "function" || Object.prototype.toString.call(r) === "[object Object]" && !u(r);
9
+ }
10
+ const y = "vc-observer-key", v = /* @__PURE__ */ p({
11
+ props: {
12
+ data: {
13
+ type: null,
14
+ required: !1
15
+ },
16
+ disabled: {
17
+ type: Boolean,
18
+ required: !1
19
+ },
20
+ onResize: {
21
+ type: Function,
22
+ required: !1
23
+ }
24
+ },
25
+ setup(r, {
26
+ slots: o
27
+ }) {
28
+ return () => {
29
+ var n;
30
+ const t = m((n = o.default) == null ? void 0 : n.call(o));
31
+ return process.env.NODE_ENV !== "production" && (t.length > 1 ? i(!1, "Find more than one child node with `children` in ResizeObserver. Please use ResizeObserver.Collection instead.") : t.length === 0 && i(!1, "`children` of ResizeObserver is empty. Nothing is in observe.")), t.map((e, s) => {
32
+ const f = (e == null ? void 0 : e.key) || `${y}-${s}`;
33
+ return a(d, l(r, {
34
+ key: f
35
+ }), b(e) ? e : {
36
+ default: () => [e]
37
+ });
38
+ });
39
+ };
40
+ }
41
+ });
42
+ v.Collection = c;
43
+ export {
44
+ k as _rs,
45
+ v as default
46
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("resize-observer-polyfill"),o=new Map;function d(c){c.forEach(b=>{var r;const{target:u}=b;(r=o.get(u))==null||r.forEach(v=>v(u))})}const g=new s(d),p=process.env.NODE_ENV!=="production"?o:null,E=process.env.NODE_ENV!=="production"?d:null;function _(c,b){var u,r,v;o.has(c)||(o.set(c,new Set),g.observe(c)),(v=(r=(u=o==null?void 0:o.get)==null?void 0:u.call(o,c))==null?void 0:r.add)==null||v.call(r,b)}function i(c,b){var u,r,v,a,f;o.has(c)&&((v=(r=(u=o==null?void 0:o.get)==null?void 0:u.call(o,c))==null?void 0:r.delete)==null||v.call(r,b),(f=(a=o==null?void 0:o.get)==null?void 0:a.call(o,c))!=null&&f.size||(g.unobserve(c),o.delete(c)))}exports._el=p;exports._rs=E;exports.observe=_;exports.unobserve=i;
@@ -0,0 +1,7 @@
1
+ export type ResizeListener = (element: Element) => void;
2
+ declare function onResize(entities: ResizeObserverEntry[]): void;
3
+ export declare const _el: Map<Element, Set<ResizeListener>> | null;
4
+ export declare const _rs: typeof onResize | null;
5
+ export declare function observe(element: Element, callback: ResizeListener): void;
6
+ export declare function unobserve(element: Element, callback: ResizeListener): void;
7
+ export {};
@@ -0,0 +1,24 @@
1
+ import E from "resize-observer-polyfill";
2
+ const o = /* @__PURE__ */ new Map();
3
+ function b(c) {
4
+ c.forEach((v) => {
5
+ var f;
6
+ const { target: r } = v;
7
+ (f = o.get(r)) == null || f.forEach((u) => u(r));
8
+ });
9
+ }
10
+ const d = new E(b), h = process.env.NODE_ENV !== "production" ? o : null, z = process.env.NODE_ENV !== "production" ? b : null;
11
+ function N(c, v) {
12
+ var r, f, u;
13
+ o.has(c) || (o.set(c, /* @__PURE__ */ new Set()), d.observe(c)), (u = (f = (r = o == null ? void 0 : o.get) == null ? void 0 : r.call(o, c)) == null ? void 0 : f.add) == null || u.call(f, v);
14
+ }
15
+ function O(c, v) {
16
+ var r, f, u, a, p;
17
+ o.has(c) && ((u = (f = (r = o == null ? void 0 : o.get) == null ? void 0 : r.call(o, c)) == null ? void 0 : f.delete) == null || u.call(f, v), (p = (a = o == null ? void 0 : o.get) == null ? void 0 : a.call(o, c)) != null && p.size || (d.unobserve(c), o.delete(c)));
18
+ }
19
+ export {
20
+ h as _el,
21
+ z as _rs,
22
+ N as observe,
23
+ O as unobserve
24
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("vue"),u=Symbol("CollectionContext"),d=n.defineComponent({props:{onBatchResize:{type:Function,required:!1}},setup(o,{slots:t}){const i=n.shallowRef(0),l=n.shallowRef([]),c=n.inject(u,()=>{}),v=(e,r,s)=>{const a=i.value+1;i.value=a,l.value.push({size:e,element:r,data:s}),Promise.resolve().then(()=>{var f;if(i.value===a){const C=l.value;l.value=[],(f=o.onBatchResize)==null||f.call(o,C)}}),c==null||c(e,r,s)};return n.provide(u,v),()=>{var e;return(e=t.default)==null?void 0:e.call(t)}}});exports.Collection=d;exports.CollectionContext=u;
@@ -0,0 +1,15 @@
1
+ import { InjectionKey } from 'vue';
2
+ import { SizeInfo } from '.';
3
+ type onCollectionResize = (size: SizeInfo, element: HTMLElement, data: any) => void;
4
+ export declare const CollectionContext: InjectionKey<onCollectionResize>;
5
+ export interface ResizeInfo {
6
+ size: SizeInfo;
7
+ element: HTMLElement;
8
+ data: any;
9
+ }
10
+ export interface CollectionProps {
11
+ /** Trigger when some children ResizeObserver changed. Collect by frame render level */
12
+ onBatchResize?: (resizeInfo: ResizeInfo[]) => void;
13
+ }
14
+ export declare const Collection: import('vue').DefineComponent<CollectionProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<CollectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
15
+ export {};
@@ -0,0 +1,36 @@
1
+ import { defineComponent as z, shallowRef as f, inject as R, provide as d } from "vue";
2
+ const a = Symbol("CollectionContext"), m = /* @__PURE__ */ z({
3
+ props: {
4
+ onBatchResize: {
5
+ type: Function,
6
+ required: !1
7
+ }
8
+ },
9
+ setup(n, {
10
+ slots: o
11
+ }) {
12
+ const t = f(0), i = f([]), c = R(a, () => {
13
+ });
14
+ return d(a, (e, r, u) => {
15
+ const l = t.value + 1;
16
+ t.value = l, i.value.push({
17
+ size: e,
18
+ element: r,
19
+ data: u
20
+ }), Promise.resolve().then(() => {
21
+ var s;
22
+ if (t.value === l) {
23
+ const v = i.value;
24
+ i.value = [], (s = n.onBatchResize) == null || s.call(n, v);
25
+ }
26
+ }), c == null || c(e, r, u);
27
+ }), () => {
28
+ var e;
29
+ return (e = o.default) == null ? void 0 : e.call(o);
30
+ };
31
+ }
32
+ });
33
+ export {
34
+ m as Collection,
35
+ a as CollectionContext
36
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const r=require("vue"),t=r.defineComponent({setup(n,{slots:e}){return()=>{var u;return(u=e.default)==null?void 0:u.call(e)}}});exports.default=t;
@@ -0,0 +1,4 @@
1
+ declare const _default: import('vue').DefineComponent<{}, () => import('vue').VNode<import('vue').RendererNode, import('vue').RendererElement, {
2
+ [key: string]: any;
3
+ }>[] | undefined, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
4
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import { defineComponent as p } from "vue";
2
+ const f = /* @__PURE__ */ p({
3
+ setup(n, {
4
+ slots: e
5
+ }) {
6
+ return () => {
7
+ var r;
8
+ return (r = e.default) == null ? void 0 : r.call(e);
9
+ };
10
+ }
11
+ });
12
+ export {
13
+ f as default
14
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue"),a=require("@v-c/util/dist/Dom/findDOMNode"),O=require("../Collection.cjs"),w=require("../utils/observerUtil.cjs"),S=require("./DomWrapper.cjs"),x=t.defineComponent({props:{data:{type:null,required:!1},disabled:{type:Boolean,required:!1},onResize:{type:Function,required:!1}},name:"SingleObserver",inheritAttrs:!1,setup(h,{expose:M,slots:f}){const i=t.shallowRef(),c=t.shallowRef(),l=t.inject(O.CollectionContext,()=>{}),n=t.shallowRef({width:-1,height:-1,offsetWidth:-1,offsetHeight:-1}),v=()=>{const e=a(i)||(i.value&&typeof i.value=="object"?a(i.value.nativeElement):null)||a(c.value);return e&&e.nodeType===3&&e.nextElementSibling?e.nextElementSibling:e},g=e=>{const{onResize:m,data:W}=h,{width:u,height:d}=e.getBoundingClientRect(),{offsetHeight:r,offsetWidth:s}=e,b=Math.floor(u),p=Math.floor(d);if(n.value.width!==b||n.value.height!==p||n.value.offsetWidth!==s||n.value.offsetHeight!==r){const R={width:b,height:p,offsetWidth:s,offsetHeight:r};n.value=R;const y=s===Math.round(u)?u:s,H=r===Math.round(d)?d:r,q={...R,offsetWidth:y,offsetHeight:H};l==null||l(q,e,W),m&&Promise.resolve().then(()=>{m(q,e)})}};let o;return t.onMounted(()=>{o=v(),o&&!h.disabled&&w.observe(o,g)}),t.onBeforeUnmount(()=>{o&&w.unobserve(o,g)}),M({getDom:v}),()=>t.createVNode(S.default,{ref:c},{default:()=>{var e;return[(e=f.default)==null?void 0:e.call(f)]}})}});exports.default=x;
@@ -0,0 +1,3 @@
1
+ import { ResizeObserverProps } from '../index.tsx';
2
+ declare const SingleObserver: import('vue').DefineComponent<ResizeObserverProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<ResizeObserverProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
3
+ export default SingleObserver;
@@ -0,0 +1,84 @@
1
+ import { defineComponent as y, shallowRef as a, inject as z, onMounted as O, onBeforeUnmount as E, createVNode as S } from "vue";
2
+ import h from "@v-c/util/dist/Dom/findDOMNode";
3
+ import { CollectionContext as q } from "../Collection.js";
4
+ import { observe as B, unobserve as C } from "../utils/observerUtil.js";
5
+ import D from "./DomWrapper.js";
6
+ const P = /* @__PURE__ */ y({
7
+ props: {
8
+ data: {
9
+ type: null,
10
+ required: !1
11
+ },
12
+ disabled: {
13
+ type: Boolean,
14
+ required: !1
15
+ },
16
+ onResize: {
17
+ type: Function,
18
+ required: !1
19
+ }
20
+ },
21
+ name: "SingleObserver",
22
+ inheritAttrs: !1,
23
+ setup(u, {
24
+ expose: w,
25
+ slots: r
26
+ }) {
27
+ const n = a(), m = a(), s = z(q, () => {
28
+ }), t = a({
29
+ width: -1,
30
+ height: -1,
31
+ offsetWidth: -1,
32
+ offsetHeight: -1
33
+ }), c = () => {
34
+ const e = h(n) || (n.value && typeof n.value == "object" ? h(n.value.nativeElement) : null) || h(m.value);
35
+ return e && e.nodeType === 3 && e.nextElementSibling ? e.nextElementSibling : e;
36
+ }, p = (e) => {
37
+ const {
38
+ onResize: g,
39
+ data: x
40
+ } = u, {
41
+ width: d,
42
+ height: l
43
+ } = e.getBoundingClientRect(), {
44
+ offsetHeight: i,
45
+ offsetWidth: f
46
+ } = e, v = Math.floor(d), b = Math.floor(l);
47
+ if (t.value.width !== v || t.value.height !== b || t.value.offsetWidth !== f || t.value.offsetHeight !== i) {
48
+ const R = {
49
+ width: v,
50
+ height: b,
51
+ offsetWidth: f,
52
+ offsetHeight: i
53
+ };
54
+ t.value = R;
55
+ const H = f === Math.round(d) ? d : f, M = i === Math.round(l) ? l : i, W = {
56
+ ...R,
57
+ offsetWidth: H,
58
+ offsetHeight: M
59
+ };
60
+ s == null || s(W, e, x), g && Promise.resolve().then(() => {
61
+ g(W, e);
62
+ });
63
+ }
64
+ };
65
+ let o;
66
+ return O(() => {
67
+ o = c(), o && !u.disabled && B(o, p);
68
+ }), E(() => {
69
+ o && C(o, p);
70
+ }), w({
71
+ getDom: c
72
+ }), () => S(D, {
73
+ ref: m
74
+ }, {
75
+ default: () => {
76
+ var e;
77
+ return [(e = r.default) == null ? void 0 : e.call(r)];
78
+ }
79
+ });
80
+ }
81
+ });
82
+ export {
83
+ P as default
84
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue"),s=require("@v-c/util"),c=require("@v-c/util/dist/Children/toArray"),d=require("./Collection.cjs"),f=require("./SingleObserver/index.cjs"),p=require("./utils/observerUtil.cjs");function b(r){return typeof r=="function"||Object.prototype.toString.call(r)==="[object Object]"&&!t.isVNode(r)}const y="vc-observer-key",u=t.defineComponent({props:{data:{type:null,required:!1},disabled:{type:Boolean,required:!1},onResize:{type:Function,required:!1}},setup(r,{slots:n}){return()=>{var i;const o=c.toArray((i=n.default)==null?void 0:i.call(n));return process.env.NODE_ENV!=="production"&&(o.length>1?s.warning(!1,"Find more than one child node with `children` in ResizeObserver. Please use ResizeObserver.Collection instead."):o.length===0&&s.warning(!1,"`children` of ResizeObserver is empty. Nothing is in observe.")),o.map((e,l)=>{const a=(e==null?void 0:e.key)||`${y}-${l}`;return t.createVNode(f.default,t.mergeProps(r,{key:a}),b(e)?e:{default:()=>[e]})})}}});u.Collection=d.Collection;exports._rs=p._rs;exports.default=u;
@@ -0,0 +1,24 @@
1
+ import { Collection } from './Collection.tsx';
2
+ import { _rs } from './utils/observerUtil';
3
+ export {
4
+ /** @private Test only for mock trigger resize event */
5
+ _rs, };
6
+ export interface SizeInfo {
7
+ width: number;
8
+ height: number;
9
+ offsetWidth: number;
10
+ offsetHeight: number;
11
+ }
12
+ export type OnResize = (size: SizeInfo, element: HTMLElement) => void;
13
+ export interface ResizeObserverProps {
14
+ /** Pass to ResizeObserver.Collection with additional data */
15
+ data?: any;
16
+ disabled?: boolean;
17
+ /** Trigger if element resized. Will always trigger when first time render. */
18
+ onResize?: OnResize;
19
+ }
20
+ declare const ResizeObserver: import('vue').DefineComponent<ResizeObserverProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<ResizeObserverProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
21
+ declare const _default: typeof ResizeObserver & {
22
+ Collection: typeof Collection;
23
+ };
24
+ export default _default;
@@ -0,0 +1,46 @@
1
+ import { defineComponent as p, createVNode as a, mergeProps as l, isVNode as u } from "vue";
2
+ import { warning as i } from "@v-c/util";
3
+ import { toArray as m } from "@v-c/util/dist/Children/toArray";
4
+ import { Collection as c } from "./Collection.js";
5
+ import d from "./SingleObserver/index.js";
6
+ import { _rs as k } from "./utils/observerUtil.js";
7
+ function b(r) {
8
+ return typeof r == "function" || Object.prototype.toString.call(r) === "[object Object]" && !u(r);
9
+ }
10
+ const y = "vc-observer-key", v = /* @__PURE__ */ p({
11
+ props: {
12
+ data: {
13
+ type: null,
14
+ required: !1
15
+ },
16
+ disabled: {
17
+ type: Boolean,
18
+ required: !1
19
+ },
20
+ onResize: {
21
+ type: Function,
22
+ required: !1
23
+ }
24
+ },
25
+ setup(r, {
26
+ slots: o
27
+ }) {
28
+ return () => {
29
+ var n;
30
+ const t = m((n = o.default) == null ? void 0 : n.call(o));
31
+ return process.env.NODE_ENV !== "production" && (t.length > 1 ? i(!1, "Find more than one child node with `children` in ResizeObserver. Please use ResizeObserver.Collection instead.") : t.length === 0 && i(!1, "`children` of ResizeObserver is empty. Nothing is in observe.")), t.map((e, s) => {
32
+ const f = (e == null ? void 0 : e.key) || `${y}-${s}`;
33
+ return a(d, l(r, {
34
+ key: f
35
+ }), b(e) ? e : {
36
+ default: () => [e]
37
+ });
38
+ });
39
+ };
40
+ }
41
+ });
42
+ v.Collection = c;
43
+ export {
44
+ k as _rs,
45
+ v as default
46
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("resize-observer-polyfill"),o=new Map;function d(c){c.forEach(b=>{var r;const{target:u}=b;(r=o.get(u))==null||r.forEach(v=>v(u))})}const g=new s(d),p=process.env.NODE_ENV!=="production"?o:null,E=process.env.NODE_ENV!=="production"?d:null;function _(c,b){var u,r,v;o.has(c)||(o.set(c,new Set),g.observe(c)),(v=(r=(u=o==null?void 0:o.get)==null?void 0:u.call(o,c))==null?void 0:r.add)==null||v.call(r,b)}function i(c,b){var u,r,v,a,f;o.has(c)&&((v=(r=(u=o==null?void 0:o.get)==null?void 0:u.call(o,c))==null?void 0:r.delete)==null||v.call(r,b),(f=(a=o==null?void 0:o.get)==null?void 0:a.call(o,c))!=null&&f.size||(g.unobserve(c),o.delete(c)))}exports._el=p;exports._rs=E;exports.observe=_;exports.unobserve=i;
@@ -0,0 +1,7 @@
1
+ export type ResizeListener = (element: Element) => void;
2
+ declare function onResize(entities: ResizeObserverEntry[]): void;
3
+ export declare const _el: Map<Element, Set<ResizeListener>> | null;
4
+ export declare const _rs: typeof onResize | null;
5
+ export declare function observe(element: Element, callback: ResizeListener): void;
6
+ export declare function unobserve(element: Element, callback: ResizeListener): void;
7
+ export {};
@@ -0,0 +1,24 @@
1
+ import E from "resize-observer-polyfill";
2
+ const o = /* @__PURE__ */ new Map();
3
+ function b(c) {
4
+ c.forEach((v) => {
5
+ var f;
6
+ const { target: r } = v;
7
+ (f = o.get(r)) == null || f.forEach((u) => u(r));
8
+ });
9
+ }
10
+ const d = new E(b), h = process.env.NODE_ENV !== "production" ? o : null, z = process.env.NODE_ENV !== "production" ? b : null;
11
+ function N(c, v) {
12
+ var r, f, u;
13
+ o.has(c) || (o.set(c, /* @__PURE__ */ new Set()), d.observe(c)), (u = (f = (r = o == null ? void 0 : o.get) == null ? void 0 : r.call(o, c)) == null ? void 0 : f.add) == null || u.call(f, v);
14
+ }
15
+ function O(c, v) {
16
+ var r, f, u, a, p;
17
+ o.has(c) && ((u = (f = (r = o == null ? void 0 : o.get) == null ? void 0 : r.call(o, c)) == null ? void 0 : f.delete) == null || u.call(f, v), (p = (a = o == null ? void 0 : o.get) == null ? void 0 : a.call(o, c)) != null && p.size || (d.unobserve(c), o.delete(c)));
18
+ }
19
+ export {
20
+ h as _el,
21
+ z as _rs,
22
+ N as observe,
23
+ O as unobserve
24
+ };
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@v-c/resize-observer",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js",
9
+ "require": "./dist/index.cjs"
10
+ },
11
+ "./dist/*": "./dist/*",
12
+ "./package.json": "./package.json"
13
+ },
14
+ "main": "dist/index.js",
15
+ "scripts": {
16
+ "build": "vite build"
17
+ },
18
+ "peerDependencies": {
19
+ "vue": "^3.0.0"
20
+ },
21
+ "dependencies": {
22
+ "@v-c/util": "workspace:*",
23
+ "classnames": "^2.5.1",
24
+ "resize-observer-polyfill": "^1.5.1"
25
+ }
26
+ }
@@ -0,0 +1,44 @@
1
+ import type { InjectionKey } from 'vue'
2
+ import type { SizeInfo } from '.'
3
+ import { defineComponent, inject, provide, shallowRef } from 'vue'
4
+
5
+ type onCollectionResize = (size: SizeInfo, element: HTMLElement, data: any) => void
6
+
7
+ export const CollectionContext: InjectionKey<onCollectionResize> = Symbol('CollectionContext')
8
+
9
+ export interface ResizeInfo {
10
+ size: SizeInfo
11
+ element: HTMLElement
12
+ data: any
13
+ }
14
+
15
+ export interface CollectionProps {
16
+ /** Trigger when some children ResizeObserver changed. Collect by frame render level */
17
+ onBatchResize?: (resizeInfo: ResizeInfo[]) => void
18
+ }
19
+
20
+ export const Collection = defineComponent<CollectionProps>({
21
+ setup(props, { slots }) {
22
+ const resizeIdRef = shallowRef(0)
23
+ const resizeInfosRef = shallowRef<ResizeInfo[]>([])
24
+ const onCollectionResize = inject(CollectionContext, () => {})
25
+ const onResize = (size: SizeInfo, element: HTMLElement, data: any) => {
26
+ const resizeId = resizeIdRef.value + 1
27
+ resizeIdRef.value = resizeId
28
+ resizeInfosRef.value.push({ size, element, data })
29
+ Promise.resolve().then(() => {
30
+ if (resizeIdRef.value === resizeId) {
31
+ const resizeInfos = resizeInfosRef.value
32
+ resizeInfosRef.value = []
33
+ props.onBatchResize?.(resizeInfos)
34
+ }
35
+ })
36
+ onCollectionResize?.(size, element, data)
37
+ }
38
+
39
+ provide(CollectionContext, onResize)
40
+ return () => {
41
+ return slots.default?.()
42
+ }
43
+ },
44
+ })
@@ -0,0 +1,7 @@
1
+ import { defineComponent } from 'vue'
2
+
3
+ export default defineComponent ({
4
+ setup(_, { slots }) {
5
+ return () => slots.default?.()
6
+ },
7
+ })
@@ -0,0 +1,92 @@
1
+ import type { ResizeObserverProps, SizeInfo } from '../index.tsx'
2
+ import findDOMNode from '@v-c/util/dist/Dom/findDOMNode'
3
+ import { defineComponent, inject, onBeforeUnmount, onMounted, shallowRef } from 'vue'
4
+ import { CollectionContext } from '../Collection'
5
+ import { observe, unobserve } from '../utils/observerUtil.ts'
6
+ import DomWrapper from './DomWrapper'
7
+
8
+ const SingleObserver = defineComponent<ResizeObserverProps>({
9
+ name: 'SingleObserver',
10
+ inheritAttrs: false,
11
+ setup(props, { expose, slots }) {
12
+ const elementRef = shallowRef<HTMLElement>()
13
+ const wrapperRef = shallowRef()
14
+ const onCollectionResize = inject(CollectionContext, () => {})
15
+ const sizeRef = shallowRef<SizeInfo>({ width: -1, height: -1, offsetWidth: -1, offsetHeight: -1 })
16
+ const getDom = () => {
17
+ const dom = findDOMNode(elementRef as any)
18
+ || (elementRef.value && typeof elementRef.value === 'object' ? findDOMNode((elementRef.value as any).nativeElement) : null)
19
+ || findDOMNode(wrapperRef.value)
20
+ // 判断当前的dom是不是一个text元素
21
+ if (dom && dom.nodeType === 3 && dom.nextElementSibling)
22
+ return dom.nextElementSibling as HTMLElement
23
+
24
+ return dom
25
+ }
26
+
27
+ const onInternalResize = (target: HTMLElement) => {
28
+ const { onResize, data } = props
29
+ const { width, height } = target.getBoundingClientRect()
30
+ const { offsetHeight, offsetWidth } = target
31
+ /**
32
+ * Resize observer trigger when content size changed.
33
+ * In most case we just care about element size,
34
+ * let's use `boundary` instead of `contentRect` here to avoid shaking.
35
+ */
36
+ const fixedWidth = Math.floor(width)
37
+ const fixedHeight = Math.floor(height)
38
+ if (
39
+ sizeRef.value.width !== fixedWidth
40
+ || sizeRef.value.height !== fixedHeight
41
+ || sizeRef.value.offsetWidth !== offsetWidth
42
+ || sizeRef.value.offsetHeight !== offsetHeight
43
+ ) {
44
+ const size = { width: fixedWidth, height: fixedHeight, offsetWidth, offsetHeight }
45
+ sizeRef.value = size
46
+
47
+ // IE is strange, right?
48
+ const mergedOffsetWidth = offsetWidth === Math.round(width) ? width : offsetWidth
49
+ const mergedOffsetHeight = offsetHeight === Math.round(height) ? height : offsetHeight
50
+
51
+ const sizeInfo = {
52
+ ...size,
53
+ offsetWidth: mergedOffsetWidth,
54
+ offsetHeight: mergedOffsetHeight,
55
+ }
56
+
57
+ // Let collection know what happened
58
+ onCollectionResize?.(sizeInfo, target, data)
59
+
60
+ if (onResize) {
61
+ // defer the callback but not defer to next frame
62
+ Promise.resolve().then(() => {
63
+ onResize(sizeInfo, target)
64
+ })
65
+ }
66
+ }
67
+ }
68
+ let currentElement: HTMLElement
69
+ onMounted(() => {
70
+ currentElement = getDom() as HTMLElement
71
+ if (currentElement && !props.disabled)
72
+ observe(currentElement, onInternalResize as any)
73
+ })
74
+
75
+ onBeforeUnmount(() => {
76
+ if (currentElement)
77
+ unobserve(currentElement, onInternalResize as any)
78
+ })
79
+ expose({
80
+ getDom,
81
+ })
82
+ return () => {
83
+ return (
84
+ <DomWrapper ref={wrapperRef}>
85
+ {slots.default?.()}
86
+ </DomWrapper>
87
+ )
88
+ }
89
+ },
90
+ })
91
+
92
+ export default SingleObserver
@@ -0,0 +1,62 @@
1
+ import { warning } from '@v-c/util'
2
+ import { toArray } from '@v-c/util/dist/Children/toArray'
3
+ import { defineComponent } from 'vue'
4
+ import { Collection } from './Collection.tsx'
5
+ import SingleObserver from './SingleObserver'
6
+ import { _rs } from './utils/observerUtil'
7
+
8
+ const INTERNAL_PREFIX_KEY = 'vc-observer-key'
9
+ export {
10
+ /** @private Test only for mock trigger resize event */
11
+ _rs,
12
+ }
13
+
14
+ export interface SizeInfo {
15
+ width: number
16
+ height: number
17
+ offsetWidth: number
18
+ offsetHeight: number
19
+ }
20
+
21
+ export type OnResize = (size: SizeInfo, element: HTMLElement) => void
22
+
23
+ export interface ResizeObserverProps {
24
+ /** Pass to ResizeObserver.Collection with additional data */
25
+ data?: any
26
+ disabled?: boolean
27
+ /** Trigger if element resized. Will always trigger when first time render. */
28
+ onResize?: OnResize
29
+ }
30
+
31
+ const ResizeObserver = defineComponent<ResizeObserverProps>({
32
+ setup(props, { slots }) {
33
+ return () => {
34
+ const childNodes = toArray(slots.default?.())
35
+ if (process.env.NODE_ENV !== 'production') {
36
+ if (childNodes.length > 1) {
37
+ warning(
38
+ false,
39
+ 'Find more than one child node with `children` in ResizeObserver. Please use ResizeObserver.Collection instead.',
40
+ )
41
+ }
42
+ else if (childNodes.length === 0) {
43
+ warning(false, '`children` of ResizeObserver is empty. Nothing is in observe.')
44
+ }
45
+ }
46
+ return childNodes.map((child, index) => {
47
+ const key = child?.key || `${INTERNAL_PREFIX_KEY}-${index}`
48
+ return (
49
+ <SingleObserver {...props} key={key}>
50
+ {child}
51
+ </SingleObserver>
52
+ )
53
+ })
54
+ }
55
+ },
56
+ })
57
+
58
+ ResizeObserver.Collection = Collection
59
+
60
+ export default ResizeObserver as typeof ResizeObserver & {
61
+ Collection: typeof Collection
62
+ }
@@ -0,0 +1,41 @@
1
+ import ResizeObserver from 'resize-observer-polyfill'
2
+
3
+ export type ResizeListener = (element: Element) => void
4
+
5
+ // =============================== Const ===============================
6
+ const elementListeners = new Map<Element, Set<ResizeListener>>()
7
+
8
+ function onResize(entities: ResizeObserverEntry[]) {
9
+ entities.forEach((entity) => {
10
+ const { target } = entity
11
+ elementListeners.get(target)?.forEach(listener => listener(target))
12
+ })
13
+ }
14
+
15
+ // Note: ResizeObserver polyfill not support option to measure border-box resize
16
+ const resizeObserver = new ResizeObserver(onResize)
17
+
18
+ // Dev env only
19
+
20
+ export const _el = process.env.NODE_ENV !== 'production' ? elementListeners : null; // eslint-disable-line
21
+
22
+ export const _rs = process.env.NODE_ENV !== 'production' ? onResize : null; // eslint-disable-line
23
+
24
+ // ============================== Observe ==============================
25
+ export function observe(element: Element, callback: ResizeListener) {
26
+ if (!elementListeners.has(element)) {
27
+ elementListeners.set(element, new Set())
28
+ resizeObserver.observe(element)
29
+ }
30
+ elementListeners?.get?.(element)?.add?.(callback)
31
+ }
32
+
33
+ export function unobserve(element: Element, callback: ResizeListener) {
34
+ if (elementListeners.has(element)) {
35
+ elementListeners?.get?.(element)?.delete?.(callback)
36
+ if (!elementListeners?.get?.(element)?.size) {
37
+ resizeObserver.unobserve(element)
38
+ elementListeners.delete(element)
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": ["../../tsconfig.json"],
3
+ "compilerOptions": {
4
+
5
+ },
6
+ "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx"]
7
+ }
@@ -0,0 +1,18 @@
1
+ import type { UserConfig } from 'vite'
2
+ import fg from 'fast-glob'
3
+ import { defineConfig, mergeConfig } from 'vite'
4
+ import { buildCommon } from '../../scripts/build.common'
5
+
6
+ const entry = fg.sync(['src/**/*.ts', 'src/**/*.tsx', '!src/**/*.test.ts', '!src/**/tests'])
7
+
8
+ export default defineConfig({
9
+ ...mergeConfig(buildCommon({
10
+ external: ['vue', 'classnames', /^@v-c\/util/, 'resize-observer-polyfill'],
11
+ }), {
12
+ build: {
13
+ lib: {
14
+ entry,
15
+ },
16
+ },
17
+ } as UserConfig),
18
+ })
@@ -0,0 +1,9 @@
1
+ import { defineProject, mergeConfig } from 'vitest/config'
2
+ import configShared from '../../vitest.config.ts'
3
+
4
+ export default mergeConfig(
5
+ configShared,
6
+ defineProject({
7
+
8
+ }),
9
+ )
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@v-c/resize-observer",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js",
9
+ "require": "./dist/index.cjs"
10
+ },
11
+ "./dist/*": "./dist/*",
12
+ "./package.json": "./package.json"
13
+ },
14
+ "main": "dist/index.js",
15
+ "scripts": {
16
+ "build": "vite build"
17
+ },
18
+ "peerDependencies": {
19
+ "vue": "^3.0.0"
20
+ },
21
+ "dependencies": {
22
+ "@v-c/util": "workspace:*",
23
+ "classnames": "^2.5.1",
24
+ "resize-observer-polyfill": "^1.5.1"
25
+ }
26
+ }
@@ -0,0 +1,44 @@
1
+ import type { InjectionKey } from 'vue'
2
+ import type { SizeInfo } from '.'
3
+ import { defineComponent, inject, provide, shallowRef } from 'vue'
4
+
5
+ type onCollectionResize = (size: SizeInfo, element: HTMLElement, data: any) => void
6
+
7
+ export const CollectionContext: InjectionKey<onCollectionResize> = Symbol('CollectionContext')
8
+
9
+ export interface ResizeInfo {
10
+ size: SizeInfo
11
+ element: HTMLElement
12
+ data: any
13
+ }
14
+
15
+ export interface CollectionProps {
16
+ /** Trigger when some children ResizeObserver changed. Collect by frame render level */
17
+ onBatchResize?: (resizeInfo: ResizeInfo[]) => void
18
+ }
19
+
20
+ export const Collection = defineComponent<CollectionProps>({
21
+ setup(props, { slots }) {
22
+ const resizeIdRef = shallowRef(0)
23
+ const resizeInfosRef = shallowRef<ResizeInfo[]>([])
24
+ const onCollectionResize = inject(CollectionContext, () => {})
25
+ const onResize = (size: SizeInfo, element: HTMLElement, data: any) => {
26
+ const resizeId = resizeIdRef.value + 1
27
+ resizeIdRef.value = resizeId
28
+ resizeInfosRef.value.push({ size, element, data })
29
+ Promise.resolve().then(() => {
30
+ if (resizeIdRef.value === resizeId) {
31
+ const resizeInfos = resizeInfosRef.value
32
+ resizeInfosRef.value = []
33
+ props.onBatchResize?.(resizeInfos)
34
+ }
35
+ })
36
+ onCollectionResize?.(size, element, data)
37
+ }
38
+
39
+ provide(CollectionContext, onResize)
40
+ return () => {
41
+ return slots.default?.()
42
+ }
43
+ },
44
+ })
@@ -0,0 +1,7 @@
1
+ import { defineComponent } from 'vue'
2
+
3
+ export default defineComponent ({
4
+ setup(_, { slots }) {
5
+ return () => slots.default?.()
6
+ },
7
+ })
@@ -0,0 +1,92 @@
1
+ import type { ResizeObserverProps, SizeInfo } from '../index.tsx'
2
+ import findDOMNode from '@v-c/util/dist/Dom/findDOMNode'
3
+ import { defineComponent, inject, onBeforeUnmount, onMounted, shallowRef } from 'vue'
4
+ import { CollectionContext } from '../Collection'
5
+ import { observe, unobserve } from '../utils/observerUtil.ts'
6
+ import DomWrapper from './DomWrapper'
7
+
8
+ const SingleObserver = defineComponent<ResizeObserverProps>({
9
+ name: 'SingleObserver',
10
+ inheritAttrs: false,
11
+ setup(props, { expose, slots }) {
12
+ const elementRef = shallowRef<HTMLElement>()
13
+ const wrapperRef = shallowRef()
14
+ const onCollectionResize = inject(CollectionContext, () => {})
15
+ const sizeRef = shallowRef<SizeInfo>({ width: -1, height: -1, offsetWidth: -1, offsetHeight: -1 })
16
+ const getDom = () => {
17
+ const dom = findDOMNode(elementRef as any)
18
+ || (elementRef.value && typeof elementRef.value === 'object' ? findDOMNode((elementRef.value as any).nativeElement) : null)
19
+ || findDOMNode(wrapperRef.value)
20
+ // 判断当前的dom是不是一个text元素
21
+ if (dom && dom.nodeType === 3 && dom.nextElementSibling)
22
+ return dom.nextElementSibling as HTMLElement
23
+
24
+ return dom
25
+ }
26
+
27
+ const onInternalResize = (target: HTMLElement) => {
28
+ const { onResize, data } = props
29
+ const { width, height } = target.getBoundingClientRect()
30
+ const { offsetHeight, offsetWidth } = target
31
+ /**
32
+ * Resize observer trigger when content size changed.
33
+ * In most case we just care about element size,
34
+ * let's use `boundary` instead of `contentRect` here to avoid shaking.
35
+ */
36
+ const fixedWidth = Math.floor(width)
37
+ const fixedHeight = Math.floor(height)
38
+ if (
39
+ sizeRef.value.width !== fixedWidth
40
+ || sizeRef.value.height !== fixedHeight
41
+ || sizeRef.value.offsetWidth !== offsetWidth
42
+ || sizeRef.value.offsetHeight !== offsetHeight
43
+ ) {
44
+ const size = { width: fixedWidth, height: fixedHeight, offsetWidth, offsetHeight }
45
+ sizeRef.value = size
46
+
47
+ // IE is strange, right?
48
+ const mergedOffsetWidth = offsetWidth === Math.round(width) ? width : offsetWidth
49
+ const mergedOffsetHeight = offsetHeight === Math.round(height) ? height : offsetHeight
50
+
51
+ const sizeInfo = {
52
+ ...size,
53
+ offsetWidth: mergedOffsetWidth,
54
+ offsetHeight: mergedOffsetHeight,
55
+ }
56
+
57
+ // Let collection know what happened
58
+ onCollectionResize?.(sizeInfo, target, data)
59
+
60
+ if (onResize) {
61
+ // defer the callback but not defer to next frame
62
+ Promise.resolve().then(() => {
63
+ onResize(sizeInfo, target)
64
+ })
65
+ }
66
+ }
67
+ }
68
+ let currentElement: HTMLElement
69
+ onMounted(() => {
70
+ currentElement = getDom() as HTMLElement
71
+ if (currentElement && !props.disabled)
72
+ observe(currentElement, onInternalResize as any)
73
+ })
74
+
75
+ onBeforeUnmount(() => {
76
+ if (currentElement)
77
+ unobserve(currentElement, onInternalResize as any)
78
+ })
79
+ expose({
80
+ getDom,
81
+ })
82
+ return () => {
83
+ return (
84
+ <DomWrapper ref={wrapperRef}>
85
+ {slots.default?.()}
86
+ </DomWrapper>
87
+ )
88
+ }
89
+ },
90
+ })
91
+
92
+ export default SingleObserver
package/src/index.tsx ADDED
@@ -0,0 +1,62 @@
1
+ import { warning } from '@v-c/util'
2
+ import { toArray } from '@v-c/util/dist/Children/toArray'
3
+ import { defineComponent } from 'vue'
4
+ import { Collection } from './Collection.tsx'
5
+ import SingleObserver from './SingleObserver'
6
+ import { _rs } from './utils/observerUtil'
7
+
8
+ const INTERNAL_PREFIX_KEY = 'vc-observer-key'
9
+ export {
10
+ /** @private Test only for mock trigger resize event */
11
+ _rs,
12
+ }
13
+
14
+ export interface SizeInfo {
15
+ width: number
16
+ height: number
17
+ offsetWidth: number
18
+ offsetHeight: number
19
+ }
20
+
21
+ export type OnResize = (size: SizeInfo, element: HTMLElement) => void
22
+
23
+ export interface ResizeObserverProps {
24
+ /** Pass to ResizeObserver.Collection with additional data */
25
+ data?: any
26
+ disabled?: boolean
27
+ /** Trigger if element resized. Will always trigger when first time render. */
28
+ onResize?: OnResize
29
+ }
30
+
31
+ const ResizeObserver = defineComponent<ResizeObserverProps>({
32
+ setup(props, { slots }) {
33
+ return () => {
34
+ const childNodes = toArray(slots.default?.())
35
+ if (process.env.NODE_ENV !== 'production') {
36
+ if (childNodes.length > 1) {
37
+ warning(
38
+ false,
39
+ 'Find more than one child node with `children` in ResizeObserver. Please use ResizeObserver.Collection instead.',
40
+ )
41
+ }
42
+ else if (childNodes.length === 0) {
43
+ warning(false, '`children` of ResizeObserver is empty. Nothing is in observe.')
44
+ }
45
+ }
46
+ return childNodes.map((child, index) => {
47
+ const key = child?.key || `${INTERNAL_PREFIX_KEY}-${index}`
48
+ return (
49
+ <SingleObserver {...props} key={key}>
50
+ {child}
51
+ </SingleObserver>
52
+ )
53
+ })
54
+ }
55
+ },
56
+ })
57
+
58
+ ResizeObserver.Collection = Collection
59
+
60
+ export default ResizeObserver as typeof ResizeObserver & {
61
+ Collection: typeof Collection
62
+ }
@@ -0,0 +1,41 @@
1
+ import ResizeObserver from 'resize-observer-polyfill'
2
+
3
+ export type ResizeListener = (element: Element) => void
4
+
5
+ // =============================== Const ===============================
6
+ const elementListeners = new Map<Element, Set<ResizeListener>>()
7
+
8
+ function onResize(entities: ResizeObserverEntry[]) {
9
+ entities.forEach((entity) => {
10
+ const { target } = entity
11
+ elementListeners.get(target)?.forEach(listener => listener(target))
12
+ })
13
+ }
14
+
15
+ // Note: ResizeObserver polyfill not support option to measure border-box resize
16
+ const resizeObserver = new ResizeObserver(onResize)
17
+
18
+ // Dev env only
19
+
20
+ export const _el = process.env.NODE_ENV !== 'production' ? elementListeners : null; // eslint-disable-line
21
+
22
+ export const _rs = process.env.NODE_ENV !== 'production' ? onResize : null; // eslint-disable-line
23
+
24
+ // ============================== Observe ==============================
25
+ export function observe(element: Element, callback: ResizeListener) {
26
+ if (!elementListeners.has(element)) {
27
+ elementListeners.set(element, new Set())
28
+ resizeObserver.observe(element)
29
+ }
30
+ elementListeners?.get?.(element)?.add?.(callback)
31
+ }
32
+
33
+ export function unobserve(element: Element, callback: ResizeListener) {
34
+ if (elementListeners.has(element)) {
35
+ elementListeners?.get?.(element)?.delete?.(callback)
36
+ if (!elementListeners?.get?.(element)?.size) {
37
+ resizeObserver.unobserve(element)
38
+ elementListeners.delete(element)
39
+ }
40
+ }
41
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": ["../../tsconfig.json"],
3
+ "compilerOptions": {
4
+
5
+ },
6
+ "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx"]
7
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,18 @@
1
+ import type { UserConfig } from 'vite'
2
+ import fg from 'fast-glob'
3
+ import { defineConfig, mergeConfig } from 'vite'
4
+ import { buildCommon } from '../../scripts/build.common'
5
+
6
+ const entry = fg.sync(['src/**/*.ts', 'src/**/*.tsx', '!src/**/*.test.ts', '!src/**/tests'])
7
+
8
+ export default defineConfig({
9
+ ...mergeConfig(buildCommon({
10
+ external: ['vue', 'classnames', /^@v-c\/util/, 'resize-observer-polyfill'],
11
+ }), {
12
+ build: {
13
+ lib: {
14
+ entry,
15
+ },
16
+ },
17
+ } as UserConfig),
18
+ })
@@ -0,0 +1,9 @@
1
+ import { defineProject, mergeConfig } from 'vitest/config'
2
+ import configShared from '../../vitest.config.ts'
3
+
4
+ export default mergeConfig(
5
+ configShared,
6
+ defineProject({
7
+
8
+ }),
9
+ )