lifecarelog
프론트엔드

minimumReleaseAge 7일이 왜 10080일까, 분 단위 설정값을 화면에 보여준 이야기

pnpm-workspace.yaml의 minimumReleaseAge는 분 단위라 7일이 10080입니다. 이 숫자를 사람이 읽는 값으로 바꿔주는 입력 컴포넌트를 직접 만들어 봤어요.

6분 읽기

설정 파일에 minimumReleaseAge: 10080이라고 적혀 있으면, 열어본 사람 열에 아홉은 이게 며칠인지 암산부터 합니다. pnpm 워크스페이스 설정에서 이 값의 단위는 분이라 7일은 7 × 24 × 60 = 10080이 돼요. 저도 처음엔 초인 줄 알고 한참 헤맸습니다.

숫자 자체는 문서 한 줄이면 끝나는 이야기인데, 제가 관심 있었던 건 다른 쪽이었어요. 내부 단위와 사람이 읽는 단위가 다를 때 입력 화면을 어떻게 만들어야 하나. 사내 설정 화면을 만들다 보면 이런 필드가 계속 나옵니다. 캐시 TTL(초), 세션 만료(분), 보존 기간(일). 그래서 이 값으로 작은 입력 컴포넌트를 직접 만들어 봤습니다.

표시 단위와 저장 단위를 분리하기

핵심은 하나예요. 저장은 항상 분, 표시는 사용자가 고른 단위. 상태를 두 개 들고 있으면 반드시 어긋나니까 저장값 하나만 상태로 두고 표시값은 계산해서 뽑았어요.

const UNITS = { 분: 1, 시간: 60, 일: 1440 } as const;
 
function ReleaseAgeInput({ minutes, onChange }) {
  const [unit, setUnit] = useState<keyof typeof UNITS>('일');
  const shown = minutes / UNITS[unit];
 
  return (
    <div>
      <input
        type="number"
        min={0}
        value={Number.isInteger(shown) ? shown : shown.toFixed(2)}
        onChange={(e) => onChange(Number(e.target.value) * UNITS[unit])}
      />
      <select value={unit} onChange={(e) => setUnit(e.target.value)}>
        {Object.keys(UNITS).map((u) => <option key={u}>{u}</option>)}
      </select>
      <p>저장값: {minutes}분</p>
    </div>
  );
}

돌려 보니 일 기준으로 7을 넣으면 아래에 10080분이 바로 찍힙니다. 이 한 줄이 생각보다 중요했어요. 설정 파일을 직접 열어볼 사람에게는 파일에 들어갈 진짜 값을 미리 보여줘야 나중에 혼란이 없거든요.

사용자 입력(7)단위 배수(1440)저장값(10080분)YAML 파일

나눠떨어지지 않는 값 처리

일 단위로 보다가 90분짜리 값을 만나면 0.0625일이 됩니다. 테스트해 보면 이 지점에서 폼이 가장 지저분해져요. 세 가지 중에 골라야 합니다.

  • 소수점을 그대로 보여준다 (정직하지만 읽기 나쁨)
  • 나눠떨어지는 단위로 자동 전환한다
  • 반올림한다 (값이 조용히 바뀌니 탈락)

저는 두 번째를 택했어요. 초기 단위를 고정하지 않고, 저장값을 나눠떨어지게 하는 가장 큰 단위를 골라주는 함수 하나면 끝납니다.

const pickUnit = (m: number) =>
  m % 1440 === 0 ? '일' : m % 60 === 0 ? '시간' : '분';

10080은 일, 90은 시간, 7은 분으로 열립니다. 코드 두 줄로 소수점이 전부 사라졌어요.

접근성에서 놓치기 쉬운 것

숫자 입력과 단위 선택이 나란히 있으면 스크린 리더로는 두 필드가 따로 읽힙니다. aria-describedby로 아래 저장값 문구를 묶어주면 "7, 일, 저장값 10080분"까지 한 번에 읽혀요. <label>도 숫자 쪽에만 달지 말고 두 컨트롤을 <fieldset>으로 감싸는 편이 낫습니다. 이건 단축할 부분이 아니에요.

  • 저장은 분 고정
  • 표시 단위는 파생
  • 실제 저장값 항상 노출
  • 단위 자동 선택

만들고 나서 남은 생각

컴포넌트 자체는 40줄이 안 되고 작업은 20분쯤 걸렸습니다. 그런데 이 패턴을 만들어 두니 다른 설정 화면에서도 계속 재사용하게 되더군요. 라이브러리를 새로 깔 일도 없었고요. <input type="number">와 <select>만으로 충분했습니다.

계산을 눈앞에서 보여주는 UI가 왜 중요한지는 플랜씨(plan-c)를 만들면서 더 확실해졌어요. 무료 금융계산기라 대출이자나 연봉 실수령을 다루는데, 결과 숫자만 던지면 사람들이 믿지 않습니다. 중간 계산 과정을 같이 보여줬을 때 비로소 "아 그래서 이 값이구나" 하고 받아들여요. 10080이라는 숫자도 똑같습니다. 그냥 숫자면 암호고, 7일 × 1440이라고 옆에 적어주면 설명이 됩니다.

설정값이 사람 친화적이지 않은 건 어쩔 수 없는 경우가 많아요. 그럴 때 프론트엔드가 할 일은 단위를 바꾸는 게 아니라, 바뀌는 과정을 보이게 만드는 것이더군요. 🙂

#pnpm#프론트엔드#폼UX

라이프케어로그 서비스가 궁금하신가요?

AI 기반 건강·일정·재활 관리 앱을 직접 써보세요.

서비스 살펴보기

관련 글

댓글

아직 댓글이 없어요. 첫 댓글을 남겨주세요.