@uniai-fe/uds-templates 0.1.19 → 0.1.20

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.
Files changed (27) hide show
  1. package/dist/styles.css +56 -7
  2. package/package.json +1 -1
  3. package/src/auth/common/container/header/StageHeader.tsx +2 -2
  4. package/src/index.scss +0 -2
  5. package/src/page-frame/desktop/index.tsx +4 -1
  6. package/src/page-frame/index.tsx +8 -2
  7. package/src/page-frame/mobile/{header/PageFrameMobileHeader.tsx → components/header/Header.tsx} +6 -6
  8. package/src/page-frame/mobile/components/header/index.ts +9 -0
  9. package/src/page-frame/mobile/components/index.tsx +14 -0
  10. package/src/page-frame/{navigation/PageFrameNavigation.tsx → mobile/components/navigation/Navigation.tsx} +3 -3
  11. package/src/page-frame/mobile/components/navigation/index.tsx +8 -0
  12. package/src/page-frame/mobile/components/page/Container.tsx +29 -0
  13. package/src/page-frame/mobile/{PageFrameMobile.tsx → components/page/Frame.tsx} +12 -9
  14. package/src/page-frame/mobile/components/page/index.tsx +11 -0
  15. package/src/page-frame/mobile/index.scss +3 -17
  16. package/src/page-frame/mobile/index.tsx +5 -2
  17. package/src/page-frame/{container/index.scss → mobile/styles/mobile.scss} +25 -7
  18. package/src/page-frame/mobile/types/index.ts +1 -0
  19. package/src/page-frame/mobile/types/page.ts +16 -0
  20. package/src/page-frame/container/PageFrameContainer.tsx +0 -24
  21. package/src/page-frame/container/index.tsx +0 -4
  22. package/src/page-frame/container/types.ts +0 -11
  23. package/src/page-frame/mobile/header/index.ts +0 -4
  24. package/src/page-frame/mobile/types.ts +0 -6
  25. package/src/page-frame/navigation/index.tsx +0 -4
  26. /package/src/page-frame/mobile/{header/page-frame-mobile-header.scss → styles/header.scss} +0 -0
  27. /package/src/page-frame/{navigation/index.scss → mobile/styles/navigation.scss} +0 -0
package/dist/styles.css CHANGED
@@ -50,7 +50,7 @@
50
50
  /* namespace 충돌을 막기 위해 모든 @use 경로에 고유 alias를 부여한다. */
51
51
 
52
52
 
53
- .page-frame-container {
53
+ .page-frame-mobile-shell {
54
54
  display: grid;
55
55
  grid-template-rows: auto 1fr auto;
56
56
  width: min(100%, var(--uds-page-frame-max-width));
@@ -60,22 +60,22 @@
60
60
  color: inherit;
61
61
  }
62
62
 
63
- .page-frame-header,
64
- .page-frame-body,
65
- .page-frame-footer {
63
+ .page-frame-mobile-shell-header,
64
+ .page-frame-mobile-shell-body,
65
+ .page-frame-mobile-shell-footer {
66
66
  width: 100%;
67
67
  }
68
68
 
69
- .page-frame-header {
69
+ .page-frame-mobile-shell-header {
70
70
  padding-top: var(--uds-page-frame-header-padding-top);
71
71
  }
72
72
 
73
- .page-frame-body {
73
+ .page-frame-mobile-shell-body {
74
74
  min-height: 0;
75
75
  overflow-y: auto;
76
76
  }
77
77
 
78
- .page-frame-footer {
78
+ .page-frame-mobile-shell-footer {
79
79
  padding-bottom: var(--uds-page-frame-footer-safe-area);
80
80
  }
81
81
 
@@ -97,6 +97,55 @@
97
97
  background-color: inherit;
98
98
  }
99
99
 
100
+ .page-frame-mobile-header {
101
+ position: relative;
102
+ display: flex;
103
+ align-items: center;
104
+ justify-content: space-between;
105
+ gap: var(--spacing-padding-2, 8px);
106
+ min-height: 40px;
107
+ }
108
+
109
+ .page-frame-mobile-header__left,
110
+ .page-frame-mobile-header__right {
111
+ width: 64px;
112
+ height: 40px;
113
+ display: inline-flex;
114
+ align-items: center;
115
+ }
116
+
117
+ .page-frame-mobile-header__back {
118
+ border: none;
119
+ background: none;
120
+ display: inline-flex;
121
+ align-items: center;
122
+ gap: var(--spacing-padding-1, 4px);
123
+ padding: var(--spacing-padding-1, 4px);
124
+ font-size: 14px;
125
+ color: var(--color-label-standard);
126
+ cursor: pointer;
127
+ }
128
+
129
+ .page-frame-mobile-header__back-icon {
130
+ font-size: 18px;
131
+ line-height: 1;
132
+ }
133
+
134
+ .page-frame-mobile-header__back-placeholder {
135
+ width: 100%;
136
+ height: 100%;
137
+ }
138
+
139
+ .page-frame-mobile-header__title {
140
+ position: absolute;
141
+ left: 50%;
142
+ transform: translateX(-50%);
143
+ margin: 0;
144
+ font-size: 16px;
145
+ font-weight: 600;
146
+ color: var(--color-label-standard);
147
+ }
148
+
100
149
  .page-frame-navigation {
101
150
  width: 100%;
102
151
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniai-fe/uds-templates",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "description": "UNIAI Design System; UI Templates Package",
5
5
  "type": "module",
6
6
  "private": false,
@@ -1,7 +1,7 @@
1
1
  import clsx from "clsx";
2
2
  import type { ReactNode } from "react";
3
3
  import { PaginationCarousel } from "@uniai-fe/uds-primitives";
4
- import { PageFrameMobileHeader } from "../../../../page-frame/mobile/header";
4
+ import { MobileFrameHeader } from "../../../../page-frame/mobile/components/header";
5
5
 
6
6
  import "./stage-header.scss";
7
7
 
@@ -35,7 +35,7 @@ export function AuthStageHeader({
35
35
  }: StageHeaderProps) {
36
36
  return (
37
37
  <div className={clsx("auth-stage-header", className)}>
38
- <PageFrameMobileHeader
38
+ <MobileFrameHeader
39
39
  title={navigationTitle}
40
40
  backIcon={backIcon}
41
41
  onBack={onBack}
package/src/index.scss CHANGED
@@ -3,9 +3,7 @@
3
3
 
4
4
  /* 템플릿 레벨 스타일을 통합해 서비스 앱이 단일 엔트리만 import하도록 구성한다. */
5
5
  /* namespace 충돌을 막기 위해 모든 @use 경로에 고유 alias를 부여한다. */
6
- @use "./page-frame/container/index.scss" as pageFrameContainer;
7
6
  @use "./page-frame/mobile/index.scss" as pageFrameMobile;
8
- @use "./page-frame/navigation/index.scss" as pageFrameNavigation;
9
7
  @use "./modal/index.scss" as modalStyles;
10
8
 
11
9
  @use "./auth/common/container/index.scss" as authCommonContainer;
@@ -4,4 +4,7 @@ import Frame from "./components";
4
4
 
5
5
  export type * from "./types";
6
6
 
7
- export { Frame };
7
+ export const DesktopFrame = {
8
+ ...Frame,
9
+ Container: Frame.Page?.Container,
10
+ };
@@ -1,5 +1,11 @@
1
- export * from "./container";
1
+ import { DesktopFrame } from "./desktop";
2
+ import { MobileFrame } from "./mobile";
3
+
2
4
  export * from "./mobile";
3
- export * from "./navigation";
4
5
  export * from "./types";
5
6
  export * from "./desktop";
7
+
8
+ export const Frame = Object.assign({}, DesktopFrame, {
9
+ Desktop: DesktopFrame,
10
+ Mobile: MobileFrame,
11
+ });
@@ -1,10 +1,10 @@
1
1
  import clsx from "clsx";
2
2
  import type { ReactNode } from "react";
3
3
 
4
- import IconBackword from "../img/chevron-backward.svg";
5
- import "./page-frame-mobile-header.scss";
4
+ import IconBackward from "../../img/chevron-backward.svg";
5
+ import "../../styles/header.scss";
6
6
 
7
- export interface PageFrameMobileHeaderProps {
7
+ export interface MobileFrameHeaderProps {
8
8
  className?: string;
9
9
  title: ReactNode;
10
10
  backIcon?: ReactNode;
@@ -17,14 +17,14 @@ export interface PageFrameMobileHeaderProps {
17
17
  * 모바일 서비스 공통 page header; 뒤로가기 버튼 + 타이틀을 노출한다.
18
18
  * @component
19
19
  */
20
- export function PageFrameMobileHeader({
20
+ export function MobileFrameHeader({
21
21
  className,
22
22
  title,
23
23
  backIcon,
24
24
  onBack,
25
25
  leftSlot,
26
26
  rightSlot,
27
- }: PageFrameMobileHeaderProps) {
27
+ }: MobileFrameHeaderProps) {
28
28
  return (
29
29
  <header className={clsx("page-frame-mobile-header", className)}>
30
30
  <div className="page-frame-mobile-header__left">
@@ -38,7 +38,7 @@ export function PageFrameMobileHeader({
38
38
  >
39
39
  <span className="page-frame-mobile-header__back-icon">
40
40
  {backIcon ?? (
41
- <IconBackword width={24} height={24} alt="뒤로가기" />
41
+ <IconBackward width={24} height={24} alt="뒤로가기" />
42
42
  )}
43
43
  </span>
44
44
  </button>
@@ -0,0 +1,9 @@
1
+ import { MobileFrameHeader } from "./Header";
2
+
3
+ const Header = {
4
+ Container: MobileFrameHeader,
5
+ };
6
+
7
+ export default Header;
8
+ export { MobileFrameHeader };
9
+ export type { MobileFrameHeaderProps } from "./Header";
@@ -0,0 +1,14 @@
1
+ import Page from "./page";
2
+ import Header from "./header";
3
+ import Navigation from "./navigation";
4
+
5
+ const Frame = {
6
+ Page,
7
+ Header,
8
+ Navigation,
9
+ };
10
+
11
+ export default Frame;
12
+ export * from "./page";
13
+ export * from "./header";
14
+ export * from "./navigation";
@@ -4,7 +4,7 @@ import {
4
4
  type BottomNavigationProps,
5
5
  } from "@uniai-fe/uds-primitives";
6
6
 
7
- export type PageFrameNavigationProps = BottomNavigationProps;
7
+ export type MobileFrameNavigationProps = BottomNavigationProps;
8
8
 
9
9
  /**
10
10
  * Page Frame 전용 navigation 래퍼.
@@ -12,10 +12,10 @@ export type PageFrameNavigationProps = BottomNavigationProps;
12
12
  * @component
13
13
  * @param {PageFrameNavigationProps} props
14
14
  */
15
- export function PageFrameNavigation({
15
+ export function MobileFrameNavigation({
16
16
  className,
17
17
  ...rest
18
- }: PageFrameNavigationProps) {
18
+ }: MobileFrameNavigationProps) {
19
19
  return (
20
20
  <BottomNavigation
21
21
  {...rest}
@@ -0,0 +1,8 @@
1
+ import "../../styles/navigation.scss";
2
+ import { MobileFrameNavigation } from "./Navigation";
3
+
4
+ const Navigation = MobileFrameNavigation;
5
+
6
+ export default Navigation;
7
+ export { MobileFrameNavigation };
8
+ export type { MobileFrameNavigationProps } from "./Navigation";
@@ -0,0 +1,29 @@
1
+ import clsx from "clsx";
2
+ import type { MobileFrameContainerProps } from "../../types";
3
+
4
+ const SHELL_CLASS = "page-frame-mobile-shell";
5
+ const SHELL_HEADER_CLASS = `${SHELL_CLASS}-header`;
6
+ const SHELL_BODY_CLASS = `${SHELL_CLASS}-body`;
7
+ const SHELL_FOOTER_CLASS = `${SHELL_CLASS}-footer`;
8
+
9
+ /**
10
+ * 모바일 전용 페이지 컨테이너; header/body/footer 영역을 순서대로 배치한다.
11
+ * @component
12
+ */
13
+ export function MobileFrameContainer({
14
+ className,
15
+ header,
16
+ headerClassName,
17
+ bodyClassName,
18
+ footer,
19
+ footerClassName,
20
+ children,
21
+ }: MobileFrameContainerProps) {
22
+ return (
23
+ <div className={clsx(SHELL_CLASS, className)}>
24
+ <div className={clsx(SHELL_HEADER_CLASS, headerClassName)}>{header}</div>
25
+ <div className={clsx(SHELL_BODY_CLASS, bodyClassName)}>{children}</div>
26
+ <div className={clsx(SHELL_FOOTER_CLASS, footerClassName)}>{footer}</div>
27
+ </div>
28
+ );
29
+ }
@@ -1,17 +1,17 @@
1
1
  "use client";
2
2
 
3
3
  import clsx from "clsx";
4
- import { PageFrameContainer } from "../container";
5
- import { PageFrameNavigation } from "../navigation";
6
- import type { PageFrameMobileProps } from "./types";
4
+ import { MobileFrameContainer } from "./Container";
5
+ import { MobileFrameNavigation } from "../navigation";
6
+ import type { MobileFrameProps } from "../../types";
7
7
  import React, { useCallback } from "react";
8
8
 
9
9
  /**
10
10
  * 모바일 전용 Page Frame 래퍼; 공통 컨테이너 위에 모바일 클래스/스타일을 덧입힌다.
11
11
  * @component
12
- * @param {PageFrameMobileProps} props
12
+ * @param {MobileFrameProps} props
13
13
  */
14
- export function PageFrameMobile({
14
+ export function MobileFrame({
15
15
  className,
16
16
  header,
17
17
  headerClassName,
@@ -19,17 +19,18 @@ export function PageFrameMobile({
19
19
  footer,
20
20
  footerClassName,
21
21
  navigationProps,
22
+ children,
22
23
  ...rest
23
- }: PageFrameMobileProps) {
24
+ }: MobileFrameProps) {
24
25
  const Footer = useCallback(
25
26
  (): React.ReactNode =>
26
27
  footer ??
27
- (navigationProps ? <PageFrameNavigation {...navigationProps} /> : null),
28
+ (navigationProps ? <MobileFrameNavigation {...navigationProps} /> : null),
28
29
  [footer, navigationProps],
29
30
  );
30
31
 
31
32
  return (
32
- <PageFrameContainer
33
+ <MobileFrameContainer
33
34
  {...rest}
34
35
  className={clsx("page-frame-mobile", className)}
35
36
  header={header}
@@ -37,6 +38,8 @@ export function PageFrameMobile({
37
38
  bodyClassName={clsx("page-frame-mobile-body", bodyClassName)}
38
39
  footer={<Footer />}
39
40
  footerClassName={clsx("page-frame-mobile-footer", footerClassName)}
40
- />
41
+ >
42
+ {children}
43
+ </MobileFrameContainer>
41
44
  );
42
45
  }
@@ -0,0 +1,11 @@
1
+ import { MobileFrameContainer } from "./Container";
2
+ import { MobileFrame } from "./Frame";
3
+
4
+ const Page = {
5
+ Frame: MobileFrame,
6
+ Container: MobileFrameContainer,
7
+ Shell: MobileFrameContainer,
8
+ };
9
+
10
+ export default Page;
11
+ export { MobileFrameContainer, MobileFrame };
@@ -1,17 +1,3 @@
1
- .page-frame-mobile {
2
- width: 100%;
3
- height: 100%;
4
- min-height: var(--uds-page-frame-height, var(--frame-device-height, 812px));
5
- max-height: 100dvh;
6
- background-color: var(--color-common-100, #ffffff);
7
- }
8
-
9
- .page-frame-mobile-header,
10
- .page-frame-mobile-body,
11
- .page-frame-mobile-footer {
12
- width: 100%;
13
- }
14
-
15
- .page-frame-mobile-body {
16
- background-color: inherit;
17
- }
1
+ @use "./styles/mobile.scss";
2
+ @use "./styles/header.scss";
3
+ @use "./styles/navigation.scss";
@@ -1,4 +1,7 @@
1
1
  import "./index.scss";
2
2
 
3
- export { PageFrameMobile } from "./PageFrameMobile";
4
- export type { PageFrameMobileProps } from "./types";
3
+ import { MobileFrame } from "./components/page/Frame";
4
+
5
+ export type { MobileFrameProps } from "./types";
6
+ export * from "./components";
7
+ export { MobileFrame };
@@ -16,7 +16,7 @@
16
16
  ); // PC에선 지정 폭으로 중앙 정렬하고, 모바일에선 100%를 유지
17
17
  }
18
18
 
19
- .page-frame-container {
19
+ .page-frame-mobile-shell {
20
20
  display: grid;
21
21
  grid-template-rows: auto 1fr auto;
22
22
  width: min(100%, var(--uds-page-frame-max-width));
@@ -28,21 +28,39 @@
28
28
  color: inherit;
29
29
  }
30
30
 
31
- .page-frame-header,
32
- .page-frame-body,
33
- .page-frame-footer {
31
+ .page-frame-mobile-shell-header,
32
+ .page-frame-mobile-shell-body,
33
+ .page-frame-mobile-shell-footer {
34
34
  width: 100%;
35
35
  }
36
36
 
37
- .page-frame-header {
37
+ .page-frame-mobile-shell-header {
38
38
  padding-top: var(--uds-page-frame-header-padding-top);
39
39
  }
40
40
 
41
- .page-frame-body {
41
+ .page-frame-mobile-shell-body {
42
42
  min-height: 0;
43
43
  overflow-y: auto;
44
44
  }
45
45
 
46
- .page-frame-footer {
46
+ .page-frame-mobile-shell-footer {
47
47
  padding-bottom: var(--uds-page-frame-footer-safe-area);
48
48
  }
49
+
50
+ .page-frame-mobile {
51
+ width: 100%;
52
+ height: 100%;
53
+ min-height: var(--uds-page-frame-height, var(--frame-device-height, 812px));
54
+ max-height: 100dvh;
55
+ background-color: var(--color-common-100, #ffffff);
56
+ }
57
+
58
+ .page-frame-mobile-header,
59
+ .page-frame-mobile-body,
60
+ .page-frame-mobile-footer {
61
+ width: 100%;
62
+ }
63
+
64
+ .page-frame-mobile-body {
65
+ background-color: inherit;
66
+ }
@@ -0,0 +1 @@
1
+ export * from "./page";
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from "react";
2
+ import type { MobileFrameNavigationProps } from "../components/navigation";
3
+
4
+ export type MobileFrameContainerProps = {
5
+ className?: string;
6
+ header?: ReactNode;
7
+ headerClassName?: string;
8
+ bodyClassName?: string;
9
+ footer?: ReactNode;
10
+ footerClassName?: string;
11
+ children: ReactNode;
12
+ };
13
+
14
+ export interface MobileFrameProps extends MobileFrameContainerProps {
15
+ navigationProps?: MobileFrameNavigationProps;
16
+ }
@@ -1,24 +0,0 @@
1
- import clsx from "clsx";
2
- import type { PageFrameContainerProps } from "./types";
3
-
4
- /**
5
- * 페이지 공통 컨테이너; header/body/footer 영역을 순서대로 배치한다.
6
- * @component
7
- */
8
- export function PageFrameContainer({
9
- className,
10
- header,
11
- headerClassName,
12
- bodyClassName,
13
- footer,
14
- footerClassName,
15
- children,
16
- }: PageFrameContainerProps) {
17
- return (
18
- <div className={clsx("page-frame-container", className)}>
19
- <div className={clsx("page-frame-header", headerClassName)}>{header}</div>
20
- <div className={clsx("page-frame-body", bodyClassName)}>{children}</div>
21
- <div className={clsx("page-frame-footer", footerClassName)}>{footer}</div>
22
- </div>
23
- );
24
- }
@@ -1,4 +0,0 @@
1
- import "./index.scss";
2
-
3
- export { PageFrameContainer } from "./PageFrameContainer";
4
- export type { PageFrameContainerProps } from "./types";
@@ -1,11 +0,0 @@
1
- import type { ReactNode } from "react";
2
-
3
- export type PageFrameContainerProps = {
4
- className?: string;
5
- header?: ReactNode;
6
- headerClassName?: string;
7
- bodyClassName?: string;
8
- footer?: ReactNode;
9
- footerClassName?: string;
10
- children: ReactNode;
11
- };
@@ -1,4 +0,0 @@
1
- export {
2
- PageFrameMobileHeader as PageFrameMobileHeader,
3
- type PageFrameMobileHeaderProps,
4
- } from "./PageFrameMobileHeader";
@@ -1,6 +0,0 @@
1
- import type { PageFrameContainerProps } from "../container";
2
- import type { PageFrameNavigationProps } from "../navigation";
3
-
4
- export interface PageFrameMobileProps extends PageFrameContainerProps {
5
- navigationProps?: PageFrameNavigationProps;
6
- }
@@ -1,4 +0,0 @@
1
- import "./index.scss";
2
-
3
- export { PageFrameNavigation } from "./PageFrameNavigation";
4
- export type { PageFrameNavigationProps } from "./PageFrameNavigation";