お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
投稿日:
言語::CSS

レスポンシブにdisplayを切り替えるCSSを書いててハマったので備忘録。

今回は例として画面幅に応じて表示する項目数を変動させるCSSを書いてみます。media queryとnth-childを使って表示数を切り替えていく感じです。

イメージとしてはこんな感じ。

SP View PC View
SPビュー
PCビュー

上手くいかないケース

このコードでは画面幅を変えても項目数に変化がありません。理由としてはnth-child(n + 4)display: none;が900pxでも保持されたままだからです。試しにdisplay: none;font-weight: bold;とかに変えてみると良くわかります。

デモページ

.example li:nth-child(n + 4) {
    display: none;
}

@media screen and (min-width: 900px) {
    .example li:nth-child(n + 6) {
        display: none;
    }
}

上手くいくケース

以下のコードではnth-childで非表示にしている部分を900pxの時に表示指定にすることで3項目表示と5項目表示が切り替わるようになっています。そりゃ指定してなければ表示されないよねっていう単純な話ですね…。

デモページ

.example li:nth-child(n + 4) {
    display: none;
}

@media screen and (min-width: 900px) {
    /** 明示的に表示させる */
    .example li:nth-child(n + 4) {
        display: list-item;
    }

    .example li:nth-child(n + 6) {
        display: none;
    }
}
投稿日:
OS::Linux::コマンド

unified形式のパッチファイルの当て方
git diff -u > diff.patchとかしたやつを当てることを想定している

サンプルコード

patch -p1 < diff.patch

解説

  • -p<n><n>はpatchファイルのパス階層をストリップする役割を持っている
  • diffファイルに記載されているファイルパスは以下の形式のためa/, b/が除去されてパッチが当たる仕組み
--- a/path/to/file
+++ b/path/to/file
投稿日:
ソフトウェア::WSL

ユーザー名を変更したいときに使えるが、ほぼ力技。きっともっと楽な方法があるはず。

確認環境

Env Ver
WSL Distri Ubuntu 20.04.4 LTS

手順

WSL内でユーザーを作る

sudo useradd new_user
sudo cp -R /home/old_user /home/new_user
# 細かい権限はどうにかするかフィルタして旧ユーザーのみ変える
chown -R new_user:new_user new_user/
# 新ユーザーのPWを設定
sudo passwd new_user
# sudo出来るようにする
sudo gpasswd -a new_user sudo

Ubuntuのデフォルトユーザーを変更する

<ディストリ名> config --default-user new_user

GitHubの無料アカウントを2つ持つことは規約で禁じられているため、例え個人用と業務用であっても2つは持てないという話がまことしやかにありますが、実は分けられるという話です。

規約違反の根拠

GitHubは利用規約でアカウントの要件として次のことを掲げており、そのまま読むと規約違反になります。

1 人の個人または 1 つの法人が複数の無料「アカウント」を保持することはできません (コンピュータアカウントも制御することを選択した場合、それは問題ありませんが、それはコンピュータの実行にのみ使用できます)

規約違反であるという説

次の記事では規約違反であるとされており、GitHub内部の人物からもその確認を取ったとされています。

規約違反ではないという説

次の記事では「会社側で有償のオーガニゼーションを契約し、仕事用アカウントを所属させていれば」規約違反でないとされています。

問い合わせてみた結果

個人的に納得できなかったのでギットハブ・ジャパン合同会社に問い合わせてみました。

結論としては公私混同を避けるため個人用と業務用で無料アカウントを2つ持つことは許容されているとのことでした。この規約の存在理由としては主にOSSでの荒らしの防止策のためということでしたので、会社側で有償のオーガニゼーションを契約するとかも特に不要という内容です。

プライベートのGitHubアカウントに業務の通知が貯まるのは嫌なので助かりました。理由としては通知が邪魔くさいことと、やっぱりプライベートと業務は分けときたいよねという思いが大きいです。

例えば兼用しているとSSOログインしていない状態でもGitHubサイト右上の通知アイコンは通知ありの状態になりますし、プライベートではSSOログイン出来ないため通知は消化できないですし、仮に出来たとしても業務時間外に消化したくないです。

またアカウントを業務とプライベートでごっちゃにしてると権利周りが面倒くさくなるため、それを避ける意味合いもあります。これは場合によっては功績として使えたりなどで、利点になることもありますが、個人的にそこはいいかなという感じです。

条件分岐でコンポーネントの出し分けをしている時に、意図したとおりにコンポーネントが出ているかどうかをテストする方法。

UIロジックのリグレッションテストで使え、分岐結果の出力を見てるだけなのでテストとして壊れづらく、運用しやすいのではないかと考えている。

テスト対象の実装コード

JSXが分岐するコード

type BaseProps = {
  id: string;
};

type SwitchExampleProps = BaseProps & {
  display: 'Foo' | 'Bar';
};

export const Foo = (props: BaseProps) => {
  return (
    <div id={props.id}>
      <p>Foo</p>
    </div>
  );
};

export const Bar = (props: BaseProps) => {
  return (
    <div id={props.id}>
      <p>Bar</p>
    </div>
  );
};

export const SwitchExample = (props: SwitchExampleProps) => {
  if (props.display === 'Foo') {
    return <Foo id={props.id} />;
  } else {
    return <Bar id={props.id} />;
  }
};

2025年版のテストコード

TestRendererが非推奨になったため、その対応。

確認環境

Env Ver
@swc/core 1.11.13
@swc/jest 0.2.37
jest 29.7.0
next 15.2.4
react 18.3.1
react-dom 18.3.1
react-test-renderer 未使用
typescript 5.8.2

テストコード

コンポーネント呼び出しと、コンポーネントの中身べた書きの二つを書いて、その二つのHTMLが等価であるかどうかを見ている。

本稿ではコールバック関数の中身までは見ていないが、そちらはロジックテストでjest.fn()を差し込んで確認すればよいと思う。

import { render } from '@testing-library/react';
import { Bar, Foo, SwitchExample } from './SwitchExample';
import { JSX } from 'react';

type TestCase = {
  name: string;
  param: Parameters<typeof SwitchExample>[0];
  actual: JSX.Element;
};

describe('SwitchExample', () => {
  const testCaseItems: TestCase[] = [
    {
      name: 'Foo',
      param: {
        id: 'hoge',
        display: 'Foo'
      },
      actual: <Foo id={'hoge'} />
    },
    {
      name: 'Bar',
      param: {
        id: 'piyo',
        display: 'Bar'
      },
      actual: <Bar id={'piyo'} />
    }
  ];

  testCaseItems.forEach((item) => {
    it(`switched condition ${item.name}`, () => {
      const { container: result } = render(
        <SwitchExample id={item.param.id} display={item.param.display} />
      );
      const { container: actual } = render(item.actual);

      expect(result.innerHTML).toStrictEqual(actual.innerHTML);
    });
  });
});

2022年版のテストコード

確認環境

Env Ver
@swc/core 1.2.133
@swc/jest 0.2.17
jest 27.4.7
next 12.0.8
react 17.0.2
react-dom 17.0.2
react-test-renderer 17.0.2
typescript 4.5.4

テストコード

react-testing-libraryの.toHaveAttribute().toHaveDisplayValue()を書き連ねるより圧倒的に楽で保守性も良いと思う

import TestRenderer from 'react-test-renderer';
import { Bar, Foo, SwitchExample } from './SwitchExample';

type TestCase = {
  name: string;
  param: Parameters<typeof SwitchExample>[0];
  actual: JSX.Element;
};

describe('SwitchExample', () => {
  const testCaseItems: TestCase[] = [
    {
      name: 'Foo',
      param: {
        id: 'hoge',
        display: 'Foo',
      },
      actual: <Foo id={'hoge'} />,
    },
    {
      name: 'Bar',
      param: {
        id: 'piyo',
        display: 'Bar',
      },
      actual: <Bar id={'piyo'} />,
    },
  ];

  testCaseItems.forEach((item) => {
    // eslint-disable-next-line jest/valid-title
    it(`switched condition ${item.name}`, () => {
      const result = TestRenderer.create(
        <SwitchExample id={item.param.id} display={item.param.display} />
      );
      const actual = TestRenderer.create(<>{item.actual}</>);

      expect(result.toJSON()).toStrictEqual(actual.toJSON());
    });
  });
});

参考記事