@jike-js/ui 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 jike-js
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # @jike-js/ui
2
+
3
+ 这是 jike 统一前端组件的参考实现,组件契约见 `frontend/UI_COMPONENT_CATALOG.md`。
4
+
5
+ 业务项目只需引入 `@jike-js/ui/styles.css` 一个样式入口;该入口在构建时包含 Token、基础层和组件层,避免漏引或形成第二份 reset。Token 的唯一源文件仍是 `frontend/tokens/design-tokens.json`,CSS 是其运行时输出。
6
+
7
+ 当前提供:`LoginShell`、`PageLayout`、`PageHeader`、`Notice`、`EmptyState`、`LoadingState`。包构建会同时检查 TypeScript,并输出单一 `styles.css`。
8
+
9
+ 本包不包含业务请求、路由、权限和项目 Logo。业务项目只能通过组件参数接入这些能力。登录文案使用 `brandTitle`、`brandSubtitle`、`formTitle`、`formSubtitle` 四个明确层级。
@@ -0,0 +1,17 @@
1
+ import type { ReactNode } from "react";
2
+ import "./styles.css";
3
+ export interface NoticeProps {
4
+ type?: "info" | "success" | "warning" | "error";
5
+ children: ReactNode;
6
+ }
7
+ export declare function Notice({ type, children }: NoticeProps): import("react").JSX.Element;
8
+ export interface EmptyStateProps {
9
+ title?: string;
10
+ description?: string;
11
+ action?: ReactNode;
12
+ }
13
+ export declare function EmptyState({ title, description, action }: EmptyStateProps): import("react").JSX.Element;
14
+ export interface LoadingStateProps {
15
+ label?: string;
16
+ }
17
+ export declare function LoadingState({ label }: LoadingStateProps): import("react").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { AlertCircle, CheckCircle2, Info, Inbox, LoaderCircle } from "lucide-react";
3
+ import "./styles.css";
4
+ export function Notice({ type = "info", children }) {
5
+ const Icon = type === "success" ? CheckCircle2 : type === "error" || type === "warning" ? AlertCircle : Info;
6
+ return _jsxs("div", { className: `jike-notice jike-notice--${type}`, role: "status", children: [_jsx(Icon, { "aria-hidden": "true" }), " ", _jsx("span", { children: children })] });
7
+ }
8
+ export function EmptyState({ title = "暂无数据", description, action }) {
9
+ return _jsxs("div", { className: "jike-empty-state", children: [_jsx(Inbox, { className: "jike-empty-state__icon", "aria-hidden": "true" }), _jsx("strong", { children: title }), description ? _jsx("p", { children: description }) : null, action] });
10
+ }
11
+ export function LoadingState({ label = "加载中..." }) {
12
+ return _jsxs("div", { className: "jike-loading-state", role: "status", children: [_jsx(LoaderCircle, { "aria-hidden": "true", className: "jike-loading-state__spinner" }), _jsx("span", { children: label })] });
13
+ }
@@ -0,0 +1,17 @@
1
+ import { type ReactNode } from "react";
2
+ import "./styles.css";
3
+ export interface LoginCredentials {
4
+ username: string;
5
+ password: string;
6
+ }
7
+ export interface LoginShellProps {
8
+ brandTitle: string;
9
+ logo: string | ReactNode;
10
+ brandSubtitle?: string;
11
+ formTitle?: string;
12
+ formSubtitle?: string;
13
+ onSubmit: (credentials: LoginCredentials) => void | Promise<void>;
14
+ loading?: boolean;
15
+ error?: string;
16
+ }
17
+ export declare function LoginShell({ brandTitle, logo, brandSubtitle, formTitle, formSubtitle, onSubmit, loading, error, }: LoginShellProps): import("react").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { LockKeyhole, LoaderCircle, LogIn, User } from "lucide-react";
3
+ import { useState } from "react";
4
+ import "./styles.css";
5
+ export function LoginShell({ brandTitle, logo, brandSubtitle = "提升工作效率,简化操作流程", formTitle = "欢迎回来", formSubtitle = "登录以继续使用", onSubmit, loading = false, error, }) {
6
+ const [username, setUsername] = useState("");
7
+ const [password, setPassword] = useState("");
8
+ async function handleSubmit(event) {
9
+ event.preventDefault();
10
+ if (loading)
11
+ return;
12
+ await onSubmit({ username: username.trim(), password: password.trim() });
13
+ }
14
+ return (_jsx("main", { className: "jike-login-shell", children: _jsxs("section", { className: "jike-login-shell__card", "aria-label": `${brandTitle}登录`, children: [_jsxs("div", { className: "jike-login-shell__brand", children: [_jsx("div", { className: "jike-login-shell__logo", children: typeof logo === "string" ? _jsx("img", { src: logo, alt: brandTitle }) : logo }), _jsx("h1", { children: brandTitle }), _jsx("p", { children: brandSubtitle })] }), _jsxs("div", { className: "jike-login-shell__form-panel", children: [_jsx("h2", { children: formTitle }), _jsx("p", { className: "jike-login-shell__hint", children: formSubtitle }), _jsxs("form", { onSubmit: handleSubmit, autoComplete: "on", noValidate: true, "aria-busy": loading, children: [_jsxs("label", { className: "jike-login-shell__field", htmlFor: "jike-login-username", children: [_jsx("span", { children: "\u7528\u6237\u540D" }), _jsxs("span", { className: "jike-login-shell__control", children: [_jsx(User, { "aria-hidden": "true" }), _jsx("input", { id: "jike-login-username", name: "username", value: username, onChange: (event) => setUsername(event.target.value), placeholder: "\u8BF7\u8F93\u5165\u7528\u6237\u540D", autoComplete: "username", disabled: loading, required: true, "aria-invalid": Boolean(error) })] })] }), _jsxs("label", { className: "jike-login-shell__field", htmlFor: "jike-login-password", children: [_jsx("span", { children: "\u5BC6\u7801" }), _jsxs("span", { className: "jike-login-shell__control", children: [_jsx(LockKeyhole, { "aria-hidden": "true" }), _jsx("input", { id: "jike-login-password", name: "password", type: "password", value: password, onChange: (event) => setPassword(event.target.value), placeholder: "\u8BF7\u8F93\u5165\u5BC6\u7801", autoComplete: "current-password", disabled: loading, required: true, "aria-invalid": Boolean(error) })] })] }), error ? _jsx("p", { className: "jike-login-shell__error", role: "alert", "aria-live": "polite", children: error }) : null, _jsxs("button", { className: "jike-login-shell__submit", type: "submit", disabled: loading, children: [loading ? "登录中..." : "登录", loading ? _jsx(LoaderCircle, { "aria-hidden": "true", className: "jike-login-shell__spinner" }) : _jsx(LogIn, { "aria-hidden": "true" })] })] })] })] }) }));
15
+ }
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from "react";
2
+ import "./styles.css";
3
+ export interface PageHeaderProps {
4
+ title: string;
5
+ description?: string;
6
+ actions?: ReactNode;
7
+ }
8
+ export declare function PageHeader({ title, description, actions }: PageHeaderProps): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import "./styles.css";
3
+ export function PageHeader({ title, description, actions }) {
4
+ return _jsxs("div", { className: "jike-page-header", children: [_jsxs("div", { children: [_jsx("h1", { children: title }), description ? _jsx("p", { children: description }) : null] }), actions ? _jsx("div", { className: "jike-page-header__actions", children: actions }) : null] });
5
+ }
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from "react";
2
+ import "./styles.css";
3
+ export interface PageLayoutProps {
4
+ children: ReactNode;
5
+ sidebar?: ReactNode;
6
+ topbar?: ReactNode;
7
+ }
8
+ export declare function PageLayout({ children, sidebar, topbar }: PageLayoutProps): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import "./styles.css";
3
+ export function PageLayout({ children, sidebar, topbar }) {
4
+ return _jsxs("div", { className: "jike-page-layout", children: [_jsx("header", { className: "jike-page-layout__topbar", children: topbar }), _jsxs("div", { className: "jike-page-layout__body", children: [sidebar ? _jsx("aside", { className: "jike-page-layout__sidebar", children: sidebar }) : null, _jsx("main", { className: "jike-page-layout__content", children: children })] })] });
5
+ }
@@ -0,0 +1,8 @@
1
+ export { LoginShell } from "./LoginShell";
2
+ export type { LoginCredentials, LoginShellProps } from "./LoginShell";
3
+ export { PageLayout } from "./PageLayout";
4
+ export type { PageLayoutProps } from "./PageLayout";
5
+ export { PageHeader } from "./PageHeader";
6
+ export type { PageHeaderProps } from "./PageHeader";
7
+ export { EmptyState, LoadingState, Notice } from "./Feedback";
8
+ export type { EmptyStateProps, LoadingStateProps, NoticeProps } from "./Feedback";
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { LoginShell } from "./LoginShell";
2
+ export { PageLayout } from "./PageLayout";
3
+ export { PageHeader } from "./PageHeader";
4
+ export { EmptyState, LoadingState, Notice } from "./Feedback";
@@ -0,0 +1,181 @@
1
+ :root {
2
+ --color-brand: #00b8a9;
3
+ --color-brand-hover: #008e80;
4
+ --color-primary: #3566ec;
5
+ --color-primary-hover: #2853d4;
6
+ --color-bg-page: #f4f7fb;
7
+ --color-bg-surface: #ffffff;
8
+ --color-bg-muted: #f8fafc;
9
+ --color-text-primary: #172033;
10
+ --color-text-secondary: #526076;
11
+ --color-text-muted: #758197;
12
+ --color-text-placeholder: #98a2b3;
13
+ --color-border: #e3e8f1;
14
+ --color-success: #18a874;
15
+ --color-success-soft: #e5f8f1;
16
+ --color-warning: #9a5a08;
17
+ --color-warning-soft: #fff3df;
18
+ --color-danger: #b42318;
19
+ --color-danger-soft: #feeceb;
20
+ --font-family-sans: "Microsoft YaHei", "PingFang SC", system-ui, sans-serif;
21
+ --font-family-mono: Consolas, "SFMono-Regular", monospace;
22
+ --font-size-xs: 12px;
23
+ --font-size-sm: 13px;
24
+ --font-size-md: 14px;
25
+ --font-size-lg: 16px;
26
+ --font-size-xl: 18px;
27
+ --font-size-2xl: 24px;
28
+ --font-size-3xl: 28px;
29
+ --line-height-body: 1.6;
30
+ --line-height-heading: 1.3;
31
+ --icon-size-sm: 16px;
32
+ --icon-size-md: 18px;
33
+ --icon-size-lg: 24px;
34
+ --icon-size-empty: 40px;
35
+ --icon-stroke-width: 2;
36
+ --space-1: 4px;
37
+ --space-2: 8px;
38
+ --space-3: 12px;
39
+ --space-4: 16px;
40
+ --space-6: 24px;
41
+ --space-8: 32px;
42
+ --radius-control: 6px;
43
+ --radius-panel: 8px;
44
+ --radius-container: 12px;
45
+ --radius-pill: 999px;
46
+ --border-width-default: 1px;
47
+ --control-input-padding-x: 12px;
48
+ --control-input-icon-padding-left: 40px;
49
+ --shadow-sm: 0 1px 3px rgba(15, 23, 42, .08);
50
+ --shadow-login: 0 8px 24px rgba(15, 23, 42, .12);
51
+ --shadow-modal: 0 20px 60px rgba(15, 23, 42, .18);
52
+ --focus-ring: 0 0 0 3px rgba(53, 102, 236, .25);
53
+ --state-disabled-opacity: 0.72;
54
+ --motion-spin-duration: 0.9s;
55
+ --modal-width-sm: 440px;
56
+ --modal-width-md: 560px;
57
+ --modal-width-lg: 720px;
58
+ --drawer-max-width: 94vw;
59
+ --control-height-sm: 32px;
60
+ --control-height: 36px;
61
+ --control-height-lg: 40px;
62
+ --page-max-width: 1280px;
63
+ --sidebar-width: 230px;
64
+ --topbar-height: 56px;
65
+ --login-container-max-width: 840px;
66
+ --login-container-width: 90%;
67
+ --login-container-min-height: 480px;
68
+ --login-column-ratio: 1fr 1fr;
69
+ --login-panel-padding-x: 50px;
70
+ --login-panel-padding-y: 40px;
71
+ --login-brand-padding-x: 40px;
72
+ --login-brand-padding-y: 40px;
73
+ --login-logo-size: 120px;
74
+ --login-logo-size-mobile: 80px;
75
+ --login-brand-min-height-mobile: 230px;
76
+ --login-control-height: 50px;
77
+ --login-subtitle-form-gap: 24px;
78
+ --login-field-gap: 16px;
79
+ --login-button-gap: 8px;
80
+ --login-form-offset-y: -24px;
81
+ --login-mobile-breakpoint: 768px;
82
+ --z-sidebar: 20;
83
+ --z-topbar: 30;
84
+ --z-modal: 70;
85
+ --z-toast: 100;
86
+ --breakpoint-sm: 576px;
87
+ --breakpoint-md: 768px;
88
+ --breakpoint-lg: 992px;
89
+ --breakpoint-xl: 1200px;
90
+ }
91
+
92
+ /* @jike-js/ui 的最小全局基础层;业务项目不再重复创建同义 reset。 */
93
+ *,
94
+ *::before,
95
+ *::after {
96
+ box-sizing: border-box;
97
+ }
98
+
99
+ html,
100
+ body,
101
+ #root {
102
+ min-height: 100%;
103
+ }
104
+
105
+ body {
106
+ margin: 0;
107
+ background: var(--color-bg-page);
108
+ color: var(--color-text-primary);
109
+ font-family: var(--font-family-sans);
110
+ -webkit-font-smoothing: antialiased;
111
+ }
112
+
113
+ button,
114
+ input,
115
+ textarea,
116
+ select {
117
+ font: inherit;
118
+ }
119
+
120
+ button {
121
+ cursor: pointer;
122
+ }
123
+
124
+ button:disabled {
125
+ cursor: not-allowed;
126
+ }
127
+
128
+ img,
129
+ svg {
130
+ display: block;
131
+ }
132
+
133
+ .jike-login-shell { box-sizing: border-box; min-height: 100vh; display: grid; place-items: center; padding: var(--space-6); background: var(--color-bg-page); color: var(--color-text-primary); font-family: var(--font-family-sans); }
134
+ .jike-login-shell__card { box-sizing: border-box; display: grid; grid-template-columns: var(--login-column-ratio); width: var(--login-container-width); max-width: var(--login-container-max-width); min-height: var(--login-container-min-height); overflow: hidden; background: var(--color-bg-surface); border: var(--border-width-default) solid var(--color-border); border-radius: var(--radius-container); box-shadow: var(--shadow-login); }
135
+ .jike-login-shell__brand { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--login-brand-padding-y) var(--login-brand-padding-x); color: var(--color-bg-surface); text-align: center; background: linear-gradient(135deg, var(--color-brand), var(--color-brand-hover)); }
136
+ .jike-login-shell__logo { display: grid; place-items: center; width: var(--login-logo-size); height: var(--login-logo-size); margin-bottom: var(--space-6); }
137
+ .jike-login-shell__logo img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; }
138
+ .jike-login-shell__brand h1, .jike-login-shell__form-panel h2 { margin: 0; font-size: var(--font-size-2xl); font-weight: 700; line-height: var(--line-height-heading); }
139
+ .jike-login-shell__brand p { margin: var(--space-4) 0 0; font-size: var(--font-size-lg); line-height: var(--line-height-body); }
140
+ .jike-login-shell__form-panel { display: flex; flex-direction: column; justify-content: center; padding: var(--login-panel-padding-y) var(--login-panel-padding-x); transform: translateY(var(--login-form-offset-y)); }
141
+ .jike-login-shell__form-panel h2 { font-size: var(--font-size-3xl); }
142
+ .jike-login-shell__hint { margin: var(--space-2) 0 var(--login-subtitle-form-gap); color: var(--color-text-muted); font-size: var(--font-size-md); }
143
+ .jike-login-shell__field { display: block; margin-bottom: var(--login-field-gap); color: var(--color-text-secondary); font-size: var(--font-size-md); font-weight: 600; }
144
+ .jike-login-shell__control { position: relative; display: block; margin-top: var(--space-2); }
145
+ .jike-login-shell__control svg { position: absolute; top: 50%; left: var(--space-4); width: var(--icon-size-sm); height: var(--icon-size-sm); color: var(--color-text-muted); transform: translateY(-50%); pointer-events: none; }
146
+ .jike-login-shell__control input { box-sizing: border-box; width: 100%; height: var(--login-control-height); padding: 0 var(--control-input-padding-x) 0 var(--control-input-icon-padding-left); color: var(--color-text-primary); font: inherit; font-size: var(--font-size-md); background: var(--color-bg-muted); border: var(--border-width-default) solid var(--color-border); border-radius: var(--radius-control); transition: border-color 160ms ease, box-shadow 160ms ease, background-color 160ms ease; }
147
+ .jike-login-shell__control input:hover:not(:disabled) { border-color: var(--color-text-muted); background: var(--color-bg-surface); }
148
+ .jike-login-shell__control input:focus { outline: none; border-color: var(--color-primary); background: var(--color-bg-surface); box-shadow: var(--focus-ring); }
149
+ .jike-login-shell__control input[aria-invalid="true"] { border-color: var(--color-danger); }
150
+ .jike-login-shell__control input[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px rgba(180, 35, 24, .18); }
151
+ .jike-login-shell__control input:disabled { cursor: not-allowed; background: var(--color-bg-muted); }
152
+ .jike-login-shell__error { margin: calc(var(--space-2) * -1) 0 var(--space-4); color: var(--color-danger); font-size: var(--font-size-sm); }
153
+ .jike-login-shell__submit { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); width: 100%; height: var(--login-control-height); margin-top: var(--login-button-gap); color: var(--color-bg-surface); font: inherit; font-size: var(--font-size-lg); font-weight: 600; background: var(--color-brand); border: var(--border-width-default) solid var(--color-brand); border-radius: var(--radius-control); transition: background-color 160ms ease, border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease; }
154
+ .jike-login-shell__submit:hover:not(:disabled) { background: var(--color-brand-hover); border-color: var(--color-brand-hover); }
155
+ .jike-login-shell__submit:focus-visible { outline: none; box-shadow: var(--focus-ring); }
156
+ .jike-login-shell__submit:active:not(:disabled) { transform: translateY(1px); }
157
+ .jike-login-shell__submit:disabled { cursor: wait; opacity: var(--state-disabled-opacity); }
158
+ .jike-login-shell__submit svg { width: var(--icon-size-md); height: var(--icon-size-md); }
159
+ .jike-login-shell__spinner, .jike-loading-state__spinner { animation: jike-spin var(--motion-spin-duration) linear infinite; }
160
+ .jike-page-layout { min-height: 100vh; background: var(--color-bg-page); color: var(--color-text-primary); font-family: var(--font-family-sans); }
161
+ .jike-page-layout__topbar { height: var(--topbar-height); background: var(--color-bg-surface); border-bottom: var(--border-width-default) solid var(--color-border); }
162
+ .jike-page-layout__body { display: flex; min-height: calc(100vh - var(--topbar-height)); }
163
+ .jike-page-layout__sidebar { width: var(--sidebar-width); flex: 0 0 auto; background: var(--color-bg-surface); border-right: var(--border-width-default) solid var(--color-border); }
164
+ .jike-page-layout__content { width: 100%; max-width: var(--page-max-width); margin: 0 auto; padding: var(--space-8); }
165
+ .jike-page-header { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-6); }
166
+ .jike-page-header h1 { margin: 0; font-size: var(--font-size-2xl); line-height: var(--line-height-heading); }
167
+ .jike-page-header p { margin: var(--space-2) 0 0; color: var(--color-text-muted); font-size: var(--font-size-sm); }
168
+ .jike-page-header__actions { display: flex; align-items: center; gap: var(--space-2); }
169
+ .jike-notice, .jike-loading-state { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-radius: var(--radius-panel); font-size: var(--font-size-sm); }
170
+ .jike-notice svg, .jike-loading-state svg { width: var(--icon-size-md); height: var(--icon-size-md); flex: 0 0 auto; }
171
+ .jike-notice--info { color: var(--color-primary); background: var(--color-bg-muted); }
172
+ .jike-notice--success { color: var(--color-success); background: var(--color-success-soft); }
173
+ .jike-notice--warning { color: var(--color-warning); background: var(--color-warning-soft); }
174
+ .jike-notice--error { color: var(--color-danger); background: var(--color-danger-soft); }
175
+ .jike-empty-state { display: grid; justify-items: center; gap: var(--space-2); padding: var(--space-8); color: var(--color-text-secondary); text-align: center; }
176
+ .jike-empty-state__icon { display: grid; place-items: center; width: var(--icon-size-empty); height: var(--icon-size-empty); color: var(--color-text-muted); }
177
+ .jike-empty-state p { margin: 0; color: var(--color-text-muted); font-size: var(--font-size-sm); }
178
+ .jike-loading-state { justify-content: center; color: var(--color-text-secondary); }
179
+ @keyframes jike-spin { to { transform: rotate(360deg); } }
180
+ /* CSS 媒体查询不能读取自定义属性;768px 与 breakpoint.md Token 保持同步。 */
181
+ @media (max-width: 768px) { .jike-login-shell { padding: var(--space-4); } .jike-login-shell__card { grid-template-columns: 1fr; width: 100%; min-height: 0; } .jike-login-shell__brand { min-height: var(--login-brand-min-height-mobile); padding: var(--space-8) var(--space-6); } .jike-login-shell__logo { width: var(--login-logo-size-mobile); height: var(--login-logo-size-mobile); } .jike-login-shell__form-panel { padding: var(--space-8) var(--space-6); transform: none; } .jike-page-layout__sidebar { display: none; } .jike-page-layout__content { padding: var(--space-6); } }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@jike-js/ui",
3
+ "version": "0.1.0",
4
+ "description": "jike 统一前端组件实现",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://gitee.com/jw2019410/jike-coderule.git",
9
+ "directory": "packages/ui"
10
+ },
11
+ "type": "module",
12
+ "files": ["dist", "README.md"],
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": "./dist/index.js",
20
+ "./styles.css": "./dist/styles.css"
21
+ },
22
+ "peerDependencies": {
23
+ "lucide-react": ">=0.468.0",
24
+ "react": ">=18.0.0",
25
+ "react-dom": ">=18.0.0"
26
+ },
27
+ "scripts": {
28
+ "prebuild": "node scripts/clean-dist.mjs",
29
+ "build": "tsc --project tsconfig.json && node scripts/copy-css.mjs",
30
+ "pack:check": "pnpm build && npm pack --dry-run"
31
+ },
32
+ "devDependencies": {
33
+ "@types/react": "^19.2.18",
34
+ "@types/react-dom": "^19.2.5",
35
+ "typescript": "^7.0.2"
36
+ }
37
+ }