npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@uniai-fe/uds-templates

v0.4.25

Published

UNIAI Design System; UI Templates Package

Readme

@uniai-fe/uds-templates

@uniai-fe/uds-foundation 토큰과 @uniai-fe/uds-primitives 기초 컴포넌트를 조합해, 서비스 앱에서 자주 반복되는 화면/플로우 템플릿을 제공하는 패키지입니다.

Next.js 서비스에서 primitives와 동일한 방식으로 Raw TypeScript 형태로 소비되며, pnpm transpilePackages 설정을 통해 빌드 파이프라인에 포함됩니다.

Peer Dependencies

  • @uniai-fe/uds-foundation@^0.0.1 (CSS 토큰 + reset)
  • @uniai-fe/uds-primitives@^0.0.2 (템플릿 내부 UI 컴포넌트)
  • react >= 19, react-dom >= 19
  • Storybook/로컬 개발용으로는 @uniai-fe/uds-foundation/css를 앱 루트에서 한 번만 import 해야 합니다.

템플릿은 primitives 위에서 동작하므로, @uniai-fe/uds-primitives가 설치되어 있지 않으면 빌드 타임에 peer dependency 경고가 발생합니다.

특징

  • 화면 단위 템플릿:
    • 로그인/회원가입/아이디·비밀번호 찾기 등 /auth/**
    • 로그인 이후 화면을 위한 모바일 페이지 프레임 /page-frame/mobile(PC는 추후 /page-frame/pc)
  • Raw TS 배포:
    • package.json exportssrc/**를 가리키며, 번들 없이 즉시 import 가능한 형태로 제공합니다.
  • 디자인시스템 일관성:
    • 스타일은 항상 @uniai-fe/uds-foundation/css에서 제공하는 CSS 변수(토큰)를 통해만 정의됩니다.
    • UI 요소는 모두 @uniai-fe/uds-primitives 컴포넌트를 조합해 구성합니다.
  • 역할 분리:
    • templates는 레이아웃/플로우/상태 표현까지 담당하고,
    • API 호출, 인증 토큰 관리, 라우팅, i18n 등 비즈니스 로직은 서비스 앱에서 구현합니다.

확인 완료 도구 목록

  • /modal
    • Modal.Provider
    • Modal.StackProvider
    • Modal.RouteReset
    • Modal.useModal
    • Modal.Alert
    • Modal.Dialog
    • createAlertModal
    • createDialogModal
    • modalStackAtom
    • ModalState
    • ModalStatePatch
    • ModalProps
    • ModalFooterButton
    • AlertTemplateOptions
    • DialogTemplateOptions
    • UseModalReturn
  • /weather
    • WeatherComponents.PageHeader
    • WeatherPageHeaderContainer
    • WeatherMockProvider
    • weatherCoordinate
    • useWeatherKorea
    • useOpenWeatherMap
  • /service-inquiry
    • ServiceInquiry.Form
    • ServiceInquiry.OpenButton
    • ServiceInquiry.NavButton
    • ServiceInquiry.useOpen
    • ServiceInquiry.useProvideContext
    • ServiceInquiry.useUserContext
    • ServiceInquiry.createModal
    • ServiceInquiryFieldMode
    • ServiceInquiryFormProps
    • ServiceInquiryFormValues
    • ServiceInquiryProvidedContext
  • /cctv
    • CCTV.Provider
    • CCTV.CamList.Container
    • CCTV.Video.Container
    • CCTV.Video.Contents
    • CCTV.Video.Overlay.Container
    • CCTV.Pagination.Container
    • CCTV.Pagination.List.Container
    • CCTV.Pagination.Button.Prev
    • CCTV.Pagination.Button.Next
    • CCTV.Viewer.Desktop.Container
    • useCctvCompanyData
    • useCctvContext
    • useCctvRtcStream
    • getServerCompanyList
    • getServerCctvToken
    • postCctvRtcToken
  • /page-frame
    • Frame
    • Frame.Mobile
    • MobileFrame
    • Frame.Desktop
    • DesktopFrame
    • MobileFrameProps
    • PageFrameDesktopNavProps
    • SitemapDataType

현재 제공 템플릿/모듈

  • /auth/**
    • 로그인 화면 템플릿 (Login)
    • 회원가입 플로우 템플릿 (Sign Up, step 기반)
    • 아이디 찾기 템플릿
    • 비밀번호 찾기/재설정 템플릿
  • /page-frame/**
    • /page-frame/mobile: 로그인 이후 화면을 위한 모바일 프레임(header/body/footer)
    • /page-frame/pc: 추후 확장 예정
  • /modal/**
    • ui-legacy 스택 기반 모달 Provider/Root/Container + 템플릿(Modal.Alert, Modal.Dialog)
    • Storybook(apps/design-storybook/src/stories/templates/modal)에서 Alert/Confirm 케이스를 검증한다.
  • /service-inquiry/**
    • 문의 입력 전용 form, 기본 원형 ? open button, page-frame nav button, 커스텀 trigger용 open hook, 페이지 context 등록 hook, request context 조립 hook, 네트워크 오류 수집 hook, modal preset factory를 제공한다.
    • 현재 form 기본 구조는 이름, 연락처, 문의 유형, 자세한 문의 내용 4필드이며, 사진 첨부는 구현 범위에서 제외한다.
    • submit transport, React Query mutation, Next.js route handler, 에러 피드백(Modal.Alert)은 서비스 앱이 소유한다.
    • 모듈 내부 Jotai registry를 사용하므로, layout 고정 버튼 1개와 페이지별 context 등록 hook 조합으로 ready-to-use 구성이 가능하다.
    • stackKey는 필요할 때만 override하고, useOpen 계열은 기본적으로 현재 pathname 기준 ${pathname}/inquiry를 사용한다.
    • modal description은 기본으로 "사용 중 문제가 있나요? 아래 내용을 적어 문의해 주세요."를 사용하고 특수 문구가 필요할 때만 dialogOptions.description으로 덮어쓴다.
    • 로그인 후 farm_name, contact를 auto-fill + readonly로 보여야 할 때는 formContextOptions.defaultValuesfarmNameField.mode, contactField.mode를 함께 전달한다.
  • /weather/**
    • page-frame header utility에 결합되는 weather header 템플릿과 weather data hook/mock 도구를 제공한다.
  • /cctv/**
    • finder/viewer/video/pagination 조합과 rtc/company-list API helper를 제공한다.
  • /page-frame/**
    • mobile/desktop private route frame, nav/header/popup 조합을 제공한다.

각 템플릿의 상세한 범위와 의사결정은 CONTEXT-*.md 문서에서 관리합니다.

Service Inquiry 도입 흐름

  1. 서비스 앱이 react-hook-form으로 defaultValuesonSubmit을 준비한다.
  2. layout 고정 버튼은 ServiceInquiry.useUserContext()로 모듈 내부 registry 기반 requestContext를 읽는다.
  3. 서비스 앱은 네트워크 오류가 발생했을 때 ServiceInquiry.useNetworkError().reportNetworkError(...)만 호출하고, 모듈이 이를 user_context.network_errors에 자동 병합한다.
  4. 각 페이지/폼은 ServiceInquiry.useProvideContext({ labels, userContext })ServiceInquiryProvidedContext를 등록한다.
  5. 비로그인 기본 버튼은 ServiceInquiry.OpenButton, 로그인 후 page-frame 진입 버튼은 ServiceInquiry.NavButton, 그 외 커스텀 버튼은 ServiceInquiry.useOpen으로 모달 open을 연결한다.
  6. modal footer confirm이 ServiceInquiry.Form submit 진입을 담당한다.
  7. 실제 submit은 서비스 앱의 useMutation + Next.js route handler + Modal.Alert 조합으로 처리한다.

service-inquiry는 구조와 request context까지만 제공하고, 네트워크 상태/재시도/성공·실패 피드백은 서비스 앱이 소유합니다.

회원가입 Step 구조

  1. Step1 — User Info (name + phone): 기본 정보 입력. PhoneInput은 인증 UI 없이 마스킹만 제공한다.
  2. Step2 — Verify & Agreement: 약관 동의 + EmailInput(인증요청/타이머/OneTimeCode). alert/confirm는 서비스 앱이 직접 처리한다.
  3. Step3 — Generate Account: username/password/confirm + password 조건 helper.
  4. Step4 — Complete: 승인 대기 안내. CTA 명칭은 “Complete”만 사용한다.

세부 props/스토리 구성은 docs/CONTEXT-SIGNUP.md, docs/CONTEXT-SIGNUP-FLOW.md, docs/STORYBOOK.md에서 확인하고 변경 시 세 문서를 동시에 업데이트한다.

설치 & 기본 설정(Next.js 예시)

pnpm add @uniai-fe/uds-foundation @uniai-fe/uds-primitives @uniai-fe/uds-templates

1) transpilePackages 설정

// next.config.ts
const nextConfig = {
  transpilePackages: [
    "@uniai-fe/uds-foundation",
    "@uniai-fe/uds-primitives",
    "@uniai-fe/uds-templates",
  ],
};

export default nextConfig;

2) 스타일 전역 주입

템플릿은 primitives 위에 구성되므로, 앱 루트에서 @uniai-fe/uds-templates/styles(Sass) 또는 @uniai-fe/uds-templates/css(번들 CSS) 중 하나를 한 번만 import 하면 foundation 토큰, primitives, templates 스타일이 모두 초기화됩니다.

/* app/globals.scss (Sass 사용 프로젝트) */
@use "@uniai-fe/uds-templates/styles";
// app/layout.tsx (Sass 비사용 프로젝트)
import "@uniai-fe/uds-templates/css";

export default function RootLayout(props: { children: React.ReactNode }) {
  return (
    <html lang="ko">
      <body>{props.children}</body>
    </html>
  );
}

간단 사용 예시

// app/(auth)/login/page.tsx
import { AuthLoginTemplate } from "@uniai-fe/uds-templates/auth";

export default function LoginPage() {
  return (
    <AuthLoginTemplate
      text={{
        title: "로그인",
        description: "서비스 이용을 위해 로그인해 주세요.",
      }}
      logoSlot={<img src="/logo.svg" alt="서비스 로고" />}
      onSubmit={async (values) => {
        // 실제 로그인 API 호출은 서비스 앱에서 구현
        // await login(values);
      }}
    />
  );
}

위 예시는 개념을 설명하기 위한 형태이며, 실제 props 구조/이름은 CONTEXT-AUTH.md에서 확정·관리합니다.

modules 레포 내부(Storybook 등)에서는 개발 편의를 위해 @uniai-fe/uds-templates/styles 엔트리를 import하지만, 외부 서비스/패키지는 @uniai-fe/uds-templates/css 엔트리만 사용해야 한다.

최근 업데이트

  • Modal CSS 변수 네임스페이스를 --modal-*, --modal-alert-*, --modal-dialog-* 세 축으로 통일했다. 기존 --dialog-* 이름을 사용하지 말고, Auth 템플릿이 Alert을 호출할 때에는 반드시 Modal.Alert 팩토리를 통해 렌더링한다.
  • Auth(회원가입/아이디 찾기/비밀번호 찾기) 템플릿은 이메일 인증 타이머 5분, alert 문구, readonly 이메일 필드, 완료 단계 헤더 제거 등 최신 플로우를 반영했다. 모듈에서 window.alert/window.confirm을 호출하지 않고, 서비스 앱이 Modal helper를 주입하는 구조를 README와 CONTEXT-AUTH*.md에 명시했다.

토큰 스코프 & ThemeProvider

  • templates SCSS는 모든 디자인 토큰을 :root에 선언하고, 빌드 시 scripts/merge-theme-root.mjs가 토큰 블록을 단일 :root { ... }로 합쳐 중복 선언을 제거합니다.
  • 서비스 앱은 foundation ThemeProvider가 주입하는 .uds-theme-root를 루트에 유지해야 하며, CSS import 순서는 @uniai-fe/uds-foundation/css@uniai-fe/uds-primitives/css@uniai-fe/uds-templates/css 입니다.
  • modules 레포(Storybook 등)는 SCSS 원본을 직접 사용하지만, 외부 프로젝트는 CSS 엔트리만 import한다는 규칙을 README/CODEX-RULES에 명시하고 있습니다.

Modal 모듈 사용법

ui-legacy에서 사용하던 모달 스택/옵션을 templates 레이어로 옮겨왔습니다. 핵심 흐름은 다음과 같습니다.

  1. Provider 1회 장착 — 서비스 레이아웃에서 <Modal.Provider />를 렌더합니다.
  2. Route Reset 장착<Modal.RouteReset />을 Provider와 같은 레벨에서 렌더해 경로 변경 시 스택을 초기화합니다.
  3. 훅 사용const { newModal, closeModal, hasBlockingModal } = Modal.useModal();
  4. 템플릿 팩토리Modal.Alert, Modal.DialogModalState 객체를 반환하므로 newModal(...)에 그대로 전달합니다.
// app/layout.tsx
import "@uniai-fe/uds-templates/styles";
import { Modal } from "@uniai-fe/uds-templates/modal";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ko">
      <body>
        <>
          {children}
          <Modal.Provider />
          <Modal.RouteReset />
        </>
      </body>
    </html>
  );
}
// 예: Alert/Confirm 호출
import { Modal } from "@uniai-fe/uds-templates/modal";

export function ExampleActions() {
  const { newModal } = Modal.useModal();

  const openAlert = () =>
    newModal(
      Modal.Alert({
        stackKey: "sample/alert",
        message: "필수 항목 동의에 체크해 주세요.",
        confirm: { label: "확인" },
      }),
    );

  const openConfirm = () =>
    newModal(
      Modal.Dialog({
        stackKey: "sample/confirm",
        title: "저장하시겠어요?",
        content: "입력한 내용이 저장되며 되돌릴 수 없습니다.",
        confirm: {
          label: "저장",
          onClick: () => {
            // 서비스 동작
          },
        },
        cancel: { label: "취소" },
      }),
    );

  return (
    <>
      <button onClick={openAlert}>Alert</button>
      <button onClick={openConfirm}>Confirm</button>
    </>
  );
}
  • footer 버튼은 ui-legacy와 동일하게 stackKey, role, defaultOptions/linkOptions 구조로 관리하며, Alert(Text)/Dialog(Solid) 규격은 templates 내부에서 보장합니다.
  • closeOnOutsideClick?: boolean으로 overlay 클릭 닫힘을 제어할 수 있습니다. 기본값은 true입니다.
  • preventRouteChange?: boolean은 현재 열린 modal 중 route 변경 확인이 필요한 modal이 있는지 집계할 때 사용합니다. 서비스 앱은 hasBlockingModal을 읽어 공통 confirm UX를 연결할 수 있습니다.
  • Route Reset을 누락하면 이전 라우트의 모달 스택이 그대로 남으므로, layout 수준에서 Provider와 함께 반드시 렌더합니다.
  • 세부 가드레일·확장 기록은 CONTEXT-MODAL.md를 참고하고, 새 템플릿을 추가할 때 해당 문서를 선행 업데이트합니다.

Scripts

패키지 루트에서 실행 가능한 대표 명령:

  • pnpm module:lint — ESLint 전역 규칙 점검
  • pnpm module:typecheck — TS 타입 검사 (tsconfig.build.json 기준)
  • pnpm module:build — lint → typecheck 순으로 배포 전 검증
  • pnpm design-templates:dev — 타입 검사 watch 모드

모노레포 루트에서는 pnpm --filter @uniai-fe/uds-templates <command> 또는 pnpm modules:build(turbo run)으로 전체 패키지를 빌드할 수 있습니다.

문서

  • CONTEXT.md — templates 패키지 전체 상황/진행 현황 인덱스
  • CONTEXT-GUIDELINES.md — templates 전역 규칙(슬롯/반응형/page-frame 적용 범위 등)
  • CONTEXT-AUTH.md/auth/** 템플릿 범위/디자인 근거/Figma 링크
  • CONTEXT-SIGNUP.md, CONTEXT-SIGNUP-FLOW.md — 회원가입 단계/훅/스토리 전략 및 Figma node 표
  • CONTEXT-PAGE-FRAME.md/page-frame/** 템플릿 범위/디자인 근거
  • FOUNDATION-USAGE-GUIDE.md — 템플릿에서 design-foundation 토큰을 사용하는 규칙
  • PRIMITIVES-USAGE-GUIDE.md — 템플릿에서 design-primitives를 사용하는 규칙
  • STORYBOOK.md — templates Storybook 가이드(로그인/회원가입/페이지 프레임 시나리오)