diff --git a/README.md b/README.md index 364527d..8244af4 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,16 @@ To let the `textarea` automatically resize, add the `x-data` and `x-autosize` di ``` -That's it! +### ⏬ Additional height + +To add additional height to the textarea - which might be necessary in some occasions - you can do so using the +"padding" modifier like so (only `px` values are supported): + +```html + +``` + +This adds additional 10px to the textarea height. You can provide any integer which best suits your needs. ## 📄 License diff --git a/dist/alpine-autosize.js b/dist/alpine-autosize.js index e7d65a4..d72af41 100644 --- a/dist/alpine-autosize.js +++ b/dist/alpine-autosize.js @@ -4,7 +4,9 @@ })((function () { 'use strict'; function Autosize(Alpine) { - Alpine.directive('autosize', (el, {}, { + Alpine.directive('autosize', (el, { + modifiers + }, { cleanup }) => { const attributes = Array.from(el.attributes); @@ -26,7 +28,13 @@ const previousResizeValue = el.style.resize; el.style.resize = 'none'; const previousMinHeight = el.style.minHeight; - el.style.minHeight = el.getBoundingClientRect().height + 'px'; + el.style.minHeight = `${el.getBoundingClientRect().height}px`; + const paddingModifier = modifiers.filter(modifier => modifier.match(/px$/i))[0] || false; + let padding = 0; + + if (paddingModifier !== false) { + padding = parseInt(paddingModifier); + } const handler = event => { const element = event.target; @@ -36,7 +44,7 @@ } element.style.height = '4px'; - element.style.height = `${element.scrollHeight}px`; + element.style.height = `${element.scrollHeight + padding}px`; }; handler({ diff --git a/dist/alpine-autosize.js.map b/dist/alpine-autosize.js.map index 72c3fb1..e99a568 100644 --- a/dist/alpine-autosize.js.map +++ b/dist/alpine-autosize.js.map @@ -1 +1 @@ -{"version":3,"file":"alpine-autosize.js","sources":["../src/index.js","../builds/cdn.js"],"sourcesContent":["function Autosize(Alpine) {\n Alpine.directive('autosize', (el, {}, { cleanup }) => {\n\n const attributes = Array.from(el.attributes);\n\n let hasWireModel = false;\n\n for (let { nodeName } of attributes) {\n if (nodeName === 'wire:model' || nodeName.startsWith('wire:model.')) {\n hasWireModel = true;\n break;\n }\n }\n\n if (!el.hasAttribute('wire:ignore') && hasWireModel) {\n el.setAttribute('wire:ignore', '');\n }\n\n const previousResizeValue = el.style.resize;\n el.style.resize = 'none';\n\n const previousMinHeight = el.style.minHeight;\n el.style.minHeight = el.getBoundingClientRect().height + 'px';\n\n const handler = (event) => {\n const element = event.target;\n if (!element.scrollHeight) {\n return;\n }\n element.style.height = '4px';\n element.style.height = `${element.scrollHeight}px`;\n };\n\n handler({ target: el });\n\n el.addEventListener('input', handler);\n\n cleanup(() => {\n el.style.resize = previousResizeValue;\n el.style.minHeight = previousMinHeight;\n el.removeEventListener('input', handler);\n });\n });\n}\n\nexport default Autosize;\n","import autosize from '../src/index.js';\n\ndocument.addEventListener('alpine:init', () => {\n autosize(window.Alpine);\n});\n"],"names":["Autosize","Alpine","directive","el","cleanup","attributes","Array","from","hasWireModel","nodeName","startsWith","hasAttribute","setAttribute","previousResizeValue","style","resize","previousMinHeight","minHeight","getBoundingClientRect","height","handler","event","element","target","scrollHeight","addEventListener","removeEventListener","document","autosize","window"],"mappings":";;;;;IAAA,SAASA,QAAT,CAAkBC,MAAlB,EAA0B;IACtBA,EAAAA,MAAM,CAACC,SAAP,CAAiB,UAAjB,EAA6B,CAACC,EAAD,EAAK,EAAL,EAAS;IAAEC,IAAAA;IAAF,GAAT,KAAyB;IAElD,UAAMC,UAAU,GAAGC,KAAK,CAACC,IAAN,CAAWJ,EAAE,CAACE,UAAd,CAAnB;IAEA,QAAIG,YAAY,GAAG,KAAnB;;IAEA,SAAK,IAAI;IAAEC,MAAAA;IAAF,KAAT,IAAyBJ,UAAzB,EAAqC;IACjC,UAAII,QAAQ,KAAK,YAAb,IAA6BA,QAAQ,CAACC,UAAT,CAAoB,aAApB,CAAjC,EAAqE;IACjEF,QAAAA,YAAY,GAAG,IAAf;IACA;IACH;IACJ;;IAED,QAAI,CAACL,EAAE,CAACQ,YAAH,CAAgB,aAAhB,CAAD,IAAmCH,YAAvC,EAAqD;IACjDL,MAAAA,EAAE,CAACS,YAAH,CAAgB,aAAhB,EAA+B,EAA/B;IACH;;IAED,UAAMC,mBAAmB,GAAGV,EAAE,CAACW,KAAH,CAASC,MAArC;IACAZ,IAAAA,EAAE,CAACW,KAAH,CAASC,MAAT,GAAkB,MAAlB;IAEA,UAAMC,iBAAiB,GAAGb,EAAE,CAACW,KAAH,CAASG,SAAnC;IACAd,IAAAA,EAAE,CAACW,KAAH,CAASG,SAAT,GAAqBd,EAAE,CAACe,qBAAH,GAA2BC,MAA3B,GAAoC,IAAzD;;IAEA,UAAMC,OAAO,GAAIC,KAAD,IAAW;IACvB,YAAMC,OAAO,GAAGD,KAAK,CAACE,MAAtB;;IACA,UAAI,CAACD,OAAO,CAACE,YAAb,EAA2B;IACvB;IACH;;IACDF,MAAAA,OAAO,CAACR,KAAR,CAAcK,MAAd,GAAuB,KAAvB;IACAG,MAAAA,OAAO,CAACR,KAAR,CAAcK,MAAd,GAAwB,GAAEG,OAAO,CAACE,YAAa,IAA/C;IACH,KAPD;;IASAJ,IAAAA,OAAO,CAAC;IAAEG,MAAAA,MAAM,EAAEpB;IAAV,KAAD,CAAP;IAEAA,IAAAA,EAAE,CAACsB,gBAAH,CAAoB,OAApB,EAA6BL,OAA7B;IAEAhB,IAAAA,OAAO,CAAC,MAAM;IACVD,MAAAA,EAAE,CAACW,KAAH,CAASC,MAAT,GAAkBF,mBAAlB;IACAV,MAAAA,EAAE,CAACW,KAAH,CAASG,SAAT,GAAqBD,iBAArB;IACAb,MAAAA,EAAE,CAACuB,mBAAH,CAAuB,OAAvB,EAAgCN,OAAhC;IACH,KAJM,CAAP;IAKH,GAzCD;IA0CH;;ICzCDO,QAAQ,CAACF,gBAAT,CAA0B,aAA1B,EAAyC,MAAM;IAC3CG,EAAAA,QAAQ,CAACC,MAAM,CAAC5B,MAAR,CAAR;IACH,CAFD;;;;;;"} \ No newline at end of file +{"version":3,"file":"alpine-autosize.js","sources":["../src/index.js","../builds/cdn.js"],"sourcesContent":["function Autosize(Alpine) {\n Alpine.directive('autosize', (el, { modifiers }, { cleanup }) => {\n const attributes = Array.from(el.attributes);\n\n let hasWireModel = false;\n\n for (let { nodeName } of attributes) {\n if (nodeName === 'wire:model' || nodeName.startsWith('wire:model.')) {\n hasWireModel = true;\n break;\n }\n }\n\n if (!el.hasAttribute('wire:ignore') && hasWireModel) {\n el.setAttribute('wire:ignore', '');\n }\n\n const previousResizeValue = el.style.resize;\n el.style.resize = 'none';\n\n const previousMinHeight = el.style.minHeight;\n el.style.minHeight = `${el.getBoundingClientRect().height}px`;\n\n const paddingModifier = modifiers.filter(modifier => modifier.match(/px$/i))[0] || false;\n let padding = 0;\n if (paddingModifier !== false) {\n padding = parseInt(paddingModifier);\n }\n\n const handler = (event) => {\n const element = event.target;\n if (!element.scrollHeight) {\n return;\n }\n element.style.height = '4px';\n element.style.height = `${element.scrollHeight + padding}px`;\n };\n\n handler({ target: el });\n\n el.addEventListener('input', handler);\n\n cleanup(() => {\n el.style.resize = previousResizeValue;\n el.style.minHeight = previousMinHeight;\n el.removeEventListener('input', handler);\n });\n });\n}\n\nexport default Autosize;\n","import autosize from '../src/index.js';\n\ndocument.addEventListener('alpine:init', () => {\n autosize(window.Alpine);\n});\n"],"names":["Autosize","Alpine","directive","el","modifiers","cleanup","attributes","Array","from","hasWireModel","nodeName","startsWith","hasAttribute","setAttribute","previousResizeValue","style","resize","previousMinHeight","minHeight","getBoundingClientRect","height","paddingModifier","filter","modifier","match","padding","parseInt","handler","event","element","target","scrollHeight","addEventListener","removeEventListener","document","autosize","window"],"mappings":";;;;;IAAA,SAASA,QAAT,CAAkBC,MAAlB,EAA0B;IACtBA,EAAAA,MAAM,CAACC,SAAP,CAAiB,UAAjB,EAA6B,CAACC,EAAD,EAAK;IAAEC,IAAAA;IAAF,GAAL,EAAoB;IAAEC,IAAAA;IAAF,GAApB,KAAoC;IAC7D,UAAMC,UAAU,GAAGC,KAAK,CAACC,IAAN,CAAWL,EAAE,CAACG,UAAd,CAAnB;IAEA,QAAIG,YAAY,GAAG,KAAnB;;IAEA,SAAK,IAAI;IAAEC,MAAAA;IAAF,KAAT,IAAyBJ,UAAzB,EAAqC;IACjC,UAAII,QAAQ,KAAK,YAAb,IAA6BA,QAAQ,CAACC,UAAT,CAAoB,aAApB,CAAjC,EAAqE;IACjEF,QAAAA,YAAY,GAAG,IAAf;IACA;IACH;IACJ;;IAED,QAAI,CAACN,EAAE,CAACS,YAAH,CAAgB,aAAhB,CAAD,IAAmCH,YAAvC,EAAqD;IACjDN,MAAAA,EAAE,CAACU,YAAH,CAAgB,aAAhB,EAA+B,EAA/B;IACH;;IAED,UAAMC,mBAAmB,GAAGX,EAAE,CAACY,KAAH,CAASC,MAArC;IACAb,IAAAA,EAAE,CAACY,KAAH,CAASC,MAAT,GAAkB,MAAlB;IAEA,UAAMC,iBAAiB,GAAGd,EAAE,CAACY,KAAH,CAASG,SAAnC;IACAf,IAAAA,EAAE,CAACY,KAAH,CAASG,SAAT,GAAsB,GAAEf,EAAE,CAACgB,qBAAH,GAA2BC,MAAO,IAA1D;IAEA,UAAMC,eAAe,GAAGjB,SAAS,CAACkB,MAAV,CAAiBC,QAAQ,IAAIA,QAAQ,CAACC,KAAT,CAAe,MAAf,CAA7B,EAAqD,CAArD,KAA2D,KAAnF;IACA,QAAIC,OAAO,GAAG,CAAd;;IACA,QAAIJ,eAAe,KAAK,KAAxB,EAA+B;IAC3BI,MAAAA,OAAO,GAAGC,QAAQ,CAACL,eAAD,CAAlB;IACH;;IAED,UAAMM,OAAO,GAAIC,KAAD,IAAW;IACvB,YAAMC,OAAO,GAAGD,KAAK,CAACE,MAAtB;;IACA,UAAI,CAACD,OAAO,CAACE,YAAb,EAA2B;IACvB;IACH;;IACDF,MAAAA,OAAO,CAACd,KAAR,CAAcK,MAAd,GAAuB,KAAvB;IACAS,MAAAA,OAAO,CAACd,KAAR,CAAcK,MAAd,GAAwB,GAAES,OAAO,CAACE,YAAR,GAAuBN,OAAQ,IAAzD;IACH,KAPD;;IASAE,IAAAA,OAAO,CAAC;IAAEG,MAAAA,MAAM,EAAE3B;IAAV,KAAD,CAAP;IAEAA,IAAAA,EAAE,CAAC6B,gBAAH,CAAoB,OAApB,EAA6BL,OAA7B;IAEAtB,IAAAA,OAAO,CAAC,MAAM;IACVF,MAAAA,EAAE,CAACY,KAAH,CAASC,MAAT,GAAkBF,mBAAlB;IACAX,MAAAA,EAAE,CAACY,KAAH,CAASG,SAAT,GAAqBD,iBAArB;IACAd,MAAAA,EAAE,CAAC8B,mBAAH,CAAuB,OAAvB,EAAgCN,OAAhC;IACH,KAJM,CAAP;IAKH,GA9CD;IA+CH;;IC9CDO,QAAQ,CAACF,gBAAT,CAA0B,aAA1B,EAAyC,MAAM;IAC3CG,EAAAA,QAAQ,CAACC,MAAM,CAACnC,MAAR,CAAR;IACH,CAFD;;;;;;"} \ No newline at end of file diff --git a/dist/alpine-autosize.min.js b/dist/alpine-autosize.min.js index 1b693db..8ad2872 100644 --- a/dist/alpine-autosize.min.js +++ b/dist/alpine-autosize.min.js @@ -1,2 +1,2 @@ -!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";document.addEventListener("alpine:init",(()=>{window.Alpine.directive("autosize",((e,{},{cleanup:t})=>{const i=Array.from(e.attributes);let n=!1;for(let{nodeName:e}of i)if("wire:model"===e||e.startsWith("wire:model.")){n=!0;break}!e.hasAttribute("wire:ignore")&&n&&e.setAttribute("wire:ignore","");const s=e.style.resize;e.style.resize="none";const r=e.style.minHeight;e.style.minHeight=e.getBoundingClientRect().height+"px";const o=e=>{const t=e.target;t.scrollHeight&&(t.style.height="4px",t.style.height=`${t.scrollHeight}px`)};o({target:e}),e.addEventListener("input",o),t((()=>{e.style.resize=s,e.style.minHeight=r,e.removeEventListener("input",o)}))}))}))})); +!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";document.addEventListener("alpine:init",(()=>{window.Alpine.directive("autosize",((e,{modifiers:t},{cleanup:i})=>{const n=Array.from(e.attributes);let s=!1;for(let{nodeName:e}of n)if("wire:model"===e||e.startsWith("wire:model.")){s=!0;break}!e.hasAttribute("wire:ignore")&&s&&e.setAttribute("wire:ignore","");const r=e.style.resize;e.style.resize="none";const o=e.style.minHeight;e.style.minHeight=`${e.getBoundingClientRect().height}px`;const l=t.filter((e=>e.match(/px$/i)))[0]||!1;let c=0;!1!==l&&(c=parseInt(l));const a=e=>{const t=e.target;t.scrollHeight&&(t.style.height="4px",t.style.height=`${t.scrollHeight+c}px`)};a({target:e}),e.addEventListener("input",a),i((()=>{e.style.resize=r,e.style.minHeight=o,e.removeEventListener("input",a)}))}))}))})); //# sourceMappingURL=alpine-autosize.min.js.map diff --git a/dist/alpine-autosize.min.js.map b/dist/alpine-autosize.min.js.map index 8bb57be..98ef49a 100644 --- a/dist/alpine-autosize.min.js.map +++ b/dist/alpine-autosize.min.js.map @@ -1 +1 @@ -{"version":3,"file":"alpine-autosize.min.js","sources":["../builds/cdn.js","../src/index.js"],"sourcesContent":["import autosize from '../src/index.js';\n\ndocument.addEventListener('alpine:init', () => {\n autosize(window.Alpine);\n});\n","function Autosize(Alpine) {\n Alpine.directive('autosize', (el, {}, { cleanup }) => {\n\n const attributes = Array.from(el.attributes);\n\n let hasWireModel = false;\n\n for (let { nodeName } of attributes) {\n if (nodeName === 'wire:model' || nodeName.startsWith('wire:model.')) {\n hasWireModel = true;\n break;\n }\n }\n\n if (!el.hasAttribute('wire:ignore') && hasWireModel) {\n el.setAttribute('wire:ignore', '');\n }\n\n const previousResizeValue = el.style.resize;\n el.style.resize = 'none';\n\n const previousMinHeight = el.style.minHeight;\n el.style.minHeight = el.getBoundingClientRect().height + 'px';\n\n const handler = (event) => {\n const element = event.target;\n if (!element.scrollHeight) {\n return;\n }\n element.style.height = '4px';\n element.style.height = `${element.scrollHeight}px`;\n };\n\n handler({ target: el });\n\n el.addEventListener('input', handler);\n\n cleanup(() => {\n el.style.resize = previousResizeValue;\n el.style.minHeight = previousMinHeight;\n el.removeEventListener('input', handler);\n });\n });\n}\n\nexport default Autosize;\n"],"names":["document","addEventListener","window","Alpine","directive","el","cleanup","attributes","Array","from","hasWireModel","nodeName","startsWith","hasAttribute","setAttribute","previousResizeValue","style","resize","previousMinHeight","minHeight","getBoundingClientRect","height","handler","event","element","target","scrollHeight","removeEventListener"],"mappings":"2FAEAA,SAASC,iBAAiB,eAAe,KAC5BC,OAAOC,OCFTC,UAAU,YAAY,CAACC,MAAUC,QAAAA,YAE9BC,EAAaC,MAAMC,KAAKJ,EAAGE,gBAE7BG,GAAe,MAEd,IAAIC,SAAEA,KAAcJ,KACJ,eAAbI,GAA6BA,EAASC,WAAW,eAAgB,CACjEF,GAAe,SAKlBL,EAAGQ,aAAa,gBAAkBH,GACnCL,EAAGS,aAAa,cAAe,UAG7BC,EAAsBV,EAAGW,MAAMC,OACrCZ,EAAGW,MAAMC,OAAS,aAEZC,EAAoBb,EAAGW,MAAMG,UACnCd,EAAGW,MAAMG,UAAYd,EAAGe,wBAAwBC,OAAS,WAEnDC,EAAWC,UACPC,EAAUD,EAAME,OACjBD,EAAQE,eAGbF,EAAQR,MAAMK,OAAS,MACvBG,EAAQR,MAAMK,OAAU,GAAEG,EAAQE,mBAGtCJ,EAAQ,CAAEG,OAAQpB,IAElBA,EAAGJ,iBAAiB,QAASqB,GAE7BhB,GAAQ,KACJD,EAAGW,MAAMC,OAASF,EAClBV,EAAGW,MAAMG,UAAYD,EACrBb,EAAGsB,oBAAoB,QAASL"} \ No newline at end of file +{"version":3,"file":"alpine-autosize.min.js","sources":["../builds/cdn.js","../src/index.js"],"sourcesContent":["import autosize from '../src/index.js';\n\ndocument.addEventListener('alpine:init', () => {\n autosize(window.Alpine);\n});\n","function Autosize(Alpine) {\n Alpine.directive('autosize', (el, { modifiers }, { cleanup }) => {\n const attributes = Array.from(el.attributes);\n\n let hasWireModel = false;\n\n for (let { nodeName } of attributes) {\n if (nodeName === 'wire:model' || nodeName.startsWith('wire:model.')) {\n hasWireModel = true;\n break;\n }\n }\n\n if (!el.hasAttribute('wire:ignore') && hasWireModel) {\n el.setAttribute('wire:ignore', '');\n }\n\n const previousResizeValue = el.style.resize;\n el.style.resize = 'none';\n\n const previousMinHeight = el.style.minHeight;\n el.style.minHeight = `${el.getBoundingClientRect().height}px`;\n\n const paddingModifier = modifiers.filter(modifier => modifier.match(/px$/i))[0] || false;\n let padding = 0;\n if (paddingModifier !== false) {\n padding = parseInt(paddingModifier);\n }\n\n const handler = (event) => {\n const element = event.target;\n if (!element.scrollHeight) {\n return;\n }\n element.style.height = '4px';\n element.style.height = `${element.scrollHeight + padding}px`;\n };\n\n handler({ target: el });\n\n el.addEventListener('input', handler);\n\n cleanup(() => {\n el.style.resize = previousResizeValue;\n el.style.minHeight = previousMinHeight;\n el.removeEventListener('input', handler);\n });\n });\n}\n\nexport default Autosize;\n"],"names":["document","addEventListener","window","Alpine","directive","el","modifiers","cleanup","attributes","Array","from","hasWireModel","nodeName","startsWith","hasAttribute","setAttribute","previousResizeValue","style","resize","previousMinHeight","minHeight","getBoundingClientRect","height","paddingModifier","filter","modifier","match","padding","parseInt","handler","event","element","target","scrollHeight","removeEventListener"],"mappings":"2FAEAA,SAASC,iBAAiB,eAAe,KAC5BC,OAAOC,OCFTC,UAAU,YAAY,CAACC,GAAMC,UAAAA,IAAeC,QAAAA,YACzCC,EAAaC,MAAMC,KAAKL,EAAGG,gBAE7BG,GAAe,MAEd,IAAIC,SAAEA,KAAcJ,KACJ,eAAbI,GAA6BA,EAASC,WAAW,eAAgB,CACjEF,GAAe,SAKlBN,EAAGS,aAAa,gBAAkBH,GACnCN,EAAGU,aAAa,cAAe,UAG7BC,EAAsBX,EAAGY,MAAMC,OACrCb,EAAGY,MAAMC,OAAS,aAEZC,EAAoBd,EAAGY,MAAMG,UACnCf,EAAGY,MAAMG,UAAa,GAAEf,EAAGgB,wBAAwBC,iBAE7CC,EAAkBjB,EAAUkB,QAAOC,GAAYA,EAASC,MAAM,UAAS,KAAM,MAC/EC,EAAU,GACU,IAApBJ,IACAI,EAAUC,SAASL,UAGjBM,EAAWC,UACPC,EAAUD,EAAME,OACjBD,EAAQE,eAGbF,EAAQd,MAAMK,OAAS,MACvBS,EAAQd,MAAMK,OAAU,GAAES,EAAQE,aAAeN,QAGrDE,EAAQ,CAAEG,OAAQ3B,IAElBA,EAAGJ,iBAAiB,QAAS4B,GAE7BtB,GAAQ,KACJF,EAAGY,MAAMC,OAASF,EAClBX,EAAGY,MAAMG,UAAYD,EACrBd,EAAG6B,oBAAoB,QAASL"} \ No newline at end of file diff --git a/examples/index.html b/examples/index.html new file mode 100644 index 0000000..8557381 --- /dev/null +++ b/examples/index.html @@ -0,0 +1,20 @@ + + + + + + + Alpine Autosize Examples + + + + + +

Examples

+

Default

+ +

With padding

+ + + diff --git a/src/index.js b/src/index.js index ced48e7..c93ee49 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,5 @@ function Autosize(Alpine) { - Alpine.directive('autosize', (el, {}, { cleanup }) => { - + Alpine.directive('autosize', (el, { modifiers }, { cleanup }) => { const attributes = Array.from(el.attributes); let hasWireModel = false; @@ -20,7 +19,13 @@ function Autosize(Alpine) { el.style.resize = 'none'; const previousMinHeight = el.style.minHeight; - el.style.minHeight = el.getBoundingClientRect().height + 'px'; + el.style.minHeight = `${el.getBoundingClientRect().height}px`; + + const paddingModifier = modifiers.filter(modifier => modifier.match(/px$/i))[0] || false; + let padding = 0; + if (paddingModifier !== false) { + padding = parseInt(paddingModifier); + } const handler = (event) => { const element = event.target; @@ -28,7 +33,7 @@ function Autosize(Alpine) { return; } element.style.height = '4px'; - element.style.height = `${element.scrollHeight}px`; + element.style.height = `${element.scrollHeight + padding}px`; }; handler({ target: el });