@godxjp/ui 23.3.0 → 23.4.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 (79) hide show
  1. package/dist/components/data-display/card.d.ts +87 -1
  2. package/dist/components/data-display/card.js +88 -15
  3. package/dist/components/data-display/index.d.ts +5 -1
  4. package/dist/components/data-display/index.js +5 -0
  5. package/dist/components/data-display/thought-chain.d.ts +42 -0
  6. package/dist/components/data-display/thought-chain.js +177 -0
  7. package/dist/components/data-display/welcome.d.ts +26 -0
  8. package/dist/components/data-display/welcome.js +37 -0
  9. package/dist/components/data-entry/attachments.d.ts +19 -0
  10. package/dist/components/data-entry/attachments.js +322 -0
  11. package/dist/components/data-entry/index.d.ts +2 -0
  12. package/dist/components/data-entry/index.js +2 -0
  13. package/dist/components/feedback/dialog.d.ts +10 -7
  14. package/dist/components/feedback/dialog.js +40 -17
  15. package/dist/components/feedback/index.d.ts +1 -1
  16. package/dist/components/general/actions.d.ts +59 -0
  17. package/dist/components/general/actions.js +253 -0
  18. package/dist/components/general/activity.js +1 -0
  19. package/dist/components/general/float-button.d.ts +41 -0
  20. package/dist/components/general/float-button.js +336 -0
  21. package/dist/components/general/index.d.ts +6 -2
  22. package/dist/components/general/index.js +12 -1
  23. package/dist/components/general/typography.d.ts +79 -4
  24. package/dist/components/general/typography.js +598 -54
  25. package/dist/components/layout/draggable-panel.d.ts +18 -0
  26. package/dist/components/layout/draggable-panel.js +189 -0
  27. package/dist/components/layout/index.d.ts +2 -0
  28. package/dist/components/layout/index.js +2 -0
  29. package/dist/components/navigation/conversations.d.ts +39 -0
  30. package/dist/components/navigation/conversations.js +371 -0
  31. package/dist/components/navigation/index.d.ts +2 -0
  32. package/dist/components/navigation/index.js +2 -0
  33. package/dist/components/ui/card.js +1 -0
  34. package/dist/i18n/messages/en.json +53 -0
  35. package/dist/i18n/messages/ja.json +53 -0
  36. package/dist/i18n/messages/vi.json +53 -0
  37. package/dist/props/components/data-display.prop.d.ts +143 -1
  38. package/dist/props/components/data-entry.prop.d.ts +76 -0
  39. package/dist/props/components/feedback.prop.d.ts +34 -1
  40. package/dist/props/components/general.prop.d.ts +440 -3
  41. package/dist/props/components/index.d.ts +2 -2
  42. package/dist/props/components/layout.prop.d.ts +63 -1
  43. package/dist/props/components/navigation.prop.d.ts +150 -0
  44. package/dist/props/registry.d.ts +426 -0
  45. package/dist/props/registry.js +546 -0
  46. package/dist/props/vocabulary/index.d.ts +1 -1
  47. package/dist/props/vocabulary/interaction.prop.d.ts +113 -0
  48. package/dist/styles/card-layout.css +30 -0
  49. package/dist/styles/core.css +1 -0
  50. package/dist/styles/data-display-layout.css +236 -0
  51. package/dist/styles/float-button-layout.css +168 -0
  52. package/dist/styles/index.css +1 -0
  53. package/dist/styles/layout.css +196 -0
  54. package/dist/styles/navigation-layout.css +139 -0
  55. package/dist/styles/text-layout.css +156 -0
  56. package/dist/tokens/base.css +7 -0
  57. package/dist/tokens/components/actions.css +14 -0
  58. package/dist/tokens/components/attachments.css +15 -0
  59. package/dist/tokens/components/conversations.css +28 -0
  60. package/dist/tokens/components/draggable-panel.css +25 -0
  61. package/dist/tokens/components/float-button.css +39 -0
  62. package/dist/tokens/components/text.css +13 -0
  63. package/dist/tokens/components/thought-chain.css +31 -0
  64. package/dist/tokens/components/welcome.css +19 -0
  65. package/dist/tokens/foundation.css +2 -0
  66. package/docs/DESIGN-AUTHORITY.md +89 -0
  67. package/docs/FRAME-COVERAGE-REPORT.md +5 -2
  68. package/docs/data-display/card/examples/tab-list.tsx +97 -0
  69. package/docs/data-display/thought-chain.tsx +176 -0
  70. package/docs/data-display/welcome.tsx +115 -0
  71. package/docs/data-entry/attachments.tsx +160 -0
  72. package/docs/feedback/dialog.tsx +50 -0
  73. package/docs/general/actions.tsx +175 -0
  74. package/docs/general/float-button.tsx +133 -0
  75. package/docs/general/typography.tsx +63 -1
  76. package/docs/layout/draggable-panel.tsx +127 -0
  77. package/docs/navigation/conversations.tsx +176 -0
  78. package/docs/roadmap/parity-audit-layout-navigation-general.md +17 -16
  79. package/package.json +3 -3
@@ -0,0 +1,127 @@
1
+ import { useState } from "react";
2
+ import { DraggablePanel, Flex, PageContainer } from "@godxjp/ui/layout";
3
+ import type { DraggablePanelPositionProp } from "@godxjp/ui/layout";
4
+ import {
5
+ Card,
6
+ CardContent,
7
+ CardDescription,
8
+ CardHeader,
9
+ CardTitle,
10
+ Badge,
11
+ Descriptions,
12
+ } from "@godxjp/ui/data-display";
13
+ import { Button, Text } from "@godxjp/ui/general";
14
+
15
+ /**
16
+ * DraggablePanel · a floating surface the person using it can MOVE.
17
+ *
18
+ * The case it exists for: an assistant docked to a corner covers the thing the
19
+ * person is asking about. Drag it by the title-bar handle, or focus the handle
20
+ * and use the arrow keys. The position is REPORTED to the page below, never
21
+ * stored by the library.
22
+ */
23
+ export default function Demo() {
24
+ const [position, setPosition] = useState<DraggablePanelPositionProp>({ x: 0, y: 0 });
25
+ const [open, setOpen] = useState(true);
26
+ const [pinned, setPinned] = useState(false);
27
+
28
+ return (
29
+ <PageContainer
30
+ title="DraggablePanel"
31
+ subtitle="floating movable surface · handle drag, arrow-key nudge, viewport-bounded"
32
+ >
33
+ <Flex direction="col" gap="lg">
34
+ <Card>
35
+ <CardHeader>
36
+ <CardTitle level={2}>Reported position</CardTitle>
37
+ <CardDescription>
38
+ Drag the panel by its handle, or focus the handle and press an arrow key. Hold Shift
39
+ for the larger step. Every frame and every nudge reports the clamped offset through
40
+ onPositionChange; the page below decides whether to remember it.
41
+ </CardDescription>
42
+ </CardHeader>
43
+ <CardContent>
44
+ <Flex direction="col" gap="md">
45
+ <Descriptions
46
+ items={[
47
+ { label: "x", value: String(Math.round(position.x)) },
48
+ { label: "y", value: String(Math.round(position.y)) },
49
+ ]}
50
+ />
51
+ <Flex gap="sm" wrap>
52
+ <Button
53
+ variant="outline"
54
+ size="sm"
55
+ onClick={() => {
56
+ setPosition({ x: 0, y: 0 });
57
+ }}
58
+ >
59
+ 角に戻す
60
+ </Button>
61
+ <Button
62
+ variant="outline"
63
+ size="sm"
64
+ onClick={() => {
65
+ setPinned((value) => !value);
66
+ }}
67
+ >
68
+ {pinned ? "移動を許可" : "その場に固定"}
69
+ </Button>
70
+ <Button
71
+ variant="outline"
72
+ size="sm"
73
+ onClick={() => {
74
+ setOpen(true);
75
+ }}
76
+ >
77
+ パネルを開く
78
+ </Button>
79
+ </Flex>
80
+ </Flex>
81
+ </CardContent>
82
+ </Card>
83
+
84
+ <Card>
85
+ <CardHeader>
86
+ <CardTitle level={2}>What it is not</CardTitle>
87
+ <CardDescription>
88
+ ResizablePanel resizes panes WITHIN a layout, Sheet is pinned to an edge, and Popover
89
+ is anchored to its trigger. None of them can be repositioned by the viewer, which is
90
+ what a floating assistant needs.
91
+ </CardDescription>
92
+ </CardHeader>
93
+ <CardContent>
94
+ <Text size="sm" tone="muted">
95
+ The panel is a labelled region, not a dialog: it interrupts nothing, traps no focus
96
+ and dims no page, so the work behind it stays usable while it is open.
97
+ </Text>
98
+ </CardContent>
99
+ </Card>
100
+ </Flex>
101
+
102
+ {open ? (
103
+ <DraggablePanel
104
+ title="アシスタント"
105
+ placement="bottom-end"
106
+ width="sm"
107
+ disabled={pinned}
108
+ position={position}
109
+ onPositionChange={setPosition}
110
+ onClose={() => {
111
+ setOpen(false);
112
+ }}
113
+ extra={<Badge tone="info">β</Badge>}
114
+ >
115
+ <Flex direction="col" gap="sm">
116
+ <Text size="sm">
117
+ この請求書の消費税区分について質問できます。テキストは選択できます。掴むのはタイトルバーのハンドルだけです。
118
+ </Text>
119
+ <Text size="xs" tone="muted">
120
+ キーボード: ハンドルにフォーカスして矢印キー · Shift で大きく移動
121
+ </Text>
122
+ </Flex>
123
+ </DraggablePanel>
124
+ ) : null}
125
+ </PageContainer>
126
+ );
127
+ }
@@ -0,0 +1,176 @@
1
+ import { useState } from "react";
2
+
3
+ import { ChatBubbleList, type ChatMessageProp } from "@godxjp/ui/data-display";
4
+ import { ChatComposer } from "@godxjp/ui/data-entry";
5
+ import { Text } from "@godxjp/ui/general";
6
+ import {
7
+ AppShell,
8
+ Flex,
9
+ MasterDetail,
10
+ PageContainer,
11
+ Sidebar,
12
+ type SidebarSectionProp,
13
+ Topbar,
14
+ } from "@godxjp/ui/layout";
15
+ import { Conversations, type ConversationsEntryProp } from "@godxjp/ui/navigation";
16
+ import { Bot, MessageSquare, Pencil, Settings, Trash2, Users } from "lucide-react";
17
+
18
+ /**
19
+ * Conversations — the session rail of a chat surface (Ant Design X `Conversations`).
20
+ *
21
+ * This page is the whole surface gh#559 is about: the rail on the left, the feed and the composer
22
+ * on the right. They were shipped one half at a time, and the missing half is why every consumer
23
+ * hand-rolled a stack of full-width Buttons — one tab stop per conversation, no per-row menu, no
24
+ * recency buckets.
25
+ *
26
+ * The three cards below are one axis each, at rest, so the API is visible without clicking:
27
+ * the live surface, the recency buckets (`groupable`), and the flat rail with a divider and a
28
+ * disabled row. Composed only from real @godxjp/ui components.
29
+ */
30
+ const sections: SidebarSectionProp[] = [
31
+ {
32
+ label: "アシスタント",
33
+ items: [
34
+ { id: "chat", label: "チャット", icon: MessageSquare },
35
+ { id: "agents", label: "エージェント", icon: Bot },
36
+ { id: "members", label: "メンバー", icon: Users },
37
+ ],
38
+ },
39
+ { label: "管理", items: [{ id: "settings", label: "設定", icon: Settings }] },
40
+ ];
41
+
42
+ /** The rail's data, bucketed by recency — the `group` field is what `groupable` reads. */
43
+ const HISTORY: ConversationsEntryProp[] = [
44
+ { key: "invoice", label: "請求書の下書きを直す", group: "今日" },
45
+ { key: "expense", label: "経費精算の規則をまとめる", group: "今日" },
46
+ { key: "travel", label: "出張手当の確認", group: "過去7日間" },
47
+ { key: "onboarding", label: "入社手続きのチェックリスト", group: "過去7日間" },
48
+ { key: "payroll", label: "給与計算の締め日について", group: "それ以前" },
49
+ ];
50
+
51
+ /** A flat rail — no buckets, one rule, one archived row. */
52
+ const FLAT: ConversationsEntryProp[] = [
53
+ { key: "invoice", label: "請求書の下書きを直す", icon: <MessageSquare /> },
54
+ { key: "expense", label: "経費精算の規則をまとめる", icon: <MessageSquare /> },
55
+ { type: "divider", key: "rule" },
56
+ { key: "archived", label: "アーカイブ済みの相談", icon: <MessageSquare />, disabled: true },
57
+ ];
58
+
59
+ const TRANSCRIPT: Record<string, ChatMessageProp[]> = {
60
+ invoice: [
61
+ { id: "m1", role: "user", content: "先月分の請求書の下書きを直したいです。" },
62
+ {
63
+ id: "m2",
64
+ role: "assistant",
65
+ content: "差分は3件でした。金額、支払期日、宛名のうちどれから直しますか。",
66
+ },
67
+ ],
68
+ expense: [
69
+ { id: "m1", role: "user", content: "経費精算の規則を3行でまとめてください。" },
70
+ {
71
+ id: "m2",
72
+ role: "assistant",
73
+ content: "領収書は原本、申請は当月末まで、3万円以上は事前承認が要ります。",
74
+ },
75
+ ],
76
+ };
77
+
78
+ export default function ConversationsDoc() {
79
+ const [active, setActive] = useState("invoice");
80
+ const [draft, setDraft] = useState("");
81
+
82
+ const menu = {
83
+ items: [
84
+ { key: "rename", label: "名前を変更", icon: <Pencil /> },
85
+ { key: "delete", label: "削除", icon: <Trash2 />, danger: true },
86
+ ],
87
+ };
88
+
89
+ return (
90
+ <AppShell
91
+ sidebar={
92
+ <Sidebar
93
+ activeId="chat"
94
+ sections={sections}
95
+ onSelect={() => {}}
96
+ product={{ name: "CoreDesk", role: "アシスタント", color: "hsl(var(--primary))" }}
97
+ />
98
+ }
99
+ topbar={<Topbar />}
100
+ >
101
+ <PageContainer
102
+ title="会話の履歴"
103
+ subtitle="過去の会話を選び、名前を変更し、不要になったものを消す · チャット面の左半分。"
104
+ >
105
+ {/* THE SURFACE. The rail is the master; the feed and the composer are the detail. */}
106
+ <MasterDetail
107
+ rail="master"
108
+ railWidth="compact"
109
+ masterViewport="compact"
110
+ masterLabel="会話の履歴"
111
+ detailLabel="選択中の会話"
112
+ detailId="assistant-transcript"
113
+ master={
114
+ <Conversations
115
+ label="会話の履歴"
116
+ items={HISTORY}
117
+ activeKey={active}
118
+ onActiveChange={setActive}
119
+ groupable={{ collapsible: true }}
120
+ creation={{ label: "新しい会話", onClick: () => setActive("invoice") }}
121
+ menu={menu}
122
+ />
123
+ }
124
+ >
125
+ <Flex direction="col" gap="md">
126
+ <ChatBubbleList
127
+ label="会話"
128
+ className="h-96"
129
+ items={TRANSCRIPT[active] ?? []}
130
+ roles={{
131
+ assistant: { placement: "start", variant: "filled" },
132
+ user: { placement: "end" },
133
+ }}
134
+ />
135
+ <ChatComposer
136
+ aria-label="メッセージ"
137
+ value={draft}
138
+ onValueChange={setDraft}
139
+ onSubmit={() => setDraft("")}
140
+ placeholder="メッセージを入力"
141
+ />
142
+ </Flex>
143
+ </MasterDetail>
144
+
145
+ {/* BUCKETS, EXPANDED. `groupable` with no options groups but never collapses. */}
146
+ <Flex direction="col" gap="sm">
147
+ <Text size="sm" weight="medium">
148
+ recency buckets · groupable
149
+ </Text>
150
+ <Text size="xs" tone="muted">
151
+ バケットの見出しは同じローヴィング順に入るので、畳む操作もレールを離れずに届く。
152
+ </Text>
153
+ <Conversations
154
+ label="会話の履歴(分類のみ)"
155
+ items={HISTORY}
156
+ defaultActiveKey="travel"
157
+ groupable
158
+ menu={menu}
159
+ />
160
+ </Flex>
161
+
162
+ {/* FLAT, WITH A RULE AND A DISABLED ROW. */}
163
+ <Flex direction="col" gap="sm">
164
+ <Text size="sm" weight="medium">
165
+ flat rail · divider and a disabled row
166
+ </Text>
167
+ <Text size="xs" tone="muted">
168
+ 無効な行は見えるが選べず、矢印キーの巡回からも外れる。無効なコントロールは
169
+ フォーカスを受け取らないため。
170
+ </Text>
171
+ <Conversations label="会話の履歴(フラット)" items={FLAT} defaultActiveKey="invoice" />
172
+ </Flex>
173
+ </PageContainer>
174
+ </AppShell>
175
+ );
176
+ }
@@ -14,8 +14,9 @@ ahead of it: `AppShell` (three navigation scopes, nav rail, mobile drawer), `Mob
14
14
  `AuthShell`, `LegalDocumentShell`, `ErrorSurface`, `AppLauncher` and `AppProvider` have no antd
15
15
  counterpart at all, and `Breadcrumb`, `Separator`, `Toolbar` and `Pagination` are already carrying
16
16
  explicit antd-parity work in their prop docs. The "missing features vs Ant Design" complaint does
17
- **not** originate here — most of what antd ships in `Space`, `Divider`, `Grid`, `Anchor`, `Affix`,
18
- `FloatButton` and `App` is genuinely a composition or an existing primitive in this system (§4.2).
17
+ **not** originate here — most of what antd ships in `Space`, `Divider`, `Grid`, `Anchor`, `Affix`
18
+ and `App` is genuinely a composition or an existing primitive in this system (§4.2). `FloatButton`
19
+ was on that list and should not have been: it shipped in gh#558. See the struck-through row in §4.2.
19
20
 
20
21
  What is real, ordered by how badly it hurts:
21
22
 
@@ -420,20 +421,20 @@ an editing lifecycle to the typographic primitive would make every `<Text>` in t
420
421
 
421
422
  ### 4.2 These antd components are **compositions** here, not gaps
422
423
 
423
- | antd | Why it is not a gap | Build it with |
424
- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
425
- | `Space` | `gap` already lives on the layout primitive, with a counted escape hatch (`data-gap-raw`). C3 fails outright. | `Flex gap` / `ResponsiveGrid gap` |
426
- | `Divider` | Exists. | `Separator` (`src/props/components/layout.prop.ts:567`) |
427
- | `Grid` / `Row` / `Col` | Exists, in the house `{base,sm,md,lg}` count model rather than a 12-column raster. | `ResponsiveGrid` + `ResponsiveGrid.Item span` (`src/components/layout/responsive-grid.tsx:115`) |
428
- | `Affix` | C1/C2/C3 all fail — it is `position: sticky` with a JS shim, and antd's own docs now recommend the CSS property. Sticky chrome is already a first-class slot here. | `PageContainer toolbar` (`layout.prop.ts:82-88`), `PageContainer stickyFooter`, `Toolbar sticky`, `DataTable sticky` |
429
- | `Anchor` | C1/C7 fail — the one real use (a long document with a contents rail) is already owned end-to-end, including scroll-spy, hash deep-linking, focus handoff and `aria-current="location"`. A second general Anchor would duplicate it. | `LegalDocumentShell` (`layout.prop.ts:1279-1331`) |
430
- | `FloatButton` / `BackTop` | C1/C2 faillayout + content + colour, positioned by the screen that wants it. `BackTop` additionally competes with the shell's own scroll ownership (`MobileShell` is deliberately the only scroll container, `layout.prop.ts:504-507`). | `Button shape="pill" size="icon-lg"` placed by the page; a token for the inset if one is missing |
431
- | `Layout.Header` / `Content` / `Footer` | Bare boxes in antd; real slots here. | `AppShell topbar` / `children` / `footer`, `Topbar`, `PageContainer` |
432
- | `App` (static-method context) | The context problem it solves does not exist here — nothing is imperative. | `AppProvider` + `Toaster` + declarative `Dialog`/`AlertDialog` |
433
- | `PageHeader` (removed from antd core) | Exists, and is wider. | `PageContainer` (`layout.prop.ts:64-139`) |
434
- | `Result` | Exists for HTTP statuses; the non-HTTP shapes are an empty state with an action. | `ErrorSurface` / `EmptyState` |
435
- | `Menu` `items` config array as the only API | Both dialects exist already: config-array for the route rails, compound parts for the overlay menus. | `Sidebar.sections` / `NavList.items` · `DropdownMenu*` |
436
- | `Dropdown.Button` | Two existing primitives plus the proposed `ButtonGroup`. | `ButtonGroup` + `Button` + `DropdownMenu` |
424
+ | antd | Why it is not a gap | Build it with |
425
+ | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
426
+ | `Space` | `gap` already lives on the layout primitive, with a counted escape hatch (`data-gap-raw`). C3 fails outright. | `Flex gap` / `ResponsiveGrid gap` |
427
+ | `Divider` | Exists. | `Separator` (`src/props/components/layout.prop.ts:567`) |
428
+ | `Grid` / `Row` / `Col` | Exists, in the house `{base,sm,md,lg}` count model rather than a 12-column raster. | `ResponsiveGrid` + `ResponsiveGrid.Item span` (`src/components/layout/responsive-grid.tsx:115`) |
429
+ | `Affix` | C1/C2/C3 all fail — it is `position: sticky` with a JS shim, and antd's own docs now recommend the CSS property. Sticky chrome is already a first-class slot here. | `PageContainer toolbar` (`layout.prop.ts:82-88`), `PageContainer stickyFooter`, `Toolbar sticky`, `DataTable sticky` |
430
+ | `Anchor` | C1/C7 fail — the one real use (a long document with a contents rail) is already owned end-to-end, including scroll-spy, hash deep-linking, focus handoff and `aria-current="location"`. A second general Anchor would duplicate it. | `LegalDocumentShell` (`layout.prop.ts:1279-1331`) |
431
+ | ~~`FloatButton` / `BackTop`~~ **SHIPPED** | **This row was wrong, and it is kept struck through rather than deleted so the reversal is legible.** It read C1/C2 as failing; the repo owner's 2026-09-12 decision (docs/DESIGN-AUTHORITY.md antd IS the standard, ported 100% first) settles the question the other way, and gh#558 supplied the C1 case the row denied: pinning a `Button` to a corner requires `position: fixed` at the call site, which `ui-audit` blocks with no legal spelling. The `BackTop`-vs-shell-scroll objection was real and is answered by antd's own `target` prop, which points BackTop at a shell's scroll region instead of the document. | `FloatButton` (`src/components/general/float-button.tsx`), insets on `--float-button-offset-block-end` / `-inline-end` |
432
+ | `Layout.Header` / `Content` / `Footer` | Bare boxes in antd; real slots here. | `AppShell topbar` / `children` / `footer`, `Topbar`, `PageContainer` |
433
+ | `App` (static-method context) | The context problem it solves does not exist here — nothing is imperative. | `AppProvider` + `Toaster` + declarative `Dialog`/`AlertDialog` |
434
+ | `PageHeader` (removed from antd core) | Exists, and is wider. | `PageContainer` (`layout.prop.ts:64-139`) |
435
+ | `Result` | Exists for HTTP statuses; the non-HTTP shapes are an empty state with an action. | `ErrorSurface` / `EmptyState` |
436
+ | `Menu` `items` config array as the only API | Both dialects exist already: config-array for the route rails, compound parts for the overlay menus. | `Sidebar.sections` / `NavList.items` · `DropdownMenu*` |
437
+ | `Dropdown.Button` | Two existing primitives plus the proposed `ButtonGroup`. | `ButtonGroup` + `Button` + `DropdownMenu` |
437
438
 
438
439
  ---
439
440
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "23.3.0",
4
- "godxUiMcp": "23.3.0",
3
+ "version": "23.4.0",
4
+ "godxUiMcp": "23.4.0",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -20,7 +20,7 @@
20
20
  }
21
21
  },
22
22
  "sideEffects": false,
23
- "description": "@godxjp/ui \u2014 shared React UI framework (shadcn + Radix + Tailwind v4).",
23
+ "description": "@godxjp/ui shared React UI framework (shadcn + Radix + Tailwind v4).",
24
24
  "files": [
25
25
  "LICENSE",
26
26
  "dist",