versoly-ui 2.0.1 → 2.2.0
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/.vscode/launch.json +28 -0
- package/.vscode/settings.template.json +4 -0
- package/README.md +25 -4
- package/dist/versoly-ui.iife.js +12 -0
- package/dist/versoly-ui.js +12 -2
- package/dist/versoly-ui.mjs +12 -0
- package/eslint.config.ts +11 -0
- package/index.html +15 -0
- package/package.json +21 -33
- package/prettier.config.js +20 -0
- package/src/index.ts +25 -0
- package/src/plugins/accordion.ts +121 -0
- package/src/plugins/collapse.ts +35 -0
- package/src/plugins/dismiss.ts +17 -0
- package/src/plugins/dropdown.ts +67 -0
- package/src/plugins/index.ts +7 -0
- package/src/plugins/modal.ts +73 -0
- package/src/plugins/tabs.ts +59 -0
- package/src/types.d.ts +22 -0
- package/src/utils/index.ts +105 -0
- package/tsconfig.json +14 -0
- package/tsdown.config.ts +22 -0
- package/vite.config.js +35 -0
- package/.babelrc +0 -7
- package/.env +0 -3
- package/dist/versoly-ui.js.map +0 -1
- package/src/js/components/accordion.js +0 -35
- package/src/js/components/collapse.js +0 -36
- package/src/js/components/common.js +0 -30
- package/src/js/components/dismiss.js +0 -13
- package/src/js/components/dropdown.js +0 -58
- package/src/js/components/modal.js +0 -60
- package/src/js/components/tabs.js +0 -53
- package/src/js/utils/index.js +0 -68
- package/src/js/versoly-ui.js +0 -1
- package/webpack.config.js +0 -53
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Debug with TSX",
|
|
9
|
+
"type": "node",
|
|
10
|
+
"request": "launch",
|
|
11
|
+
"program": "${file}",
|
|
12
|
+
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/tsx",
|
|
13
|
+
"cwd": "${workspaceRoot}",
|
|
14
|
+
"skipFiles": ["<node_internals>/**", "node_modules/**"],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "Debug Current Test File",
|
|
18
|
+
"type": "node",
|
|
19
|
+
"request": "launch",
|
|
20
|
+
"autoAttachChildProcesses": true,
|
|
21
|
+
"program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
|
|
22
|
+
"args": ["run", "${relativeFile}"],
|
|
23
|
+
"smartStep": true,
|
|
24
|
+
"console": "integratedTerminal",
|
|
25
|
+
"skipFiles": ["<node_internals>/**", "**/node_modules/**"],
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
}
|
package/README.md
CHANGED
|
@@ -5,15 +5,14 @@
|
|
|
5
5
|
<a href="https://versoly.com/versoly-ui" align=""><h1>Versoly UI</h1></a>
|
|
6
6
|
<p>Tailwind CSS components library based on Bootstrap, build websites without reinventing the wheel.</p>
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
<p>
|
|
10
9
|
<a href="https://discord.versoly.com"><img src="https://flat.badgen.net/badge/icon/discord?icon=discord&label" alt="Discord"></a>
|
|
11
10
|
<a href="https://versoly.com/versoly-ui/getting-started/license/"><img src="https://img.shields.io/badge/license-MIT-blue" alt="Licenese"></a>
|
|
12
11
|
<a href="https://bundlephobia.com/result?p=versoly-ui">
|
|
13
12
|
<img src="https://flat.badgen.net/bundlephobia/minzip/versoly-ui?icon=packagephobia&label&color=blue&cache=10800" alt="gzip bundle size">
|
|
14
13
|
</a>
|
|
15
|
-
<a href="https://unpkg.com/versoly-ui@2.
|
|
16
|
-
<img src="https://flat.badgen.net/badgesize/brotli/https://unpkg.com/versoly-ui@2.
|
|
14
|
+
<a href="https://unpkg.com/versoly-ui@2.1.1/dist/versoly-ui.js">
|
|
15
|
+
<img src="https://flat.badgen.net/badgesize/brotli/https://unpkg.com/versoly-ui@2.1.1/dist/versoly-ui.js?icon=jsdelivr&label&color=blue&cache=10800" alt="brotli bundle size">
|
|
17
16
|
</a>
|
|
18
17
|
</p>
|
|
19
18
|
</div>
|
|
@@ -28,7 +27,29 @@ For full documentation, visit [versoly.com/versoly-ui](https://versoly.com/verso
|
|
|
28
27
|
|
|
29
28
|
Versoly UI is an open source components library built on Tailwind CSS and based on Bootstrap classes and components. Websites usually always include a small number of the same components such as buttons, cards and navbars. Versoly UI provides these components similar to Bootstrap and allows for developers to easily swap styling between projects without the manual work.
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
- **Components**
|
|
31
|
+
- [Accordion](https://versoly.com/versoly-ui/components/accordion)
|
|
32
|
+
- [Alert](https://versoly.com/versoly-ui/components/alert)
|
|
33
|
+
- [Badge](https://versoly.com/versoly-ui/components/badge)
|
|
34
|
+
- [Button](https://versoly.com/versoly-ui/components/button)
|
|
35
|
+
- [Button Group](https://versoly.com/versoly-ui/components/button-group)
|
|
36
|
+
- [Card](https://versoly.com/versoly-ui/components/card)
|
|
37
|
+
- [Footer](https://versoly.com/versoly-ui/components/footer)
|
|
38
|
+
- [Icon](https://versoly.com/versoly-ui/components/icon)
|
|
39
|
+
- [Modal](https://versoly.com/versoly-ui/components/modal)
|
|
40
|
+
- [Navbar](https://versoly.com/versoly-ui/components/navbar)
|
|
41
|
+
- [Pagination](https://versoly.com/versoly-ui/components/pagination)
|
|
42
|
+
- [Parallax](https://versoly.com/versoly-ui/components/parallax)
|
|
43
|
+
- [Progress](https://versoly.com/versoly-ui/components/progress)
|
|
44
|
+
- [Tab](https://versoly.com/versoly-ui/components/tab)
|
|
45
|
+
- [Table](https://versoly.com/versoly-ui/components/table)
|
|
46
|
+
|
|
47
|
+
- **Forms**
|
|
48
|
+
- [Inputs](https://versoly.com/versoly-ui/forms/inputs)
|
|
49
|
+
- [Select](https://versoly.com/versoly-ui/forms/select)
|
|
50
|
+
- [Checkbox](https://versoly.com/versoly-ui/forms/checkbox)
|
|
51
|
+
- [Radio](https://versoly.com/versoly-ui/forms/radio)
|
|
52
|
+
- [Layout](https://versoly.com/versoly-ui/forms/layout)
|
|
32
53
|
|
|
33
54
|
## Getting started
|
|
34
55
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
(function(){let e=e=>document.querySelector(e),t=(e,t=document)=>Array.from(t.querySelectorAll(e)),n=t=>{let n=t.dataset.target;return n?e(n):null},r=e=>{let t=window.getComputedStyle(e).getPropertyValue(`transition-duration`);return t?parseInt(t.replace(`s`,``))*1e3+1:0},i=e=>e.getAttribute(`aria-expanded`)===`true`,a=(e,t,n)=>{t.forEach(t=>{e.addEventListener(t,n)})},o=e=>{document.addEventListener(`keydown`,t=>{t.key===`Escape`&&e()})},s=(e,n,r)=>()=>t(e).forEach(e=>{e.addEventListener(n,()=>r(e))}),c=()=>window.addEventListener(`resize`,()=>{t(`[data-toggle="collapse"]`).forEach(e=>{let t=n(e);t&&(e.setAttribute(`aria-expanded`,`false`),t.classList.remove(`show`),t.classList.remove(`block`),t.style.height=`auto`,t.style.overflow=``)})}),l=t=>new Promise(n=>{if(e(t))return n(e(t));let r=new MutationObserver(()=>{e(t)&&(n(e(t)),r.disconnect())});r.observe(document.body,{childList:!0,subtree:!0})}),u=e=>{let t=e.dataset.options;if(!t)return{};try{return JSON.parse(t.replaceAll(`'`,`"`))}catch(e){return{}}},d=e=>{let n=`[data-toggle="${e}"]`;return t(n)};function f(e){"@babel/helpers - typeof";return f=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},f(e)}function p(e,t){if(f(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(f(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function m(e){var t=p(e,`string`);return f(t)==`symbol`?t:t+``}function h(e,t,n){return(t=m(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function _(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?g(Object(n),!0).forEach(function(t){h(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):g(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}let v=(e,t,n)=>{t.style.overflow=`hidden`,t.style.height=`0`,e.setAttribute(`aria-expanded`,`true`),t.classList.add(`block`),t.classList.add(`show`),t.classList.remove(`hidden`),window.setTimeout(()=>{t.style.height=`${t.scrollHeight}px`},33),window.setTimeout(()=>{t.style.overflow=``},n)},y=(e,t,n)=>{t.style.overflow=`hidden`,t.style.height=`0`,e.setAttribute(`aria-expanded`,`false`),t.classList.remove(`show`),window.setTimeout(()=>{t.classList.remove(`block`),t.classList.add(`hidden`)},n)},b=e=>{let{min:n,max:o}=_({min:0,max:null},u(e)),s=o===null,c=t(`.accordion-item [aria-expanded]`,e).reduce((e,t)=>{let n=t.closest(`.accordion-item`),r=n==null?void 0:n.querySelector(`.accordion-collapse`);return n&&r instanceof HTMLElement&&e.push({trigger:t,target:r}),e},[]),l=()=>c.filter(({trigger:e})=>i(e)).length,d=({trigger:e,target:t})=>{let a=i(e),o=r(t);s===!1&&l()===n&&a||(a||v(e,t,o),s===!1?c.forEach(t=>{!a&&t.trigger===e||y(t.trigger,t.target,o)}):a&&y(e,t,o))};c.forEach(e=>{a(e.trigger,[`click`],()=>d(e))}),n===1&&l()===0&&c.length>0&&c[0].trigger.click()},x=()=>{t(`.accordion-header[data-toggle=accordion]`).forEach(e=>{console.log(e);let t=e.closest(`.accordion`);if(t){t.setAttribute(`data-toggle`,`accordion`),e.hasAttribute(`data-parent`)&&!t.hasAttribute(`data-options`)&&t.setAttribute(`data-options`,`{'min': 1, 'max': 1}`);return}e.removeAttribute(`data-toggle`)}),d(`accordion`).forEach(b)},S=s(`[data-dismiss]`,`click`,e=>{let t=n(e);t||(t=e.closest(`.${e.getAttribute(`data-dismiss`)}`)),t&&(t.classList.add(`opacity-0`),setTimeout(()=>t.remove(),r(t)))}),C=s(`[data-toggle="collapse"]`,`click`,e=>{let t=n(e);if(!t)return;let i=r(t);if(t.style.overflow=`hidden`,t.style.height=`0px`,e.getAttribute(`aria-expanded`)===`true`){e.setAttribute(`aria-expanded`,`false`),t.classList.remove(`show`),window.setTimeout(()=>t.classList.remove(`block`),i);return}e.setAttribute(`aria-expanded`,`true`),t.classList.add(`block`),t.classList.add(`show`),window.setTimeout(()=>{t.querySelectorAll(`.dropdown-menu`).forEach(e=>e.classList.add(`hidden`));let e=t.scrollHeight;t.querySelectorAll(`.dropdown-menu`).forEach(e=>e.classList.remove(`hidden`)),t.style.height=`${e}px`},32),window.setTimeout(()=>t.style.overflow=``,i)}),w=e=>{let{computePosition:t,shift:n,offset:r}=window.FloatingUIDOM,i=e.nextElementSibling,s=e.parentElement;if(!i||!s||!(i instanceof HTMLElement)||!(s instanceof HTMLElement))return;let c=u(e),l=[r(6),n({padding:5})];function d(){t(e,i,{placement:c.placement||`bottom`,middleware:l}).then(({x:e,y:t})=>{Object.assign(i.style,{left:`${e}px`,top:`${t}px`})})}let f=()=>{i.style.display=`block`,window.requestAnimationFrame(()=>{i.classList.add(`opacity-100`,`visible`)}),d()},p=()=>{i.style.display=``,i.classList.remove(`opacity-100`,`visible`)};s.addEventListener(`focusout`,e=>{e!=null&&e.relatedTarget&&(s.contains(e.relatedTarget)||!document.hasFocus()||p())}),a(e,[`click`],()=>{if(i.style.display===`block`){p();return}f()}),o(p)},T=()=>d(`dropdown`).forEach(w),E={closeButton:`fixed right-0 top-0 z-50 text-white px-5 close`},D=e=>{let{size:t,beforeShown:n,id:r,imgSrc:i,iframeSrc:a}=_({id:`v-modal`,size:void 0,beforeShown:void 0,imgSrc:void 0,iframeSrc:void 0},u(e)),s=e.dataset.html||``;i&&(s=`<img src="${i}">`),a&&(s=`<iframe allow="autoplay" class="aspect-video w-full" src="${a}" allowfullscreen="" autoplay=""></iframe>`);let c=`<div class="modal" id="${r}">
|
|
2
|
+
<div class="modal-content ${t?`modal-${t}`:``}">
|
|
3
|
+
${s}
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<button onclick="removeModal('${r}')" type="button" class="${E.closeButton}" data-dismiss="modal" aria-label="Close">
|
|
7
|
+
<span class="text-4xl" aria-hidden="true">×</span>
|
|
8
|
+
</button>
|
|
9
|
+
|
|
10
|
+
<div class="modal-bg" onclick="removeModal('${r}')"></div>
|
|
11
|
+
</div>
|
|
12
|
+
`;o(()=>window.removeModal(r)),document.body.style.overflow=`hidden`,document.body.insertAdjacentHTML(`beforeend`,c),l(`#${r}`).then(e=>{n&&window[n](),window.setTimeout(()=>e.classList.add(`opacity-100`),32)})},O=(e=`v-modal`)=>{let t=document.getElementById(e);t&&(t.classList.remove(`opacity-100`),window.setTimeout(()=>{t.remove(),document.body.style.overflow=``},500))};window.removeModal=O;let k=s(`[data-toggle="modal"]`,`click`,D),A=s(`[role="tab"]`,`click`,t=>{if(t.getAttribute(`aria-selected`)===`true`)return null;let n=e(`[aria-labelledby="${t.getAttribute(`aria-controls`)}"]`);if(!n)return null;let r=t.classList.value,i=t.parentNode;for(;i&&(!(i instanceof HTMLElement)||i.getAttribute(`role`)!==`tablist`);)i=i.parentNode;if(!(i instanceof HTMLElement))return null;let a=i.querySelectorAll(`[aria-selected="true"]`);if(!a||a.length===0)return null;let o=a[0].classList.value;if(i.querySelectorAll(`[role="tab"]`).forEach(e=>{e.classList=r,e.setAttribute(`aria-selected`,`false`)}),t.classList=o,t.setAttribute(`aria-selected`,`true`),n.getAttribute(`role`)===`tabcontent`){Array.from(n.children).forEach(e=>{e.getAttribute(`role`)===`tabpanel`&&e.classList.remove(`hidden`)});return}if(!n.parentNode)return null;Array.from(n.parentNode.children).forEach(e=>{e.getAttribute(`role`)===`tabpanel`&&e.classList.add(`hidden`)}),n.classList.remove(`hidden`)});(function(){window.vInitialized=!1,window.initializeVUI=()=>{window.vInitialized||(window.vInitialized=!0,x(),C(),S(),T(),k(),A(),c())},document.addEventListener(`DOMContentLoaded`,window.initializeVUI),document.readyState!==`loading`&&window.initializeVUI()})()})();
|
package/dist/versoly-ui.js
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const e=e=>document.querySelector(e),t=(e,t=document)=>Array.from(t.querySelectorAll(e)),n=t=>{let n=t.dataset.target;return n?e(n):null},r=e=>{let t=window.getComputedStyle(e).getPropertyValue(`transition-duration`);return t?parseInt(t.replace(`s`,``))*1e3+1:0},i=e=>e.getAttribute(`aria-expanded`)===`true`,a=(e,t,n)=>{t.forEach(t=>{e.addEventListener(t,n)})},o=e=>{document.addEventListener(`keydown`,t=>{t.key===`Escape`&&e()})},s=(e,n,r)=>()=>t(e).forEach(e=>{e.addEventListener(n,()=>r(e))}),c=()=>window.addEventListener(`resize`,()=>{t(`[data-toggle="collapse"]`).forEach(e=>{let t=n(e);t&&(e.setAttribute(`aria-expanded`,`false`),t.classList.remove(`show`),t.classList.remove(`block`),t.style.height=`auto`,t.style.overflow=``)})}),l=t=>new Promise(n=>{if(e(t))return n(e(t));let r=new MutationObserver(()=>{e(t)&&(n(e(t)),r.disconnect())});r.observe(document.body,{childList:!0,subtree:!0})}),u=e=>{let t=e.dataset.options;if(!t)return{};try{return JSON.parse(t.replaceAll(`'`,`"`))}catch(e){return{}}},d=e=>{let n=`[data-toggle="${e}"]`;return t(n)};function f(e){"@babel/helpers - typeof";return f=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},f(e)}function p(e,t){if(f(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(f(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function m(e){var t=p(e,`string`);return f(t)==`symbol`?t:t+``}function h(e,t,n){return(t=m(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function g(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function _(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?g(Object(n),!0).forEach(function(t){h(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):g(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}const v=(e,t,n)=>{t.style.overflow=`hidden`,t.style.height=`0`,e.setAttribute(`aria-expanded`,`true`),t.classList.add(`block`),t.classList.add(`show`),t.classList.remove(`hidden`),window.setTimeout(()=>{t.style.height=`${t.scrollHeight}px`},33),window.setTimeout(()=>{t.style.overflow=``},n)},y=(e,t,n)=>{t.style.overflow=`hidden`,t.style.height=`0`,e.setAttribute(`aria-expanded`,`false`),t.classList.remove(`show`),window.setTimeout(()=>{t.classList.remove(`block`),t.classList.add(`hidden`)},n)},b=e=>{let{min:n,max:o}=_({min:0,max:null},u(e)),s=o===null,c=t(`.accordion-item [aria-expanded]`,e).reduce((e,t)=>{let n=t.closest(`.accordion-item`),r=n==null?void 0:n.querySelector(`.accordion-collapse`);return n&&r instanceof HTMLElement&&e.push({trigger:t,target:r}),e},[]),l=()=>c.filter(({trigger:e})=>i(e)).length,d=({trigger:e,target:t})=>{let a=i(e),o=r(t);s===!1&&l()===n&&a||(a||v(e,t,o),s===!1?c.forEach(t=>{!a&&t.trigger===e||y(t.trigger,t.target,o)}):a&&y(e,t,o))};c.forEach(e=>{a(e.trigger,[`click`],()=>d(e))}),n===1&&l()===0&&c.length>0&&c[0].trigger.click()},x=()=>{t(`.accordion-header[data-toggle=accordion]`).forEach(e=>{console.log(e);let t=e.closest(`.accordion`);if(t){t.setAttribute(`data-toggle`,`accordion`),e.hasAttribute(`data-parent`)&&!t.hasAttribute(`data-options`)&&t.setAttribute(`data-options`,`{'min': 1, 'max': 1}`);return}e.removeAttribute(`data-toggle`)}),d(`accordion`).forEach(b)},S=e=>{let t=n(e);t||(t=e.closest(`.${e.getAttribute(`data-dismiss`)}`)),t&&(t.classList.add(`opacity-0`),setTimeout(()=>t.remove(),r(t)))},C=s(`[data-dismiss]`,`click`,S),w=e=>{let t=n(e);if(!t)return;let i=r(t);if(t.style.overflow=`hidden`,t.style.height=`0px`,e.getAttribute(`aria-expanded`)===`true`){e.setAttribute(`aria-expanded`,`false`),t.classList.remove(`show`),window.setTimeout(()=>t.classList.remove(`block`),i);return}e.setAttribute(`aria-expanded`,`true`),t.classList.add(`block`),t.classList.add(`show`),window.setTimeout(()=>{t.querySelectorAll(`.dropdown-menu`).forEach(e=>e.classList.add(`hidden`));let e=t.scrollHeight;t.querySelectorAll(`.dropdown-menu`).forEach(e=>e.classList.remove(`hidden`)),t.style.height=`${e}px`},32),window.setTimeout(()=>t.style.overflow=``,i)},T=s(`[data-toggle="collapse"]`,`click`,w),E=e=>{let{computePosition:t,shift:n,offset:r}=window.FloatingUIDOM,i=e.nextElementSibling,s=e.parentElement;if(!i||!s||!(i instanceof HTMLElement)||!(s instanceof HTMLElement))return;let c=u(e),l=[r(6),n({padding:5})];function d(){t(e,i,{placement:c.placement||`bottom`,middleware:l}).then(({x:e,y:t})=>{Object.assign(i.style,{left:`${e}px`,top:`${t}px`})})}let f=()=>{i.style.display=`block`,window.requestAnimationFrame(()=>{i.classList.add(`opacity-100`,`visible`)}),d()},p=()=>{i.style.display=``,i.classList.remove(`opacity-100`,`visible`)};s.addEventListener(`focusout`,e=>{e!=null&&e.relatedTarget&&(s.contains(e.relatedTarget)||!document.hasFocus()||p())}),a(e,[`click`],()=>{if(i.style.display===`block`){p();return}f()}),o(p)},D=()=>d(`dropdown`).forEach(E),O={closeButton:`fixed right-0 top-0 z-50 text-white px-5 close`},k=e=>{let{size:t,beforeShown:n,id:r,imgSrc:i,iframeSrc:a}=_({id:`v-modal`,size:void 0,beforeShown:void 0,imgSrc:void 0,iframeSrc:void 0},u(e)),s=e.dataset.html||``;i&&(s=`<img src="${i}">`),a&&(s=`<iframe allow="autoplay" class="aspect-video w-full" src="${a}" allowfullscreen="" autoplay=""></iframe>`);let c=`<div class="modal" id="${r}">
|
|
2
|
+
<div class="modal-content ${t?`modal-${t}`:``}">
|
|
3
|
+
${s}
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<button onclick="removeModal('${r}')" type="button" class="${O.closeButton}" data-dismiss="modal" aria-label="Close">
|
|
7
|
+
<span class="text-4xl" aria-hidden="true">×</span>
|
|
8
|
+
</button>
|
|
9
|
+
|
|
10
|
+
<div class="modal-bg" onclick="removeModal('${r}')"></div>
|
|
11
|
+
</div>
|
|
12
|
+
`;o(()=>window.removeModal(r)),document.body.style.overflow=`hidden`,document.body.insertAdjacentHTML(`beforeend`,c),l(`#${r}`).then(e=>{n&&window[n](),window.setTimeout(()=>e.classList.add(`opacity-100`),32)})},A=(e=`v-modal`)=>{let t=document.getElementById(e);t&&(t.classList.remove(`opacity-100`),window.setTimeout(()=>{t.remove(),document.body.style.overflow=``},500))};window.removeModal=A;const j=s(`[data-toggle="modal"]`,`click`,k),M=t=>{if(t.getAttribute(`aria-selected`)===`true`)return null;let n=e(`[aria-labelledby="${t.getAttribute(`aria-controls`)}"]`);if(!n)return null;let r=t.classList.value,i=t.parentNode;for(;i&&(!(i instanceof HTMLElement)||i.getAttribute(`role`)!==`tablist`);)i=i.parentNode;if(!(i instanceof HTMLElement))return null;let a=i.querySelectorAll(`[aria-selected="true"]`);if(!a||a.length===0)return null;let o=a[0].classList.value;if(i.querySelectorAll(`[role="tab"]`).forEach(e=>{e.classList=r,e.setAttribute(`aria-selected`,`false`)}),t.classList=o,t.setAttribute(`aria-selected`,`true`),n.getAttribute(`role`)===`tabcontent`){Array.from(n.children).forEach(e=>{e.getAttribute(`role`)===`tabpanel`&&e.classList.remove(`hidden`)});return}if(!n.parentNode)return null;Array.from(n.parentNode.children).forEach(e=>{e.getAttribute(`role`)===`tabpanel`&&e.classList.add(`hidden`)}),n.classList.remove(`hidden`)},N=s(`[role="tab"]`,`click`,M);(function(){window.vInitialized=!1,window.initializeVUI=()=>{window.vInitialized||(window.vInitialized=!0,x(),T(),C(),D(),j(),N(),c())},document.addEventListener(`DOMContentLoaded`,window.initializeVUI),document.readyState!==`loading`&&window.initializeVUI()})();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const e=e=>document.querySelector(e),t=(e,t=document)=>Array.from(t.querySelectorAll(e)),n=t=>{let n=t.dataset.target;return n?e(n):null},r=e=>{let t=window.getComputedStyle(e).getPropertyValue(`transition-duration`);return t?parseInt(t.replace(`s`,``))*1e3+1:0},i=e=>e.getAttribute(`aria-expanded`)===`true`,a=(e,t,n)=>{t.forEach(t=>{e.addEventListener(t,n)})},o=e=>{document.addEventListener(`keydown`,t=>{t.key===`Escape`&&e()})},s=(e,n,r)=>()=>t(e).forEach(e=>{e.addEventListener(n,()=>r(e))}),c=()=>window.addEventListener(`resize`,()=>{t(`[data-toggle="collapse"]`).forEach(e=>{let t=n(e);t&&(e.setAttribute(`aria-expanded`,`false`),t.classList.remove(`show`),t.classList.remove(`block`),t.style.height=`auto`,t.style.overflow=``)})}),l=t=>new Promise(n=>{if(e(t))return n(e(t));let r=new MutationObserver(()=>{e(t)&&(n(e(t)),r.disconnect())});r.observe(document.body,{childList:!0,subtree:!0})}),u=e=>{let t=e.dataset.options;if(!t)return{};try{return JSON.parse(t.replaceAll(`'`,`"`))}catch{return{}}},d=e=>{let n=`[data-toggle="${e}"]`;return t(n)},f=(e,t,n)=>{t.style.overflow=`hidden`,t.style.height=`0`,e.setAttribute(`aria-expanded`,`true`),t.classList.add(`block`),t.classList.add(`show`),t.classList.remove(`hidden`),window.setTimeout(()=>{t.style.height=`${t.scrollHeight}px`},33),window.setTimeout(()=>{t.style.overflow=``},n)},p=(e,t,n)=>{t.style.overflow=`hidden`,t.style.height=`0`,e.setAttribute(`aria-expanded`,`false`),t.classList.remove(`show`),window.setTimeout(()=>{t.classList.remove(`block`),t.classList.add(`hidden`)},n)},m=e=>{let{min:n,max:o}={min:0,max:null,...u(e)},s=o===null,c=t(`.accordion-item [aria-expanded]`,e).reduce((e,t)=>{let n=t.closest(`.accordion-item`),r=n?.querySelector(`.accordion-collapse`);return n&&r instanceof HTMLElement&&e.push({trigger:t,target:r}),e},[]),l=()=>c.filter(({trigger:e})=>i(e)).length,d=({trigger:e,target:t})=>{let a=i(e),o=r(t);s===!1&&l()===n&&a||(a||f(e,t,o),s===!1?c.forEach(t=>{!a&&t.trigger===e||p(t.trigger,t.target,o)}):a&&p(e,t,o))};c.forEach(e=>{a(e.trigger,[`click`],()=>d(e))}),n===1&&l()===0&&c.length>0&&c[0].trigger.click()},h=()=>{t(`.accordion-header[data-toggle=accordion]`).forEach(e=>{console.log(e);let t=e.closest(`.accordion`);if(t){t.setAttribute(`data-toggle`,`accordion`),e.hasAttribute(`data-parent`)&&!t.hasAttribute(`data-options`)&&t.setAttribute(`data-options`,`{'min': 1, 'max': 1}`);return}e.removeAttribute(`data-toggle`)}),d(`accordion`).forEach(m)},g=s(`[data-dismiss]`,`click`,e=>{let t=n(e);t||=e.closest(`.${e.getAttribute(`data-dismiss`)}`),t&&(t.classList.add(`opacity-0`),setTimeout(()=>t.remove(),r(t)))}),_=s(`[data-toggle="collapse"]`,`click`,e=>{let t=n(e);if(!t)return;let i=r(t);if(t.style.overflow=`hidden`,t.style.height=`0px`,e.getAttribute(`aria-expanded`)===`true`){e.setAttribute(`aria-expanded`,`false`),t.classList.remove(`show`),window.setTimeout(()=>t.classList.remove(`block`),i);return}e.setAttribute(`aria-expanded`,`true`),t.classList.add(`block`),t.classList.add(`show`),window.setTimeout(()=>{t.querySelectorAll(`.dropdown-menu`).forEach(e=>e.classList.add(`hidden`));let e=t.scrollHeight;t.querySelectorAll(`.dropdown-menu`).forEach(e=>e.classList.remove(`hidden`)),t.style.height=`${e}px`},32),window.setTimeout(()=>t.style.overflow=``,i)}),v=e=>{let{computePosition:t,shift:n,offset:r}=window.FloatingUIDOM,i=e.nextElementSibling,s=e.parentElement;if(!i||!s||!(i instanceof HTMLElement)||!(s instanceof HTMLElement))return;let c=u(e),l=[r(6),n({padding:5})];function d(){t(e,i,{placement:c.placement||`bottom`,middleware:l}).then(({x:e,y:t})=>{Object.assign(i.style,{left:`${e}px`,top:`${t}px`})})}let f=()=>{i.style.display=`block`,window.requestAnimationFrame(()=>{i.classList.add(`opacity-100`,`visible`)}),d()},p=()=>{i.style.display=``,i.classList.remove(`opacity-100`,`visible`)};s.addEventListener(`focusout`,e=>{e?.relatedTarget&&(s.contains(e.relatedTarget)||!document.hasFocus()||p())}),a(e,[`click`],()=>{if(i.style.display===`block`){p();return}f()}),o(p)},y=()=>d(`dropdown`).forEach(v),b={closeButton:`fixed right-0 top-0 z-50 text-white px-5 close`},x=e=>{let{size:t,beforeShown:n,id:r,imgSrc:i,iframeSrc:a}={id:`v-modal`,size:void 0,beforeShown:void 0,imgSrc:void 0,iframeSrc:void 0,...u(e)},s=e.dataset.html||``;i&&(s=`<img src="${i}">`),a&&(s=`<iframe allow="autoplay" class="aspect-video w-full" src="${a}" allowfullscreen="" autoplay=""></iframe>`);let c=`<div class="modal" id="${r}">
|
|
2
|
+
<div class="modal-content ${t?`modal-${t}`:``}">
|
|
3
|
+
${s}
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<button onclick="removeModal('${r}')" type="button" class="${b.closeButton}" data-dismiss="modal" aria-label="Close">
|
|
7
|
+
<span class="text-4xl" aria-hidden="true">×</span>
|
|
8
|
+
</button>
|
|
9
|
+
|
|
10
|
+
<div class="modal-bg" onclick="removeModal('${r}')"></div>
|
|
11
|
+
</div>
|
|
12
|
+
`;o(()=>window.removeModal(r)),document.body.style.overflow=`hidden`,document.body.insertAdjacentHTML(`beforeend`,c),l(`#${r}`).then(e=>{n&&window[n](),window.setTimeout(()=>e.classList.add(`opacity-100`),32)})},S=(e=`v-modal`)=>{let t=document.getElementById(e);t&&(t.classList.remove(`opacity-100`),window.setTimeout(()=>{t.remove(),document.body.style.overflow=``},500))};window.removeModal=S;const C=s(`[data-toggle="modal"]`,`click`,x),w=s(`[role="tab"]`,`click`,t=>{if(t.getAttribute(`aria-selected`)===`true`)return null;let n=e(`[aria-labelledby="${t.getAttribute(`aria-controls`)}"]`);if(!n)return null;let r=t.classList.value,i=t.parentNode;for(;i&&(!(i instanceof HTMLElement)||i.getAttribute(`role`)!==`tablist`);)i=i.parentNode;if(!(i instanceof HTMLElement))return null;let a=i.querySelectorAll(`[aria-selected="true"]`);if(!a||a.length===0)return null;let o=a[0].classList.value;if(i.querySelectorAll(`[role="tab"]`).forEach(e=>{e.classList=r,e.setAttribute(`aria-selected`,`false`)}),t.classList=o,t.setAttribute(`aria-selected`,`true`),n.getAttribute(`role`)===`tabcontent`){Array.from(n.children).forEach(e=>{e.getAttribute(`role`)===`tabpanel`&&e.classList.remove(`hidden`)});return}if(!n.parentNode)return null;Array.from(n.parentNode.children).forEach(e=>{e.getAttribute(`role`)===`tabpanel`&&e.classList.add(`hidden`)}),n.classList.remove(`hidden`)});(function(){window.vInitialized=!1,window.initializeVUI=()=>{window.vInitialized||(window.vInitialized=!0,h(),_(),g(),y(),C(),w(),c())},document.addEventListener(`DOMContentLoaded`,window.initializeVUI),document.readyState!==`loading`&&window.initializeVUI()})();
|
package/eslint.config.ts
ADDED
package/index.html
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Versoly UI</title>
|
|
7
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
<style></style>
|
|
9
|
+
</head>
|
|
10
|
+
|
|
11
|
+
<body>
|
|
12
|
+
<script src="https://d1pnnwteuly8z3.cloudfront.net/libs/floating-ui/1.0.1/floating-ui.min.js"></script>
|
|
13
|
+
<script src="./dist/versoly-ui.js"></script>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "versoly-ui",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Versoly UI - Tailwind CSS framework based on Bootstrap",
|
|
5
|
+
"author": "Versoly",
|
|
5
6
|
"keywords": [
|
|
6
|
-
"versoly",
|
|
7
|
-
"versoly ui",
|
|
8
|
-
"tailwind",
|
|
9
7
|
"tailwind components",
|
|
10
8
|
"tailwind elements",
|
|
11
9
|
"tailwind library",
|
|
12
10
|
"tailwind sections",
|
|
13
|
-
"tailwind css",
|
|
14
11
|
"tailwind ui",
|
|
15
12
|
"ui kit",
|
|
16
13
|
"bootstrap to tailwind",
|
|
17
|
-
"html",
|
|
18
|
-
"css",
|
|
19
|
-
"javascript",
|
|
20
14
|
"dropdown Floating UI"
|
|
21
15
|
],
|
|
22
16
|
"license": "MIT",
|
|
23
|
-
"main": "dist/versoly-ui.js",
|
|
17
|
+
"main": "./dist/versoly-ui.js",
|
|
18
|
+
"unpkg": "dist/versoly-ui.iife.js",
|
|
19
|
+
"jsdelivr": "dist/versoly-ui.iife.js",
|
|
20
|
+
"module": "./dist/versoly-ui.mjs",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": "./dist/versoly-ui.js",
|
|
23
|
+
"./package.json": "./package.json"
|
|
24
|
+
},
|
|
24
25
|
"repository": {
|
|
25
26
|
"type": "git",
|
|
26
27
|
"url": "git+https://github.com/versoly/versoly-ui.git"
|
|
@@ -33,31 +34,18 @@
|
|
|
33
34
|
"Volkan Kaya <volkan@versoly.com>"
|
|
34
35
|
],
|
|
35
36
|
"scripts": {
|
|
36
|
-
"
|
|
37
|
-
"build": "
|
|
38
|
-
"build:
|
|
39
|
-
"build:js": "run-s build:webpack"
|
|
37
|
+
"dev": "vite",
|
|
38
|
+
"build": "tsdown",
|
|
39
|
+
"build:watch": "tsdown --watch"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"core-js": "^3.8.1",
|
|
51
|
-
"file-loader": "^6.2.0",
|
|
52
|
-
"npm-run-all": "^4.1.5",
|
|
53
|
-
"source-map-loader": "^2.0.0",
|
|
54
|
-
"terser-webpack-plugin": "^5.3.1",
|
|
55
|
-
"webpack": "^5.47.0",
|
|
56
|
-
"webpack-cli": "^4.7.2",
|
|
57
|
-
"webpack-dev-server": "^3.11.2"
|
|
58
|
-
},
|
|
59
|
-
"author": "Versoly",
|
|
60
|
-
"dependencies": {
|
|
61
|
-
"@floating-ui/dom": "^1.0.1"
|
|
42
|
+
"@kainstar/eslint-config": "^2.0.0",
|
|
43
|
+
"eslint": "^9.35.0",
|
|
44
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
45
|
+
"prettier": "^3.6.2",
|
|
46
|
+
"tsdown": "^0.15.1",
|
|
47
|
+
"type-fest": "^4.41.0",
|
|
48
|
+
"typescript": "^5.9.2",
|
|
49
|
+
"vite": "^7.1.5"
|
|
62
50
|
}
|
|
63
51
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** @type {import('prettier').Config} */
|
|
2
|
+
export default {
|
|
3
|
+
printWidth: 120,
|
|
4
|
+
singleQuote: true,
|
|
5
|
+
proseWrap: 'never',
|
|
6
|
+
overrides: [
|
|
7
|
+
{
|
|
8
|
+
files: '**/*.json',
|
|
9
|
+
options: {
|
|
10
|
+
parser: 'json-stringify',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
files: ['.vscode/*.json', '**/tsconfig.json'],
|
|
15
|
+
options: {
|
|
16
|
+
parser: 'jsonc',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { accordion, collapse, dismiss, dropdown, modal, tabs, handleResize } from './plugins/index';
|
|
2
|
+
|
|
3
|
+
(function () {
|
|
4
|
+
window.vInitialized = false;
|
|
5
|
+
window.initializeVUI = () => {
|
|
6
|
+
if (window.vInitialized) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
window.vInitialized = true;
|
|
11
|
+
accordion();
|
|
12
|
+
collapse();
|
|
13
|
+
dismiss();
|
|
14
|
+
dropdown();
|
|
15
|
+
modal();
|
|
16
|
+
tabs();
|
|
17
|
+
|
|
18
|
+
handleResize();
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
document.addEventListener('DOMContentLoaded', window.initializeVUI);
|
|
22
|
+
if (document.readyState !== 'loading') {
|
|
23
|
+
window.initializeVUI();
|
|
24
|
+
}
|
|
25
|
+
})();
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { IAccordionOptions } from 'src/types';
|
|
2
|
+
import {
|
|
3
|
+
addEventListeners,
|
|
4
|
+
getDuration,
|
|
5
|
+
getElementsBySelectors,
|
|
6
|
+
getElementsByToggle,
|
|
7
|
+
getIsAriaExpanded,
|
|
8
|
+
parseElementOptions,
|
|
9
|
+
} from '../utils/index';
|
|
10
|
+
|
|
11
|
+
interface IAccordionItem {
|
|
12
|
+
trigger: HTMLElement;
|
|
13
|
+
target: HTMLElement;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const handleOpen = (trigger: HTMLElement, target: HTMLElement, duration: number) => {
|
|
17
|
+
target.style.overflow = 'hidden';
|
|
18
|
+
target.style.height = '0';
|
|
19
|
+
|
|
20
|
+
trigger.setAttribute('aria-expanded', 'true');
|
|
21
|
+
target.classList.add('block');
|
|
22
|
+
target.classList.add('show');
|
|
23
|
+
target.classList.remove('hidden');
|
|
24
|
+
|
|
25
|
+
window.setTimeout(() => {
|
|
26
|
+
target.style.height = `${target.scrollHeight}px`;
|
|
27
|
+
}, 33);
|
|
28
|
+
|
|
29
|
+
window.setTimeout(() => {
|
|
30
|
+
target.style.overflow = '';
|
|
31
|
+
}, duration);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const handleClose = (trigger: HTMLElement, target: HTMLElement, duration: number) => {
|
|
35
|
+
target.style.overflow = 'hidden';
|
|
36
|
+
target.style.height = '0';
|
|
37
|
+
|
|
38
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
39
|
+
target.classList.remove('show');
|
|
40
|
+
|
|
41
|
+
window.setTimeout(() => {
|
|
42
|
+
target.classList.remove('block');
|
|
43
|
+
target.classList.add('hidden');
|
|
44
|
+
}, duration);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const Accordion = (element: HTMLElement) => {
|
|
48
|
+
const options: IAccordionOptions = {
|
|
49
|
+
min: 0,
|
|
50
|
+
max: null,
|
|
51
|
+
...parseElementOptions(element),
|
|
52
|
+
};
|
|
53
|
+
const { min, max } = options;
|
|
54
|
+
|
|
55
|
+
const canOpenMultiple = max === null;
|
|
56
|
+
|
|
57
|
+
const items: IAccordionItem[] = getElementsBySelectors('.accordion-item [aria-expanded]', element).reduce(
|
|
58
|
+
(acc: IAccordionItem[], trigger) => {
|
|
59
|
+
const item = trigger.closest('.accordion-item');
|
|
60
|
+
const target = item?.querySelector('.accordion-collapse');
|
|
61
|
+
if (item && target instanceof HTMLElement) {
|
|
62
|
+
acc.push({ trigger, target });
|
|
63
|
+
}
|
|
64
|
+
return acc;
|
|
65
|
+
},
|
|
66
|
+
[],
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const getOpenCount = () => items.filter(({ trigger }) => getIsAriaExpanded(trigger)).length;
|
|
70
|
+
|
|
71
|
+
const toggle = ({ trigger, target }: IAccordionItem) => {
|
|
72
|
+
const isOpen = getIsAriaExpanded(trigger);
|
|
73
|
+
const duration = getDuration(target);
|
|
74
|
+
|
|
75
|
+
if (canOpenMultiple === false && getOpenCount() === min && isOpen) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!isOpen) {
|
|
80
|
+
handleOpen(trigger, target, duration);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (canOpenMultiple === false) {
|
|
84
|
+
items.forEach((item) => {
|
|
85
|
+
if (!isOpen && item.trigger === trigger) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
handleClose(item.trigger, item.target, duration);
|
|
89
|
+
});
|
|
90
|
+
} else if (isOpen) {
|
|
91
|
+
handleClose(trigger, target, duration);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
items.forEach((item) => {
|
|
96
|
+
addEventListeners(item.trigger, ['click'], () => toggle(item));
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
if (min === 1 && getOpenCount() === 0 && items.length > 0) {
|
|
100
|
+
items[0].trigger.click();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const accordion = () => {
|
|
105
|
+
// legacy support for accordion via data attributes on headers
|
|
106
|
+
getElementsBySelectors('.accordion-header[data-toggle=accordion]').forEach((element) => {
|
|
107
|
+
const parentAccordion = element.closest('.accordion');
|
|
108
|
+
if (parentAccordion) {
|
|
109
|
+
parentAccordion.setAttribute('data-toggle', 'accordion');
|
|
110
|
+
|
|
111
|
+
if (element.hasAttribute('data-parent') && !parentAccordion.hasAttribute('data-options')) {
|
|
112
|
+
parentAccordion.setAttribute('data-options', "{'min': 1, 'max': 1}");
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
element.removeAttribute('data-toggle');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
getElementsByToggle('accordion').forEach(Accordion);
|
|
121
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getDuration, getTarget, addEventListenerToSelector } from '../utils/index';
|
|
2
|
+
|
|
3
|
+
const Collapse = (element: HTMLElement) => {
|
|
4
|
+
const target = getTarget(element);
|
|
5
|
+
if (!target) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const duration = getDuration(target);
|
|
10
|
+
target.style.overflow = 'hidden';
|
|
11
|
+
target.style.height = '0px';
|
|
12
|
+
|
|
13
|
+
if (element.getAttribute('aria-expanded') === 'true') {
|
|
14
|
+
element.setAttribute('aria-expanded', 'false');
|
|
15
|
+
target.classList.remove('show');
|
|
16
|
+
|
|
17
|
+
window.setTimeout(() => target.classList.remove('block'), duration);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
element.setAttribute('aria-expanded', 'true');
|
|
22
|
+
target.classList.add('block');
|
|
23
|
+
target.classList.add('show');
|
|
24
|
+
|
|
25
|
+
window.setTimeout(() => {
|
|
26
|
+
target.querySelectorAll('.dropdown-menu').forEach((m) => m.classList.add('hidden'));
|
|
27
|
+
const navHeight = target.scrollHeight;
|
|
28
|
+
target.querySelectorAll('.dropdown-menu').forEach((m) => m.classList.remove('hidden'));
|
|
29
|
+
target.style.height = `${navHeight}px`;
|
|
30
|
+
}, 32);
|
|
31
|
+
|
|
32
|
+
window.setTimeout(() => (target.style.overflow = ''), duration);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const collapse = addEventListenerToSelector('[data-toggle="collapse"]', 'click', Collapse);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getDuration, getTarget, addEventListenerToSelector } from '../utils/index';
|
|
2
|
+
|
|
3
|
+
const Dismiss = (element: HTMLElement) => {
|
|
4
|
+
let target = getTarget(element);
|
|
5
|
+
if (!target) {
|
|
6
|
+
target = element.closest(`.${element.getAttribute('data-dismiss')}`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (!target) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
target.classList.add('opacity-0');
|
|
14
|
+
setTimeout(() => target.remove(), getDuration(target));
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const dismiss = addEventListenerToSelector('[data-dismiss]', 'click', Dismiss);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { addEventListeners, addEscapeListener, getElementsByToggle, parseElementOptions } from '../utils/index';
|
|
2
|
+
|
|
3
|
+
const Dropdown = (trigger: HTMLElement) => {
|
|
4
|
+
const { computePosition, shift, offset } = window.FloatingUIDOM;
|
|
5
|
+
const target = trigger.nextElementSibling as HTMLElement;
|
|
6
|
+
const parent = trigger.parentElement as HTMLElement;
|
|
7
|
+
|
|
8
|
+
if (!target || !parent || !(target instanceof HTMLElement) || !(parent instanceof HTMLElement)) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const options = parseElementOptions(trigger);
|
|
13
|
+
|
|
14
|
+
const middleware = [
|
|
15
|
+
offset(6),
|
|
16
|
+
shift({
|
|
17
|
+
padding: 5,
|
|
18
|
+
}),
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
function update() {
|
|
22
|
+
computePosition(trigger, target, {
|
|
23
|
+
placement: options.placement || 'bottom',
|
|
24
|
+
middleware,
|
|
25
|
+
}).then(({ x, y }: { x: number; y: number }) => {
|
|
26
|
+
Object.assign(target.style, {
|
|
27
|
+
left: `${x}px`,
|
|
28
|
+
top: `${y}px`,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const show = () => {
|
|
34
|
+
target.style.display = 'block';
|
|
35
|
+
window.requestAnimationFrame(() => {
|
|
36
|
+
target.classList.add('opacity-100', 'visible');
|
|
37
|
+
});
|
|
38
|
+
update();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const hide = () => {
|
|
42
|
+
target.style.display = '';
|
|
43
|
+
target.classList.remove('opacity-100', 'visible');
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const toggle = () => {
|
|
47
|
+
if (target.style.display === 'block') {
|
|
48
|
+
hide();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
show();
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
parent.addEventListener('focusout', (event) => {
|
|
55
|
+
if (!event?.relatedTarget) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (parent.contains(event.relatedTarget as Node) || !document.hasFocus()) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
hide();
|
|
62
|
+
});
|
|
63
|
+
addEventListeners(trigger, ['click'], toggle);
|
|
64
|
+
addEscapeListener(hide);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const dropdown = () => getElementsByToggle('dropdown').forEach(Dropdown);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { accordion } from './accordion';
|
|
2
|
+
export { dismiss } from './dismiss';
|
|
3
|
+
export { collapse } from './collapse';
|
|
4
|
+
export { dropdown } from './dropdown';
|
|
5
|
+
export { modal } from './modal';
|
|
6
|
+
export { tabs } from './tabs';
|
|
7
|
+
export { handleResize } from '../utils';
|