@x-plat/design-system 0.7.2 → 0.8.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.
- package/dist/components/AutoResizeTextArea/index.css +2 -0
- package/dist/components/Button/index.css +2 -1
- package/dist/components/Button/index.d.cts +6 -0
- package/dist/components/Button/index.d.ts +6 -0
- package/dist/components/Chart/index.cjs +8 -1
- package/dist/components/Chart/index.js +8 -1
- package/dist/components/ChatInput/index.css +4 -0
- package/dist/components/DatePicker/index.css +4 -1
- package/dist/components/Input/index.css +2 -0
- package/dist/components/Link/index.cjs +64 -0
- package/dist/components/Link/index.css +25 -0
- package/dist/components/Link/index.d.cts +27 -0
- package/dist/components/Link/index.d.ts +27 -0
- package/dist/components/Link/index.js +37 -0
- package/dist/components/LinkButton/index.cjs +64 -0
- package/dist/components/LinkButton/index.css +106 -0
- package/dist/components/LinkButton/index.d.cts +28 -0
- package/dist/components/LinkButton/index.d.ts +28 -0
- package/dist/components/LinkButton/index.js +37 -0
- package/dist/components/TextArea/index.css +2 -0
- package/dist/components/Tooltip/index.cjs +77 -32
- package/dist/components/Tooltip/index.d.cts +10 -2
- package/dist/components/Tooltip/index.d.ts +10 -2
- package/dist/components/Tooltip/index.js +77 -32
- package/dist/components/index.cjs +247 -153
- package/dist/components/index.css +36 -1
- package/dist/components/index.d.cts +2 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +222 -130
- package/dist/index.cjs +266 -172
- package/dist/index.css +36 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +239 -147
- package/guidelines/AGENT_PROMPT.md +2 -2
- package/guidelines/Guidelines.md +2 -1
- package/guidelines/components/button.md +54 -0
- package/guidelines/components/card.md +15 -19
- package/guidelines/components/link.md +35 -0
- package/guidelines/components/overlay.md +30 -1
- package/package.json +1 -1
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
.lib-xplat-auto-resize-textarea-wrapper .lib-xplat-auto-resize-textarea:focus-within {
|
|
22
22
|
border-color: var(--semantic-interaction-focus-ring);
|
|
23
23
|
box-shadow: 0 0 0 2px var(--semantic-interaction-overlay-10);
|
|
24
|
+
outline: 2px solid transparent;
|
|
25
|
+
outline-offset: 2px;
|
|
24
26
|
}
|
|
25
27
|
.lib-xplat-auto-resize-textarea-wrapper .lib-xplat-auto-resize-textarea:has(> textarea:not(:placeholder-shown)):not(:focus-within) {
|
|
26
28
|
border-color: var(--semantic-border-tertiary);
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
font-weight: var(--semantic-typo-label-1-m-weight);
|
|
40
40
|
letter-spacing: var(--semantic-typo-label-1-m-ls);
|
|
41
41
|
}
|
|
42
|
-
.lib-xplat-button:disabled
|
|
42
|
+
.lib-xplat-button:disabled,
|
|
43
|
+
.lib-xplat-button.disabled {
|
|
43
44
|
cursor: not-allowed;
|
|
44
45
|
background-color: var(--semantic-surface-neutral-disabled) !important;
|
|
45
46
|
border-color: var(--semantic-surface-neutral-disabled) !important;
|
|
@@ -9,6 +9,12 @@ interface ButtonProps extends Omit<ButtonAttributes, "className"> {
|
|
|
9
9
|
type?: ButtonType;
|
|
10
10
|
size?: ButtonSize;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 버튼은 `<button>` 으로만 렌더된다. 누르면 **무언가 일어나는** 자리에 쓴다.
|
|
14
|
+
*
|
|
15
|
+
* 이동하는 자리는 버튼이 아니라 링크다. 버튼처럼 보여야 하면 `LinkButton`,
|
|
16
|
+
* 본문 속 텍스트 링크는 `Link` 를 쓴다.
|
|
17
|
+
*/
|
|
12
18
|
declare const Button: {
|
|
13
19
|
(props: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
14
20
|
displayName: string;
|
|
@@ -9,6 +9,12 @@ interface ButtonProps extends Omit<ButtonAttributes, "className"> {
|
|
|
9
9
|
type?: ButtonType;
|
|
10
10
|
size?: ButtonSize;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* 버튼은 `<button>` 으로만 렌더된다. 누르면 **무언가 일어나는** 자리에 쓴다.
|
|
14
|
+
*
|
|
15
|
+
* 이동하는 자리는 버튼이 아니라 링크다. 버튼처럼 보여야 하면 `LinkButton`,
|
|
16
|
+
* 본문 속 텍스트 링크는 `Link` 를 쓴다.
|
|
17
|
+
*/
|
|
12
18
|
declare const Button: {
|
|
13
19
|
(props: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
14
20
|
displayName: string;
|
|
@@ -172,9 +172,16 @@ var useChartTooltip = (enabled) => {
|
|
|
172
172
|
}, []);
|
|
173
173
|
return { tooltip, show, hide, move, containerRef };
|
|
174
174
|
};
|
|
175
|
+
var formatTick = (value, maxVal) => {
|
|
176
|
+
const step = maxVal / 4;
|
|
177
|
+
if (!Number.isFinite(step) || step <= 0) return "0";
|
|
178
|
+
const decimals = step >= 1 ? 0 : Math.min(4, Math.ceil(-Math.log10(step)));
|
|
179
|
+
const fixed = value.toFixed(decimals);
|
|
180
|
+
return decimals === 0 ? Number(fixed).toLocaleString("en-US") : fixed;
|
|
181
|
+
};
|
|
175
182
|
var GridLines = import_react.default.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
|
|
176
183
|
const y = PADDING.top + (1 - ratio) * chartH;
|
|
177
|
-
const val =
|
|
184
|
+
const val = formatTick(maxVal * ratio, maxVal);
|
|
178
185
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { children: [
|
|
179
186
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: PADDING.left, y1: y, x2: width - PADDING.right, y2: y, className: "chart-grid" }),
|
|
180
187
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", { x: PADDING.left - 8, y: y + 4, className: "chart-axis-label", textAnchor: "end", children: val })
|
|
@@ -136,9 +136,16 @@ var useChartTooltip = (enabled) => {
|
|
|
136
136
|
}, []);
|
|
137
137
|
return { tooltip, show, hide, move, containerRef };
|
|
138
138
|
};
|
|
139
|
+
var formatTick = (value, maxVal) => {
|
|
140
|
+
const step = maxVal / 4;
|
|
141
|
+
if (!Number.isFinite(step) || step <= 0) return "0";
|
|
142
|
+
const decimals = step >= 1 ? 0 : Math.min(4, Math.ceil(-Math.log10(step)));
|
|
143
|
+
const fixed = value.toFixed(decimals);
|
|
144
|
+
return decimals === 0 ? Number(fixed).toLocaleString("en-US") : fixed;
|
|
145
|
+
};
|
|
139
146
|
var GridLines = React.memo(({ width, height, chartH, maxVal }) => /* @__PURE__ */ jsx(Fragment, { children: [0, 0.25, 0.5, 0.75, 1].map((ratio) => {
|
|
140
147
|
const y = PADDING.top + (1 - ratio) * chartH;
|
|
141
|
-
const val =
|
|
148
|
+
const val = formatTick(maxVal * ratio, maxVal);
|
|
142
149
|
return /* @__PURE__ */ jsxs("g", { children: [
|
|
143
150
|
/* @__PURE__ */ jsx("line", { x1: PADDING.left, y1: y, x2: width - PADDING.right, y2: y, className: "chart-grid" }),
|
|
144
151
|
/* @__PURE__ */ jsx("text", { x: PADDING.left - 8, y: y + 4, className: "chart-axis-label", textAnchor: "end", children: val })
|
|
@@ -99,6 +99,8 @@
|
|
|
99
99
|
.lib-xplat-auto-resize-textarea-wrapper .lib-xplat-auto-resize-textarea:focus-within {
|
|
100
100
|
border-color: var(--semantic-interaction-focus-ring);
|
|
101
101
|
box-shadow: 0 0 0 2px var(--semantic-interaction-overlay-10);
|
|
102
|
+
outline: 2px solid transparent;
|
|
103
|
+
outline-offset: 2px;
|
|
102
104
|
}
|
|
103
105
|
.lib-xplat-auto-resize-textarea-wrapper .lib-xplat-auto-resize-textarea:has(> textarea:not(:placeholder-shown)):not(:focus-within) {
|
|
104
106
|
border-color: var(--semantic-border-tertiary);
|
|
@@ -144,6 +146,8 @@
|
|
|
144
146
|
.lib-xplat-chat-input:focus-within {
|
|
145
147
|
border-color: var(--semantic-interaction-focus-ring);
|
|
146
148
|
box-shadow: 0 0 0 2px var(--semantic-interaction-overlay-10);
|
|
149
|
+
outline: 2px solid transparent;
|
|
150
|
+
outline-offset: 2px;
|
|
147
151
|
}
|
|
148
152
|
.lib-xplat-chat-input.disabled {
|
|
149
153
|
background-color: var(--semantic-surface-neutral-secondary);
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
font-weight: var(--semantic-typo-label-1-m-weight);
|
|
40
40
|
letter-spacing: var(--semantic-typo-label-1-m-ls);
|
|
41
41
|
}
|
|
42
|
-
.lib-xplat-button:disabled
|
|
42
|
+
.lib-xplat-button:disabled,
|
|
43
|
+
.lib-xplat-button.disabled {
|
|
43
44
|
cursor: not-allowed;
|
|
44
45
|
background-color: var(--semantic-surface-neutral-disabled) !important;
|
|
45
46
|
border-color: var(--semantic-surface-neutral-disabled) !important;
|
|
@@ -127,6 +128,8 @@
|
|
|
127
128
|
.lib-xplat-input-wrap .lib-xplat-input:focus-within {
|
|
128
129
|
border-color: var(--semantic-interaction-focus-ring);
|
|
129
130
|
box-shadow: 0 0 0 2px var(--semantic-interaction-overlay-10);
|
|
131
|
+
outline: 2px solid transparent;
|
|
132
|
+
outline-offset: 2px;
|
|
130
133
|
}
|
|
131
134
|
.lib-xplat-input-wrap .lib-xplat-input:has(> input:not(:placeholder-shown)):not(:focus-within) {
|
|
132
135
|
border-color: var(--semantic-border-tertiary);
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
.lib-xplat-input-wrap .lib-xplat-input:focus-within {
|
|
22
22
|
border-color: var(--semantic-interaction-focus-ring);
|
|
23
23
|
box-shadow: 0 0 0 2px var(--semantic-interaction-overlay-10);
|
|
24
|
+
outline: 2px solid transparent;
|
|
25
|
+
outline-offset: 2px;
|
|
24
26
|
}
|
|
25
27
|
.lib-xplat-input-wrap .lib-xplat-input:has(> input:not(:placeholder-shown)):not(:focus-within) {
|
|
26
28
|
border-color: var(--semantic-border-tertiary);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/components/Link/index.ts
|
|
21
|
+
var Link_exports = {};
|
|
22
|
+
__export(Link_exports, {
|
|
23
|
+
Link: () => Link_default
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(Link_exports);
|
|
26
|
+
|
|
27
|
+
// ../../node_modules/clsx/dist/clsx.mjs
|
|
28
|
+
function r(e) {
|
|
29
|
+
var t, f, n = "";
|
|
30
|
+
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
31
|
+
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
32
|
+
var o = e.length;
|
|
33
|
+
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
34
|
+
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
35
|
+
return n;
|
|
36
|
+
}
|
|
37
|
+
function clsx() {
|
|
38
|
+
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
39
|
+
return n;
|
|
40
|
+
}
|
|
41
|
+
var clsx_default = clsx;
|
|
42
|
+
|
|
43
|
+
// src/components/Link/Link.tsx
|
|
44
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
45
|
+
var Link = (props) => {
|
|
46
|
+
const { children, href, underline = "always", target, rel, ...rest } = props;
|
|
47
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
48
|
+
"a",
|
|
49
|
+
{
|
|
50
|
+
className: clsx_default("lib-xplat-link", `underline-${underline}`),
|
|
51
|
+
href,
|
|
52
|
+
target,
|
|
53
|
+
rel: target === "_blank" ? rel ?? "noopener noreferrer" : rel,
|
|
54
|
+
...rest,
|
|
55
|
+
children
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
Link.displayName = "Link";
|
|
60
|
+
var Link_default = Link;
|
|
61
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
62
|
+
0 && (module.exports = {
|
|
63
|
+
Link
|
|
64
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* src/components/Link/link.scss */
|
|
2
|
+
.lib-xplat-link {
|
|
3
|
+
color: var(--semantic-text-link);
|
|
4
|
+
cursor: pointer;
|
|
5
|
+
text-underline-offset: 2px;
|
|
6
|
+
text-decoration-thickness: 1px;
|
|
7
|
+
border-radius: var(--spacing-radius-sm);
|
|
8
|
+
transition: text-decoration-color 0.28s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
9
|
+
}
|
|
10
|
+
.lib-xplat-link.underline-always {
|
|
11
|
+
text-decoration: underline;
|
|
12
|
+
}
|
|
13
|
+
.lib-xplat-link.underline-hover {
|
|
14
|
+
text-decoration: none;
|
|
15
|
+
}
|
|
16
|
+
.lib-xplat-link.underline-hover:hover {
|
|
17
|
+
text-decoration: underline;
|
|
18
|
+
}
|
|
19
|
+
.lib-xplat-link.underline-none {
|
|
20
|
+
text-decoration: none;
|
|
21
|
+
}
|
|
22
|
+
.lib-xplat-link:focus-visible {
|
|
23
|
+
outline: 2px solid var(--semantic-interaction-focus-ring);
|
|
24
|
+
outline-offset: 2px;
|
|
25
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type Underline = "always" | "hover" | "none";
|
|
5
|
+
interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "color" | "href"> {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
href: string;
|
|
8
|
+
/**
|
|
9
|
+
* 밑줄 표시 방식. 기본은 `"always"`.
|
|
10
|
+
*
|
|
11
|
+
* 본문 속 링크는 색만으로 구분하면 색각 이상이 있는 사용자가 놓친다.
|
|
12
|
+
* 주변 텍스트와 확실히 구분되는 자리(내비게이션·목록 등)에서만 `"hover"` 나
|
|
13
|
+
* `"none"` 으로 내린다.
|
|
14
|
+
*/
|
|
15
|
+
underline?: Underline;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 본문 속 텍스트 링크. 크기·굵기는 주변 텍스트를 그대로 물려받는다.
|
|
19
|
+
*
|
|
20
|
+
* 버튼처럼 보여야 하는 링크는 `LinkButton` 을 쓴다.
|
|
21
|
+
*/
|
|
22
|
+
declare const Link: {
|
|
23
|
+
(props: LinkProps): react_jsx_runtime.JSX.Element;
|
|
24
|
+
displayName: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { Link };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type Underline = "always" | "hover" | "none";
|
|
5
|
+
interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "color" | "href"> {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
href: string;
|
|
8
|
+
/**
|
|
9
|
+
* 밑줄 표시 방식. 기본은 `"always"`.
|
|
10
|
+
*
|
|
11
|
+
* 본문 속 링크는 색만으로 구분하면 색각 이상이 있는 사용자가 놓친다.
|
|
12
|
+
* 주변 텍스트와 확실히 구분되는 자리(내비게이션·목록 등)에서만 `"hover"` 나
|
|
13
|
+
* `"none"` 으로 내린다.
|
|
14
|
+
*/
|
|
15
|
+
underline?: Underline;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 본문 속 텍스트 링크. 크기·굵기는 주변 텍스트를 그대로 물려받는다.
|
|
19
|
+
*
|
|
20
|
+
* 버튼처럼 보여야 하는 링크는 `LinkButton` 을 쓴다.
|
|
21
|
+
*/
|
|
22
|
+
declare const Link: {
|
|
23
|
+
(props: LinkProps): react_jsx_runtime.JSX.Element;
|
|
24
|
+
displayName: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { Link };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// ../../node_modules/clsx/dist/clsx.mjs
|
|
2
|
+
function r(e) {
|
|
3
|
+
var t, f, n = "";
|
|
4
|
+
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
5
|
+
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
6
|
+
var o = e.length;
|
|
7
|
+
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
8
|
+
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
9
|
+
return n;
|
|
10
|
+
}
|
|
11
|
+
function clsx() {
|
|
12
|
+
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
13
|
+
return n;
|
|
14
|
+
}
|
|
15
|
+
var clsx_default = clsx;
|
|
16
|
+
|
|
17
|
+
// src/components/Link/Link.tsx
|
|
18
|
+
import { jsx } from "react/jsx-runtime";
|
|
19
|
+
var Link = (props) => {
|
|
20
|
+
const { children, href, underline = "always", target, rel, ...rest } = props;
|
|
21
|
+
return /* @__PURE__ */ jsx(
|
|
22
|
+
"a",
|
|
23
|
+
{
|
|
24
|
+
className: clsx_default("lib-xplat-link", `underline-${underline}`),
|
|
25
|
+
href,
|
|
26
|
+
target,
|
|
27
|
+
rel: target === "_blank" ? rel ?? "noopener noreferrer" : rel,
|
|
28
|
+
...rest,
|
|
29
|
+
children
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
Link.displayName = "Link";
|
|
34
|
+
var Link_default = Link;
|
|
35
|
+
export {
|
|
36
|
+
Link_default as Link
|
|
37
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/components/LinkButton/index.ts
|
|
21
|
+
var LinkButton_exports = {};
|
|
22
|
+
__export(LinkButton_exports, {
|
|
23
|
+
LinkButton: () => LinkButton_default
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(LinkButton_exports);
|
|
26
|
+
|
|
27
|
+
// ../../node_modules/clsx/dist/clsx.mjs
|
|
28
|
+
function r(e) {
|
|
29
|
+
var t, f, n = "";
|
|
30
|
+
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
31
|
+
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
32
|
+
var o = e.length;
|
|
33
|
+
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
34
|
+
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
35
|
+
return n;
|
|
36
|
+
}
|
|
37
|
+
function clsx() {
|
|
38
|
+
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
39
|
+
return n;
|
|
40
|
+
}
|
|
41
|
+
var clsx_default = clsx;
|
|
42
|
+
|
|
43
|
+
// src/components/LinkButton/LinkButton.tsx
|
|
44
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
45
|
+
var LinkButton = (props) => {
|
|
46
|
+
const { children, href, type = "primary", size = "md", target, rel, ...rest } = props;
|
|
47
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
48
|
+
"a",
|
|
49
|
+
{
|
|
50
|
+
className: clsx_default("lib-xplat-button", type, size),
|
|
51
|
+
href,
|
|
52
|
+
target,
|
|
53
|
+
rel: target === "_blank" ? rel ?? "noopener noreferrer" : rel,
|
|
54
|
+
...rest,
|
|
55
|
+
children
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
LinkButton.displayName = "LinkButton";
|
|
60
|
+
var LinkButton_default = LinkButton;
|
|
61
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
62
|
+
0 && (module.exports = {
|
|
63
|
+
LinkButton
|
|
64
|
+
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/* src/components/Button/button.scss */
|
|
2
|
+
.lib-xplat-button {
|
|
3
|
+
width: 100%;
|
|
4
|
+
display: inline-flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
gap: var(--spacing-space-2);
|
|
8
|
+
white-space: nowrap;
|
|
9
|
+
border-radius: var(--spacing-radius-md);
|
|
10
|
+
font-weight: var(--semantic-typo-label-1-m-weight);
|
|
11
|
+
cursor: pointer;
|
|
12
|
+
border: 1px solid transparent;
|
|
13
|
+
transition: background-color 0.28s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
14
|
+
}
|
|
15
|
+
.lib-xplat-button.sm {
|
|
16
|
+
height: var(--spacing-control-height-sm);
|
|
17
|
+
padding: 0 var(--spacing-space-3);
|
|
18
|
+
font-family: var(--semantic-typo-caption-1-r-font);
|
|
19
|
+
font-size: var(--semantic-typo-caption-1-r-size);
|
|
20
|
+
line-height: var(--semantic-typo-caption-1-r-lh);
|
|
21
|
+
font-weight: var(--semantic-typo-caption-1-r-weight);
|
|
22
|
+
letter-spacing: var(--semantic-typo-caption-1-r-ls);
|
|
23
|
+
}
|
|
24
|
+
.lib-xplat-button.md {
|
|
25
|
+
height: var(--spacing-control-height-md);
|
|
26
|
+
padding: 0 var(--spacing-space-4);
|
|
27
|
+
font-family: var(--semantic-typo-label-2-m-font);
|
|
28
|
+
font-size: var(--semantic-typo-label-2-m-size);
|
|
29
|
+
line-height: var(--semantic-typo-label-2-m-lh);
|
|
30
|
+
font-weight: var(--semantic-typo-label-2-m-weight);
|
|
31
|
+
letter-spacing: var(--semantic-typo-label-2-m-ls);
|
|
32
|
+
}
|
|
33
|
+
.lib-xplat-button.lg {
|
|
34
|
+
height: var(--spacing-control-height-lg);
|
|
35
|
+
padding: 0 var(--spacing-space-6);
|
|
36
|
+
font-family: var(--semantic-typo-label-1-m-font);
|
|
37
|
+
font-size: var(--semantic-typo-label-1-m-size);
|
|
38
|
+
line-height: var(--semantic-typo-label-1-m-lh);
|
|
39
|
+
font-weight: var(--semantic-typo-label-1-m-weight);
|
|
40
|
+
letter-spacing: var(--semantic-typo-label-1-m-ls);
|
|
41
|
+
}
|
|
42
|
+
.lib-xplat-button:disabled,
|
|
43
|
+
.lib-xplat-button.disabled {
|
|
44
|
+
cursor: not-allowed;
|
|
45
|
+
background-color: var(--semantic-surface-neutral-disabled) !important;
|
|
46
|
+
border-color: var(--semantic-surface-neutral-disabled) !important;
|
|
47
|
+
color: var(--semantic-text-disabled) !important;
|
|
48
|
+
}
|
|
49
|
+
.lib-xplat-button.primary {
|
|
50
|
+
color: var(--semantic-text-inverse);
|
|
51
|
+
background-color: var(--semantic-surface-brand-default);
|
|
52
|
+
}
|
|
53
|
+
.lib-xplat-button.primary:hover:not(:disabled) {
|
|
54
|
+
background-color: var(--semantic-surface-brand-strong);
|
|
55
|
+
}
|
|
56
|
+
.lib-xplat-button.primary:active:not(:disabled) {
|
|
57
|
+
background-color: var(--semantic-surface-brand-strong);
|
|
58
|
+
}
|
|
59
|
+
.lib-xplat-button.primary:focus-visible {
|
|
60
|
+
outline: 2px solid var(--semantic-interaction-focus-ring);
|
|
61
|
+
outline-offset: 2px;
|
|
62
|
+
}
|
|
63
|
+
.lib-xplat-button.secondary {
|
|
64
|
+
color: var(--semantic-surface-brand-default);
|
|
65
|
+
background-color: var(--semantic-surface-neutral-primary);
|
|
66
|
+
border-color: var(--semantic-border-primary);
|
|
67
|
+
}
|
|
68
|
+
.lib-xplat-button.secondary:hover:not(:disabled) {
|
|
69
|
+
background-color: var(--semantic-surface-neutral-secondary);
|
|
70
|
+
}
|
|
71
|
+
.lib-xplat-button.secondary:active:not(:disabled) {
|
|
72
|
+
background-color: var(--semantic-surface-neutral-tertiary);
|
|
73
|
+
}
|
|
74
|
+
.lib-xplat-button.secondary:focus-visible {
|
|
75
|
+
outline: 2px solid var(--semantic-interaction-focus-ring);
|
|
76
|
+
outline-offset: 2px;
|
|
77
|
+
}
|
|
78
|
+
.lib-xplat-button.danger {
|
|
79
|
+
color: var(--semantic-text-inverse);
|
|
80
|
+
background-color: var(--semantic-surface-error-default);
|
|
81
|
+
}
|
|
82
|
+
.lib-xplat-button.danger:hover:not(:disabled) {
|
|
83
|
+
background-color: var(--semantic-surface-error-strong);
|
|
84
|
+
}
|
|
85
|
+
.lib-xplat-button.danger:active:not(:disabled) {
|
|
86
|
+
background-color: var(--semantic-surface-error-strong);
|
|
87
|
+
}
|
|
88
|
+
.lib-xplat-button.danger:focus-visible {
|
|
89
|
+
outline: 2px solid var(--semantic-interaction-focus-ring);
|
|
90
|
+
outline-offset: 2px;
|
|
91
|
+
}
|
|
92
|
+
.lib-xplat-button.ghost {
|
|
93
|
+
color: var(--semantic-text-secondary);
|
|
94
|
+
background-color: transparent;
|
|
95
|
+
border-color: transparent;
|
|
96
|
+
}
|
|
97
|
+
.lib-xplat-button.ghost:hover:not(:disabled) {
|
|
98
|
+
background-color: var(--semantic-surface-neutral-secondary);
|
|
99
|
+
}
|
|
100
|
+
.lib-xplat-button.ghost:active:not(:disabled) {
|
|
101
|
+
background-color: var(--semantic-surface-neutral-disabled);
|
|
102
|
+
}
|
|
103
|
+
.lib-xplat-button.ghost:focus-visible {
|
|
104
|
+
outline: 2px solid var(--semantic-interaction-focus-ring);
|
|
105
|
+
outline-offset: 2px;
|
|
106
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type LinkButtonType = "primary" | "secondary" | "danger" | "ghost";
|
|
5
|
+
type LinkButtonSize = "sm" | "md" | "lg";
|
|
6
|
+
interface LinkButtonProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "type" | "color" | "href"> {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
href: string;
|
|
9
|
+
type?: LinkButtonType;
|
|
10
|
+
size?: LinkButtonSize;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 버튼처럼 보이지만 **이동하는** 링크. `<a>` 로 렌더된다.
|
|
14
|
+
*
|
|
15
|
+
* 우클릭 메뉴·새 탭으로 열기·링크 미리보기가 동작해야 하는 자리에 쓴다.
|
|
16
|
+
* `<button>` 으로 만들면 그게 전부 막힌다.
|
|
17
|
+
*
|
|
18
|
+
* 누르면 무언가 **일어나는** 자리는 `Button`, 본문 속 텍스트 링크는 `Link` 다.
|
|
19
|
+
*
|
|
20
|
+
* `width: 100%` 가 들어 있어 부모를 꽉 채운다. 내용만큼만 차지해야 하면
|
|
21
|
+
* 감싸는 요소에 `width: fit-content` 를 준다.
|
|
22
|
+
*/
|
|
23
|
+
declare const LinkButton: {
|
|
24
|
+
(props: LinkButtonProps): react_jsx_runtime.JSX.Element;
|
|
25
|
+
displayName: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { LinkButton };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type LinkButtonType = "primary" | "secondary" | "danger" | "ghost";
|
|
5
|
+
type LinkButtonSize = "sm" | "md" | "lg";
|
|
6
|
+
interface LinkButtonProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "type" | "color" | "href"> {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
href: string;
|
|
9
|
+
type?: LinkButtonType;
|
|
10
|
+
size?: LinkButtonSize;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 버튼처럼 보이지만 **이동하는** 링크. `<a>` 로 렌더된다.
|
|
14
|
+
*
|
|
15
|
+
* 우클릭 메뉴·새 탭으로 열기·링크 미리보기가 동작해야 하는 자리에 쓴다.
|
|
16
|
+
* `<button>` 으로 만들면 그게 전부 막힌다.
|
|
17
|
+
*
|
|
18
|
+
* 누르면 무언가 **일어나는** 자리는 `Button`, 본문 속 텍스트 링크는 `Link` 다.
|
|
19
|
+
*
|
|
20
|
+
* `width: 100%` 가 들어 있어 부모를 꽉 채운다. 내용만큼만 차지해야 하면
|
|
21
|
+
* 감싸는 요소에 `width: fit-content` 를 준다.
|
|
22
|
+
*/
|
|
23
|
+
declare const LinkButton: {
|
|
24
|
+
(props: LinkButtonProps): react_jsx_runtime.JSX.Element;
|
|
25
|
+
displayName: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { LinkButton };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// ../../node_modules/clsx/dist/clsx.mjs
|
|
2
|
+
function r(e) {
|
|
3
|
+
var t, f, n = "";
|
|
4
|
+
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
5
|
+
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
6
|
+
var o = e.length;
|
|
7
|
+
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
8
|
+
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
9
|
+
return n;
|
|
10
|
+
}
|
|
11
|
+
function clsx() {
|
|
12
|
+
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
13
|
+
return n;
|
|
14
|
+
}
|
|
15
|
+
var clsx_default = clsx;
|
|
16
|
+
|
|
17
|
+
// src/components/LinkButton/LinkButton.tsx
|
|
18
|
+
import { jsx } from "react/jsx-runtime";
|
|
19
|
+
var LinkButton = (props) => {
|
|
20
|
+
const { children, href, type = "primary", size = "md", target, rel, ...rest } = props;
|
|
21
|
+
return /* @__PURE__ */ jsx(
|
|
22
|
+
"a",
|
|
23
|
+
{
|
|
24
|
+
className: clsx_default("lib-xplat-button", type, size),
|
|
25
|
+
href,
|
|
26
|
+
target,
|
|
27
|
+
rel: target === "_blank" ? rel ?? "noopener noreferrer" : rel,
|
|
28
|
+
...rest,
|
|
29
|
+
children
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
LinkButton.displayName = "LinkButton";
|
|
34
|
+
var LinkButton_default = LinkButton;
|
|
35
|
+
export {
|
|
36
|
+
LinkButton_default as LinkButton
|
|
37
|
+
};
|
|
@@ -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);
|