CLI GUI를 CSS로 OSS 해 보았습니다.
아티팩트
UI : htps : // cぃ-구이. 푹 푹 빠져서 p. 이 m
리포지토리 : htps : // 기주 b. 코 m / 쿄야바바 / c ぃぐ
할 수 있는 일
기본적인 기능으로서 이하만 실장해 보았다.
그것만으로는 지루하지 않기 때문에, 인수를 취하는 샘플로서 이하를 추가했다.
기술 사양
터미널 스타일의 UI를 만들기 위해 Angular을 사용하고 싶었기 때문에 Angular CLI에서 개발했습니다.
HTML
HTML은 간단하고, 아래만. 그 후는 컨트롤러 측에서 제어한다.
<div id="jsi-cliLog" class="g-cli__wrapper" (click)="focus()">
<pre [innerHTML]="cliLog"></pre>
<form (submit)="addLog()" novalidate>
<span>$</span>
<input id="jsi-cliValue" type="text" name="cliValue" [(ngModel)]="cliValue" />
</form>
</div>
CSS
터미널풍의 UI는 이하의 CSS로 재현했다. 이하에 기재한 것은 대략적인 부분만으로 세세한 조정의 부분은 할애. 컨트롤러 측에서 생성한 HTML에 스타일을 맞추기 위해 Angular의
/deep/
공간을 사용하고 있다. (전체는 여기부터):host /deep/ .g-cli__wrapper {
overflow: auto;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #000000;
font-family: monospace;
color: #FFFFFF;
> form {
> input {
width: calc(100vw - 1em * 3 - 0.5em);
border: 0;
outline: 0;
background-color: inherit;
color: inherit;
}
}
}
<input>에 대한 focus
터미널 라이크에 어디를 클릭해도 입력을 시작할 수 있도록,
<div>
전체의 어디를 클릭해도 <input>
에 focus 할 수 있도록(듯이) 했다. 로그의 문자열을 드래그하여 선택하는 경우에는 focus 하고 싶지 않으므로 window.getSelection()
를 보고 분기.public focus(): void {
if (window.getSelection().toString()) return;
document.getElementById('jsi-cliValue').focus();
}
입력값 출력
<input>
필드에 Enter 하면, 컨트롤러의 모델 this.cliValue
를 this.cliLog
에 추가해, 입력치를 판정해 명령이 되어 있으면 처리한다. 그리고는, 나중에 위키와 아래키로 과거의 입력치를 호출하고 싶기 때문에 this.history
에 등록해, 모델을 클리어 한다.public addLog(): void {
this.cliLog += `
<span>-(cli-gui)</span> : ${this.generateDateString()}
<span>$</span> ${this.cliValue}`;
this.analyzeInput(this.cliValue);
this.history.push(this.cliValue);
this.lastAttachedHistoryNumber = null;
this.initializeValue();
}
명령 입력 값 결정 및 처리
입력한 값을 공백별로 분할하여 배열로 하고
cli-gui
private analyzeInput(value: string): void {
const commands = value.trim().split(' ').filter(val => val !== '');
if (commands.length === 0) return;
if (commands[0] === 'cli-gui' && commands.length > 0) {
this.do(commands);
} else {
this.cliLog += `
<em>command ${commands[0]} is not found.</em>`;
}
}
이런 느낌. 한 번에 여러 명령이 입력되는 것은 고려하지 않기 때문에
this.do()
만 보았습니다.private do(commands: Array<string>): void {
switch (commands[1]) {
case 'clear' {
...
} break;
case 'help': {
...
} break;
case 'cats': {
...
명령 인수를보고 처리를 분기
commands[1]
에 대해서는 인수를 취해 처리를 분기하고 싶기 때문에, 조금 구현을 추가해, 커멘드의 인수와 그 인수의 다음에 입력되고 있는 값을 보도록(듯이) 했다.case 'cats':
case '-l': {
let targetCats = this.cats;
for (let i = 2; i < commands.length - 2; i++) {
switch (commands[i]) {
case '--country':
if (!commands[i + 1]) {
this.cliLog += `
<em>'country' filter must be supplied an argument.</em>`;
return;
}
targetCats = targetCats.filter(cat => cat.country.toLowerCase() === commands[i + 1].toLowerCase());
break;
case ...
위 스크롤 방식으로 하기 위한 강제 스크롤
CLI의 경우 로그가 쌓여 있어도 항상 맨 아래에 입력 필드가 표시되어 있지 않으면 안된다. 또한, 사용자가 과거의 로그를 쓰러뜨리려고 위로 스크롤할 수도 있다(그러므로, CSS의 position 속성으로 강제적으로 화면 하단에 입력 필드를 고정할 수 없다).
그래서 사용자가 문자열을 드래그하지 않는 한 항상 화면을 맨 아래로 스크롤하기로 결정했습니다. 다음 메서드는 항상 템플릿에서 호출됩니다.
public fetchingForScrolling(): void {
if (window.getSelection().toString()) return;
document.getElementById('jsi-cliLog').scrollTop = Number.MAX_SAFE_INTEGER;
}
이 앱의 사용법
솔직히 언제나 되지 않지만, 언젠가 사용하고 싶어지는 날이 올 것이다. 어쩌면.
Reference
이 문제에 관하여(CLI GUI를 CSS로 OSS 해 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kyoyababa/items/4f7d39c8e87d4aa3cd8b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)