qm-law-ui 0.0.1
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 +204 -0
- package/dist/components/law-button/index.vue.d.ts +26 -0
- package/dist/components/law-button/types.d.ts +14 -0
- package/dist/components/law-dialog/index.vue.d.ts +40 -0
- package/dist/components/law-dialog/types.d.ts +13 -0
- package/dist/hooks/use-law-theme.d.ts +9 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +291 -0
- package/dist/index.umd.cjs +1 -0
- package/dist/style.css +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/package.json +57 -0
- package/src/components/law-button/index.vue +106 -0
- package/src/components/law-button/types.ts +22 -0
- package/src/components/law-dialog/index.vue +100 -0
- package/src/components/law-dialog/types.ts +12 -0
- package/src/env.d.ts +12 -0
- package/src/hooks/use-law-theme.ts +66 -0
- package/src/index.ts +35 -0
- package/src/styles/theme.css +84 -0
- package/src/styles/variables.css +192 -0
- package/src/utils/index.ts +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# LawUI
|
|
2
|
+
|
|
3
|
+
基于 **Law0S Design System** 设计规范、封装 **Element Plus** 的 Vue 3 组件库。
|
|
4
|
+
|
|
5
|
+
## 技术约束
|
|
6
|
+
|
|
7
|
+
| 项 | 说明 |
|
|
8
|
+
| ------ | ------------------------------------------------------------------------ |
|
|
9
|
+
| 运行时 | Vue 3.3+、Element Plus 2.10.x ~ 2.13.x |
|
|
10
|
+
| 构建 | TypeScript 5.x、Vite 5 |
|
|
11
|
+
| 包规范 | `vue` 与 `element-plus` 仅声明在 `peerDependencies`,不打入产物 |
|
|
12
|
+
| 主题 | 纯 CSS Variables(`--law-*` → `--el-*`),禁止 SCSS 混入 |
|
|
13
|
+
| 组件 | `<script setup lang="ts">`,`inheritAttrs: false` 手动透传 attrs / slots |
|
|
14
|
+
|
|
15
|
+
## 安装
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add qm-law-ui element-plus vue
|
|
19
|
+
# 或
|
|
20
|
+
npm install qm-law-ui element-plus vue
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 样式引入顺序(必须遵守)
|
|
24
|
+
|
|
25
|
+
Element Plus 基础样式必须先于 LawUI 主题映射层加载,否则 `--el-*` 变量无法被 Law 设计令牌正确覆盖。
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
// main.ts
|
|
29
|
+
import "element-plus/dist/index.css"; // ① Element Plus 基础样式
|
|
30
|
+
import "qm-law-ui/theme.css"; // ② Law → El CSS Variables 映射层
|
|
31
|
+
import "qm-law-ui/style.css"; // ③ 组件聚合样式(构建产物)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> **顺序不可调换**:`element-plus.css` → `qm-law-ui/theme.css` → `qm-law-ui/style.css`
|
|
35
|
+
|
|
36
|
+
## 插件注册
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// main.ts
|
|
40
|
+
import { createApp } from "vue";
|
|
41
|
+
import ElementPlus from "element-plus";
|
|
42
|
+
import LawUI from "qm-law-ui";
|
|
43
|
+
import App from "./App.vue";
|
|
44
|
+
|
|
45
|
+
import "element-plus/dist/index.css";
|
|
46
|
+
import "qm-law-ui/theme.css";
|
|
47
|
+
import "qm-law-ui/style.css";
|
|
48
|
+
|
|
49
|
+
const app = createApp(App);
|
|
50
|
+
app.use(ElementPlus);
|
|
51
|
+
app.use(LawUI);
|
|
52
|
+
app.mount("#app");
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 按需引入组件
|
|
56
|
+
|
|
57
|
+
```vue
|
|
58
|
+
<script setup lang="ts">
|
|
59
|
+
import { LawButton, LawDialog } from "qm-law-ui";
|
|
60
|
+
import type { LawButtonProps, LawDialogProps } from "qm-law-ui";
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<template>
|
|
64
|
+
<LawButton type="primary">提交</LawButton>
|
|
65
|
+
<LawDialog v-model="visible" title="提示">内容</LawDialog>
|
|
66
|
+
</template>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 暗色模式
|
|
70
|
+
|
|
71
|
+
在根节点设置以下任一方式即可切换暗色主题(`theme.css` 三重选择器兼容):
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<!-- 方式一:data 属性 -->
|
|
75
|
+
<html data-theme="dark">
|
|
76
|
+
<!-- 方式二:class -->
|
|
77
|
+
<html class="dark">
|
|
78
|
+
<!-- 方式三::root 伪类 -->
|
|
79
|
+
<html class="dark">
|
|
80
|
+
<!-- 配合 :root.dark 选择器 -->
|
|
81
|
+
</html>
|
|
82
|
+
</html>
|
|
83
|
+
</html>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
也可通过 `useLawTheme()` composable 动态切换(第三批提供)。
|
|
87
|
+
|
|
88
|
+
## 本地开发(组件演示)
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pnpm install
|
|
92
|
+
pnpm dev # 启动 examples 沙箱,终端会打印实际地址(默认 5173)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
入口文件:
|
|
96
|
+
|
|
97
|
+
- `examples/index.html` — HTML 入口
|
|
98
|
+
- `examples/main.ts` — 挂载 Vue,注册 Element Plus + LawUI
|
|
99
|
+
- `examples/App.vue` — 按钮 / 对话框演示页
|
|
100
|
+
|
|
101
|
+
> 若浏览器 404,请**以终端打印的 Local 地址为准**(端口被占用时会变成 5174、5175…)。先关掉其他 Vite 进程,或执行 `lsof -ti:5174 | xargs kill` 后重新 `pnpm dev`。
|
|
102
|
+
|
|
103
|
+
> 不要直接运行根目录的 `vite`(无 `index.html` 会 404),务必使用 `pnpm dev`。`examples/vite.config.ts` 已将 `root` 指向 `examples/` 目录。
|
|
104
|
+
|
|
105
|
+
## 构建与发布
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
pnpm build
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
产物目录 `dist/`:
|
|
112
|
+
|
|
113
|
+
| 文件 | 说明 |
|
|
114
|
+
| ---------------------------- | --------------------------------------- |
|
|
115
|
+
| `index.js` / `index.umd.cjs` | ES / UMD 模块 |
|
|
116
|
+
| `index.d.ts` | TypeScript 类型声明 |
|
|
117
|
+
| `theme.css` | `--law-*` → `--el-*` 映射层(独立输出) |
|
|
118
|
+
| `style.css` | 组件 scoped 样式聚合 |
|
|
119
|
+
|
|
120
|
+
发布前自动执行 `prepublishOnly` → `pnpm run build`。
|
|
121
|
+
|
|
122
|
+
## 发布到 npm
|
|
123
|
+
|
|
124
|
+
### 1. 发布前检查
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
pnpm build # 生成 dist/
|
|
128
|
+
npm pack --dry-run # 预览将要上传的文件列表
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
确认 `package.json` 中:
|
|
132
|
+
|
|
133
|
+
- `name`:npm 上未被占用的包名(`qm-law-ui` 可能已被占用,可改为 `@你的用户名/qm-law-ui` 并在 `name` 字段填写)
|
|
134
|
+
- `version`:遵循 semver,每次发布需递增
|
|
135
|
+
- `files`:已包含 `dist` 与 `src`(当前配置正确)
|
|
136
|
+
|
|
137
|
+
若使用 scoped 包名,在 `package.json` 增加:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
"publishConfig": {
|
|
141
|
+
"access": "public"
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 2. 登录 npm
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npm login
|
|
149
|
+
npm whoami
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
无账号请先在 [https://www.npmjs.com/signup](https://www.npmjs.com/signup) 注册。
|
|
153
|
+
|
|
154
|
+
### 3. 发布
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# 可选:修改版本号
|
|
158
|
+
npm version patch # 0.1.0 → 0.1.1
|
|
159
|
+
|
|
160
|
+
# 发布(prepublishOnly 会自动执行 build)
|
|
161
|
+
npm publish
|
|
162
|
+
|
|
163
|
+
# scoped 包首次发布需公开
|
|
164
|
+
npm publish --access public
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 4. 消费者安装
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
npm install qm-law-ui element-plus vue
|
|
171
|
+
# 或 scoped:npm install @你的用户名/qm-law-ui element-plus vue
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### 5. 更新版本
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
npm version minor # 新功能
|
|
178
|
+
npm version patch # 修复
|
|
179
|
+
npm publish
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 目录结构
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
qm-law-ui/
|
|
186
|
+
├── src/
|
|
187
|
+
│ ├── components/ # law-button、law-dialog 等
|
|
188
|
+
│ ├── hooks/ # use-law-theme
|
|
189
|
+
│ ├── styles/ # variables.css、theme.css
|
|
190
|
+
│ ├── utils/
|
|
191
|
+
│ └── index.ts # 插件入口
|
|
192
|
+
├── examples/ # 本地调试沙箱(第三批)
|
|
193
|
+
├── vite.config.ts
|
|
194
|
+
├── tsconfig.json
|
|
195
|
+
└── package.json
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## 分批路线图
|
|
199
|
+
|
|
200
|
+
| 批次 | 内容 | 状态 |
|
|
201
|
+
| ------ | ------------------------------------------------------------------------------- | ------ |
|
|
202
|
+
| **一** | 项目骨架、`package.json`、`vite.config.ts`、`tsconfig`、`.gitignore`、本 README | 已完成 |
|
|
203
|
+
| **二** | `variables.css`、`theme.css`(完整映射)、`law-button`、`law-dialog` | 已完成 |
|
|
204
|
+
| **三** | `use-law-theme`、`src/index.ts` 入口、`examples/` 沙箱、构建验证 | 已完成 |
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { LawButtonProps, LawButtonSize } from './types';
|
|
2
|
+
declare function __VLS_template(): {
|
|
3
|
+
attrs: Partial<{}>;
|
|
4
|
+
slots: {
|
|
5
|
+
default?(_: {}): any;
|
|
6
|
+
loading?(_: {}): any;
|
|
7
|
+
icon?(_: {}): any;
|
|
8
|
+
};
|
|
9
|
+
refs: {};
|
|
10
|
+
rootEl: any;
|
|
11
|
+
};
|
|
12
|
+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
13
|
+
declare const __VLS_component: import('vue').DefineComponent<LawButtonProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
14
|
+
click: (evt: MouseEvent) => any;
|
|
15
|
+
}, string, import('vue').PublicProps, Readonly<LawButtonProps> & Readonly<{
|
|
16
|
+
onClick?: ((evt: MouseEvent) => any) | undefined;
|
|
17
|
+
}>, {
|
|
18
|
+
lawSize: LawButtonSize;
|
|
19
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
20
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
21
|
+
export default _default;
|
|
22
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
23
|
+
new (): {
|
|
24
|
+
$slots: S;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ButtonEmits, ButtonProps } from 'element-plus/es/components/button';
|
|
2
|
+
/** Law 按钮尺寸(对齐 Law0S 设计规范) */
|
|
3
|
+
export type LawButtonSize = "lg" | "md" | "sm";
|
|
4
|
+
export interface LawButtonOwnProps {
|
|
5
|
+
/** Law 设计规范尺寸,映射至 Element Plus size */
|
|
6
|
+
lawSize?: LawButtonSize;
|
|
7
|
+
}
|
|
8
|
+
export type LawButtonProps = LawButtonOwnProps & Partial<ButtonProps>;
|
|
9
|
+
export type LawButtonEmits = ButtonEmits;
|
|
10
|
+
export type LawButtonSlots = {
|
|
11
|
+
default?: () => unknown;
|
|
12
|
+
loading?: () => unknown;
|
|
13
|
+
icon?: () => unknown;
|
|
14
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
declare function __VLS_template(): {
|
|
2
|
+
attrs: Partial<{}>;
|
|
3
|
+
slots: {
|
|
4
|
+
default?(_: {}): any;
|
|
5
|
+
header?(_: {
|
|
6
|
+
close: () => void;
|
|
7
|
+
titleId: string;
|
|
8
|
+
titleClass: string;
|
|
9
|
+
}): any;
|
|
10
|
+
title?(_: {}): any;
|
|
11
|
+
footer?(_: {}): any;
|
|
12
|
+
};
|
|
13
|
+
refs: {};
|
|
14
|
+
rootEl: any;
|
|
15
|
+
};
|
|
16
|
+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
17
|
+
declare const __VLS_component: import('vue').DefineComponent<Partial<import('element-plus').DialogProps>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
18
|
+
open: () => any;
|
|
19
|
+
opened: () => any;
|
|
20
|
+
close: () => any;
|
|
21
|
+
closed: () => any;
|
|
22
|
+
"update:modelValue": (value: boolean) => any;
|
|
23
|
+
openAutoFocus: () => any;
|
|
24
|
+
closeAutoFocus: () => any;
|
|
25
|
+
}, string, import('vue').PublicProps, Readonly<Partial<import('element-plus').DialogProps>> & Readonly<{
|
|
26
|
+
onOpen?: (() => any) | undefined;
|
|
27
|
+
onOpened?: (() => any) | undefined;
|
|
28
|
+
onClose?: (() => any) | undefined;
|
|
29
|
+
onClosed?: (() => any) | undefined;
|
|
30
|
+
"onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
|
|
31
|
+
onOpenAutoFocus?: (() => any) | undefined;
|
|
32
|
+
onCloseAutoFocus?: (() => any) | undefined;
|
|
33
|
+
}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
34
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
35
|
+
export default _default;
|
|
36
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
37
|
+
new (): {
|
|
38
|
+
$slots: S;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { DialogEmits, DialogProps } from 'element-plus/es/components/dialog';
|
|
2
|
+
export type LawDialogProps = Partial<DialogProps>;
|
|
3
|
+
export type LawDialogEmits = DialogEmits;
|
|
4
|
+
export type LawDialogSlots = {
|
|
5
|
+
default?: () => unknown;
|
|
6
|
+
header?: (props: {
|
|
7
|
+
close: () => void;
|
|
8
|
+
titleId: string;
|
|
9
|
+
titleClass: string;
|
|
10
|
+
}) => unknown;
|
|
11
|
+
title?: () => unknown;
|
|
12
|
+
footer?: () => unknown;
|
|
13
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
export type LawThemeMode = 'light' | 'dark';
|
|
3
|
+
export interface UseLawThemeReturn {
|
|
4
|
+
mode: Ref<LawThemeMode>;
|
|
5
|
+
setTheme: (theme: LawThemeMode) => void;
|
|
6
|
+
toggleTheme: () => void;
|
|
7
|
+
isDark: () => boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function useLawTheme(initial?: LawThemeMode): UseLawThemeReturn;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Plugin } from 'vue';
|
|
2
|
+
import { default as LawButton } from './components/law-button/index.vue';
|
|
3
|
+
import { default as LawDialog } from './components/law-dialog/index.vue';
|
|
4
|
+
export { LawButton, LawDialog };
|
|
5
|
+
export { useLawTheme } from './hooks/use-law-theme';
|
|
6
|
+
export type { LawThemeMode, UseLawThemeReturn } from './hooks/use-law-theme';
|
|
7
|
+
export * from './utils';
|
|
8
|
+
export type { LawButtonProps, LawButtonEmits, LawButtonSlots, LawButtonSize, LawButtonOwnProps, } from './components/law-button/types';
|
|
9
|
+
export type { LawDialogProps, LawDialogEmits, LawDialogSlots, } from './components/law-dialog/types';
|
|
10
|
+
declare const LawUI: Plugin;
|
|
11
|
+
export default LawUI;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { defineComponent, useAttrs, computed, openBlock, createBlock, unref, mergeProps, createSlots, withCtx, renderSlot, normalizeProps, guardReactiveProps, ref } from "vue";
|
|
2
|
+
import { ElButton, ElDialog } from "element-plus";
|
|
3
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
4
|
+
...{
|
|
5
|
+
name: "LawButton",
|
|
6
|
+
inheritAttrs: false
|
|
7
|
+
},
|
|
8
|
+
__name: "index",
|
|
9
|
+
props: {
|
|
10
|
+
lawSize: { default: "md" },
|
|
11
|
+
size: {},
|
|
12
|
+
disabled: { type: Boolean },
|
|
13
|
+
type: {},
|
|
14
|
+
icon: {},
|
|
15
|
+
nativeType: {},
|
|
16
|
+
loading: { type: Boolean },
|
|
17
|
+
loadingIcon: {},
|
|
18
|
+
plain: { type: Boolean },
|
|
19
|
+
text: { type: Boolean },
|
|
20
|
+
link: { type: Boolean },
|
|
21
|
+
bg: { type: Boolean },
|
|
22
|
+
autofocus: { type: Boolean },
|
|
23
|
+
round: { type: Boolean },
|
|
24
|
+
circle: { type: Boolean },
|
|
25
|
+
color: {},
|
|
26
|
+
dark: { type: Boolean },
|
|
27
|
+
autoInsertSpace: { type: Boolean },
|
|
28
|
+
tag: {}
|
|
29
|
+
},
|
|
30
|
+
emits: ["click"],
|
|
31
|
+
setup(__props, { emit: __emit }) {
|
|
32
|
+
const props = __props;
|
|
33
|
+
const emit = __emit;
|
|
34
|
+
const attrs = useAttrs();
|
|
35
|
+
const elSizeMap = {
|
|
36
|
+
lg: "large",
|
|
37
|
+
md: "default",
|
|
38
|
+
sm: "small"
|
|
39
|
+
};
|
|
40
|
+
const mergedProps = computed(() => {
|
|
41
|
+
const { lawSize, size, ...rest } = props;
|
|
42
|
+
return {
|
|
43
|
+
...attrs,
|
|
44
|
+
...rest,
|
|
45
|
+
size: size ?? elSizeMap[lawSize]
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
const computedStyle = computed(() => {
|
|
49
|
+
const heightMap = {
|
|
50
|
+
lg: "var(--law-btn-size-lg)",
|
|
51
|
+
md: "var(--law-btn-size-md)",
|
|
52
|
+
sm: "var(--law-btn-size-sm)"
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
minHeight: heightMap[props.lawSize]
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
function onClick(evt) {
|
|
59
|
+
emit("click", evt);
|
|
60
|
+
}
|
|
61
|
+
return (_ctx, _cache) => {
|
|
62
|
+
return openBlock(), createBlock(unref(ElButton), mergeProps(mergedProps.value, {
|
|
63
|
+
style: computedStyle.value,
|
|
64
|
+
class: "law-button",
|
|
65
|
+
onClick
|
|
66
|
+
}), createSlots({
|
|
67
|
+
default: withCtx(() => [
|
|
68
|
+
renderSlot(_ctx.$slots, "default", {}, void 0, true)
|
|
69
|
+
]),
|
|
70
|
+
_: 2
|
|
71
|
+
}, [
|
|
72
|
+
_ctx.$slots.loading ? {
|
|
73
|
+
name: "loading",
|
|
74
|
+
fn: withCtx(() => [
|
|
75
|
+
renderSlot(_ctx.$slots, "loading", {}, void 0, true)
|
|
76
|
+
]),
|
|
77
|
+
key: "0"
|
|
78
|
+
} : void 0,
|
|
79
|
+
_ctx.$slots.icon ? {
|
|
80
|
+
name: "icon",
|
|
81
|
+
fn: withCtx(() => [
|
|
82
|
+
renderSlot(_ctx.$slots, "icon", {}, void 0, true)
|
|
83
|
+
]),
|
|
84
|
+
key: "1"
|
|
85
|
+
} : void 0
|
|
86
|
+
]), 1040, ["style"]);
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
const _export_sfc = (sfc, props) => {
|
|
91
|
+
const target = sfc.__vccOpts || sfc;
|
|
92
|
+
for (const [key, val] of props) {
|
|
93
|
+
target[key] = val;
|
|
94
|
+
}
|
|
95
|
+
return target;
|
|
96
|
+
};
|
|
97
|
+
const LawButton = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-de110ae2"]]);
|
|
98
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
99
|
+
...{
|
|
100
|
+
name: "LawDialog",
|
|
101
|
+
inheritAttrs: false
|
|
102
|
+
},
|
|
103
|
+
__name: "index",
|
|
104
|
+
props: {
|
|
105
|
+
appendToBody: { type: Boolean },
|
|
106
|
+
appendTo: {},
|
|
107
|
+
beforeClose: {},
|
|
108
|
+
destroyOnClose: { type: Boolean },
|
|
109
|
+
closeOnClickModal: { type: Boolean },
|
|
110
|
+
closeOnPressEscape: { type: Boolean },
|
|
111
|
+
lockScroll: { type: Boolean },
|
|
112
|
+
modal: { type: Boolean },
|
|
113
|
+
modalPenetrable: { type: Boolean },
|
|
114
|
+
openDelay: {},
|
|
115
|
+
closeDelay: {},
|
|
116
|
+
top: {},
|
|
117
|
+
modelValue: { type: Boolean },
|
|
118
|
+
modalClass: {},
|
|
119
|
+
headerClass: {},
|
|
120
|
+
bodyClass: {},
|
|
121
|
+
footerClass: {},
|
|
122
|
+
width: {},
|
|
123
|
+
zIndex: {},
|
|
124
|
+
trapFocus: { type: Boolean },
|
|
125
|
+
headerAriaLevel: {},
|
|
126
|
+
transition: {},
|
|
127
|
+
center: { type: Boolean },
|
|
128
|
+
alignCenter: { type: Boolean },
|
|
129
|
+
closeIcon: {},
|
|
130
|
+
draggable: { type: Boolean },
|
|
131
|
+
overflow: { type: Boolean },
|
|
132
|
+
fullscreen: { type: Boolean },
|
|
133
|
+
showClose: { type: Boolean },
|
|
134
|
+
title: {},
|
|
135
|
+
ariaLevel: {}
|
|
136
|
+
},
|
|
137
|
+
emits: ["open", "opened", "close", "closed", "update:modelValue", "openAutoFocus", "closeAutoFocus"],
|
|
138
|
+
setup(__props, { emit: __emit }) {
|
|
139
|
+
const props = __props;
|
|
140
|
+
const emit = __emit;
|
|
141
|
+
const attrs = useAttrs();
|
|
142
|
+
const mergedProps = computed(() => ({
|
|
143
|
+
...attrs,
|
|
144
|
+
...props
|
|
145
|
+
}));
|
|
146
|
+
function onOpen() {
|
|
147
|
+
emit("open");
|
|
148
|
+
}
|
|
149
|
+
function onOpened() {
|
|
150
|
+
emit("opened");
|
|
151
|
+
}
|
|
152
|
+
function onClose() {
|
|
153
|
+
emit("close");
|
|
154
|
+
}
|
|
155
|
+
function onClosed() {
|
|
156
|
+
emit("closed");
|
|
157
|
+
}
|
|
158
|
+
function onUpdateModelValue(value) {
|
|
159
|
+
emit("update:modelValue", value);
|
|
160
|
+
}
|
|
161
|
+
function onOpenAutoFocus() {
|
|
162
|
+
emit("openAutoFocus");
|
|
163
|
+
}
|
|
164
|
+
function onCloseAutoFocus() {
|
|
165
|
+
emit("closeAutoFocus");
|
|
166
|
+
}
|
|
167
|
+
return (_ctx, _cache) => {
|
|
168
|
+
return openBlock(), createBlock(unref(ElDialog), mergeProps(mergedProps.value, {
|
|
169
|
+
class: "law-dialog",
|
|
170
|
+
onOpen,
|
|
171
|
+
onOpened,
|
|
172
|
+
onClose,
|
|
173
|
+
onClosed,
|
|
174
|
+
"onUpdate:modelValue": onUpdateModelValue,
|
|
175
|
+
onOpenAutoFocus,
|
|
176
|
+
onCloseAutoFocus
|
|
177
|
+
}), createSlots({
|
|
178
|
+
default: withCtx(() => [
|
|
179
|
+
renderSlot(_ctx.$slots, "default", {}, void 0, true)
|
|
180
|
+
]),
|
|
181
|
+
_: 2
|
|
182
|
+
}, [
|
|
183
|
+
_ctx.$slots.header ? {
|
|
184
|
+
name: "header",
|
|
185
|
+
fn: withCtx((headerProps) => [
|
|
186
|
+
renderSlot(_ctx.$slots, "header", normalizeProps(guardReactiveProps(headerProps)), void 0, true)
|
|
187
|
+
]),
|
|
188
|
+
key: "0"
|
|
189
|
+
} : void 0,
|
|
190
|
+
_ctx.$slots.title ? {
|
|
191
|
+
name: "title",
|
|
192
|
+
fn: withCtx(() => [
|
|
193
|
+
renderSlot(_ctx.$slots, "title", {}, void 0, true)
|
|
194
|
+
]),
|
|
195
|
+
key: "1"
|
|
196
|
+
} : void 0,
|
|
197
|
+
_ctx.$slots.footer ? {
|
|
198
|
+
name: "footer",
|
|
199
|
+
fn: withCtx(() => [
|
|
200
|
+
renderSlot(_ctx.$slots, "footer", {}, void 0, true)
|
|
201
|
+
]),
|
|
202
|
+
key: "2"
|
|
203
|
+
} : void 0
|
|
204
|
+
]), 1040);
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
const LawDialog = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-cdda79d0"]]);
|
|
209
|
+
const THEME_ATTR$1 = "data-theme";
|
|
210
|
+
const DARK_CLASS$1 = "dark";
|
|
211
|
+
function applyTheme(theme) {
|
|
212
|
+
if (typeof document === "undefined") return;
|
|
213
|
+
const root = document.documentElement;
|
|
214
|
+
if (theme === "dark") {
|
|
215
|
+
root.setAttribute(THEME_ATTR$1, "dark");
|
|
216
|
+
root.classList.add(DARK_CLASS$1);
|
|
217
|
+
} else {
|
|
218
|
+
root.removeAttribute(THEME_ATTR$1);
|
|
219
|
+
root.classList.remove(DARK_CLASS$1);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function detectTheme() {
|
|
223
|
+
if (typeof document === "undefined") return "light";
|
|
224
|
+
const root = document.documentElement;
|
|
225
|
+
if (root.getAttribute(THEME_ATTR$1) === "dark" || root.classList.contains(DARK_CLASS$1)) {
|
|
226
|
+
return "dark";
|
|
227
|
+
}
|
|
228
|
+
return "light";
|
|
229
|
+
}
|
|
230
|
+
function useLawTheme(initial = "light") {
|
|
231
|
+
const mode = ref(detectTheme() || initial);
|
|
232
|
+
function setTheme(theme) {
|
|
233
|
+
mode.value = theme;
|
|
234
|
+
applyTheme(theme);
|
|
235
|
+
}
|
|
236
|
+
function toggleTheme() {
|
|
237
|
+
setTheme(mode.value === "dark" ? "light" : "dark");
|
|
238
|
+
}
|
|
239
|
+
function isDark() {
|
|
240
|
+
return mode.value === "dark";
|
|
241
|
+
}
|
|
242
|
+
applyTheme(mode.value);
|
|
243
|
+
return {
|
|
244
|
+
mode,
|
|
245
|
+
setTheme,
|
|
246
|
+
toggleTheme,
|
|
247
|
+
isDark
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
const THEME_ATTR = "data-theme";
|
|
251
|
+
const DARK_CLASS = "dark";
|
|
252
|
+
function isLawDarkMode() {
|
|
253
|
+
if (typeof document === "undefined") return false;
|
|
254
|
+
const root = document.documentElement;
|
|
255
|
+
return root.getAttribute(THEME_ATTR) === "dark" || root.classList.contains(DARK_CLASS);
|
|
256
|
+
}
|
|
257
|
+
function getLawThemeMode() {
|
|
258
|
+
return isLawDarkMode() ? "dark" : "light";
|
|
259
|
+
}
|
|
260
|
+
function mergeLawClass(...classes) {
|
|
261
|
+
return classes.filter(Boolean).join(" ");
|
|
262
|
+
}
|
|
263
|
+
function mapLawButtonSize(size) {
|
|
264
|
+
const map = {
|
|
265
|
+
lg: "large",
|
|
266
|
+
md: "default",
|
|
267
|
+
sm: "small"
|
|
268
|
+
};
|
|
269
|
+
return map[size];
|
|
270
|
+
}
|
|
271
|
+
const components = [LawButton, LawDialog];
|
|
272
|
+
const LawUI = {
|
|
273
|
+
install(app) {
|
|
274
|
+
components.forEach((component) => {
|
|
275
|
+
const name = component.name;
|
|
276
|
+
if (name) {
|
|
277
|
+
app.component(name, component);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
export {
|
|
283
|
+
LawButton,
|
|
284
|
+
LawDialog,
|
|
285
|
+
LawUI as default,
|
|
286
|
+
getLawThemeMode,
|
|
287
|
+
isLawDarkMode,
|
|
288
|
+
mapLawButtonSize,
|
|
289
|
+
mergeLawClass,
|
|
290
|
+
useLawTheme
|
|
291
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o(exports,require("vue"),require("element-plus")):"function"==typeof define&&define.amd?define(["exports","vue","element-plus"],o):o((e="undefined"!=typeof globalThis?globalThis:e||self).LawUI={},e.Vue,e.ElementPlus)}(this,function(e,o,t){"use strict";const n=(e,o)=>{const t=e.__vccOpts||e;for(const[n,l]of o)t[n]=l;return t},l=n(o.defineComponent({name:"LawButton",inheritAttrs:!1,__name:"index",props:{lawSize:{default:"md"},size:{},disabled:{type:Boolean},type:{},icon:{},nativeType:{},loading:{type:Boolean},loadingIcon:{},plain:{type:Boolean},text:{type:Boolean},link:{type:Boolean},bg:{type:Boolean},autofocus:{type:Boolean},round:{type:Boolean},circle:{type:Boolean},color:{},dark:{type:Boolean},autoInsertSpace:{type:Boolean},tag:{}},emits:["click"],setup(e,{emit:n}){const l=e,a=n,s=o.useAttrs(),i={lg:"large",md:"default",sm:"small"},d=o.computed(()=>{const{lawSize:e,size:o,...t}=l;return{...s,...t,size:o??i[e]}}),r=o.computed(()=>({minHeight:{lg:"var(--law-btn-size-lg)",md:"var(--law-btn-size-md)",sm:"var(--law-btn-size-sm)"}[l.lawSize]}));function u(e){a("click",e)}return(e,n)=>(o.openBlock(),o.createBlock(o.unref(t.ElButton),o.mergeProps(d.value,{style:r.value,class:"law-button",onClick:u}),o.createSlots({default:o.withCtx(()=>[o.renderSlot(e.$slots,"default",{},void 0,!0)]),_:2},[e.$slots.loading?{name:"loading",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"loading",{},void 0,!0)]),key:"0"}:void 0,e.$slots.icon?{name:"icon",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"icon",{},void 0,!0)]),key:"1"}:void 0]),1040,["style"]))}}),[["__scopeId","data-v-de110ae2"]]),a=n(o.defineComponent({name:"LawDialog",inheritAttrs:!1,__name:"index",props:{appendToBody:{type:Boolean},appendTo:{},beforeClose:{},destroyOnClose:{type:Boolean},closeOnClickModal:{type:Boolean},closeOnPressEscape:{type:Boolean},lockScroll:{type:Boolean},modal:{type:Boolean},modalPenetrable:{type:Boolean},openDelay:{},closeDelay:{},top:{},modelValue:{type:Boolean},modalClass:{},headerClass:{},bodyClass:{},footerClass:{},width:{},zIndex:{},trapFocus:{type:Boolean},headerAriaLevel:{},transition:{},center:{type:Boolean},alignCenter:{type:Boolean},closeIcon:{},draggable:{type:Boolean},overflow:{type:Boolean},fullscreen:{type:Boolean},showClose:{type:Boolean},title:{},ariaLevel:{}},emits:["open","opened","close","closed","update:modelValue","openAutoFocus","closeAutoFocus"],setup(e,{emit:n}){const l=e,a=n,s=o.useAttrs(),i=o.computed(()=>({...s,...l}));function d(){a("open")}function r(){a("opened")}function u(){a("close")}function c(){a("closed")}function p(e){a("update:modelValue",e)}function f(){a("openAutoFocus")}function m(){a("closeAutoFocus")}return(e,n)=>(o.openBlock(),o.createBlock(o.unref(t.ElDialog),o.mergeProps(i.value,{class:"law-dialog",onOpen:d,onOpened:r,onClose:u,onClosed:c,"onUpdate:modelValue":p,onOpenAutoFocus:f,onCloseAutoFocus:m}),o.createSlots({default:o.withCtx(()=>[o.renderSlot(e.$slots,"default",{},void 0,!0)]),_:2},[e.$slots.header?{name:"header",fn:o.withCtx(t=>[o.renderSlot(e.$slots,"header",o.normalizeProps(o.guardReactiveProps(t)),void 0,!0)]),key:"0"}:void 0,e.$slots.title?{name:"title",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"title",{},void 0,!0)]),key:"1"}:void 0,e.$slots.footer?{name:"footer",fn:o.withCtx(()=>[o.renderSlot(e.$slots,"footer",{},void 0,!0)]),key:"2"}:void 0]),1040))}}),[["__scopeId","data-v-cdda79d0"]]),s="data-theme",i="dark";function d(e){if("undefined"==typeof document)return;const o=document.documentElement;"dark"===e?(o.setAttribute(s,"dark"),o.classList.add(i)):(o.removeAttribute(s),o.classList.remove(i))}function r(){if("undefined"==typeof document)return!1;const e=document.documentElement;return"dark"===e.getAttribute("data-theme")||e.classList.contains("dark")}const u=[l,a],c={install(e){u.forEach(o=>{const t=o.name;t&&e.component(t,o)})}};e.LawButton=l,e.LawDialog=a,e.default=c,e.getLawThemeMode=function(){return r()?"dark":"light"},e.isLawDarkMode=r,e.mapLawButtonSize=function(e){return{lg:"large",md:"default",sm:"small"}[e]},e.mergeLawClass=function(...e){return e.filter(Boolean).join(" ")},e.useLawTheme=function(e="light"){const t=o.ref(function(){if("undefined"==typeof document)return"light";const e=document.documentElement;return"dark"===e.getAttribute(s)||e.classList.contains(i)?"dark":"light"}()||e);function n(e){t.value=e,d(e)}return d(t.value),{mode:t,setTheme:n,toggleTheme:function(){n("dark"===t.value?"light":"dark")},isDark:function(){return"dark"===t.value}}},Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.law-button[data-v-de110ae2]{font-family:var(--law-font-family-zh);border-radius:var(--law-radius-sm)}.law-button.el-button--default[data-v-de110ae2]:not(.is-disabled):hover{background-color:var(--law-btn-default-hover-bg);color:var(--law-btn-default-hover-color);border-color:var(--law-primary)}.law-button.el-button--primary[data-v-de110ae2]:not(.is-disabled):hover{background-color:var(--law-btn-primary-hover-bg);color:var(--law-btn-primary-hover-color);border-color:var(--law-btn-primary-hover-bg)}.law-button.el-button--success[data-v-de110ae2]:not(.is-disabled):hover{background-color:var(--law-btn-success-hover-bg);color:var(--law-btn-success-hover-color)}.law-button.el-button--warning[data-v-de110ae2]:not(.is-disabled):hover{background-color:var(--law-btn-warning-hover-bg);color:var(--law-btn-warning-hover-color)}.law-button.el-button--danger[data-v-de110ae2]:not(.is-disabled):hover{background-color:var(--law-btn-danger-hover-bg);color:var(--law-btn-danger-hover-color)}.law-button.el-button--info[data-v-de110ae2]:not(.is-disabled):hover{background-color:var(--law-btn-info-hover-bg);color:var(--law-btn-info-hover-color)}.law-dialog[data-v-cdda79d0]{--el-dialog-border-radius: var(--law-radius-md);font-family:var(--law-font-family-zh)}.law-dialog[data-v-cdda79d0] .el-dialog__header{color:var(--law-text-primary);font-weight:var(--law-font-weight-semibold)}.law-dialog[data-v-cdda79d0] .el-dialog__body{color:var(--law-text-regular);font-size:var(--law-font-size-body);line-height:var(--law-line-height-body)}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LawThemeMode } from '../hooks/use-law-theme';
|
|
2
|
+
/** 判断当前是否为暗色模式 */
|
|
3
|
+
export declare function isLawDarkMode(): boolean;
|
|
4
|
+
/** 获取当前主题模式 */
|
|
5
|
+
export declare function getLawThemeMode(): LawThemeMode;
|
|
6
|
+
/** 合并 class 名称 */
|
|
7
|
+
export declare function mergeLawClass(...classes: Array<string | false | null | undefined>): string;
|
|
8
|
+
/** 将 Law 按钮尺寸映射为 Element Plus size */
|
|
9
|
+
export declare function mapLawButtonSize(size: 'lg' | 'md' | 'sm'): 'large' | 'default' | 'small';
|