@nurihaus/web-design-system 3.4.0 → 3.6.0

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.
@@ -56,6 +56,7 @@ Avatar · OptionBadge · IconTextBadge · IconTextOptionBadge · Skeleton · Tex
56
56
 
57
57
  - [Avatar](#avatar)
58
58
  - [CTAButton](#ctabutton)
59
+ - [Callout](#callout)
59
60
  - [OptionBadge](#optionbadge)
60
61
  - [IconTextBadge](#icontextbadge)
61
62
  - [IconTextOptionBadge](#icontextoptionbadge)
@@ -123,14 +124,20 @@ import { CTAButton } from '@nurihaus/web-design-system/cta-button'; // 이 컴
123
124
  import { CTAButton } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
124
125
  ```
125
126
 
126
- **언제 쓴다.** 저장, 확인, 다음 단계처럼 사용자가 실행하는 동작 버튼에 쓴다. `variant`로 강조 단계를 고르고, `loading`이 true면 `text` 대신 Spinner가 표시된다. Google·Apple·Facebook 로그인 버튼은 `variant="social"`(흰 바탕·검정 글자, 공급자 가이드)에 공급자 로고를 `leftIcon`으로 준다.
127
+ **언제 쓴다.** 저장, 확인, 다음 단계처럼 사용자가 실행하는 동작 버튼에 쓴다. `variant`로 강조 단계를 고르고, `loading`이 true면 `text` 대신 Spinner가 표시된다. Google·Apple·Facebook 로그인 버튼은 `variant="social"`(흰 바탕·검정 글자, 공급자 가이드)에 공급자 로고를 `leftIcon`으로 준다. `callout`을 주면 버튼 오른쪽 위 모서리에 말풍선(Callout)을 끼운다(예: "최근 사용") — 버튼 글자는 움직이지 않고 자리는 DS 가 잡는다. 말풍선 글자도 버튼 안이라 버튼의 접근 가능한 이름에 이어진다(스크린 리더도 "최근 사용"을 듣는다).
127
128
 
128
129
  **쓰지 않는다.** 확인과 취소 두 버튼을 가진 대화상자는 버튼을 직접 배치하지 말고 ModalWithDoubleButton을 쓴다. 화면 안의 패널 전환은 Tabs, 사이드 메뉴 항목은 CollapsibleMenu를 쓴다.
129
130
 
130
131
  ```tsx
131
132
  <>
132
133
  <CTAButton variant="primary" size="m" text="저장" onClick={() => {}} />
133
- <CTAButton variant="social" size="l" text="Google로 계속하기" leftIcon={<img src="/icons/google.svg" alt="" />} />
134
+ <CTAButton
135
+ variant="social"
136
+ size="l"
137
+ text="Google로 계속하기"
138
+ leftIcon={<img src="/icons/google.svg" alt="" />}
139
+ callout="최근 사용"
140
+ />
134
141
  </>
135
142
  ```
136
143
 
@@ -144,11 +151,40 @@ import { CTAButton } from '@nurihaus/web-design-system'; // 루트.
144
151
  | `variant` | `'neutral' \| 'primary' \| 'outlined' \| 'secondary' \| 'ghost' \| 'confirm' \| 'social'` | | `'primary'` |
145
152
  | `leftIcon` | `ReactNode` | | |
146
153
  | `rightIcon` | `ReactNode` | | |
154
+ | `callout` | `ReactNode` | | |
147
155
  | `loading` | `boolean` | | |
148
156
  | `trackProps` | `Record<string, string \| number \| boolean>` | | |
149
157
 
150
158
  이 밖에 React·HTML 기본 속성 276개를 받는다.
151
159
 
160
+ ## Callout
161
+
162
+ ```ts
163
+ import { Callout } from '@nurihaus/web-design-system/callout'; // 이 컴포넌트만 싣는다 (권장)
164
+ import { Callout } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
165
+ ```
166
+
167
+ **언제 쓴다.** 버튼 같은 대상에 붙어 늘 떠 있는 짧은 라벨 말풍선에 쓴다(예: 로그인 버튼의 "최근 사용"). 꼬리 자리는 `tail`(`bottom-start` 기본·`bottom-end`·`top-start`·`top-end`)로 고른다. 나타날 때 꼬리에서 튀어나온 뒤 세 번 둥실 움직이고 멈춘다(동작 줄이기 설정이면 움직이지 않는다). 모션은 쓰는 쪽이 고르지 않는다. 버튼에 붙일 때는 Callout 을 직접 놓지 말고 CTAButton 의 `callout` prop 을 쓴다 — 모서리 자리를 DS 가 잡는다. 그 밖의 대상에 놓을 때는 자리(`position: absolute`·위치)를 쓰는 쪽이 `className` 으로 정한다. 위치는 `top`·`right` 같은 값으로 잡는다 — `transform` 은 등장 모션이 쓰므로 덮어써진다. `.base-callout` 이 꼬리 기준으로 `position: relative` 를 가지므로 한 단계 구체적인 선택자(`.slot > .x`)로 덮는다.
168
+
169
+ **쓰지 않는다.** 마우스를 올리거나 포커스했을 때만 설명을 보여 주려면 Tooltip 을 쓴다. 상태값·분류 라벨은 OptionBadge 를 쓴다.
170
+
171
+ ```tsx
172
+ <>
173
+ <Callout text="최근 사용" />
174
+ <Callout text="새 기능" tail="top-end" />
175
+ <CTAButton variant="social" size="l" text="Google로 계속하기" callout="최근 사용" />
176
+ </>
177
+ ```
178
+
179
+ ### props
180
+
181
+ | prop | 타입 | 필수 | 기본값 |
182
+ | --- | --- | --- | --- |
183
+ | `text` | `ReactNode` | 예 | |
184
+ | `tail` | `'bottom-start' \| 'bottom-end' \| 'top-start' \| 'top-end'` | | `'bottom-start'` |
185
+
186
+ 이 밖에 React·HTML 기본 속성 265개를 받는다.
187
+
152
188
  ## OptionBadge
153
189
 
154
190
  ```ts
@@ -156,23 +192,19 @@ import { OptionBadge } from '@nurihaus/web-design-system/option-badge'; // 이
156
192
  import { OptionBadge } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
157
193
  ```
158
194
 
159
- **언제 쓴다.** 상태값이나 분류처럼 짧은 값 하나(`option`)를 라벨로 보여줄 때 쓴다. `variant`로 색을 고른다(`neutral`·`primary`·`danger`·`outlined`). 색 prop 은 없다. `tooltip`을 주면 마우스를 올렸을 때 설명이 뜬다. 버튼 같은 대상의 모서리에 늘 떠 있는 말풍선(예: 로그인 버튼의 "최근 사용")은 `variant="callout"`이다 — 꼬리가 아래 왼쪽을 가리키고, 자리(`position: absolute` 와 위치)는 쓰는 쪽이 `className`으로 정한다.
195
+ **언제 쓴다.** 상태값이나 분류처럼 짧은 값 하나(`option`)를 라벨로 보여줄 때 쓴다. `variant`로 색을 고른다(`neutral`·`primary`·`danger`·`outlined`). 색 prop 은 없다. `tooltip`을 주면 마우스를 올렸을 때 설명이 뜬다. 대상에 붙어 늘 떠 있는 말풍선은 Callout 을 쓴다.
160
196
 
161
197
  **쓰지 않는다.** 아이콘이 함께 필요하면 IconTextBadge를, 아이콘과 텍스트 오른쪽에 수치 같은 부가 값까지 붙여야 하면 IconTextOptionBadge를 쓴다. 클릭 동작이 필요한 요소에는 CTAButton을 쓴다.
162
198
 
163
199
  ```tsx
164
- <>
165
- <OptionBadge option="진행 중" variant="primary" size="s" width="fit-content" />
166
- {/* 자리는 쓰는 쪽 CSS: 감싼 요소 position: relative, .last-used { position: absolute; top: -12px; right: 14px; } */}
167
- <OptionBadge option="최근 사용" variant="callout" size="xs" width="fit-content" className="last-used" />
168
- </>
200
+ <OptionBadge option="진행 중" variant="primary" size="s" width="fit-content" />
169
201
  ```
170
202
 
171
203
  ### props
172
204
 
173
205
  | prop | 타입 | 필수 | 기본값 |
174
206
  | --- | --- | --- | --- |
175
- | `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined' \| 'callout'` | | `'neutral'` |
207
+ | `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined'` | | `'neutral'` |
176
208
  | `width` | `string \| number` | | `'100%'` |
177
209
  | `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | | `'xl'` |
178
210
  | `option` | `ReactNode` | 예 | |
@@ -208,7 +240,7 @@ import { IconTextBadge } from '@nurihaus/web-design-system'; // 루
208
240
 
209
241
  | prop | 타입 | 필수 | 기본값 |
210
242
  | --- | --- | --- | --- |
211
- | `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined' \| 'callout'` | | `'neutral'` |
243
+ | `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined'` | | `'neutral'` |
212
244
  | `width` | `string \| number` | | `'100%'` |
213
245
  | `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | | `'xl'` |
214
246
  | `icon` | `ReactNode` | 예 | |
@@ -245,7 +277,7 @@ import { IconTextOptionBadge } from '@nurihaus/web-design-system'; /
245
277
 
246
278
  | prop | 타입 | 필수 | 기본값 |
247
279
  | --- | --- | --- | --- |
248
- | `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined' \| 'callout'` | | `'neutral'` |
280
+ | `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined'` | | `'neutral'` |
249
281
  | `width` | `string \| number` | | `'100%'` |
250
282
  | `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | | `'xl'` |
251
283
  | `icon` | `ReactNode` | 예 | |
@@ -0,0 +1,220 @@
1
+ "use client";
2
+ import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
3
+ import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8__ from "react/jsx-runtime";
4
+ /******/ var __webpack_modules__ = ({
5
+
6
+ /***/ 1163
7
+ (__unused_webpack_module, __webpack_exports__, __nuri_require__) {
8
+
9
+ /* harmony export */ __nuri_require__.d(__webpack_exports__, {
10
+ /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
11
+ /* harmony export */ });
12
+ /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __nuri_require__(612);
13
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __nuri_require__(1041);
14
+ /* harmony import */ var _helpers_utils_getMergedProps__WEBPACK_IMPORTED_MODULE_2__ = __nuri_require__(7335);
15
+ /* harmony import */ var _base_callout__WEBPACK_IMPORTED_MODULE_3__ = __nuri_require__(1211);
16
+ /* harmony import */ var _callout_props__WEBPACK_IMPORTED_MODULE_4__ = __nuri_require__(7810);
17
+ var __assign = undefined && undefined.__assign || function () {
18
+ __assign = Object.assign || function (t) {
19
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
20
+ s = arguments[i];
21
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
22
+ }
23
+ return t;
24
+ };
25
+ return __assign.apply(this, arguments);
26
+ };
27
+ var __rest = undefined && undefined.__rest || function (s, e) {
28
+ var t = {};
29
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
30
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
32
+ }
33
+ return t;
34
+ };
35
+
36
+
37
+
38
+
39
+
40
+ /** 대상에 붙어 늘 떠 있는 작은 말풍선 (ADR 0007). 자리는 쓰는 쪽이 정한다 — CTAButton 은 `callout` prop 으로 모서리에 끼운다 */
41
+ var Callout = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_1__.forwardRef)(function (props, ref) {
42
+ var _a = (0,_helpers_utils_getMergedProps__WEBPACK_IMPORTED_MODULE_2__/* .getMergedProps */ .p)(props, _callout_props__WEBPACK_IMPORTED_MODULE_4__/* .calloutProps */ .B),
43
+ text = _a.text,
44
+ restProps = __rest(_a, ["text"]);
45
+ return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_base_callout__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A, __assign({
46
+ ref: ref
47
+ }, restProps, {
48
+ children: text
49
+ }));
50
+ });
51
+ Callout.displayName = 'Callout';
52
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Callout);
53
+
54
+ /***/ },
55
+
56
+ /***/ 1041
57
+ (module, __unused_webpack_exports, __nuri_require__) {
58
+
59
+ var x = (y) => {
60
+ var x = {}; __nuri_require__.d(x, y); return x
61
+ }
62
+ var y = (x) => (() => (x))
63
+ module.exports = x({ ["forwardRef"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.forwardRef) });
64
+
65
+ /***/ },
66
+
67
+ /***/ 612
68
+ (module, __unused_webpack_exports, __nuri_require__) {
69
+
70
+ var x = (y) => {
71
+ var x = {}; __nuri_require__.d(x, y); return x
72
+ }
73
+ var y = (x) => (() => (x))
74
+ module.exports = x({ ["jsx"]: () => (__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_179142b8__.jsx) });
75
+
76
+ /***/ }
77
+
78
+ /******/ });
79
+ /************************************************************************/
80
+ /******/ // The module cache
81
+ /******/ var __webpack_module_cache__ = {};
82
+ /******/
83
+ /******/ // The require function
84
+ /******/ function __nuri_require__(moduleId) {
85
+ /******/ // Check if module is in cache
86
+ /******/ var cachedModule = __webpack_module_cache__[moduleId];
87
+ /******/ if (cachedModule !== undefined) {
88
+ /******/ return cachedModule.exports;
89
+ /******/ }
90
+ /******/ // Create a new module (and put it into the cache)
91
+ /******/ var module = __webpack_module_cache__[moduleId] = {
92
+ /******/ // no module.id needed
93
+ /******/ // no module.loaded needed
94
+ /******/ exports: {}
95
+ /******/ };
96
+ /******/
97
+ /******/ // Execute the module function
98
+ /******/ __webpack_modules__[moduleId](module, module.exports, __nuri_require__);
99
+ /******/
100
+ /******/ // Return the exports of the module
101
+ /******/ return module.exports;
102
+ /******/ }
103
+ /******/
104
+ /******/ // expose the modules object (__webpack_modules__)
105
+ /******/ __nuri_require__.m = __webpack_modules__;
106
+ /******/
107
+ /************************************************************************/
108
+ /******/ /* webpack/runtime/chunk loaded */
109
+ /******/ (() => {
110
+ /******/ var deferred = [];
111
+ /******/ __nuri_require__.O = (result, chunkIds, fn, priority) => {
112
+ /******/ if(chunkIds) {
113
+ /******/ priority = priority || 0;
114
+ /******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
115
+ /******/ deferred[i] = [chunkIds, fn, priority];
116
+ /******/ return;
117
+ /******/ }
118
+ /******/ var notFulfilled = Infinity;
119
+ /******/ for (var i = 0; i < deferred.length; i++) {
120
+ /******/ var [chunkIds, fn, priority] = deferred[i];
121
+ /******/ var fulfilled = true;
122
+ /******/ for (var j = 0; j < chunkIds.length; j++) {
123
+ /******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__nuri_require__.O).every((key) => (__nuri_require__.O[key](chunkIds[j])))) {
124
+ /******/ chunkIds.splice(j--, 1);
125
+ /******/ } else {
126
+ /******/ fulfilled = false;
127
+ /******/ if(priority < notFulfilled) notFulfilled = priority;
128
+ /******/ }
129
+ /******/ }
130
+ /******/ if(fulfilled) {
131
+ /******/ deferred.splice(i--, 1)
132
+ /******/ var r = fn();
133
+ /******/ if (r !== undefined) result = r;
134
+ /******/ }
135
+ /******/ }
136
+ /******/ return result;
137
+ /******/ };
138
+ /******/ })();
139
+ /******/
140
+ /******/ /* webpack/runtime/define property getters */
141
+ /******/ (() => {
142
+ /******/ // define getter functions for harmony exports
143
+ /******/ __nuri_require__.d = (exports, definition) => {
144
+ /******/ for(var key in definition) {
145
+ /******/ if(__nuri_require__.o(definition, key) && !__nuri_require__.o(exports, key)) {
146
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
147
+ /******/ }
148
+ /******/ }
149
+ /******/ };
150
+ /******/ })();
151
+ /******/
152
+ /******/ /* webpack/runtime/hasOwnProperty shorthand */
153
+ /******/ (() => {
154
+ /******/ __nuri_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
155
+ /******/ })();
156
+ /******/
157
+ /******/ /* webpack/runtime/export webpack runtime */
158
+ /******/ export { __nuri_require__ };
159
+ /******/
160
+ /******/ /* webpack/runtime/import chunk loading */
161
+ /******/ (() => {
162
+ /******/ // no baseURI
163
+ /******/
164
+ /******/ // object to store loaded and loading chunks
165
+ /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
166
+ /******/ // [resolve, Promise] = chunk loading, 0 = chunk loaded
167
+ /******/ var installedChunks = {
168
+ /******/ 937: 0
169
+ /******/ };
170
+ /******/
171
+ /******/ var installChunk = (data) => {
172
+ /******/ var {__webpack_esm_ids__, __webpack_esm_modules__, __webpack_esm_runtime__} = data;
173
+ /******/ // add "modules" to the modules object,
174
+ /******/ // then flag all "ids" as loaded and fire callback
175
+ /******/ var moduleId, chunkId, i = 0;
176
+ /******/ for(moduleId in __webpack_esm_modules__) {
177
+ /******/ if(__nuri_require__.o(__webpack_esm_modules__, moduleId)) {
178
+ /******/ __nuri_require__.m[moduleId] = __webpack_esm_modules__[moduleId];
179
+ /******/ }
180
+ /******/ }
181
+ /******/ if(__webpack_esm_runtime__) __webpack_esm_runtime__(__nuri_require__);
182
+ /******/ for(;i < __webpack_esm_ids__.length; i++) {
183
+ /******/ chunkId = __webpack_esm_ids__[i];
184
+ /******/ if(__nuri_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
185
+ /******/ installedChunks[chunkId][0]();
186
+ /******/ }
187
+ /******/ installedChunks[__webpack_esm_ids__[i]] = 0;
188
+ /******/ }
189
+ /******/ __nuri_require__.O();
190
+ /******/ }
191
+ /******/
192
+ /******/ // no chunk on demand loading
193
+ /******/
194
+ /******/ // no prefetching
195
+ /******/
196
+ /******/ // no preloaded
197
+ /******/
198
+ /******/ __nuri_require__.C = installChunk;
199
+ /******/
200
+ /******/ __nuri_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);
201
+ /******/ // no HMR
202
+ /******/
203
+ /******/ // no HMR manifest
204
+ /******/ })();
205
+ /******/
206
+ /************************************************************************/
207
+ /******/
208
+ /******/ import * as __webpack_chunk_1__ from "./chunk-6364.js";
209
+ /******/ __nuri_require__.C(__webpack_chunk_1__);
210
+ /******/ import * as __webpack_chunk_2__ from "./chunk-2496.js";
211
+ /******/ __nuri_require__.C(__webpack_chunk_2__);
212
+ /******/
213
+ /******/ // startup
214
+ /******/ // Load entry module and return exports
215
+ /******/ // This entry module depends on other loaded chunks and execution need to be delayed
216
+ /******/ var __webpack_exports__ = __nuri_require__.O(undefined, [6364,2496], () => (__nuri_require__(1163)))
217
+ /******/ __webpack_exports__ = __nuri_require__.O(__webpack_exports__);
218
+ /******/ const __webpack_exports__default = __webpack_exports__.A;
219
+ /******/ export { __webpack_exports__default as default };
220
+ /******/
@@ -0,0 +1,70 @@
1
+ "use client";
2
+ export const __webpack_esm_id__ = 2496;
3
+ export const __webpack_esm_ids__ = [2496];
4
+ export const __webpack_esm_modules__ = {
5
+
6
+ /***/ 1211
7
+ (__unused_webpack_module, __webpack_exports__, __nuri_require__) {
8
+
9
+ /* harmony export */ __nuri_require__.d(__webpack_exports__, {
10
+ /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
11
+ /* harmony export */ });
12
+ /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __nuri_require__(612);
13
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __nuri_require__(1041);
14
+ /* harmony import */ var _helpers_utils_classNames__WEBPACK_IMPORTED_MODULE_2__ = __nuri_require__(3274);
15
+ var __assign = undefined && undefined.__assign || function () {
16
+ __assign = Object.assign || function (t) {
17
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
18
+ s = arguments[i];
19
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
20
+ }
21
+ return t;
22
+ };
23
+ return __assign.apply(this, arguments);
24
+ };
25
+ var __rest = undefined && undefined.__rest || function (s, e) {
26
+ var t = {};
27
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
28
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
29
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
30
+ }
31
+ return t;
32
+ };
33
+
34
+
35
+
36
+ // span 이다 — CTAButton 처럼 button 안에도 들어간다 (button 안에는 div 를 둘 수 없다)
37
+ var BaseCallout = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_1__.forwardRef)(function (props, ref) {
38
+ var className = props.className,
39
+ restProps = __rest(props, ["className"]);
40
+ return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("span", __assign({
41
+ ref: ref,
42
+ className: (0,_helpers_utils_classNames__WEBPACK_IMPORTED_MODULE_2__/* .classNames */ .x)('nuri-theme base-callout', className)
43
+ }, restProps));
44
+ });
45
+ BaseCallout.displayName = 'BaseCallout';
46
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BaseCallout);
47
+
48
+ /***/ },
49
+
50
+ /***/ 7810
51
+ (__unused_webpack_module, __webpack_exports__, __nuri_require__) {
52
+
53
+ /* harmony export */ __nuri_require__.d(__webpack_exports__, {
54
+ /* harmony export */ B: () => (/* binding */ calloutProps)
55
+ /* harmony export */ });
56
+ /* unused harmony export tail */
57
+ /** 꼬리가 나오는 자리. `bottom-start` 는 말풍선 아래 왼쪽에서 아래를 가리킨다 */
58
+ var tail = ['bottom-start', 'bottom-end', 'top-start', 'top-end'];
59
+ var calloutProps = {
60
+ tail: {
61
+ type: 'className',
62
+ className: 'tail',
63
+ values: tail,
64
+ "default": 'bottom-start'
65
+ }
66
+ };
67
+
68
+ /***/ }
69
+
70
+ };
@@ -0,0 +1,79 @@
1
+ "use client";
2
+ export const __webpack_esm_id__ = 5226;
3
+ export const __webpack_esm_ids__ = [5226];
4
+ export const __webpack_esm_modules__ = {
5
+
6
+ /***/ 9976
7
+ (__unused_webpack_module, __webpack_exports__, __nuri_require__) {
8
+
9
+ /* harmony export */ __nuri_require__.d(__webpack_exports__, {
10
+ /* harmony export */ Lr: () => (/* binding */ ctaButtonProps)
11
+ /* harmony export */ });
12
+ /* unused harmony exports variant, sizes */
13
+ /* harmony import */ var _helpers_props_common_props__WEBPACK_IMPORTED_MODULE_0__ = __nuri_require__(7298);
14
+
15
+ var variant = ['primary', 'secondary', 'ghost', 'neutral', 'confirm', 'outlined', 'social'];
16
+ var sizes = ['xs', 's', 'm', 'l', 'xl'];
17
+ var ctaButtonProps = {
18
+ variant: {
19
+ type: 'className',
20
+ className: 'variant',
21
+ values: variant,
22
+ "default": 'primary'
23
+ },
24
+ size: (0,_helpers_props_common_props__WEBPACK_IMPORTED_MODULE_0__/* .sizeProp */ .lw)(sizes, 'm')
25
+ };
26
+
27
+ /***/ },
28
+
29
+ /***/ 1163
30
+ (__unused_webpack_module, __webpack_exports__, __nuri_require__) {
31
+
32
+ /* harmony export */ __nuri_require__.d(__webpack_exports__, {
33
+ /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
34
+ /* harmony export */ });
35
+ /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __nuri_require__(612);
36
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __nuri_require__(1041);
37
+ /* harmony import */ var _helpers_utils_getMergedProps__WEBPACK_IMPORTED_MODULE_2__ = __nuri_require__(7335);
38
+ /* harmony import */ var _base_callout__WEBPACK_IMPORTED_MODULE_3__ = __nuri_require__(1211);
39
+ /* harmony import */ var _callout_props__WEBPACK_IMPORTED_MODULE_4__ = __nuri_require__(7810);
40
+ var __assign = undefined && undefined.__assign || function () {
41
+ __assign = Object.assign || function (t) {
42
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
43
+ s = arguments[i];
44
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
45
+ }
46
+ return t;
47
+ };
48
+ return __assign.apply(this, arguments);
49
+ };
50
+ var __rest = undefined && undefined.__rest || function (s, e) {
51
+ var t = {};
52
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
53
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
54
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
55
+ }
56
+ return t;
57
+ };
58
+
59
+
60
+
61
+
62
+
63
+ /** 대상에 붙어 늘 떠 있는 작은 말풍선 (ADR 0007). 자리는 쓰는 쪽이 정한다 — CTAButton 은 `callout` prop 으로 모서리에 끼운다 */
64
+ var Callout = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_1__.forwardRef)(function (props, ref) {
65
+ var _a = (0,_helpers_utils_getMergedProps__WEBPACK_IMPORTED_MODULE_2__/* .getMergedProps */ .p)(props, _callout_props__WEBPACK_IMPORTED_MODULE_4__/* .calloutProps */ .B),
66
+ text = _a.text,
67
+ restProps = __rest(_a, ["text"]);
68
+ return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_base_callout__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A, __assign({
69
+ ref: ref
70
+ }, restProps, {
71
+ children: text
72
+ }));
73
+ });
74
+ Callout.displayName = 'Callout';
75
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Callout);
76
+
77
+ /***/ }
78
+
79
+ };
package/dist/chunk-910.js CHANGED
@@ -14,9 +14,10 @@ export const __webpack_esm_modules__ = {
14
14
  /* harmony import */ var _helpers_hooks_useTrack__WEBPACK_IMPORTED_MODULE_2__ = __nuri_require__(4560);
15
15
  /* harmony import */ var _helpers_utils_classNames__WEBPACK_IMPORTED_MODULE_3__ = __nuri_require__(3274);
16
16
  /* harmony import */ var _helpers_utils_getMergedProps__WEBPACK_IMPORTED_MODULE_4__ = __nuri_require__(7335);
17
- /* harmony import */ var _loading_spinner_spinner__WEBPACK_IMPORTED_MODULE_5__ = __nuri_require__(6302);
18
- /* harmony import */ var _base_button__WEBPACK_IMPORTED_MODULE_6__ = __nuri_require__(8933);
19
- /* harmony import */ var _button_props__WEBPACK_IMPORTED_MODULE_7__ = __nuri_require__(9976);
17
+ /* harmony import */ var _callout_callout__WEBPACK_IMPORTED_MODULE_5__ = __nuri_require__(1163);
18
+ /* harmony import */ var _loading_spinner_spinner__WEBPACK_IMPORTED_MODULE_6__ = __nuri_require__(6302);
19
+ /* harmony import */ var _base_button__WEBPACK_IMPORTED_MODULE_7__ = __nuri_require__(8933);
20
+ /* harmony import */ var _button_props__WEBPACK_IMPORTED_MODULE_8__ = __nuri_require__(9976);
20
21
  var __assign = undefined && undefined.__assign || function () {
21
22
  __assign = Object.assign || function (t) {
22
23
  for (var s, i = 1, n = arguments.length; i < n; i++) {
@@ -43,30 +44,35 @@ var __rest = undefined && undefined.__rest || function (s, e) {
43
44
 
44
45
 
45
46
 
47
+
46
48
  var CTAButton = /*#__PURE__*/(0,react__WEBPACK_IMPORTED_MODULE_1__.forwardRef)(function (props, ref) {
47
- var _a = (0,_helpers_utils_getMergedProps__WEBPACK_IMPORTED_MODULE_4__/* .getMergedProps */ .p)(props, _button_props__WEBPACK_IMPORTED_MODULE_7__/* .ctaButtonProps */ .Lr),
49
+ var _a = (0,_helpers_utils_getMergedProps__WEBPACK_IMPORTED_MODULE_4__/* .getMergedProps */ .p)(props, _button_props__WEBPACK_IMPORTED_MODULE_8__/* .ctaButtonProps */ .Lr),
48
50
  className = _a.className,
49
51
  text = _a.text,
50
52
  leftIcon = _a.leftIcon,
51
53
  rightIcon = _a.rightIcon,
54
+ callout = _a.callout,
52
55
  _onClick = _a.onClick,
53
56
  track = _a.track,
54
57
  trackProps = _a.trackProps,
55
- restProps = __rest(_a, ["className", "text", "leftIcon", "rightIcon", "onClick", "track", "trackProps"]);
58
+ restProps = __rest(_a, ["className", "text", "leftIcon", "rightIcon", "callout", "onClick", "track", "trackProps"]);
56
59
  var emit = (0,_helpers_hooks_useTrack__WEBPACK_IMPORTED_MODULE_2__/* .useTrack */ .n)('CTAButton', {
57
60
  track: track,
58
61
  trackProps: trackProps
59
62
  });
60
- return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_base_button__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A, __assign({
63
+ return (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(_base_button__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A, __assign({
61
64
  ref: ref,
62
- className: (0,_helpers_utils_classNames__WEBPACK_IMPORTED_MODULE_3__/* .classNames */ .x)(className, 'cta-button'),
63
- loadingComponent: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_loading_spinner_spinner__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A, {}),
65
+ className: (0,_helpers_utils_classNames__WEBPACK_IMPORTED_MODULE_3__/* .classNames */ .x)(className, 'cta-button', callout ? 'with-callout' : undefined),
66
+ loadingComponent: (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_loading_spinner_spinner__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A, {}),
64
67
  onClick: function onClick(event) {
65
68
  emit('click');
66
69
  _onClick === null || _onClick === void 0 ? void 0 : _onClick(event);
67
70
  }
68
71
  }, restProps, {
69
- children: [leftIcon, text, rightIcon]
72
+ children: [leftIcon, text, rightIcon, callout ? (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(_callout_callout__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A, {
73
+ className: 'cta-button-callout',
74
+ text: callout
75
+ }) : null]
70
76
  }));
71
77
  });
72
78
  CTAButton.displayName = 'CTAButton';
@@ -1,10 +1,10 @@
1
- export declare const variant: readonly ["neutral", "primary", "danger", "outlined", "callout"];
1
+ export declare const variant: readonly ["neutral", "primary", "danger", "outlined"];
2
2
  export declare const sizes: readonly ["xs", "s", "m", "l", "xl"];
3
3
  export declare const iconTextBadgeProps: {
4
4
  variant: {
5
5
  type: "className";
6
6
  className: string;
7
- values: readonly ["neutral", "primary", "danger", "outlined", "callout"];
7
+ values: readonly ["neutral", "primary", "danger", "outlined"];
8
8
  default: "neutral";
9
9
  };
10
10
  size: import("../../helpers/types/propsDef").ClassNamePropsType<readonly ["xs", "s", "m", "l", "xl"]>;
@@ -14,7 +14,7 @@ export declare const iconTextOptionBadgeProps: {
14
14
  variant: {
15
15
  type: "className";
16
16
  className: string;
17
- values: readonly ["neutral", "primary", "danger", "outlined", "callout"];
17
+ values: readonly ["neutral", "primary", "danger", "outlined"];
18
18
  default: "neutral";
19
19
  };
20
20
  size: import("../../helpers/types/propsDef").ClassNamePropsType<readonly ["xs", "s", "m", "l", "xl"]>;
@@ -24,7 +24,7 @@ export declare const optionBadgeProps: {
24
24
  variant: {
25
25
  type: "className";
26
26
  className: string;
27
- values: readonly ["neutral", "primary", "danger", "outlined", "callout"];
27
+ values: readonly ["neutral", "primary", "danger", "outlined"];
28
28
  default: "neutral";
29
29
  };
30
30
  size: import("../../helpers/types/propsDef").ClassNamePropsType<readonly ["xs", "s", "m", "l", "xl"]>;
@@ -7,7 +7,7 @@ declare const meta: {
7
7
  control: {
8
8
  type: "select";
9
9
  };
10
- options: readonly ["neutral", "primary", "danger", "outlined", "callout"];
10
+ options: readonly ["neutral", "primary", "danger", "outlined"];
11
11
  };
12
12
  size: {
13
13
  control: {
@@ -15,4 +15,6 @@ export interface CTAButtonProps extends ComponentPropsWithRef<'button'>, CommonB
15
15
  text: string | ReactNode;
16
16
  leftIcon?: ReactNode;
17
17
  rightIcon?: ReactNode;
18
+ /** 버튼 오른쪽 위 모서리에 끼우는 말풍선(Callout) 글자. 글자는 움직이지 않는다. 로딩 중에는 Spinner 와 바뀌어 숨는다 */
19
+ callout?: ReactNode;
18
20
  }
@@ -0,0 +1,4 @@
1
+ declare const BaseCallout: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & {
2
+ ref?: ((instance: HTMLSpanElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLSpanElement> | null | undefined;
3
+ }, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
4
+ export default BaseCallout;
@@ -0,0 +1,10 @@
1
+ /** 꼬리가 나오는 자리. `bottom-start` 는 말풍선 아래 왼쪽에서 아래를 가리킨다 */
2
+ export declare const tail: readonly ["bottom-start", "bottom-end", "top-start", "top-end"];
3
+ export declare const calloutProps: {
4
+ tail: {
5
+ type: "className";
6
+ className: string;
7
+ values: readonly ["bottom-start", "bottom-end", "top-start", "top-end"];
8
+ default: "bottom-start";
9
+ };
10
+ };
@@ -0,0 +1,7 @@
1
+ import { ComponentPropsWithRef, ReactNode } from 'react';
2
+ import { tail } from './callout-props';
3
+ export type BaseCalloutProps = ComponentPropsWithRef<'span'>;
4
+ export interface CalloutProps extends Omit<ComponentPropsWithRef<'span'>, 'children'> {
5
+ text: ReactNode;
6
+ tail?: (typeof tail)[number];
7
+ }
@@ -0,0 +1,5 @@
1
+ import { CalloutProps } from './callout-type';
2
+ /** 대상에 붙어 늘 떠 있는 작은 말풍선 (ADR 0007). 자리는 쓰는 쪽이 정한다 — CTAButton 은 `callout` prop 으로 모서리에 끼운다 */
3
+ declare const Callout: import("react").ForwardRefExoticComponent<Omit<CalloutProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
4
+ export default Callout;
5
+ export type { CalloutProps } from './callout-type';
@@ -0,0 +1,22 @@
1
+ import type { StoryObj } from '@storybook/react-webpack5';
2
+ declare const meta: {
3
+ title: string;
4
+ component: import("react").ForwardRefExoticComponent<Omit<import("./callout-type").CalloutProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
5
+ argTypes: {
6
+ tail: {
7
+ control: {
8
+ type: "select";
9
+ };
10
+ options: readonly ["bottom-start", "bottom-end", "top-start", "top-end"];
11
+ };
12
+ };
13
+ args: {
14
+ text: string;
15
+ };
16
+ };
17
+ export default meta;
18
+ type Story = StoryObj<typeof meta>;
19
+ export declare const Default: Story;
20
+ export declare const Tails: Story;
21
+ /** CTAButton 의 callout prop — 버튼 오른쪽 위 모서리에 끼운다 */
22
+ export declare const OnButton: Story;