Skip to content

Base Utilities ​

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

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

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>

tooltipWhenEllipsis는 useElementBounding으로 폭 변화를 관찰해 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로 위에 올려야 가려지지 않습니다.
  • HorizontalOverflowFade의 fadeColor 불일치는 가장 흔한 시각 버그입니다.
  • PlainTextViewer의 contentTestId / viewportTestId는 필수입니다. 기존 E2E 셀렉터를 유지하기 위한 설계입니다.