@axis-ds/agentic-ui 1.3.0 → 1.5.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/README.md +71 -1
- package/dist/agent-avatar/index.js +6 -16
- package/dist/agent-avatar/index.mjs +75 -4
- package/dist/approval-card/index.js +6 -16
- package/dist/approval-card/index.mjs +86 -4
- package/dist/attachment-card/index.js +5 -17
- package/dist/attachment-card/index.mjs +101 -4
- package/dist/code-block/index.js +2 -3
- package/dist/code-block/index.mjs +76 -3
- package/dist/constants/a11y-labels.d.mts +86 -0
- package/dist/constants/a11y-labels.d.ts +86 -0
- package/dist/constants/a11y-labels.js +105 -0
- package/dist/{chunk-SCZ4BQ2G.mjs → constants/a11y-labels.mjs} +21 -17
- package/dist/context-panel/index.js +2 -3
- package/dist/context-panel/index.mjs +99 -3
- package/dist/diff-viewer/index.js +8 -17
- package/dist/diff-viewer/index.mjs +155 -4
- package/dist/feedback-buttons/index.js +7 -16
- package/dist/feedback-buttons/index.mjs +65 -4
- package/dist/index.js +36 -1732
- package/dist/index.mjs +18 -55
- package/dist/message-bubble/index.js +5 -15
- package/dist/message-bubble/index.mjs +98 -4
- package/dist/plan-card/index.js +6 -28
- package/dist/plan-card/index.mjs +143 -4
- package/dist/recovery-banner/index.js +1 -3
- package/dist/recovery-banner/index.mjs +70 -3
- package/dist/run-progress/index.js +5 -19
- package/dist/run-progress/index.mjs +128 -4
- package/dist/source-panel/index.js +5 -15
- package/dist/source-panel/index.mjs +88 -4
- package/dist/step-timeline/index.js +3 -17
- package/dist/step-timeline/index.mjs +69 -4
- package/dist/streaming-text/index.js +2 -3
- package/dist/streaming-text/index.mjs +59 -3
- package/dist/surface-renderer/index.js +1 -3
- package/dist/surface-renderer/index.mjs +79 -3
- package/dist/thinking-indicator/index.js +3 -5
- package/dist/thinking-indicator/index.mjs +45 -3
- package/dist/token-usage-indicator/index.js +1 -3
- package/dist/token-usage-indicator/index.mjs +81 -3
- package/dist/tool-call-card/index.js +5 -18
- package/dist/tool-call-card/index.mjs +108 -4
- package/package.json +39 -7
- package/tailwind.css +10 -0
- package/dist/chunk-42KEAZ2Y.mjs +0 -109
- package/dist/chunk-4CMUEGLK.mjs +0 -80
- package/dist/chunk-4V4BWBRC.mjs +0 -77
- package/dist/chunk-7HTVJ6MK.mjs +0 -94
- package/dist/chunk-DPLGRVNQ.mjs +0 -95
- package/dist/chunk-FYAMA32G.mjs +0 -50
- package/dist/chunk-GQYOOLDL.mjs +0 -63
- package/dist/chunk-IOF4OET6.mjs +0 -162
- package/dist/chunk-J4FIMXXG.mjs +0 -106
- package/dist/chunk-JY7MTMMB.mjs +0 -83
- package/dist/chunk-KJVPVBET.mjs +0 -103
- package/dist/chunk-OYQX3SL4.mjs +0 -152
- package/dist/chunk-QS6GQNSE.mjs +0 -86
- package/dist/chunk-R4CMHIRO.mjs +0 -72
- package/dist/chunk-SCXUEQLI.mjs +0 -136
- package/dist/chunk-UDL4M5RP.mjs +0 -75
- package/dist/chunk-WFYQINWD.mjs +0 -115
- package/dist/chunk-ZW4Z27AB.mjs +0 -84
package/README.md
CHANGED
|
@@ -10,6 +10,35 @@ npm install @axis-ds/agentic-ui
|
|
|
10
10
|
pnpm add @axis-ds/agentic-ui
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
## Tailwind 연동
|
|
14
|
+
|
|
15
|
+
### Tailwind CSS 4
|
|
16
|
+
|
|
17
|
+
Tailwind CSS 4(`@import "tailwindcss"`, create-next-app 15.5 기본)에서는 `@import "tailwindcss"` 가 있는 전역 CSS 에 두 줄을 더합니다.
|
|
18
|
+
|
|
19
|
+
```css
|
|
20
|
+
/* app/globals.css */
|
|
21
|
+
@import "tailwindcss";
|
|
22
|
+
@import "@axis-ds/tokens/css/tailwind4";
|
|
23
|
+
@import "@axis-ds/agentic-ui/tailwind.css";
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- `@axis-ds/agentic-ui/tailwind.css` 는 스타일 규칙 없이 `@source "./dist"` 한 줄만 담습니다. Tailwind 4 는 `node_modules` 를 스캔하지 않아서, 이 줄이 없으면 컴포넌트가 쓰는 `bg-[var(--axis-agent-avatar-assistant)]` 같은 클래스가 생성되지 않습니다. 경로는 파일 기준 상대 경로라 npm · pnpm 설치 모두 동작합니다.
|
|
27
|
+
- `@import "tailwindcss"` 가 있는 같은 파일에서 import 합니다. 다른 CSS 파일이나 JS/TSX 에서 import 하면 스캔 경로가 그 컴파일에 들어가지 않습니다.
|
|
28
|
+
- `@axis-ds/tokens/css/tailwind4` 는 `rounded-md` · `font-mono` 등을 AXIS 변수로 매핑하고 토큰 변수를 base 레이어로 함께 불러옵니다. pnpm 처럼 의존성을 끌어올리지 않는 설치에서는 `@axis-ds/tokens` 를 직접 설치해야 이 import 가 풀립니다. 브랜드 CSS · create-next-app 기본 `:root` 와의 충돌은 `@axis-ds/tokens` README 를 참고하세요.
|
|
29
|
+
- 이 패키지는 `@axis-ds/ui-react` 에서 유틸리티 함수만 가져옵니다. 앱에서 `@axis-ds/ui-react` 컴포넌트를 직접 쓸 때만 `@import "@axis-ds/ui-react/tailwind.css";` 를 함께 넣습니다.
|
|
30
|
+
|
|
31
|
+
### Tailwind CSS 3
|
|
32
|
+
|
|
33
|
+
`tailwind.config` 에는 `@axis-ds/tokens/tailwind` preset 과 함께 컴포넌트 파일을 `content` 에 넣습니다.
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
content: [
|
|
37
|
+
"./src/**/*.{js,ts,jsx,tsx}",
|
|
38
|
+
"./node_modules/@axis-ds/agentic-ui/**/*.{js,jsx}",
|
|
39
|
+
],
|
|
40
|
+
```
|
|
41
|
+
|
|
13
42
|
## 사용법
|
|
14
43
|
|
|
15
44
|
```tsx
|
|
@@ -18,9 +47,50 @@ import { StreamingText, ToolCallCard } from '@axis-ds/agentic-ui';
|
|
|
18
47
|
import { StreamingText } from '@axis-ds/agentic-ui/streaming-text';
|
|
19
48
|
```
|
|
20
49
|
|
|
50
|
+
컴포넌트마다 서브패스(`@axis-ds/agentic-ui/<컴포넌트 이름의 kebab-case>`)가 있습니다. 1.5.0 에서 그동안 루트로만 import 할 수 있던 `agent-avatar` · `recovery-banner` · `source-panel` · `step-timeline` · `surface-renderer` · `thinking-indicator` 서브패스를 더했습니다.
|
|
51
|
+
|
|
52
|
+
## 서버 컴포넌트 (Next.js App Router)
|
|
53
|
+
|
|
54
|
+
1.5.0 부터 `"use client"` 를 쓰지 않은 서버 컴포넌트(create-next-app 기본 `app/page.tsx` 등)에서 바로 import 해 렌더할 수 있습니다. 루트와 서브패스 결과가 같습니다.
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
// app/page.tsx (서버 컴포넌트)
|
|
58
|
+
import { CodeBlock, MessageBubble, StreamingText } from '@axis-ds/agentic-ui';
|
|
59
|
+
|
|
60
|
+
export default function Page() {
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
<MessageBubble role="assistant" content="안녕하세요" />
|
|
64
|
+
<CodeBlock code="pnpm add @axis-ds/agentic-ui" language="bash" />
|
|
65
|
+
<StreamingText text="응답을 생성하고 있어요" />
|
|
66
|
+
</>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**클라이언트 경계가 있는 컴포넌트**: 아래 7개는 패키지 `dist` 파일에 `"use client"` 가 있어, 서버 컴포넌트가 렌더하면 그 컴포넌트만 브라우저에서 hydrate 됩니다(복사 · 펼침 · 보기 모드 전환 · 피드백 선택 · 타이핑 애니메이션).
|
|
72
|
+
|
|
73
|
+
`CodeBlock` · `ContextPanel` · `DiffViewer` · `FeedbackButtons` · `SourcePanel` · `StreamingText` · `ToolCallCard`
|
|
74
|
+
|
|
75
|
+
나머지 11개(`AgentAvatar` · `ApprovalCard` · `AttachmentCard` · `MessageBubble` · `PlanCard` · `RecoveryBanner` · `RunProgress` · `StepTimeline` · `SurfaceRenderer` · `ThinkingIndicator` · `TokenUsageIndicator`)와 루트 배럴에는 지시문이 없어 서버에서 렌더됩니다. 판단 기준은 `useState` · `useEffect` · `useRef` 같은 클라이언트 전용 API 와 컴포넌트 안에서 이벤트 핸들러를 직접 만드는지이며, 목록은 패키지 소스 `scripts/client-modules.mjs` 한 곳에서 관리합니다.
|
|
76
|
+
|
|
77
|
+
**서버 컴포넌트에서 함수 prop 은 넘길 수 없습니다**: `onCopy` · `onFeedback` · `onComplete` · `onRetry` · `onApprove` 같은 함수는 서버에서 클라이언트로 직렬화할 수 없어 React 가 오류를 냅니다(React Server Components 규칙). 함수 prop 없이 쓰면 서버에서 렌더되고, 핸들러가 필요하면 그 부분을 `"use client"` 파일로 만들어 그 안에서 씁니다.
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
// app/feedback.tsx
|
|
81
|
+
'use client';
|
|
82
|
+
import { FeedbackButtons } from '@axis-ds/agentic-ui';
|
|
83
|
+
|
|
84
|
+
export function Feedback({ messageId }: { messageId: string }) {
|
|
85
|
+
return <FeedbackButtons messageId={messageId} onFeedback={(id, f) => console.log(id, f)} />;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- 이 패키지는 `@axis-ds/ui-react` 루트에서 `cn` 을 가져옵니다. 그래서 서브패스 하나만 import 해도 서버 그래프에 `@axis-ds/ui-react` 의 Radix 클라이언트 참조가 함께 실릴 수 있습니다(1.4.0 에도 있던 현상).
|
|
90
|
+
|
|
21
91
|
## 컴포넌트 목록
|
|
22
92
|
|
|
23
|
-
|
|
93
|
+
AgentAvatar, ApprovalCard, AttachmentCard, CodeBlock, ContextPanel, DiffViewer, FeedbackButtons, MessageBubble, PlanCard, RecoveryBanner, RunProgress, SourcePanel, StepTimeline, StreamingText, SurfaceRenderer, ThinkingIndicator, TokenUsageIndicator, ToolCallCard
|
|
24
94
|
|
|
25
95
|
## 문서
|
|
26
96
|
|
|
@@ -16,36 +16,26 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/agent-avatar/index.tsx
|
|
21
19
|
var agent_avatar_exports = {};
|
|
22
20
|
__export(agent_avatar_exports, {
|
|
23
21
|
AgentAvatar: () => AgentAvatar
|
|
24
22
|
});
|
|
25
23
|
module.exports = __toCommonJS(agent_avatar_exports);
|
|
26
|
-
var import_ui_react = require("@axis-ds/ui-react");
|
|
27
|
-
|
|
28
|
-
// src/constants/a11y-labels.ts
|
|
29
|
-
var AGENT_STATUS_LABELS = {
|
|
30
|
-
online: "\uC628\uB77C\uC778",
|
|
31
|
-
busy: "\uC0AC\uC6A9 \uC911",
|
|
32
|
-
offline: "\uC624\uD504\uB77C\uC778"
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
// src/agent-avatar/index.tsx
|
|
36
24
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
37
|
-
var
|
|
25
|
+
var import_ui_react = require("@axis-ds/ui-react");
|
|
26
|
+
var import_a11y_labels = require("../constants/a11y-labels.js");
|
|
27
|
+
const sizeStyles = {
|
|
38
28
|
sm: "w-6 h-6 text-xs",
|
|
39
29
|
md: "w-8 h-8 text-sm",
|
|
40
30
|
lg: "w-10 h-10 text-base",
|
|
41
31
|
xl: "w-12 h-12 text-lg"
|
|
42
32
|
};
|
|
43
|
-
|
|
33
|
+
const statusStyles = {
|
|
44
34
|
online: "bg-[var(--axis-status-success)]",
|
|
45
35
|
busy: "bg-[var(--axis-status-warning)]",
|
|
46
36
|
offline: "bg-[var(--axis-status-neutral)]"
|
|
47
37
|
};
|
|
48
|
-
|
|
38
|
+
const typeColors = {
|
|
49
39
|
assistant: "bg-[var(--axis-agent-avatar-assistant)]",
|
|
50
40
|
tool: "bg-[var(--axis-agent-avatar-tool)]",
|
|
51
41
|
system: "bg-[var(--axis-agent-avatar-system)]"
|
|
@@ -59,7 +49,7 @@ function AgentAvatar({
|
|
|
59
49
|
className
|
|
60
50
|
}) {
|
|
61
51
|
const initials = name.split(" ").map((n) => n[0]).join("").slice(0, 2).toUpperCase();
|
|
62
|
-
const statusLabel = status ? AGENT_STATUS_LABELS[status] : "";
|
|
52
|
+
const statusLabel = status ? import_a11y_labels.AGENT_STATUS_LABELS[status] : "";
|
|
63
53
|
const ariaLabel = `${name}${statusLabel ? `, ${statusLabel}` : ""}`;
|
|
64
54
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
65
55
|
"div",
|
|
@@ -1,7 +1,78 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
} from "../
|
|
4
|
-
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "@axis-ds/ui-react";
|
|
3
|
+
import { AGENT_STATUS_LABELS } from "../constants/a11y-labels.mjs";
|
|
4
|
+
const sizeStyles = {
|
|
5
|
+
sm: "w-6 h-6 text-xs",
|
|
6
|
+
md: "w-8 h-8 text-sm",
|
|
7
|
+
lg: "w-10 h-10 text-base",
|
|
8
|
+
xl: "w-12 h-12 text-lg"
|
|
9
|
+
};
|
|
10
|
+
const statusStyles = {
|
|
11
|
+
online: "bg-[var(--axis-status-success)]",
|
|
12
|
+
busy: "bg-[var(--axis-status-warning)]",
|
|
13
|
+
offline: "bg-[var(--axis-status-neutral)]"
|
|
14
|
+
};
|
|
15
|
+
const typeColors = {
|
|
16
|
+
assistant: "bg-[var(--axis-agent-avatar-assistant)]",
|
|
17
|
+
tool: "bg-[var(--axis-agent-avatar-tool)]",
|
|
18
|
+
system: "bg-[var(--axis-agent-avatar-system)]"
|
|
19
|
+
};
|
|
20
|
+
function AgentAvatar({
|
|
21
|
+
name,
|
|
22
|
+
src,
|
|
23
|
+
size = "md",
|
|
24
|
+
status,
|
|
25
|
+
type = "assistant",
|
|
26
|
+
className
|
|
27
|
+
}) {
|
|
28
|
+
const initials = name.split(" ").map((n) => n[0]).join("").slice(0, 2).toUpperCase();
|
|
29
|
+
const statusLabel = status ? AGENT_STATUS_LABELS[status] : "";
|
|
30
|
+
const ariaLabel = `${name}${statusLabel ? `, ${statusLabel}` : ""}`;
|
|
31
|
+
return /* @__PURE__ */ jsxs(
|
|
32
|
+
"div",
|
|
33
|
+
{
|
|
34
|
+
role: "img",
|
|
35
|
+
"aria-label": ariaLabel,
|
|
36
|
+
className: cn("relative inline-flex", className),
|
|
37
|
+
children: [
|
|
38
|
+
src ? /* @__PURE__ */ jsx(
|
|
39
|
+
"img",
|
|
40
|
+
{
|
|
41
|
+
src,
|
|
42
|
+
alt: "",
|
|
43
|
+
"aria-hidden": "true",
|
|
44
|
+
className: cn(
|
|
45
|
+
"rounded-full object-cover",
|
|
46
|
+
sizeStyles[size]
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
) : /* @__PURE__ */ jsx(
|
|
50
|
+
"div",
|
|
51
|
+
{
|
|
52
|
+
"aria-hidden": "true",
|
|
53
|
+
className: cn(
|
|
54
|
+
"rounded-full flex items-center justify-center font-medium text-[var(--axis-agent-avatar-text)]",
|
|
55
|
+
sizeStyles[size],
|
|
56
|
+
typeColors[type]
|
|
57
|
+
),
|
|
58
|
+
children: initials
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
status && /* @__PURE__ */ jsx(
|
|
62
|
+
"span",
|
|
63
|
+
{
|
|
64
|
+
"aria-hidden": "true",
|
|
65
|
+
className: cn(
|
|
66
|
+
"absolute bottom-0 right-0 rounded-full border-2 border-[var(--axis-surface-default)]",
|
|
67
|
+
size === "sm" ? "w-2 h-2" : "w-3 h-3",
|
|
68
|
+
statusStyles[status]
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
}
|
|
5
76
|
export {
|
|
6
77
|
AgentAvatar
|
|
7
78
|
};
|
|
@@ -26,26 +26,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
mod
|
|
27
27
|
));
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/approval-card/index.tsx
|
|
31
29
|
var approval_card_exports = {};
|
|
32
30
|
__export(approval_card_exports, {
|
|
33
31
|
ApprovalCard: () => ApprovalCard
|
|
34
32
|
});
|
|
35
33
|
module.exports = __toCommonJS(approval_card_exports);
|
|
34
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
36
35
|
var React = __toESM(require("react"));
|
|
37
36
|
var import_ui_react = require("@axis-ds/ui-react");
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
var SEVERITY_LABELS = {
|
|
41
|
-
info: "\uC815\uBCF4",
|
|
42
|
-
warning: "\uC8FC\uC758",
|
|
43
|
-
error: "\uC624\uB958"
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// src/approval-card/index.tsx
|
|
47
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
48
|
-
var severityStyles = {
|
|
37
|
+
var import_a11y_labels = require("../constants/a11y-labels.js");
|
|
38
|
+
const severityStyles = {
|
|
49
39
|
info: {
|
|
50
40
|
border: "border-l-[var(--axis-status-info)]",
|
|
51
41
|
icon: "text-[var(--axis-status-info)]",
|
|
@@ -62,12 +52,12 @@ var severityStyles = {
|
|
|
62
52
|
bg: "bg-[var(--axis-surface-error)]"
|
|
63
53
|
}
|
|
64
54
|
};
|
|
65
|
-
|
|
55
|
+
const severityIcons = {
|
|
66
56
|
info: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
67
57
|
warning: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
|
|
68
58
|
error: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) })
|
|
69
59
|
};
|
|
70
|
-
|
|
60
|
+
const actionVariantStyles = {
|
|
71
61
|
default: "bg-[var(--axis-button-bg-default)] text-[var(--axis-button-text-default)] hover:bg-[var(--axis-button-bg-hover)]",
|
|
72
62
|
secondary: "bg-[var(--axis-button-secondary-bg-default)] text-[var(--axis-text-primary)] hover:bg-[var(--axis-button-secondary-bg-hover)]",
|
|
73
63
|
ghost: "bg-transparent text-[var(--axis-text-primary)] hover:bg-[var(--axis-surface-secondary)]",
|
|
@@ -87,7 +77,7 @@ function ApprovalCard({
|
|
|
87
77
|
const baseId = id || generatedId;
|
|
88
78
|
const titleId = `${baseId}-title`;
|
|
89
79
|
const descId = `${baseId}-desc`;
|
|
90
|
-
const severityLabel = SEVERITY_LABELS[severity];
|
|
80
|
+
const severityLabel = import_a11y_labels.SEVERITY_LABELS[severity];
|
|
91
81
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
92
82
|
"div",
|
|
93
83
|
{
|
|
@@ -1,7 +1,89 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
} from "
|
|
4
|
-
import "../
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "@axis-ds/ui-react";
|
|
4
|
+
import { SEVERITY_LABELS } from "../constants/a11y-labels.mjs";
|
|
5
|
+
const severityStyles = {
|
|
6
|
+
info: {
|
|
7
|
+
border: "border-l-[var(--axis-status-info)]",
|
|
8
|
+
icon: "text-[var(--axis-status-info)]",
|
|
9
|
+
bg: "bg-[var(--axis-surface-info)]"
|
|
10
|
+
},
|
|
11
|
+
warning: {
|
|
12
|
+
border: "border-l-[var(--axis-status-warning)]",
|
|
13
|
+
icon: "text-[var(--axis-status-warning)]",
|
|
14
|
+
bg: "bg-[var(--axis-surface-warning)]"
|
|
15
|
+
},
|
|
16
|
+
error: {
|
|
17
|
+
border: "border-l-[var(--axis-status-error)]",
|
|
18
|
+
icon: "text-[var(--axis-status-error)]",
|
|
19
|
+
bg: "bg-[var(--axis-surface-error)]"
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const severityIcons = {
|
|
23
|
+
info: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
24
|
+
warning: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
|
|
25
|
+
error: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) })
|
|
26
|
+
};
|
|
27
|
+
const actionVariantStyles = {
|
|
28
|
+
default: "bg-[var(--axis-button-bg-default)] text-[var(--axis-button-text-default)] hover:bg-[var(--axis-button-bg-hover)]",
|
|
29
|
+
secondary: "bg-[var(--axis-button-secondary-bg-default)] text-[var(--axis-text-primary)] hover:bg-[var(--axis-button-secondary-bg-hover)]",
|
|
30
|
+
ghost: "bg-transparent text-[var(--axis-text-primary)] hover:bg-[var(--axis-surface-secondary)]",
|
|
31
|
+
destructive: "bg-[var(--axis-button-destructive-bg-default)] text-[var(--axis-button-destructive-text-default)] hover:bg-[var(--axis-button-destructive-bg-hover)]"
|
|
32
|
+
};
|
|
33
|
+
function ApprovalCard({
|
|
34
|
+
id,
|
|
35
|
+
title,
|
|
36
|
+
description,
|
|
37
|
+
severity = "info",
|
|
38
|
+
actions,
|
|
39
|
+
children,
|
|
40
|
+
className
|
|
41
|
+
}) {
|
|
42
|
+
const styles = severityStyles[severity];
|
|
43
|
+
const generatedId = React.useId();
|
|
44
|
+
const baseId = id || generatedId;
|
|
45
|
+
const titleId = `${baseId}-title`;
|
|
46
|
+
const descId = `${baseId}-desc`;
|
|
47
|
+
const severityLabel = SEVERITY_LABELS[severity];
|
|
48
|
+
return /* @__PURE__ */ jsx(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
role: "region",
|
|
52
|
+
"aria-labelledby": titleId,
|
|
53
|
+
"aria-describedby": description ? descId : void 0,
|
|
54
|
+
className: cn(
|
|
55
|
+
"rounded-lg border border-l-4 p-4",
|
|
56
|
+
"bg-[var(--axis-surface-default)] border-[var(--axis-border-default)]",
|
|
57
|
+
styles.border,
|
|
58
|
+
className
|
|
59
|
+
),
|
|
60
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
|
|
61
|
+
/* @__PURE__ */ jsx("div", { className: cn("flex-shrink-0 mt-0.5", styles.icon), "aria-hidden": "true", children: severityIcons[severity] }),
|
|
62
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
63
|
+
/* @__PURE__ */ jsxs("span", { className: "sr-only", children: [
|
|
64
|
+
severityLabel,
|
|
65
|
+
" \uC54C\uB9BC:"
|
|
66
|
+
] }),
|
|
67
|
+
/* @__PURE__ */ jsx("h4", { id: titleId, className: "text-sm font-semibold text-[var(--axis-text-primary)]", children: title }),
|
|
68
|
+
description && /* @__PURE__ */ jsx("p", { id: descId, className: "mt-1 text-sm text-[var(--axis-text-secondary)]", children: description }),
|
|
69
|
+
children && /* @__PURE__ */ jsx("div", { className: "mt-3", children }),
|
|
70
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 mt-4", children: actions.map((action, index) => /* @__PURE__ */ jsx(
|
|
71
|
+
"button",
|
|
72
|
+
{
|
|
73
|
+
onClick: action.onClick,
|
|
74
|
+
className: cn(
|
|
75
|
+
"px-3 py-1.5 text-sm font-medium rounded-md transition-colors",
|
|
76
|
+
actionVariantStyles[action.variant || "default"]
|
|
77
|
+
),
|
|
78
|
+
children: action.label
|
|
79
|
+
},
|
|
80
|
+
index
|
|
81
|
+
)) })
|
|
82
|
+
] })
|
|
83
|
+
] })
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
}
|
|
5
87
|
export {
|
|
6
88
|
ApprovalCard
|
|
7
89
|
};
|
|
@@ -16,34 +16,22 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
return to;
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/attachment-card/index.tsx
|
|
21
19
|
var attachment_card_exports = {};
|
|
22
20
|
__export(attachment_card_exports, {
|
|
23
21
|
AttachmentCard: () => AttachmentCard
|
|
24
22
|
});
|
|
25
23
|
module.exports = __toCommonJS(attachment_card_exports);
|
|
26
|
-
var import_ui_react = require("@axis-ds/ui-react");
|
|
27
|
-
|
|
28
|
-
// src/constants/a11y-labels.ts
|
|
29
|
-
var ATTACHMENT_TYPE_LABELS = {
|
|
30
|
-
image: "\uC774\uBBF8\uC9C0",
|
|
31
|
-
document: "\uBB38\uC11C",
|
|
32
|
-
code: "\uCF54\uB4DC",
|
|
33
|
-
archive: "\uC555\uCD95 \uD30C\uC77C",
|
|
34
|
-
other: "\uAE30\uD0C0 \uD30C\uC77C"
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
// src/attachment-card/index.tsx
|
|
38
24
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
39
|
-
var
|
|
25
|
+
var import_ui_react = require("@axis-ds/ui-react");
|
|
26
|
+
var import_a11y_labels = require("../constants/a11y-labels.js");
|
|
27
|
+
const typeIcons = {
|
|
40
28
|
image: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
41
29
|
document: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }),
|
|
42
30
|
code: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" }) }),
|
|
43
31
|
archive: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" }) }),
|
|
44
32
|
other: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) })
|
|
45
33
|
};
|
|
46
|
-
|
|
34
|
+
const formatFileSize = (bytes) => {
|
|
47
35
|
if (bytes < 1024) return `${bytes} B`;
|
|
48
36
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
49
37
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
@@ -59,7 +47,7 @@ function AttachmentCard({
|
|
|
59
47
|
onRemove,
|
|
60
48
|
className
|
|
61
49
|
}) {
|
|
62
|
-
const typeLabel = ATTACHMENT_TYPE_LABELS[type];
|
|
50
|
+
const typeLabel = import_a11y_labels.ATTACHMENT_TYPE_LABELS[type];
|
|
63
51
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
64
52
|
"div",
|
|
65
53
|
{
|
|
@@ -1,7 +1,104 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
} from "../
|
|
4
|
-
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "@axis-ds/ui-react";
|
|
3
|
+
import { ATTACHMENT_TYPE_LABELS } from "../constants/a11y-labels.mjs";
|
|
4
|
+
const typeIcons = {
|
|
5
|
+
image: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
6
|
+
document: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }),
|
|
7
|
+
code: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" }) }),
|
|
8
|
+
archive: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" }) }),
|
|
9
|
+
other: /* @__PURE__ */ jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) })
|
|
10
|
+
};
|
|
11
|
+
const formatFileSize = (bytes) => {
|
|
12
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
13
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
14
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
15
|
+
};
|
|
16
|
+
function AttachmentCard({
|
|
17
|
+
type,
|
|
18
|
+
name,
|
|
19
|
+
size,
|
|
20
|
+
url,
|
|
21
|
+
thumbnail,
|
|
22
|
+
status = "complete",
|
|
23
|
+
progress,
|
|
24
|
+
onRemove,
|
|
25
|
+
className
|
|
26
|
+
}) {
|
|
27
|
+
const typeLabel = ATTACHMENT_TYPE_LABELS[type];
|
|
28
|
+
return /* @__PURE__ */ jsxs(
|
|
29
|
+
"div",
|
|
30
|
+
{
|
|
31
|
+
role: "article",
|
|
32
|
+
"aria-label": `${typeLabel}: ${name}`,
|
|
33
|
+
className: cn(
|
|
34
|
+
"flex items-center gap-3 rounded-lg border p-3",
|
|
35
|
+
"bg-[var(--axis-surface-default)] border-[var(--axis-border-default)]",
|
|
36
|
+
status === "error" && "border-[var(--axis-status-error-border)]",
|
|
37
|
+
className
|
|
38
|
+
),
|
|
39
|
+
children: [
|
|
40
|
+
thumbnail ? /* @__PURE__ */ jsx(
|
|
41
|
+
"img",
|
|
42
|
+
{
|
|
43
|
+
src: thumbnail,
|
|
44
|
+
alt: "",
|
|
45
|
+
"aria-hidden": "true",
|
|
46
|
+
className: "w-10 h-10 rounded object-cover flex-shrink-0"
|
|
47
|
+
}
|
|
48
|
+
) : /* @__PURE__ */ jsx(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
className: "w-10 h-10 rounded flex items-center justify-center flex-shrink-0 bg-[var(--axis-surface-secondary)] text-[var(--axis-icon-secondary)]",
|
|
52
|
+
"aria-hidden": "true",
|
|
53
|
+
children: typeIcons[type]
|
|
54
|
+
}
|
|
55
|
+
),
|
|
56
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
57
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--axis-text-primary)] truncate", children: url ? /* @__PURE__ */ jsx(
|
|
58
|
+
"a",
|
|
59
|
+
{
|
|
60
|
+
href: url,
|
|
61
|
+
target: "_blank",
|
|
62
|
+
rel: "noopener noreferrer",
|
|
63
|
+
className: "hover:underline",
|
|
64
|
+
"aria-label": `${name} (\uC0C8 \uCC3D\uC5D0\uC11C \uC5F4\uB9BC)`,
|
|
65
|
+
children: name
|
|
66
|
+
}
|
|
67
|
+
) : name }),
|
|
68
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-[var(--axis-text-tertiary)]", children: [
|
|
69
|
+
/* @__PURE__ */ jsx("span", { children: typeLabel }),
|
|
70
|
+
size !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
71
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
72
|
+
/* @__PURE__ */ jsx("span", { children: formatFileSize(size) })
|
|
73
|
+
] }),
|
|
74
|
+
status === "error" && /* @__PURE__ */ jsx("span", { className: "text-[var(--axis-text-error)]", children: "\uC5C5\uB85C\uB4DC \uC2E4\uD328" })
|
|
75
|
+
] }),
|
|
76
|
+
status === "uploading" && progress !== void 0 && /* @__PURE__ */ jsx("div", { className: "mt-1.5 h-1 rounded-full bg-[var(--axis-surface-secondary)] overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
77
|
+
"div",
|
|
78
|
+
{
|
|
79
|
+
className: "h-full rounded-full bg-[var(--axis-status-running)] transition-all",
|
|
80
|
+
style: { width: `${progress}%` },
|
|
81
|
+
role: "progressbar",
|
|
82
|
+
"aria-valuenow": progress,
|
|
83
|
+
"aria-valuemin": 0,
|
|
84
|
+
"aria-valuemax": 100,
|
|
85
|
+
"aria-label": "\uC5C5\uB85C\uB4DC \uC9C4\uD589\uB960"
|
|
86
|
+
}
|
|
87
|
+
) })
|
|
88
|
+
] }),
|
|
89
|
+
onRemove && /* @__PURE__ */ jsx(
|
|
90
|
+
"button",
|
|
91
|
+
{
|
|
92
|
+
onClick: onRemove,
|
|
93
|
+
"aria-label": `${name} \uC0AD\uC81C`,
|
|
94
|
+
className: "flex-shrink-0 p-1 rounded-md text-[var(--axis-text-tertiary)] hover:text-[var(--axis-text-secondary)] hover:bg-[var(--axis-surface-secondary)] transition-colors",
|
|
95
|
+
children: /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
}
|
|
5
102
|
export {
|
|
6
103
|
AttachmentCard
|
|
7
104
|
};
|
package/dist/code-block/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
"use strict";
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
@@ -26,16 +27,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
27
|
mod
|
|
27
28
|
));
|
|
28
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/code-block/index.tsx
|
|
31
30
|
var code_block_exports = {};
|
|
32
31
|
__export(code_block_exports, {
|
|
33
32
|
CodeBlock: () => CodeBlock
|
|
34
33
|
});
|
|
35
34
|
module.exports = __toCommonJS(code_block_exports);
|
|
35
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
36
36
|
var React = __toESM(require("react"));
|
|
37
37
|
var import_ui_react = require("@axis-ds/ui-react");
|
|
38
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
39
38
|
function CodeBlock({
|
|
40
39
|
code,
|
|
41
40
|
language,
|
|
@@ -1,6 +1,79 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "@axis-ds/ui-react";
|
|
5
|
+
function CodeBlock({
|
|
6
|
+
code,
|
|
7
|
+
language,
|
|
8
|
+
filename,
|
|
9
|
+
showLineNumbers = false,
|
|
10
|
+
onCopy,
|
|
11
|
+
maxHeight,
|
|
12
|
+
className
|
|
13
|
+
}) {
|
|
14
|
+
const [copied, setCopied] = React.useState(false);
|
|
15
|
+
const handleCopy = async () => {
|
|
16
|
+
try {
|
|
17
|
+
await navigator.clipboard.writeText(code);
|
|
18
|
+
setCopied(true);
|
|
19
|
+
onCopy?.(code);
|
|
20
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
21
|
+
} catch {
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const lines = code.split("\n");
|
|
25
|
+
return /* @__PURE__ */ jsxs(
|
|
26
|
+
"div",
|
|
27
|
+
{
|
|
28
|
+
className: cn(
|
|
29
|
+
"rounded-lg border overflow-hidden",
|
|
30
|
+
"bg-[var(--axis-surface-default)] border-[var(--axis-border-default)]",
|
|
31
|
+
className
|
|
32
|
+
),
|
|
33
|
+
children: [
|
|
34
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-3 py-2 border-b border-[var(--axis-border-default)] bg-[var(--axis-surface-secondary)]", children: [
|
|
35
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
36
|
+
filename && /* @__PURE__ */ jsx("code", { className: "text-xs font-mono text-[var(--axis-text-primary)] truncate", children: filename }),
|
|
37
|
+
language && /* @__PURE__ */ jsx("span", { className: "text-xs px-1.5 py-0.5 rounded bg-[var(--axis-surface-tertiary)] text-[var(--axis-text-tertiary)]", children: language })
|
|
38
|
+
] }),
|
|
39
|
+
/* @__PURE__ */ jsx(
|
|
40
|
+
"button",
|
|
41
|
+
{
|
|
42
|
+
onClick: handleCopy,
|
|
43
|
+
"aria-label": copied ? "\uBCF5\uC0AC\uB428" : "\uCF54\uB4DC \uBCF5\uC0AC",
|
|
44
|
+
className: "flex items-center gap-1 px-2 py-1 text-xs rounded-md text-[var(--axis-text-secondary)] hover:bg-[var(--axis-surface-tertiary)] transition-colors",
|
|
45
|
+
children: copied ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
46
|
+
/* @__PURE__ */ jsx("svg", { className: "w-3.5 h-3.5 text-[var(--axis-status-success)]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }),
|
|
47
|
+
/* @__PURE__ */ jsx("span", { children: "\uBCF5\uC0AC\uB428" })
|
|
48
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
49
|
+
/* @__PURE__ */ jsx("svg", { className: "w-3.5 h-3.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) }),
|
|
50
|
+
/* @__PURE__ */ jsx("span", { children: "\uBCF5\uC0AC" })
|
|
51
|
+
] })
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
] }),
|
|
55
|
+
/* @__PURE__ */ jsx(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
className: "overflow-auto",
|
|
59
|
+
style: maxHeight ? { maxHeight } : void 0,
|
|
60
|
+
children: /* @__PURE__ */ jsx("pre", { className: "p-3 text-sm leading-relaxed", children: /* @__PURE__ */ jsx("code", { className: "text-[var(--axis-text-primary)] font-mono", children: showLineNumbers ? /* @__PURE__ */ jsx("table", { className: "border-collapse w-full", role: "presentation", children: /* @__PURE__ */ jsx("tbody", { children: lines.map((line, i) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
"td",
|
|
63
|
+
{
|
|
64
|
+
className: "select-none text-right pr-4 text-[var(--axis-text-tertiary)] w-8",
|
|
65
|
+
"aria-hidden": "true",
|
|
66
|
+
children: i + 1
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
/* @__PURE__ */ jsx("td", { className: "whitespace-pre", children: line })
|
|
70
|
+
] }, i)) }) }) : code }) })
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
}
|
|
4
77
|
export {
|
|
5
78
|
CodeBlock
|
|
6
79
|
};
|