Open25

JavaScript,TypeScript,CSS等のメモ

scirexsscirexs

SVG作成

手順

  1. Vecteezy で作成
  2. SVGOMG で最適化
    • Style to attributesPrefer viewBox to width/heightをon
  3. Copy as textアイコンでソースコピー&貼り付け

調整

  • 大きさ調整する場合
    • svgタグ内のwidth,height属性を変更、調整する
  • 色変更する場合
    • pathタグ内のfill属性を変更、調整する

Font to SVG

scirexsscirexs

クラステンプレ

class FooClass {
  static FIELD = 0;
  field1 = 0;   // public
  #field2 = 0;  // private

  constructor(arg1, arg2) {
    this.field1 = arg1;
    this.#field2 = arg2;
  }

  method1() {}

  get field1() {
    return this.field1;
  }
  set field1(arg) {
    this.field1 = arg;
  }

  static classMethod1() {}
}
scirexsscirexs

CSSをJSから操作

// CSSカスタムプロパティ操作
currentStyle = getComputedStyle(element).getPropertyValue("--foo");
element.style.setProperty("--foo","bar");

// CSS静的指定操作
currentStyle = element.style.[property];
element.style.[property] = "value";

// CSS動的指定操作
currentStyle = element.getAttribute("style");
element.setAttribute("style", "property:value;");

scirexsscirexs

TypeScriptオブジェクトの型色々

  • 基本の型定義

    type CustomObject1 = { foo: string, bar: number, baz?: boolean };
    //----------
    const obj1 = { foo: "foo", bar: 1 };
    
  • 全ての定義プロパティが必須

    type CustomObject2 = { foo: string, bar: number, baz: boolean };
    type CustomObject3 = Required<CustomObject1>;
    //----------
    const obj2 = { foo: "foo", bar: 1, baz: true };
    const obj3 = { foo: "foo", bar: 1, baz: true };
    
  • 定義プロパティが必須で他プロパティを任意に持つ

    interface CustomObject4 { foo: string, bar: number }
    type CustomObject11 = { foo: string, bar: number, [key: string]: unknown };
    //----------
    const obj4 = { foo: "foo", bar: 1, qux: 3n };
    const obj11 = { foo: "foo", bar: 1, qux: 3n };
    
  • 定義プロパティの任意のプロパティを持つ

    type CustomObject5 = Partial<CustomObject1>;
    //----------
    const obj5_1 = { bar: 1 };
    const obj5_2 = {};
    
  • 定義プロパティの任意のプロパティを1つ以上持つ

    type AtLeastOne<T, K = keyof T> = K extends keyof T ? Required<Pick<T, K>> : never;
    type CustomObject6 = AtLeastOne<CustomObject1>;
    //----------
    const obj6_1 = { foo: "foo" };
    // const obj6_2 = {};
    
  • ハッシュマップライクな定義

    type MapKey = string | number | symbol;
    type MapLike<K extends MapKey, V> = {[key in K]: V};
    type CustomObject7 = Record<string, number>;
    type CustomObject8 = MapLike<string, number>;
    //----------
    const obj7 = {};
    obj7["foo"] = 0;
    obj7["bar"] = 1;
    const obj8 = {};
    obj7["foo"] = 2;
    obj7["bar"] = 3;
    
  • 読み取り専用の型定義

    type CustomObject9 = Readonly<CustomObject1>;
    //----------
    const obj9 = { foo: "foo", bar: 1 };  // Object.freeze(obj9); is preferred
    
  • ネストオブジェクトへの再帰的Partial適用

    type DeepPartial<T> = {
      [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
    };
    type PartialNest = DeepPartial<NestObject>;
    
scirexsscirexs

TailwindCSSでカスタムfont-faceを使用する方法

/src/app.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  @font-face {
    font-family: "NotoSansJP";
    src: url("/font/nsjp-400.woff2") format("woff2");  /* /static/font/nsjp-400.woff2 */
    font-weight: 400;
    font-style: normal;
    font-display: swap;
  }
}
scirexsscirexs

簡易タグID生成スクリプト (Z,zは使用しない)
組み合わせ: 50x60x60x60=10,800,000通り

function getRandomAlphanumeric(nodigit: boolean) {
  const ALPHABETIC = [[65, 25],[97, 25]];  // A:65 [A-Y], a:97 [a-y]
  const ALPHANUMERIC = [...ALPHABETIC, [48, 10]];  // 0:48 [0-9]
  const baseAry = nodigit ? ALPHABETIC : ALPHANUMERIC;
  const [base, rate] = baseAry[Math.trunc(Math.random() * baseAry.length)];
  return Math.trunc(base + (Math.random() * rate));
}

function getTagId(len: number) {
  const ary = Array(len).fill(null).map((_,i) => getRandomAlphanumeric(!Boolean(i)));
  return String.fromCharCode(...ary);
}

console.log(getTagId(4));
scirexsscirexs

Vitest expect api

expect(x).
not. // !

// bool,nullable
toBeTruthy,toBeFalsy // Boolean(x) is true/false
toBeUndefined,toBeDefined // x === void 0 or not
toBeNull // x === null
toBeNaN // Number.isNaN(x)

// primitive
toBe // x === arg
toBeTypeOf // typeof x === arg
toBeInstanceOf // x instanceof arg
toBeOneOf // x is one of allowed ary values as arg

// number
toBeGreaterThan,toBeGreaterThanOrEqual,toBeLessThan,toBeLessThanOrEqual // x>,x>=,x<,x<=
// floating point number
toBeCloseTo // x === arg
// string
toMatch // x.test(/arg/)
toContain // x.includes()

// object
toHaveLength // x.length === arg
toHaveProperty // ObjecthasOwn(x, arg) or x.arg1 === arg2
toEqual // x is same structure(properties) with arg
toStrictEqual // x is same structure(properties) and values with arg

// array
toContain // x.includes()

// error
toThrowError // if error or not
scirexsscirexs

Visually Hidden

.visually-hidden {
  position: absolute;
  height: 1px;
  width: 1px;
  margin: -1px;
  padding: 0;
  clip: rect(0 0 0 0);
  border: 0;
  overflow: hidden;
  white-space: nowrap;
}
scirexsscirexs

画面端中央

.top-center {
  position: fixed;
  top: 0;
  left: 50%;
  translate: -50%;
}
.left-center {
  position: fixed;
  top: 50%;
  left: 0;
  translate: 0 -50%;
}
.right-center {
  position: fixed;
  top: 50%;
  right: 0;
  translate: 0 -50%;
}
.bottom-center {
  position: fixed;
  left: 50%;
  bottom: 0;
  translate: -50%;
}
scirexsscirexs

Tailwindで局所カスタムプロパティ宣言

<div class="[--hi:#DC143C]">
  <div class="text-(--hi)">hello</div>
</div>