inquirer-file-selector
Advanced tools
Comparing version
@@ -1,6 +0,6 @@ | ||
import M from"path";import{createPrompt as G,isBackspaceKey as J,isDownKey as R,isEnterKey as Q,isUpKey as b,makeTheme as V,useKeypress as X,useMemo as w,usePagination as Y,usePrefix as Z,useState as S}from"@inquirer/core";import c from"@inquirer/figures";import a from"chalk";import q from"fs";import D from"path";var P="\x1B[?25l";function K(e){return e.name==="escape"}function x(e){return e.endsWith(D.sep)?e:`${e}${D.sep}`}function z(e){return e.replace(/\x1B\[\d+m/g,"")}function L(e){return e.reduce((r,n)=>Math.max(r,z(n).length),0)}function E(e,r){return Array.isArray(r)?r.some(n=>e.name.endsWith(n)):typeof r=="function"?r(e):!0}function U(e){return q.readdirSync(e,{withFileTypes:!0}).map(r=>({name:r.name,path:D.join(r.parentPath,r.name),isDir:r.isDirectory()})).sort((r,n)=>r.isDir&&!n.isDir?-1:!r.isDir&&n.isDir?1:r.name.localeCompare(n.name))}var ee={icon:{linePrefix:e=>e?`${c.lineUpRight}${c.line.repeat(2)} `:`${c.lineUpDownRight}${c.line.repeat(2)} `},style:{disabled:e=>a.dim(e),active:e=>a.cyan(e),noFilesFound:e=>a.red(e),directory:e=>a.yellow(e),file:e=>a.white(e),currentDir:e=>a.magenta(e),help:e=>a.white(e),key:e=>a.cyan(e)}},ce=G((e,r)=>{let{pageSize:n=10,hideNonMatch:j=!1,disabledLabel:k=" (not allowed)",allowCancel:v=!1,canceledLabel:A="Canceled",noFilesFound:B="No files found"}=e,[C,F]=S("pending"),s=V(ee,e.theme),d=Z({theme:s}),[h,I]=S(M.resolve(process.cwd(),e.path||".")),o=w(()=>{let t=U(h);for(let i of t)i.isDisabled=!i.isDir&&!E(i,e.match||e.extensions);return j?t.filter(i=>!i.isDisabled):t},[h]),f=w(()=>{let t=o.findIndex(l=>!l.isDisabled),i=o.findLastIndex(l=>!l.isDisabled);return t===-1?{first:0,last:0}:{first:t,last:i}},[o]),[m,g]=S(f.first),u=o[m];X((t,i)=>{if(Q(t))u.isDir?(I(u.path),g(f.first)):u.isDisabled||(F("done"),r(u.path));else if(b(t)||R(t)){if(i.clearLine(0),b(t)&&m!==f.first||R(t)&&m!==f.last){let l=b(t)?-1:1,p=m;do p=(p+l+o.length)%o.length;while(o[p].isDisabled);g(p)}}else J(t)?(I(M.resolve(h,"..")),g(f.first)):K(t)&&v&&(F("canceled"),r("canceled"))});let T=Y({items:o,active:m,renderItem({item:t,index:i,isActive:l}){let p=i===o.length-1,$=s.icon.linePrefix(p);if(t.isDisabled)return s.style.disabled(`${$}${t.name}${k}`);let N=t.isDir?s.style.directory:s.style.file,O=l?s.style.active:N,W=t.isDir?`${$}${x(t.name)}`:`${$}${t.name}`;return O(W)},pageSize:n,loop:!1}),y=s.style.message(e.message);if(C==="canceled")return`${d} ${y} ${s.style.error(A)}`;if(C==="done")return`${d} ${y} ${s.style.answer(u.path)}`;let _=s.style.currentDir(x(h)),H=w(()=>{let t=[s.style.help(`Use ${s.style.key(c.arrowUp+c.arrowDown)} to navigate through the list`),s.style.help(`Press ${s.style.key("<backspace>")} to navigate to the parent directory`),s.style.help(`Press ${s.style.key("<enter>")} to select a file or navigate to a directory`)];v&&t.push(s.style.help(`Press ${s.style.key("<esc>")} to cancel the selection`));let i=L(t);return`${c.lineBold.repeat(i)} | ||
import j from"path";import{createPrompt as J,isBackspaceKey as Q,isDownKey as k,isEnterKey as V,isUpKey as I,makeTheme as X,useKeypress as Y,useMemo as w,usePagination as Z,usePrefix as ee,useState as S}from"@inquirer/core";import p from"@inquirer/figures";import a from"chalk";import z from"fs";import x from"path";var K="\x1B[?25l";function L(e){return e.name==="escape"}function b(e){return e.endsWith(x.sep)?e:`${e}${x.sep}`}function G(e){return e.replace(/\x1B\[\d+m/g,"")}function E(e){return e.reduce((r,i)=>Math.max(r,G(i).length),0)}function U(e,r){return Array.isArray(r)?r.some(i=>e.name.endsWith(i)):typeof r=="function"?r(e):!0}function M(e){return z.readdirSync(e,{withFileTypes:!0}).map(r=>({name:r.name,path:x.join(r.parentPath,r.name),isDir:r.isDirectory()}))}function R(e,r){return e.sort((i,c)=>i.isDisabled&&!c.isDisabled?1:!i.isDisabled&&c.isDisabled||i.isDir&&!c.isDir?-1:!i.isDir&&c.isDir?1:i.name.localeCompare(c.name)).filter(i=>!r||!i.isDisabled)}var te={icon:{linePrefix:e=>e?`${p.lineUpRight}${p.line.repeat(2)} `:`${p.lineUpDownRight}${p.line.repeat(2)} `},style:{disabled:e=>a.dim(e),active:e=>a.cyan(e),noFilesFound:e=>a.red(e),directory:e=>a.yellow(e),file:e=>a.white(e),currentDir:e=>a.magenta(e),help:e=>a.white(e),key:e=>a.cyan(e)}},pe=J((e,r)=>{let{pageSize:i=10,hideNonMatch:c=!1,disabledLabel:A=" (not allowed)",allowCancel:v=!1,canceledLabel:B="Canceled",noFilesFound:_="No files found"}=e,[C,F]=S("pending"),s=X(te,e.theme),g=ee({theme:s}),[d,T]=S(j.resolve(process.cwd(),e.path||".")),o=w(()=>{let t=M(d);for(let n of t)n.isDisabled=!n.isDir&&!U(n,e.match||e.extensions);return R(t,c)},[d]),m=w(()=>{let t=o.findIndex(l=>!l.isDisabled),n=o.findLastIndex(l=>!l.isDisabled);return t===-1?{first:0,last:0}:{first:t,last:n}},[o]),[u,y]=S(m.first),h=o[u];Y((t,n)=>{if(V(t))h.isDir?(T(h.path),y(m.first)):h.isDisabled||(F("done"),r(h.path));else if(I(t)||k(t)){if(n.clearLine(0),I(t)&&u!==m.first||k(t)&&u!==m.last){let l=I(t)?-1:1,f=u;do f=(f+l+o.length)%o.length;while(o[f].isDisabled);y(f)}}else Q(t)?(T(j.resolve(d,"..")),y(m.first)):L(t)&&v&&(F("canceled"),r("canceled"))});let P=Z({items:o,active:u,renderItem({item:t,index:n,isActive:l}){let f=n===o.length-1,$=s.icon.linePrefix(f);if(t.isDisabled)return s.style.disabled(`${$}${t.name}${A}`);let O=t.isDir?s.style.directory:s.style.file,W=l?s.style.active:O,q=t.isDir?`${$}${b(t.name)}`:`${$}${t.name}`;return W(q)},pageSize:i,loop:!1}),D=s.style.message(e.message);if(C==="canceled")return`${g} ${D} ${s.style.error(B)}`;if(C==="done")return`${g} ${D} ${s.style.answer(h.path)}`;let H=s.style.currentDir(b(d)),N=w(()=>{let t=[s.style.help(`Use ${s.style.key(p.arrowUp+p.arrowDown)} to navigate through the list`),s.style.help(`Press ${s.style.key("<backspace>")} to navigate to the parent directory`),s.style.help(`Press ${s.style.key("<enter>")} to select a file or navigate to a directory`)];v&&t.push(s.style.help(`Press ${s.style.key("<esc>")} to cancel the selection`));let n=E(t);return`${p.lineBold.repeat(n)} | ||
${t.join(` | ||
`)}`},[]);return`${d} ${y} | ||
${_} | ||
${T.length?T:s.style.noFilesFound(B)} | ||
${H}${P}`});export{ce as default}; | ||
`)}`},[]);return`${g} ${D} | ||
${H} | ||
${P.length?P:s.style.noFilesFound(_)} | ||
${N}${K}`});export{pe as default}; |
@@ -5,3 +5,3 @@ { | ||
"description": "Inquerer file selector prompt.", | ||
"version": "0.3.0", | ||
"version": "0.3.1", | ||
"license": "MIT", | ||
@@ -27,2 +27,3 @@ "type": "module", | ||
"@biomejs/biome": "1.8.3", | ||
"@inquirer/select": "2.4.7", | ||
"@inquirer/type": "1.5.2", | ||
@@ -29,0 +30,0 @@ "@tsconfig/node18": "18.2.4", |
@@ -6,3 +6,3 @@ <h1 align="center"> | ||
<p align="center"> | ||
<b>An file selector prompt implementation for <a href="https://github.com/SBoudrias/Inquirer.js">Inquirer.js</a>.</b> | ||
An file selector prompt implementation for <a href="https://github.com/SBoudrias/Inquirer.js">Inquirer.js</a>. | ||
</p> | ||
@@ -18,6 +18,6 @@ | ||
 | ||
</div> | ||
 | ||
## Installation | ||
@@ -44,13 +44,13 @@ | ||
|--------|------|----------|-------------| | ||
| message | `string` | ✔ | The message to display in the prompt. | | ||
| path | `string` | | The path to the directory where it will be started.<br/> **Default**: `process.cwd()` | | ||
| pageSize | `number` | | The maximum number of items to display in the list.<br/> **Default**: `10` | | ||
| match | `(file: Item) => boolean` | | A function to filter the files.<br/> If not provided, all files will be included. | | ||
| hideNonMatch | `boolean` | | If true, the list will be filtered to only show files that match the extensions.<br/> **Default**: `false` | | ||
| disabledLabel | `string` | | The label to display when a file is disabled.<br/> **Default**: ` (not allowed)` | | ||
| allowCancel | `boolean` | | If true, the prompt will allow the user to cancel the selection.<br/> **Default**: `false` | | ||
| canceledLabel | `string` | | The label to display when the prompt is canceled.<br/> **Default**: `Canceled` | | ||
| noFilesFound | `string` | | The message to display when no files are found.<br/> **Default**: `No files found` | | ||
| theme | [See Theming](#theming) | | The theme to use for the file selector. | | ||
| ~~extensions~~ | ~~`string[]`~~ | | ~~The extensions to filter the files.~~<br/>(Deprecated in favor of `match` option) | | ||
| `message` | `string` | ✔ | The message to display in the prompt. | | ||
| `path` | `string` | | The path to the directory where it will be started.<br/> **Default**: `process.cwd()` | | ||
| `pageSize` | `number` | | The maximum number of items to display in the list.<br/> **Default**: `10` | | ||
| `match` | `(file: Item) => boolean` | | A function to filter the files.<br/> If not provided, all files will be included. | | ||
| `hideNonMatch` | `boolean` | | If true, the list will be filtered to only show files that match the extensions.<br/> **Default**: `false` | | ||
| `disabledLabel` | `string` | | The label to display when a file is disabled.<br/> **Default**: ` (not allowed)` | | ||
| `allowCancel` | `boolean` | | If true, the prompt will allow the user to cancel the selection.<br/> **Default**: `false` | | ||
| `canceledLabel` | `string` | | The label to display when the prompt is canceled.<br/> **Default**: `Canceled` | | ||
| `noFilesFound` | `string` | | The message to display when no files are found.<br/> **Default**: `No files found` | | ||
| `theme` | [See Theming](#theming) | | The theme to use for the file selector. | | ||
| ~~`extensions`~~ | ~~`string[]`~~ | | ~~The extensions to filter the files.~~<br/>(Deprecated in favor of `match` option) | | ||
@@ -115,2 +115,25 @@ ## Theming | ||
## Examples | ||
For examples look in the examples/ directory. You can execute the examples using node. | ||
```shell | ||
cd examples/ | ||
node <example-name>.js | ||
``` | ||
> [!NOTE] | ||
> Before running the examples, make sure you have installed the dependencies with `npm install` and compiled the project with `npm run build`. | ||
## Contributing | ||
1. Fork it! | ||
2. Create your feature branch: `git checkout -b my-new-feature` | ||
3. Commit your changes: `git commit -am "feat: my new feature"` | ||
4. Push to the branch: `git push origin my-new-feature` | ||
5. Submit a pull request :D | ||
> [!NOTE] | ||
> The commit message should follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. | ||
## Copyright & License | ||
@@ -117,0 +140,0 @@ |
13649
6.62%146
0.69%139
19.83%6
20%