@uniai-fe/uds-templates 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -136,8 +136,9 @@ export default function LoginPage() {
136
136
  ui-legacy에서 사용하던 모달 스택/옵션을 templates 레이어로 옮겨왔습니다. 핵심 흐름은 다음과 같습니다.
137
137
 
138
138
  1. **Provider 1회 장착** — 서비스 레이아웃에서 `<Modal.Provider />`를 렌더합니다.
139
- 2. **훅 사용**`const { newModal, closeModal } = Modal.useModal();`
140
- 3. **템플릿 팩토리** — `Modal.Alert`, `Modal.Dialog`이 `ModalState` 객체를 반환하므로 `newModal(...)`에 그대로 전달합니다.
139
+ 2. **Route Reset 장착** `<Modal.RouteReset />`을 Provider와 같은 레벨에서 렌더해 경로 변경 시 스택을 초기화합니다.
140
+ 3. **훅 사용** — `const { newModal, closeModal } = Modal.useModal();`
141
+ 4. **템플릿 팩토리** — `Modal.Alert`, `Modal.Dialog`이 `ModalState` 객체를 반환하므로 `newModal(...)`에 그대로 전달합니다.
141
142
 
142
143
  ```tsx
143
144
  // app/layout.tsx
@@ -152,8 +153,11 @@ export default function RootLayout({
152
153
  return (
153
154
  <html lang="ko">
154
155
  <body>
155
- {children}
156
- <Modal.Provider />
156
+ <>
157
+ {children}
158
+ <Modal.Provider />
159
+ <Modal.RouteReset />
160
+ </>
157
161
  </body>
158
162
  </html>
159
163
  );
@@ -202,6 +206,7 @@ export function ExampleActions() {
202
206
  ```
203
207
 
204
208
  - footer 버튼은 ui-legacy와 동일하게 `stackKey`, `role`, `defaultOptions/linkOptions` 구조로 관리하며, Alert(Text)/Dialog(Solid) 규격은 templates 내부에서 보장합니다.
209
+ - Route Reset을 누락하면 이전 라우트의 모달 스택이 그대로 남으므로, layout 수준에서 Provider와 함께 반드시 렌더합니다.
205
210
  - 세부 가드레일·확장 기록은 `CONTEXT-MODAL.md`를 참고하고, 새 템플릿을 추가할 때 해당 문서를 선행 업데이트합니다.
206
211
 
207
212
  ## Scripts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniai-fe/uds-templates",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "UNIAI Design System; UI Templates Package",
5
5
  "type": "module",
6
6
  "private": false,
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { useMemo } from "react";
2
4
  import { useWatch, type Path } from "react-hook-form";
3
5
  import type React from "react";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import clsx from "clsx";
2
4
  import { useMemo } from "react";
3
5
  import type { MouseEvent } from "react";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import clsx from "clsx";
2
4
  import { useMemo } from "react";
3
5
  import { useForm } from "react-hook-form";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { useCallback, useEffect, useMemo } from "react";
2
4
  import type { ReactNode } from "react";
3
5
  import { useWatch } from "react-hook-form";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import "../styles/password-set-field.scss";
2
4
 
3
5
  import { useMemo } from "react";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import clsx from "clsx";
2
4
  import type { FindAccountIdCompleteProps } from "../types";
3
5
  import AuthCompleteTemplate from "../../common/complete/Template";
@@ -5,7 +7,7 @@ import AuthCompleteTemplate from "../../common/complete/Template";
5
7
  const DEFAULT_TITLE = "아이디 찾기 완료";
6
8
  const DEFAULT_ID_LABEL = "아이디";
7
9
  const DEFAULT_REGISTERED_LABEL = "가입일";
8
- const DEFAULT_DESCRIPTION = "입력하신 정보로 계정을 찾았어요.";
10
+ const DEFAULT_DESCRIPTION = "로그인 페이지로 이동하여 로그인합니다.";
9
11
  const DEFAULT_CTA_LABEL = "로그인하기";
10
12
 
11
13
  /**
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import type { ReactNode } from "react";
2
4
  import FindAccountInfoStep from "../../common/find/markup/InfoStep";
3
5
  import type { FindAccountInfoStepProps } from "../../common/find/types";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import FindAccountCodeStep from "../../common/find/markup/CodeStep";
2
4
  import type { FindAccountCodeStepProps } from "../../common/find/types";
3
5
 
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import clsx from "clsx";
2
4
  import { useMemo } from "react";
3
5
  import { FormProvider, useForm } from "react-hook-form";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { useMemo } from "react";
2
4
  import { useWatch } from "react-hook-form";
3
5
  import type { ReactNode } from "react";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { useMemo } from "react";
2
4
  import type { ReactNode } from "react";
3
5
  import {
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { useMemo } from "react";
2
4
  import { useWatch } from "react-hook-form";
3
5
  import type { ReactNode } from "react";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { useMemo } from "react";
2
4
  import { useWatch } from "react-hook-form";
3
5
  import type { ReactNode } from "react";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { useMemo } from "react";
2
4
  import { useWatch } from "react-hook-form";
3
5
  import type { ReactNode } from "react";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { useMemo } from "react";
2
4
  import { FormProvider, useForm } from "react-hook-form";
3
5
  import { Button, Input, type InputProps } from "@uniai-fe/uds-primitives";
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { useMemo } from "react";
2
4
  import { useForm } from "react-hook-form";
3
5
  import {
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { useMemo, useState } from "react";
2
4
  import { useForm } from "react-hook-form";
3
5
  import {
@@ -7,7 +7,7 @@ import clsx from "clsx";
7
7
  import { useModal } from "../hooks/useModal";
8
8
  import { ModalContainer } from "./Container";
9
9
 
10
- import type { ModalProps, ModalShowState, ModalState } from "../../types";
10
+ import type { ModalShowState, ModalState } from "../../types";
11
11
 
12
12
  type ModalRootProps = ModalState & {
13
13
  index: number;
@@ -0,0 +1,25 @@
1
+ "use client";
2
+
3
+ import { useEffect } from "react";
4
+ import { usePathname } from "next/navigation";
5
+ import { useSetAtom } from "jotai";
6
+
7
+ import { modalStackAtom } from "../jotai/atoms";
8
+
9
+ /**
10
+ * Modal Route Reset; 라우트 변경 시 모달 스택 초기화
11
+ * @component
12
+ * @desc
13
+ * - Next.js pathname 변경을 감지해 `modalStackAtom`을 빈 배열로 되돌린다.
14
+ * - 최상위 layout에서 `<Modal.RouteReset />`을 Provider와 함께 렌더링해야 한다.
15
+ */
16
+ export function ModalRouteReset() {
17
+ const pathname = usePathname();
18
+ const resetStack = useSetAtom(modalStackAtom);
19
+
20
+ useEffect(() => {
21
+ resetStack([]);
22
+ }, [pathname, resetStack]);
23
+
24
+ return null;
25
+ }
@@ -1,16 +1,26 @@
1
1
  import "./index.scss";
2
2
 
3
3
  import { ModalProvider } from "./core/components/Provider";
4
+ import { ModalRouteReset } from "./core/components/RouteReset";
4
5
  import { useModal } from "./core/hooks/useModal";
5
6
  import { createAlertModal } from "./templates/Alert";
6
7
  import { createDialogModal } from "./templates/Dialog";
8
+ import { modalStackAtom } from "./core/jotai/atoms";
7
9
 
8
10
  export const Modal = {
9
11
  Provider: ModalProvider,
12
+ RouteReset: ModalRouteReset,
10
13
  useModal,
11
14
  Alert: createAlertModal,
12
15
  Dialog: createDialogModal,
13
16
  };
14
17
 
15
- export { ModalProvider, useModal, createAlertModal, createDialogModal };
18
+ export {
19
+ ModalProvider,
20
+ ModalRouteReset,
21
+ useModal,
22
+ createAlertModal,
23
+ createDialogModal,
24
+ modalStackAtom,
25
+ };
16
26
  export type * from "./types";