CLI GUI를 CSS로 OSS 해 보았습니다.

16239 단어 CSSAngularcli
조금 무슨 말을 하는지 모르겠다. 라고 말할 것이므로 보충하면, CLI 바람의 외형의 GUI를 CSS로 만들어 보았으므로 OSS로서 공개해 사용할 수 있도록 해 보았다, 가 됩니다. 바퀴의 재발명적인 놀이.

아티팩트



UI : htps : // cぃ-구이. 푹 푹 빠져서 p. 이 m
리포지토리 : htps : // 기주 b. 코 m / 쿄야바바 / c ぃぐ



할 수 있는 일



기본적인 기능으로서 이하만 실장해 보았다.
  • clear : 로그 지우기
  • help : 명령 목록 출력
  • version : 앱 버전 출력

  • 그것만으로는 지루하지 않기 때문에, 인수를 취하는 샘플로서 이하를 추가했다.
  • cats : 고양이 데이터베이스에서 품종을 나열하고 출력 (품종 국가 필터 및 이름 정렬)

  • 기술 사양



    터미널 스타일의 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.cliValuethis.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 += `
    
    &nbsp;&nbsp;<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 += `
    
    &nbsp;&nbsp;<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;
    }
    

    이 앱의 사용법



    솔직히 언제나 되지 않지만, 언젠가 사용하고 싶어지는 날이 올 것이다. 어쩌면.

    좋은 웹페이지 즐겨찾기