@x-plat/design-system 0.7.2 → 0.8.1

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 (52) hide show
  1. package/dist/components/AutoResizeTextArea/index.css +2 -0
  2. package/dist/components/Button/index.css +2 -1
  3. package/dist/components/Button/index.d.cts +6 -0
  4. package/dist/components/Button/index.d.ts +6 -0
  5. package/dist/components/Chart/index.cjs +8 -1
  6. package/dist/components/Chart/index.js +8 -1
  7. package/dist/components/ChatInput/index.css +4 -0
  8. package/dist/components/DatePicker/index.cjs +388 -400
  9. package/dist/components/DatePicker/index.css +7 -1
  10. package/dist/components/DatePicker/index.js +375 -387
  11. package/dist/components/Dropdown/index.cjs +21 -26
  12. package/dist/components/Dropdown/index.js +20 -25
  13. package/dist/components/Input/index.css +2 -0
  14. package/dist/components/Link/index.cjs +64 -0
  15. package/dist/components/Link/index.css +25 -0
  16. package/dist/components/Link/index.d.cts +27 -0
  17. package/dist/components/Link/index.d.ts +27 -0
  18. package/dist/components/Link/index.js +37 -0
  19. package/dist/components/LinkButton/index.cjs +64 -0
  20. package/dist/components/LinkButton/index.css +106 -0
  21. package/dist/components/LinkButton/index.d.cts +28 -0
  22. package/dist/components/LinkButton/index.d.ts +28 -0
  23. package/dist/components/LinkButton/index.js +37 -0
  24. package/dist/components/Modal/index.cjs +18 -28
  25. package/dist/components/Modal/index.css +3 -0
  26. package/dist/components/Modal/index.js +17 -27
  27. package/dist/components/PopOver/index.cjs +18 -23
  28. package/dist/components/PopOver/index.js +17 -22
  29. package/dist/components/Select/index.cjs +337 -342
  30. package/dist/components/Select/index.js +336 -341
  31. package/dist/components/TextArea/index.css +2 -0
  32. package/dist/components/Tooltip/index.cjs +92 -52
  33. package/dist/components/Tooltip/index.d.cts +10 -2
  34. package/dist/components/Tooltip/index.d.ts +10 -2
  35. package/dist/components/Tooltip/index.js +91 -51
  36. package/dist/components/index.cjs +578 -488
  37. package/dist/components/index.css +39 -1
  38. package/dist/components/index.d.cts +2 -0
  39. package/dist/components/index.d.ts +2 -0
  40. package/dist/components/index.js +527 -439
  41. package/dist/index.cjs +602 -512
  42. package/dist/index.css +39 -1
  43. package/dist/index.d.cts +2 -0
  44. package/dist/index.d.ts +2 -0
  45. package/dist/index.js +549 -461
  46. package/guidelines/AGENT_PROMPT.md +2 -2
  47. package/guidelines/Guidelines.md +2 -1
  48. package/guidelines/components/button.md +54 -0
  49. package/guidelines/components/card.md +15 -19
  50. package/guidelines/components/link.md +35 -0
  51. package/guidelines/components/overlay.md +30 -1
  52. package/package.json +1 -1
@@ -44,6 +44,8 @@
44
44
  .lib-xplat-textarea-wrap .lib-xplat-textarea:focus {
45
45
  border-color: var(--semantic-interaction-focus-ring);
46
46
  box-shadow: 0 0 0 2px var(--semantic-interaction-overlay-10);
47
+ outline: 2px solid transparent;
48
+ outline-offset: 2px;
47
49
  }
48
50
  .lib-xplat-textarea-wrap .lib-xplat-textarea:not(:placeholder-shown):not(:focus) {
49
51
  border-color: var(--semantic-border-tertiary);
@@ -35,18 +35,13 @@ __export(Tooltip_exports, {
35
35
  module.exports = __toCommonJS(Tooltip_exports);
36
36
 
37
37
  // src/components/Tooltip/Tooltip.tsx
38
- var import_react2 = __toESM(require("react"), 1);
38
+ var import_react = __toESM(require("react"), 1);
39
39
 
40
40
  // src/tokens/hooks/Portal.tsx
41
- var import_react = __toESM(require("react"), 1);
42
41
  var import_react_dom = __toESM(require("react-dom"), 1);
43
- var import_jsx_runtime = require("react/jsx-runtime");
44
- var PortalContainerContext = import_react.default.createContext(null);
45
42
  var Portal = ({ children }) => {
46
- const contextContainer = import_react.default.useContext(PortalContainerContext);
47
43
  if (typeof document === "undefined") return null;
48
- const container = contextContainer ?? document.body;
49
- return import_react_dom.default.createPortal(children, container);
44
+ return import_react_dom.default.createPortal(children, document.body);
50
45
  };
51
46
  Portal.displayName = "Portal";
52
47
  var Portal_default = Portal;
@@ -68,67 +63,111 @@ function clsx() {
68
63
  var clsx_default = clsx;
69
64
 
70
65
  // src/components/Tooltip/Tooltip.tsx
71
- var import_jsx_runtime2 = require("react/jsx-runtime");
66
+ var import_jsx_runtime = require("react/jsx-runtime");
72
67
  var OFFSET = 12;
68
+ var GAP = 8;
73
69
  var SHOW_DELAY = 300;
74
70
  var Tooltip = (props) => {
75
71
  const {
76
- type = "dark",
72
+ children,
77
73
  title,
78
74
  description,
79
- children,
75
+ type = "dark",
76
+ follow = false,
80
77
  disabled = false
81
78
  } = props;
82
- const triggerRef = import_react2.default.useRef(null);
83
- const tooltipRef = import_react2.default.useRef(null);
84
- const [visible, setVisible] = import_react2.default.useState(false);
85
- const [pos, setPos] = import_react2.default.useState({ left: 0, top: 0 });
86
- const delayTimer = import_react2.default.useRef(0);
87
- const calculatePos = import_react2.default.useCallback((clientX, clientY) => {
79
+ const triggerRef = import_react.default.useRef(null);
80
+ const tooltipRef = import_react.default.useRef(null);
81
+ const [visible, setVisible] = import_react.default.useState(false);
82
+ const [pos, setPos] = import_react.default.useState({ left: 0, top: 0 });
83
+ const delayTimer = import_react.default.useRef(0);
84
+ const rafRef = import_react.default.useRef(0);
85
+ const cursor = import_react.default.useRef(null);
86
+ const clamp = import_react.default.useCallback((left, top, w, h) => {
87
+ const vw = window.innerWidth;
88
+ const vh = window.innerHeight;
89
+ return {
90
+ left: Math.min(Math.max(GAP, left), Math.max(GAP, vw - w - GAP)),
91
+ top: Math.min(Math.max(GAP, top), Math.max(GAP, vh - h - GAP))
92
+ };
93
+ }, []);
94
+ const placeAtCursor = import_react.default.useCallback((x, y) => {
88
95
  const el = tooltipRef.current;
89
96
  if (!el) return;
90
97
  const w = el.offsetWidth;
91
98
  const h = el.offsetHeight;
92
- const vw = window.innerWidth;
93
- let left = clientX + OFFSET;
94
- let top = clientY - h - OFFSET;
95
- if (left + w > vw - 8) left = clientX - w - OFFSET;
96
- if (top < 8) top = clientY + OFFSET;
97
- if (left < 8) left = 8;
98
- setPos({ left, top });
99
- }, []);
100
- const handleMouseEnter = import_react2.default.useCallback(() => {
99
+ let left = x + OFFSET;
100
+ let top = y - h - OFFSET;
101
+ if (left + w > window.innerWidth - GAP) left = x - w - OFFSET;
102
+ if (top < GAP) top = y + OFFSET;
103
+ setPos(clamp(left, top, w, h));
104
+ }, [clamp]);
105
+ const placeAtTrigger = import_react.default.useCallback(() => {
106
+ const el = tooltipRef.current;
107
+ const trigger = triggerRef.current;
108
+ if (!el || !trigger) return;
109
+ const w = el.offsetWidth;
110
+ const h = el.offsetHeight;
111
+ const rect = trigger.getBoundingClientRect();
112
+ let top = rect.top - h - GAP;
113
+ if (top < GAP) top = rect.bottom + GAP;
114
+ const left = rect.left + rect.width / 2 - w / 2;
115
+ setPos(clamp(left, top, w, h));
116
+ }, [clamp]);
117
+ const reposition = import_react.default.useCallback(() => {
118
+ if (follow && cursor.current) {
119
+ placeAtCursor(cursor.current.x, cursor.current.y);
120
+ } else {
121
+ placeAtTrigger();
122
+ }
123
+ }, [follow, placeAtCursor, placeAtTrigger]);
124
+ const handleMouseEnter = import_react.default.useCallback((e) => {
101
125
  if (disabled) return;
102
- delayTimer.current = window.setTimeout(() => {
103
- setVisible(true);
104
- }, SHOW_DELAY);
126
+ cursor.current = { x: e.clientX, y: e.clientY };
127
+ delayTimer.current = window.setTimeout(() => setVisible(true), SHOW_DELAY);
105
128
  }, [disabled]);
106
- const handleMouseMove = import_react2.default.useCallback((e) => {
107
- if (!visible) return;
108
- calculatePos(e.clientX, e.clientY);
109
- }, [visible, calculatePos]);
110
- const handleMouseLeave = import_react2.default.useCallback(() => {
129
+ const handleMouseMove = import_react.default.useCallback((e) => {
130
+ cursor.current = { x: e.clientX, y: e.clientY };
131
+ if (!visible || !follow) return;
132
+ cancelAnimationFrame(rafRef.current);
133
+ rafRef.current = requestAnimationFrame(() => {
134
+ if (cursor.current) placeAtCursor(cursor.current.x, cursor.current.y);
135
+ });
136
+ }, [visible, follow, placeAtCursor]);
137
+ const close = import_react.default.useCallback(() => {
111
138
  window.clearTimeout(delayTimer.current);
139
+ cancelAnimationFrame(rafRef.current);
112
140
  setVisible(false);
113
141
  }, []);
114
- const handleClick = import_react2.default.useCallback(() => {
115
- window.clearTimeout(delayTimer.current);
116
- setVisible(false);
117
- }, []);
118
- const handleFocus = import_react2.default.useCallback(() => {
142
+ const handleMouseLeave = import_react.default.useCallback(() => {
143
+ cursor.current = null;
144
+ close();
145
+ }, [close]);
146
+ const handleFocus = import_react.default.useCallback(() => {
119
147
  if (disabled) return;
148
+ cursor.current = null;
120
149
  setVisible(true);
121
150
  }, [disabled]);
122
- const handleBlur = import_react2.default.useCallback(() => {
123
- setVisible(false);
151
+ import_react.default.useLayoutEffect(() => {
152
+ if (!visible) return;
153
+ reposition();
154
+ }, [visible, reposition]);
155
+ import_react.default.useEffect(() => {
156
+ if (!visible || follow) return;
157
+ const onChange = () => placeAtTrigger();
158
+ window.addEventListener("scroll", onChange, true);
159
+ window.addEventListener("resize", onChange);
160
+ return () => {
161
+ window.removeEventListener("scroll", onChange, true);
162
+ window.removeEventListener("resize", onChange);
163
+ };
164
+ }, [visible, follow, placeAtTrigger]);
165
+ import_react.default.useEffect(() => () => {
166
+ window.clearTimeout(delayTimer.current);
167
+ cancelAnimationFrame(rafRef.current);
124
168
  }, []);
125
- import_react2.default.useLayoutEffect(() => {
126
- if (!visible || !triggerRef.current) return;
127
- const rect = triggerRef.current.getBoundingClientRect();
128
- calculatePos(rect.right, rect.top);
129
- }, [visible, calculatePos]);
130
- if (!title && !description) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
131
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
169
+ if (!title && !description) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
170
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
132
171
  "div",
133
172
  {
134
173
  ref: triggerRef,
@@ -136,20 +175,21 @@ var Tooltip = (props) => {
136
175
  onMouseEnter: handleMouseEnter,
137
176
  onMouseMove: handleMouseMove,
138
177
  onMouseLeave: handleMouseLeave,
139
- onClick: handleClick,
178
+ onClick: close,
140
179
  onFocus: handleFocus,
141
- onBlur: handleBlur,
180
+ onBlur: close,
142
181
  children: [
143
182
  children,
144
- visible && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
183
+ visible && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal_default, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
145
184
  "div",
146
185
  {
147
186
  ref: tooltipRef,
187
+ role: "tooltip",
148
188
  className: clsx_default("lib-xplat-tooltip", type),
149
189
  style: { position: "fixed", left: pos.left, top: pos.top },
150
190
  children: [
151
- title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "tooltip-title", children: title }),
152
- description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "tooltip-desc", children: description })
191
+ title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tooltip-title", children: title }),
192
+ description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tooltip-desc", children: description })
153
193
  ]
154
194
  }
155
195
  ) })
@@ -1,10 +1,18 @@
1
1
  import React from 'react';
2
2
 
3
3
  interface TooltipProps {
4
- type?: "dark" | "light";
4
+ children: React.ReactNode;
5
5
  title?: React.ReactNode;
6
6
  description?: React.ReactNode;
7
- children: React.ReactNode;
7
+ type?: "dark" | "light";
8
+ /**
9
+ * 커서를 따라다닌다. 기본값은 `false` — 트리거 요소 기준으로 고정된다
10
+ * (PopOver/Dropdown/Select 와 같은 방식).
11
+ *
12
+ * 넓은 영역 안에서 **가리키는 지점**이 의미를 가질 때만 켠다. 버튼이나
13
+ * 아이콘처럼 대상이 작은 경우는 고정이 읽기 편하다.
14
+ */
15
+ follow?: boolean;
8
16
  disabled?: boolean;
9
17
  }
10
18
  declare const Tooltip: React.FC<TooltipProps>;
@@ -1,10 +1,18 @@
1
1
  import React from 'react';
2
2
 
3
3
  interface TooltipProps {
4
- type?: "dark" | "light";
4
+ children: React.ReactNode;
5
5
  title?: React.ReactNode;
6
6
  description?: React.ReactNode;
7
- children: React.ReactNode;
7
+ type?: "dark" | "light";
8
+ /**
9
+ * 커서를 따라다닌다. 기본값은 `false` — 트리거 요소 기준으로 고정된다
10
+ * (PopOver/Dropdown/Select 와 같은 방식).
11
+ *
12
+ * 넓은 영역 안에서 **가리키는 지점**이 의미를 가질 때만 켠다. 버튼이나
13
+ * 아이콘처럼 대상이 작은 경우는 고정이 읽기 편하다.
14
+ */
15
+ follow?: boolean;
8
16
  disabled?: boolean;
9
17
  }
10
18
  declare const Tooltip: React.FC<TooltipProps>;
@@ -1,16 +1,11 @@
1
1
  // src/components/Tooltip/Tooltip.tsx
2
- import React2 from "react";
2
+ import React from "react";
3
3
 
4
4
  // src/tokens/hooks/Portal.tsx
5
- import React from "react";
6
5
  import ReactDOM from "react-dom";
7
- import { jsx } from "react/jsx-runtime";
8
- var PortalContainerContext = React.createContext(null);
9
6
  var Portal = ({ children }) => {
10
- const contextContainer = React.useContext(PortalContainerContext);
11
7
  if (typeof document === "undefined") return null;
12
- const container = contextContainer ?? document.body;
13
- return ReactDOM.createPortal(children, container);
8
+ return ReactDOM.createPortal(children, document.body);
14
9
  };
15
10
  Portal.displayName = "Portal";
16
11
  var Portal_default = Portal;
@@ -32,66 +27,110 @@ function clsx() {
32
27
  var clsx_default = clsx;
33
28
 
34
29
  // src/components/Tooltip/Tooltip.tsx
35
- import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
30
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
36
31
  var OFFSET = 12;
32
+ var GAP = 8;
37
33
  var SHOW_DELAY = 300;
38
34
  var Tooltip = (props) => {
39
35
  const {
40
- type = "dark",
36
+ children,
41
37
  title,
42
38
  description,
43
- children,
39
+ type = "dark",
40
+ follow = false,
44
41
  disabled = false
45
42
  } = props;
46
- const triggerRef = React2.useRef(null);
47
- const tooltipRef = React2.useRef(null);
48
- const [visible, setVisible] = React2.useState(false);
49
- const [pos, setPos] = React2.useState({ left: 0, top: 0 });
50
- const delayTimer = React2.useRef(0);
51
- const calculatePos = React2.useCallback((clientX, clientY) => {
43
+ const triggerRef = React.useRef(null);
44
+ const tooltipRef = React.useRef(null);
45
+ const [visible, setVisible] = React.useState(false);
46
+ const [pos, setPos] = React.useState({ left: 0, top: 0 });
47
+ const delayTimer = React.useRef(0);
48
+ const rafRef = React.useRef(0);
49
+ const cursor = React.useRef(null);
50
+ const clamp = React.useCallback((left, top, w, h) => {
51
+ const vw = window.innerWidth;
52
+ const vh = window.innerHeight;
53
+ return {
54
+ left: Math.min(Math.max(GAP, left), Math.max(GAP, vw - w - GAP)),
55
+ top: Math.min(Math.max(GAP, top), Math.max(GAP, vh - h - GAP))
56
+ };
57
+ }, []);
58
+ const placeAtCursor = React.useCallback((x, y) => {
52
59
  const el = tooltipRef.current;
53
60
  if (!el) return;
54
61
  const w = el.offsetWidth;
55
62
  const h = el.offsetHeight;
56
- const vw = window.innerWidth;
57
- let left = clientX + OFFSET;
58
- let top = clientY - h - OFFSET;
59
- if (left + w > vw - 8) left = clientX - w - OFFSET;
60
- if (top < 8) top = clientY + OFFSET;
61
- if (left < 8) left = 8;
62
- setPos({ left, top });
63
- }, []);
64
- const handleMouseEnter = React2.useCallback(() => {
63
+ let left = x + OFFSET;
64
+ let top = y - h - OFFSET;
65
+ if (left + w > window.innerWidth - GAP) left = x - w - OFFSET;
66
+ if (top < GAP) top = y + OFFSET;
67
+ setPos(clamp(left, top, w, h));
68
+ }, [clamp]);
69
+ const placeAtTrigger = React.useCallback(() => {
70
+ const el = tooltipRef.current;
71
+ const trigger = triggerRef.current;
72
+ if (!el || !trigger) return;
73
+ const w = el.offsetWidth;
74
+ const h = el.offsetHeight;
75
+ const rect = trigger.getBoundingClientRect();
76
+ let top = rect.top - h - GAP;
77
+ if (top < GAP) top = rect.bottom + GAP;
78
+ const left = rect.left + rect.width / 2 - w / 2;
79
+ setPos(clamp(left, top, w, h));
80
+ }, [clamp]);
81
+ const reposition = React.useCallback(() => {
82
+ if (follow && cursor.current) {
83
+ placeAtCursor(cursor.current.x, cursor.current.y);
84
+ } else {
85
+ placeAtTrigger();
86
+ }
87
+ }, [follow, placeAtCursor, placeAtTrigger]);
88
+ const handleMouseEnter = React.useCallback((e) => {
65
89
  if (disabled) return;
66
- delayTimer.current = window.setTimeout(() => {
67
- setVisible(true);
68
- }, SHOW_DELAY);
90
+ cursor.current = { x: e.clientX, y: e.clientY };
91
+ delayTimer.current = window.setTimeout(() => setVisible(true), SHOW_DELAY);
69
92
  }, [disabled]);
70
- const handleMouseMove = React2.useCallback((e) => {
71
- if (!visible) return;
72
- calculatePos(e.clientX, e.clientY);
73
- }, [visible, calculatePos]);
74
- const handleMouseLeave = React2.useCallback(() => {
75
- window.clearTimeout(delayTimer.current);
76
- setVisible(false);
77
- }, []);
78
- const handleClick = React2.useCallback(() => {
93
+ const handleMouseMove = React.useCallback((e) => {
94
+ cursor.current = { x: e.clientX, y: e.clientY };
95
+ if (!visible || !follow) return;
96
+ cancelAnimationFrame(rafRef.current);
97
+ rafRef.current = requestAnimationFrame(() => {
98
+ if (cursor.current) placeAtCursor(cursor.current.x, cursor.current.y);
99
+ });
100
+ }, [visible, follow, placeAtCursor]);
101
+ const close = React.useCallback(() => {
79
102
  window.clearTimeout(delayTimer.current);
103
+ cancelAnimationFrame(rafRef.current);
80
104
  setVisible(false);
81
105
  }, []);
82
- const handleFocus = React2.useCallback(() => {
106
+ const handleMouseLeave = React.useCallback(() => {
107
+ cursor.current = null;
108
+ close();
109
+ }, [close]);
110
+ const handleFocus = React.useCallback(() => {
83
111
  if (disabled) return;
112
+ cursor.current = null;
84
113
  setVisible(true);
85
114
  }, [disabled]);
86
- const handleBlur = React2.useCallback(() => {
87
- setVisible(false);
115
+ React.useLayoutEffect(() => {
116
+ if (!visible) return;
117
+ reposition();
118
+ }, [visible, reposition]);
119
+ React.useEffect(() => {
120
+ if (!visible || follow) return;
121
+ const onChange = () => placeAtTrigger();
122
+ window.addEventListener("scroll", onChange, true);
123
+ window.addEventListener("resize", onChange);
124
+ return () => {
125
+ window.removeEventListener("scroll", onChange, true);
126
+ window.removeEventListener("resize", onChange);
127
+ };
128
+ }, [visible, follow, placeAtTrigger]);
129
+ React.useEffect(() => () => {
130
+ window.clearTimeout(delayTimer.current);
131
+ cancelAnimationFrame(rafRef.current);
88
132
  }, []);
89
- React2.useLayoutEffect(() => {
90
- if (!visible || !triggerRef.current) return;
91
- const rect = triggerRef.current.getBoundingClientRect();
92
- calculatePos(rect.right, rect.top);
93
- }, [visible, calculatePos]);
94
- if (!title && !description) return /* @__PURE__ */ jsx2(Fragment, { children });
133
+ if (!title && !description) return /* @__PURE__ */ jsx(Fragment, { children });
95
134
  return /* @__PURE__ */ jsxs(
96
135
  "div",
97
136
  {
@@ -100,20 +139,21 @@ var Tooltip = (props) => {
100
139
  onMouseEnter: handleMouseEnter,
101
140
  onMouseMove: handleMouseMove,
102
141
  onMouseLeave: handleMouseLeave,
103
- onClick: handleClick,
142
+ onClick: close,
104
143
  onFocus: handleFocus,
105
- onBlur: handleBlur,
144
+ onBlur: close,
106
145
  children: [
107
146
  children,
108
- visible && /* @__PURE__ */ jsx2(Portal_default, { children: /* @__PURE__ */ jsxs(
147
+ visible && /* @__PURE__ */ jsx(Portal_default, { children: /* @__PURE__ */ jsxs(
109
148
  "div",
110
149
  {
111
150
  ref: tooltipRef,
151
+ role: "tooltip",
112
152
  className: clsx_default("lib-xplat-tooltip", type),
113
153
  style: { position: "fixed", left: pos.left, top: pos.top },
114
154
  children: [
115
- title && /* @__PURE__ */ jsx2("div", { className: "tooltip-title", children: title }),
116
- description && /* @__PURE__ */ jsx2("div", { className: "tooltip-desc", children: description })
155
+ title && /* @__PURE__ */ jsx("div", { className: "tooltip-title", children: title }),
156
+ description && /* @__PURE__ */ jsx("div", { className: "tooltip-desc", children: description })
117
157
  ]
118
158
  }
119
159
  ) })