@axis-ds/agentic-ui 1.4.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.
Files changed (62) hide show
  1. package/README.md +42 -1
  2. package/dist/agent-avatar/index.js +6 -16
  3. package/dist/agent-avatar/index.mjs +75 -4
  4. package/dist/approval-card/index.js +6 -16
  5. package/dist/approval-card/index.mjs +86 -4
  6. package/dist/attachment-card/index.js +5 -17
  7. package/dist/attachment-card/index.mjs +101 -4
  8. package/dist/code-block/index.js +2 -3
  9. package/dist/code-block/index.mjs +76 -3
  10. package/dist/constants/a11y-labels.d.mts +86 -0
  11. package/dist/constants/a11y-labels.d.ts +86 -0
  12. package/dist/constants/a11y-labels.js +105 -0
  13. package/dist/{chunk-SCZ4BQ2G.mjs → constants/a11y-labels.mjs} +21 -17
  14. package/dist/context-panel/index.js +2 -3
  15. package/dist/context-panel/index.mjs +99 -3
  16. package/dist/diff-viewer/index.js +8 -17
  17. package/dist/diff-viewer/index.mjs +155 -4
  18. package/dist/feedback-buttons/index.js +7 -16
  19. package/dist/feedback-buttons/index.mjs +65 -4
  20. package/dist/index.js +36 -1732
  21. package/dist/index.mjs +18 -55
  22. package/dist/message-bubble/index.js +5 -15
  23. package/dist/message-bubble/index.mjs +98 -4
  24. package/dist/plan-card/index.js +6 -28
  25. package/dist/plan-card/index.mjs +143 -4
  26. package/dist/recovery-banner/index.js +1 -3
  27. package/dist/recovery-banner/index.mjs +70 -3
  28. package/dist/run-progress/index.js +5 -19
  29. package/dist/run-progress/index.mjs +128 -4
  30. package/dist/source-panel/index.js +5 -15
  31. package/dist/source-panel/index.mjs +88 -4
  32. package/dist/step-timeline/index.js +3 -17
  33. package/dist/step-timeline/index.mjs +69 -4
  34. package/dist/streaming-text/index.js +2 -3
  35. package/dist/streaming-text/index.mjs +59 -3
  36. package/dist/surface-renderer/index.js +1 -3
  37. package/dist/surface-renderer/index.mjs +79 -3
  38. package/dist/thinking-indicator/index.js +3 -5
  39. package/dist/thinking-indicator/index.mjs +45 -3
  40. package/dist/token-usage-indicator/index.js +1 -3
  41. package/dist/token-usage-indicator/index.mjs +81 -3
  42. package/dist/tool-call-card/index.js +5 -18
  43. package/dist/tool-call-card/index.mjs +108 -4
  44. package/package.json +35 -5
  45. package/dist/chunk-42KEAZ2Y.mjs +0 -109
  46. package/dist/chunk-4CMUEGLK.mjs +0 -80
  47. package/dist/chunk-4V4BWBRC.mjs +0 -77
  48. package/dist/chunk-7HTVJ6MK.mjs +0 -94
  49. package/dist/chunk-DPLGRVNQ.mjs +0 -95
  50. package/dist/chunk-FYAMA32G.mjs +0 -50
  51. package/dist/chunk-GQYOOLDL.mjs +0 -63
  52. package/dist/chunk-IOF4OET6.mjs +0 -162
  53. package/dist/chunk-J4FIMXXG.mjs +0 -106
  54. package/dist/chunk-JY7MTMMB.mjs +0 -83
  55. package/dist/chunk-KJVPVBET.mjs +0 -103
  56. package/dist/chunk-OYQX3SL4.mjs +0 -152
  57. package/dist/chunk-QS6GQNSE.mjs +0 -86
  58. package/dist/chunk-R4CMHIRO.mjs +0 -72
  59. package/dist/chunk-SCXUEQLI.mjs +0 -136
  60. package/dist/chunk-UDL4M5RP.mjs +0 -75
  61. package/dist/chunk-WFYQINWD.mjs +0 -115
  62. package/dist/chunk-ZW4Z27AB.mjs +0 -84
package/README.md CHANGED
@@ -47,9 +47,50 @@ import { StreamingText, ToolCallCard } from '@axis-ds/agentic-ui';
47
47
  import { StreamingText } from '@axis-ds/agentic-ui/streaming-text';
48
48
  ```
49
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
+
50
91
  ## 컴포넌트 목록
51
92
 
52
- RunProgress, ApprovalCard, StreamingText, ToolCallCard, MessageBubble, FeedbackButtons, CodeBlock, DiffViewer, PlanCard, ContextPanel, TokenUsageIndicator, AttachmentCard
93
+ AgentAvatar, ApprovalCard, AttachmentCard, CodeBlock, ContextPanel, DiffViewer, FeedbackButtons, MessageBubble, PlanCard, RecoveryBanner, RunProgress, SourcePanel, StepTimeline, StreamingText, SurfaceRenderer, ThinkingIndicator, TokenUsageIndicator, ToolCallCard
53
94
 
54
95
  ## 문서
55
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 sizeStyles = {
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
- var statusStyles = {
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
- var typeColors = {
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
- AgentAvatar
3
- } from "../chunk-JY7MTMMB.mjs";
4
- import "../chunk-SCZ4BQ2G.mjs";
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
- // src/constants/a11y-labels.ts
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
- var severityIcons = {
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
- var actionVariantStyles = {
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
- ApprovalCard
3
- } from "../chunk-7HTVJ6MK.mjs";
4
- import "../chunk-SCZ4BQ2G.mjs";
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 typeIcons = {
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
- var formatFileSize = (bytes) => {
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
- AttachmentCard
3
- } from "../chunk-42KEAZ2Y.mjs";
4
- import "../chunk-SCZ4BQ2G.mjs";
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
  };
@@ -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
- import {
2
- CodeBlock
3
- } from "../chunk-4CMUEGLK.mjs";
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
  };