@phila/phila-ui-collapse-panel 0.0.1-beta.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.
package/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # CollapsePanel Component
2
+
3
+ A simple, customizable Vue 3. CollapsePanel component built with TypeScript and Vite.
4
+ Customizable component for toggling visibility of content.
5
+
6
+ ## Features
7
+
8
+ - 🎯 TypeScript support with full type definitions
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @phila/phila-ui-collapse-panel
14
+ # or
15
+ yarn add @phila/phila-ui-collapse-panel
16
+ # or
17
+ pnpm add @phila/phila-ui-collapse-panel
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ```vue
23
+ <script setup lang="ts">
24
+ import { CollapsePanel } from "@phila/phila-ui-collapse-panel";
25
+ </script>
26
+ <template>...Add basic component template here...</template>
27
+ ```
28
+
29
+ ## Props
30
+
31
+ | Prop | Type | Default | Description |
32
+ | ---- | ---- | ------- | ----------- |
33
+
34
+ | ...Add props here...
35
+
36
+ ## Events
37
+
38
+ | Event | Payload | Description |
39
+ | ----- | ------- | ----------- |
40
+
41
+ | ...Add events here...
42
+
43
+ ## Examples
44
+
45
+ ...Add examples here...
46
+
47
+ ## Development
48
+
49
+ ### Install Dependencies
50
+
51
+ ```bash
52
+ pnpm install
53
+ ```
54
+
55
+ ### Run Demo
56
+
57
+ ```bash
58
+ pnpm dev
59
+ ```
60
+
61
+ ### Build Library
62
+
63
+ ```bash
64
+ pnpm build
65
+ ```
66
+
67
+ ### Type Check
68
+
69
+ ```bash
70
+ pnpm type-check
71
+ ```
72
+
73
+ ## License
74
+
75
+ MIT
@@ -0,0 +1,43 @@
1
+ import { CollapsePanelProps } from './index';
2
+ declare function __VLS_template(): {
3
+ attrs: Partial<{}>;
4
+ slots: {
5
+ toggle?(_: {
6
+ open: boolean;
7
+ ariaLabel: string;
8
+ ariaExpanded: boolean;
9
+ ariaControls: string;
10
+ onClickToggle: (event: Event) => void;
11
+ onClickOpen: (event?: Event) => void;
12
+ focusChange: (e: FocusEvent) => void;
13
+ onClick: (event: Event) => void;
14
+ }): any;
15
+ default?(_: {
16
+ id: string;
17
+ open: boolean;
18
+ onClickToggle: (event: Event) => void;
19
+ focusChange: (e: FocusEvent) => void;
20
+ hidden: boolean;
21
+ }): any;
22
+ };
23
+ refs: {};
24
+ rootEl: HTMLDivElement;
25
+ };
26
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
27
+ declare const __VLS_component: import('vue').DefineComponent<CollapsePanelProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<CollapsePanelProps> & Readonly<{}>, {
28
+ group: string;
29
+ blurClose: boolean;
30
+ openSingle: boolean;
31
+ mouseOverToggle: boolean;
32
+ outsideClickClose: boolean;
33
+ escapeKeyClose: boolean;
34
+ toggleAttrs: Partial<import('vue').ButtonHTMLAttributes>;
35
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
36
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
37
+ export default _default;
38
+ type __VLS_WithTemplateSlots<T, S> = T & {
39
+ new (): {
40
+ $slots: S;
41
+ };
42
+ };
43
+ //# sourceMappingURL=CollapsePanel.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollapsePanel.vue.d.ts","sourceRoot":"","sources":["../src/CollapsePanel.vue"],"names":[],"mappings":"AA+DA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA0BlD,iBAAS,cAAc;WA+CT,OAAO,IAA6B;;;;;;;;;;;YAXtB,GAAG;;;;;;;YACF,GAAG;;;;EAe/B;AAeD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;;;;wFAQnB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAapG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { BaseProps } from '@phila/phila-ui-core';
2
+ import { UseCollapseProps } from '@phila/phila-ui-core/utils';
3
+ export { default as CollapsePanel } from './CollapsePanel.vue';
4
+ export type CollapsePanelProps = BaseProps & UseCollapseProps;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("vue");o.ref("");o.reactive({validateOnBlur:!1,validateOnInput:!1,validateOnChange:!1,validateOnMount:!1,required:!1,isValid:!0,errors:[]});const d=o.ref({}),c=o.ref(),y=400,T=o.ref(null);function A(e){const n=e?.group??"global",t=(l,r)=>{d.value[n][l]=r},f=(l,r)=>{d.value[n]={[l]:r}},p=l=>d.value[n][l]??!1,s=l=>{t(l,!p(l))},k=l=>{f(l,!p(l))},v=()=>{d.value[n]={}},a=l=>{l.key==="Escape"&&(t(e.id,!1),m())},g=l=>{if(!e)return;const r=l.target,[C]=Object.keys(d.value[n]).filter(w=>d.value[n][w]===!0),b=document.getElementById(C),P=document.querySelector(`[aria-controls="${C}"]`),h=r.getAttribute("aria-controls")===C||P?.contains(l.target);b&&!b.contains(r)&&!h&&(t(e.id,!1),m())},u=()=>{e&&(c.value=setTimeout(()=>{t(e.id,!1),m()},y))},i=()=>{e&&e.mouseOverToggle===!0&&(T.value=e.id,c.value=setTimeout(()=>{O()},y))},B=()=>{e&&e.mouseOverToggle===!0&&(T.value=null,clearTimeout(c.value),c.value=setTimeout(()=>{T.value!==e.id&&(t(e.id,!1),m())},y))},S=l=>{if(!e)return;const{relatedTarget:r}=l;if(!r||r.getAttribute("aria-controls")===e.id)return;const C=document.getElementById(e.id);C&&C.contains(r)||(clearTimeout(c.value),c.value=setTimeout(()=>{e.openSingle?f(e.id,!1):t(e.id,!1),m()},y))},L=()=>{e&&(e.outsideClickClose&&(document.addEventListener("click",g),document.addEventListener("touchend",g)),e.escapeKeyClose&&document.addEventListener("keydown",a))},m=()=>{document.removeEventListener("click",g),document.removeEventListener("touchend",g),document.removeEventListener("keydown",a),document.removeEventListener("scroll",u)},E=l=>{e&&(l?.preventDefault(),clearTimeout(c.value),L())},M=l=>{e&&(E(l),e.openSingle?k(e.id):s(e.id))},O=l=>{e&&(E(l),e.openSingle?f(e.id,!0):t(e.id,!0))};return o.onBeforeMount(()=>{d.value[n]||v()}),o.onUnmounted(()=>{m()}),{state:d,timeout:c,toggle:s,toggleSingle:k,setCollapsed:t,setSingleCollapsed:f,isCollapsed:p,reset:v,onMouseEnter:i,onMouseLeave:B,focusChange:S,onClickToggle:M,onClickOpen:O}}const I=["data-toggle","aria-label","aria-expanded","aria-controls"],q=o.defineComponent({__name:"CollapsePanel",props:{className:{},id:{},group:{default:void 0},blurClose:{type:Boolean,default:!1},openSingle:{type:Boolean,default:!1},mouseOverToggle:{type:Boolean,default:!1},outsideClickClose:{type:Boolean,default:!1},escapeKeyClose:{type:Boolean,default:!1},toggleAttrs:{default:void 0}},setup(e){const n=e,{isCollapsed:t,onMouseEnter:f,onMouseLeave:p,onClickToggle:s,onClickOpen:k,focusChange:v}=A(n),a=o.computed(()=>t(n.id));return(g,u)=>(o.openBlock(),o.createElementBlock("div",{onMouseenter:u[1]||(u[1]=(...i)=>o.unref(f)&&o.unref(f)(...i)),onMouseleave:u[2]||(u[2]=(...i)=>o.unref(p)&&o.unref(p)(...i)),onFocusout:u[3]||(u[3]=(...i)=>o.unref(v)&&o.unref(v)(...i))},[o.renderSlot(g.$slots,"toggle",o.normalizeProps(o.guardReactiveProps({open:a.value,ariaLabel:a.value?"Close panel":"Open panel",ariaExpanded:a.value,ariaControls:e.id,onClickToggle:o.unref(s),onClickOpen:o.unref(k),focusChange:o.unref(v),onClick:o.unref(s)})),()=>[o.createElementVNode("button",o.mergeProps({"data-toggle":e.id,"aria-label":a.value?"Close panel":"Open panel","aria-expanded":a.value,"aria-controls":e.id},e.toggleAttrs,{onClick:u[0]||(u[0]=o.withModifiers((...i)=>o.unref(s)&&o.unref(s)(...i),["prevent"]))}),null,16,I)]),o.renderSlot(g.$slots,"default",o.normalizeProps(o.guardReactiveProps({id:e.id,open:a.value,onClickToggle:o.unref(s),focusChange:o.unref(v),hidden:!a.value})))],32))}});exports.CollapsePanel=q;
package/dist/index.mjs ADDED
@@ -0,0 +1,134 @@
1
+ import { ref as T, reactive as q, onBeforeMount as D, onUnmounted as K, defineComponent as N, computed as V, createElementBlock as j, openBlock as z, unref as l, renderSlot as b, normalizeProps as M, guardReactiveProps as S, createElementVNode as F, mergeProps as R, withModifiers as U } from "vue";
2
+ T("");
3
+ q({
4
+ validateOnBlur: !1,
5
+ validateOnInput: !1,
6
+ validateOnChange: !1,
7
+ validateOnMount: !1,
8
+ required: !1,
9
+ isValid: !0,
10
+ errors: []
11
+ });
12
+ const d = T({}), c = T(), E = 400, y = T(null);
13
+ function G(e) {
14
+ const t = e?.group ?? "global", n = (o, i) => {
15
+ d.value[t][o] = i;
16
+ }, v = (o, i) => {
17
+ d.value[t] = { [o]: i };
18
+ }, p = (o) => d.value[t][o] ?? !1, r = (o) => {
19
+ n(o, !p(o));
20
+ }, k = (o) => {
21
+ v(o, !p(o));
22
+ }, g = () => {
23
+ d.value[t] = {};
24
+ }, a = (o) => {
25
+ o.key === "Escape" && (n(e.id, !1), m());
26
+ }, f = (o) => {
27
+ if (!e) return;
28
+ const i = o.target, [C] = Object.keys(d.value[t]).filter(($) => d.value[t][$] === !0), L = document.getElementById(C), I = document.querySelector(`[aria-controls="${C}"]`), x = i.getAttribute("aria-controls") === C || I?.contains(o.target);
29
+ L && !L.contains(i) && !x && (n(e.id, !1), m());
30
+ }, u = () => {
31
+ e && (c.value = setTimeout(() => {
32
+ n(e.id, !1), m();
33
+ }, E));
34
+ }, s = () => {
35
+ e && e.mouseOverToggle === !0 && (y.value = e.id, c.value = setTimeout(() => {
36
+ B();
37
+ }, E));
38
+ }, P = () => {
39
+ e && e.mouseOverToggle === !0 && (y.value = null, clearTimeout(c.value), c.value = setTimeout(() => {
40
+ y.value !== e.id && (n(e.id, !1), m());
41
+ }, E));
42
+ }, h = (o) => {
43
+ if (!e) return;
44
+ const { relatedTarget: i } = o;
45
+ if (!i || i.getAttribute("aria-controls") === e.id)
46
+ return;
47
+ const C = document.getElementById(e.id);
48
+ C && C.contains(i) || (clearTimeout(c.value), c.value = setTimeout(() => {
49
+ e.openSingle ? v(e.id, !1) : n(e.id, !1), m();
50
+ }, E));
51
+ }, w = () => {
52
+ e && (e.outsideClickClose && (document.addEventListener("click", f), document.addEventListener("touchend", f)), e.escapeKeyClose && document.addEventListener("keydown", a));
53
+ }, m = () => {
54
+ document.removeEventListener("click", f), document.removeEventListener("touchend", f), document.removeEventListener("keydown", a), document.removeEventListener("scroll", u);
55
+ }, O = (o) => {
56
+ e && (o?.preventDefault(), clearTimeout(c.value), w());
57
+ }, A = (o) => {
58
+ e && (O(o), e.openSingle ? k(e.id) : r(e.id));
59
+ }, B = (o) => {
60
+ e && (O(o), e.openSingle ? v(e.id, !0) : n(e.id, !0));
61
+ };
62
+ return D(() => {
63
+ d.value[t] || g();
64
+ }), K(() => {
65
+ m();
66
+ }), {
67
+ state: d,
68
+ timeout: c,
69
+ toggle: r,
70
+ toggleSingle: k,
71
+ setCollapsed: n,
72
+ setSingleCollapsed: v,
73
+ isCollapsed: p,
74
+ reset: g,
75
+ onMouseEnter: s,
76
+ onMouseLeave: P,
77
+ focusChange: h,
78
+ onClickToggle: A,
79
+ onClickOpen: B
80
+ };
81
+ }
82
+ const H = ["data-toggle", "aria-label", "aria-expanded", "aria-controls"], Q = /* @__PURE__ */ N({
83
+ __name: "CollapsePanel",
84
+ props: {
85
+ className: {},
86
+ id: {},
87
+ group: { default: void 0 },
88
+ blurClose: { type: Boolean, default: !1 },
89
+ openSingle: { type: Boolean, default: !1 },
90
+ mouseOverToggle: { type: Boolean, default: !1 },
91
+ outsideClickClose: { type: Boolean, default: !1 },
92
+ escapeKeyClose: { type: Boolean, default: !1 },
93
+ toggleAttrs: { default: void 0 }
94
+ },
95
+ setup(e) {
96
+ const t = e, { isCollapsed: n, onMouseEnter: v, onMouseLeave: p, onClickToggle: r, onClickOpen: k, focusChange: g } = G(t), a = V(() => n(t.id));
97
+ return (f, u) => (z(), j("div", {
98
+ onMouseenter: u[1] || (u[1] = //@ts-ignore
99
+ (...s) => l(v) && l(v)(...s)),
100
+ onMouseleave: u[2] || (u[2] = //@ts-ignore
101
+ (...s) => l(p) && l(p)(...s)),
102
+ onFocusout: u[3] || (u[3] = //@ts-ignore
103
+ (...s) => l(g) && l(g)(...s))
104
+ }, [
105
+ b(f.$slots, "toggle", M(S({
106
+ open: a.value,
107
+ ariaLabel: a.value ? "Close panel" : "Open panel",
108
+ ariaExpanded: a.value,
109
+ ariaControls: e.id,
110
+ onClickToggle: l(r),
111
+ onClickOpen: l(k),
112
+ focusChange: l(g),
113
+ onClick: l(r)
114
+ })), () => [
115
+ F("button", R({
116
+ "data-toggle": e.id,
117
+ "aria-label": a.value ? "Close panel" : "Open panel",
118
+ "aria-expanded": a.value,
119
+ "aria-controls": e.id
120
+ }, e.toggleAttrs, {
121
+ onClick: u[0] || (u[0] = U(
122
+ //@ts-ignore
123
+ (...s) => l(r) && l(r)(...s),
124
+ ["prevent"]
125
+ ))
126
+ }), null, 16, H)
127
+ ]),
128
+ b(f.$slots, "default", M(S({ id: e.id, open: a.value, onClickToggle: l(r), focusChange: l(g), hidden: !a.value })))
129
+ ], 32));
130
+ }
131
+ });
132
+ export {
133
+ Q as CollapsePanel
134
+ };
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@phila/phila-ui-collapse-panel",
3
+ "version": "0.0.1-beta.1",
4
+ "type": "module",
5
+ "description": "Customizable component for toggling visibility of content. ",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "keywords": [
20
+ "ui",
21
+ "collapse-panel",
22
+ "vue",
23
+ "component"
24
+ ],
25
+ "author": "",
26
+ "license": "MIT",
27
+ "peerDependencies": {
28
+ "vue": "^3.0.0"
29
+ },
30
+ "dependencies": {
31
+ "@phila/phila-ui-core": "2.2.0-beta.2"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^24.0.0",
35
+ "@vitejs/plugin-vue": "^6.0.1",
36
+ "eslint": "^9.0.0",
37
+ "typescript": "^5.8.3",
38
+ "vite": "^7.0.6",
39
+ "vite-plugin-dts": "^4.5.4",
40
+ "vite-plugin-lib-inject-css": "^2.2.2"
41
+ },
42
+ "scripts": {
43
+ "build": "vite build",
44
+ "build-win": "vite build",
45
+ "dev": "vite build --watch",
46
+ "lint": "eslint src --ext .ts,.tsx,.vue",
47
+ "lint:fix": "eslint src --ext .ts,.tsx,.vue --fix",
48
+ "type-check": "tsc --noEmit",
49
+ "clean": "rm -rf dist",
50
+ "format": "prettier --write .",
51
+ "format:check": "prettier --check ."
52
+ }
53
+ }