Skip to content

Base Utilities

@jennifersoft/apm-componentsbase 모듈 중 개별 문서가 없는 보조 컴포넌트 모음입니다. 이 문서는 @jennifersoft/apm-components@1.4.1 기준으로 정리했습니다.

같은 모듈의 다른 컴포넌트는 아래 문서를 참고하세요.

TooltipBalloon

말풍선 형태의 툴팁 컨테이너입니다. 위치 계산은 하지 않고 모양과 방향만 담당합니다.

Prop타입기본값설명
positionTooltipPosition'center-right'꼬리 방향
cursorNonebooleanfalse커서 앵커(삼각형) 숨김
backgroundColorstring'rgba(0, 0, 0, 0.75)'배경색
widthnumberundefined고정 폭. 미지정 시 콘텐츠 폭
typescript
type TooltipPosition =
    | 'top-left' | 'top-center' | 'top-right'
    | 'bottom-left' | 'bottom-center' | 'bottom-right'
    | 'center-right' | 'center-left';
vue
<script setup lang="ts">
import { TooltipBalloon } from '@jennifersoft/apm-components';
</script>

<template>
    <TooltipBalloon position="top-center" :width="200">
        응답시간이 임계치를 초과했습니다.
    </TooltipBalloon>
</template>

PopoverBalloon과 달리 기본 배경이 반투명 검정입니다. 밝은 배경 툴팁이 필요하면 backgroundColor에 테마 토큰을 넘기세요.

BoldTextByIndex

문자열에서 지정한 인덱스의 글자만 굵게 표시합니다. 검색어 매칭 하이라이트에 사용합니다.

Prop타입기본값설명
contentstring— (필수)원문
indicesnumber[][]굵게 표시할 문자 인덱스
tooltipWhenEllipsisbooleanfalse말줄임 발생 시에만 툴팁 표시

인덱스는 문자 단위입니다. 부분 문자열이 아니라 흩어진 글자를 강조할 수 있어 퍼지 검색(fuzzy match) 결과 표시에 적합합니다.

vue
<script setup lang="ts">
import { BoldTextByIndex } from '@jennifersoft/apm-components';
// "OrderService" 에서 O, r, d, S 를 강조
</script>

<template>
    <BoldTextByIndex
        content="OrderService"
        :indices="[0, 1, 2, 5]"
        tooltip-when-ellipsis
    />
</template>

tooltipWhenEllipsisuseElementBounding으로 폭 변화를 관찰해 scrollWidth > clientWidth일 때만 툴팁을 노출합니다. 잘리지 않은 텍스트에는 툴팁이 뜨지 않습니다.

NOTE

content는 정규식 이스케이프 후 문자 단위로 분해되어 <span>으로 감싸집니다. HTML을 넘겨 마크업을 주입할 수는 없습니다.

아래 데모는 검색어 글자를 순서대로 훑어 매칭 위치를 만드는 퍼지 매칭입니다. ose처럼 떨어진 글자를 입력해도 각 위치가 강조됩니다.

HorizontalOverflowFade

가로로 넘치는 콘텐츠의 양끝을 페이드 처리해 스크롤 가능함을 알립니다.

Prop타입기본값설명
ariaLabelstringundefined스크롤 영역 접근성 이름
fadeWidthnumber61좌우 페이드 너비
fadeColorstring'var(--gray-50)'페이드가 수렴하는 색
hideScrollbarbooleanfalse스크롤바를 감추고 페이드로만 안내
wheelHorizontalbooleanfalse세로 휠을 가로 이동으로 변환
vue
<script setup lang="ts">
import { HorizontalOverflowFade } from '@jennifersoft/apm-components';
</script>

<template>
    <HorizontalOverflowFade
        aria-label="추천 질문"
        :fade-width="40"
        fade-color="var(--surface-50)"
        hide-scrollbar
        wheel-horizontal
    >
        <button v-for="q in questions" :key="q.id">{{ q.text }}</button>
    </HorizontalOverflowFade>
</template>

IMPORTANT

fadeColor컨텐츠 표면색과 반드시 맞춰야 합니다. 기본값 var(--gray-50)과 실제 배경이 다르면 양끝에 색 띠가 보입니다.

wheelHorizontal은 트랙패드가 없는 일반 마우스 사용자를 위한 옵션입니다.

CloudBackground

흐릿한 원들이 천천히 떠다니는 장식 배경입니다. AI 채팅 빈 화면 등에 사용합니다.

Prop타입기본값설명
blobsreadonly CloudBackgroundBlob[]— (필수)그릴 원 목록
blurnumber70원을 뭉개는 정도
opacitynumber0.25전체 불투명도
typescript
interface CloudBackgroundBlob {
    /** 원의 **중심** 세로 위치 (CSS 길이) */
    top: string;
    /** 원의 **중심** 가로 위치 (CSS 길이) */
    left: string;
    /** 가로 지름. 백분율은 컨테이너 너비 기준 */
    size: string;
    /** 세로 지름. 생략하면 size와 같아 정원 */
    height?: string;
    /** 디자인 토큰 변수를 그대로 전달 */
    color: string;
    /** 떠다니는 궤도. 생략 시 나열 순서대로 1·2·3 순환 */
    drift?: 1 | 2 | 3;
    /** 음수를 주면 애니메이션 중간부터 시작해 원끼리 어긋난다 */
    delaySeconds?: number;
    durationSeconds?: number;
}
vue
<script setup lang="ts">
import { CloudBackground } from '@jennifersoft/apm-components';

const blobs = [
    { top: '20%', left: '30%', size: '40%', color: 'var(--blue-300)' },
    { top: '60%', left: '70%', size: '35%', color: 'var(--purple-300)', delaySeconds: -4 },
    { top: '40%', left: '55%', size: '30%', color: 'var(--cyan-300)', delaySeconds: -8 },
];
</script>

<template>
    <div style="position: relative">
        <CloudBackground :blobs="blobs" :blur="90" :opacity="0.2" />
        <div style="position: relative">실제 콘텐츠</div>
    </div>
</template>

top / left가 원의 모서리가 아니라 중심임에 주의하세요. 컨테이너가 좁을수록 blur를 줄여야 원 형태가 남습니다.

PlainTextViewer

로그·상태 원문 같은 대용량 플레인 텍스트를 보여주는 뷰어입니다.

Prop타입기본값설명
textstring— (필수)실제 원문
ariaLabelstring— (필수)스크롤 영역·코드 블록 공용 접근성 이름
contentTestIdstring— (필수)호출부의 기존 E2E 식별자 보존용
viewportTestIdstring— (필수)세로 스크롤 영역 식별자
fontSizenumber14PLAIN_TEXT_VIEWER_FONT_SIZE_PX
lineHeightnumber20PLAIN_TEXT_VIEWER_LINE_HEIGHT_PX
backgroundColorstring'var(--surface-50)'뷰포트와 가로 페이드가 공유
emptyTextstringundefined없으면 빈 영역 유지
disableScrollAnchoringbooleanfalse호출부가 직접 위치를 보정할 때
virtualizedbooleantrue화면 주변 줄만 렌더
typescript
emit('scroll', event: Event)
vue
<script setup lang="ts">
import { PlainTextViewer } from '@jennifersoft/apm-components';
</script>

<template>
    <PlainTextViewer
        :text="logText"
        aria-label="애플리케이션 로그"
        content-test-id="log-content"
        viewport-test-id="log-viewport"
        empty-text="표시할 로그가 없습니다."
        @scroll="onScroll"
    />
</template>

disableScrollAnchoring

로그 앞쪽에 내용을 prepend할 때, 브라우저의 스크롤 앵커링과 호출부의 위치 보정이 충돌해 화면이 튈 수 있습니다. 호출부가 직접 스크롤 위치를 잡는다면 이 옵션을 켜세요.

virtualized

기본값 true로 화면 주변 줄만 렌더합니다. 전체 텍스트를 DOM에 올려야 하는 경우(예: 브라우저 찾기 기능으로 전체 검색)에만 false로 두세요.

주의사항

  • CloudBackground는 장식 요소입니다. 콘텐츠를 position: relative로 위에 올려야 가려지지 않습니다.
  • HorizontalOverflowFadefadeColor 불일치는 가장 흔한 시각 버그입니다.
  • PlainTextViewercontentTestId / viewportTestId는 필수입니다. 기존 E2E 셀렉터를 유지하기 위한 설계입니다.