ylwl-cpscoms 1.1.0 → 1.2.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 (38) hide show
  1. package/package.json +2 -3
  2. package/src/DtTable/DtTable/347/273/204/344/273/266/344/275/277/347/224/250/346/226/207/346/241/243.md +0 -819
  3. package/src/DtTable/index.vue +0 -779
  4. package/src/SlAlert/SlAlert.stories.js +0 -108
  5. package/src/SlAlert/index.vue +0 -55
  6. package/src/SlAlert/remark.md +0 -16
  7. package/src/SlDescriptions/SlDescriptions.stories.js +0 -119
  8. package/src/SlDescriptions/index.vue +0 -60
  9. package/src/SlDescriptions/renderOptions.vue +0 -27
  10. package/src/SlDialog/README-PLUS.md +0 -74
  11. package/src/SlDialog/README.md +0 -114
  12. package/src/SlDialog/dialogPlus.js +0 -160
  13. package/src/SlDialog/index.js +0 -170
  14. package/src/SlDrawer/SlDrawer.stories.js +0 -154
  15. package/src/SlDrawer/index.js +0 -62
  16. package/src/SlForm/SlForm.stories.js +0 -120
  17. package/src/SlForm/index.vue +0 -506
  18. package/src/SlForm/mixinRender.js +0 -228
  19. package/src/SlForm/otherItem/titleItem.vue +0 -31
  20. package/src/SlForm/remark.md +0 -607
  21. package/src/SlGuide/SlGuide.stories.js +0 -100
  22. package/src/SlGuide/index.vue +0 -166
  23. package/src/SlGuide/remark.md +0 -90
  24. package/src/SlMessageBox/index.js +0 -35
  25. package/src/SlPage/README.md +0 -515
  26. package/src/SlPage/SlPage.stories.js +0 -125
  27. package/src/SlPage/index.vue +0 -303
  28. package/src/SlPage/remark.md +0 -283
  29. package/src/SlTable/SlTable.stories.js +0 -118
  30. package/src/SlTable/components/colSetting.vue +0 -86
  31. package/src/SlTable/index.vue +0 -541
  32. package/src/SlTitle/SlTitle.stories.js +0 -98
  33. package/src/SlTitle/index.vue +0 -49
  34. package/src/global.css +0 -5
  35. package/src/index.js +0 -49
  36. package/src/store/index.js +0 -20
  37. package/src/utils/index.js +0 -47
  38. package/src/utils/tableConfig.js +0 -33
@@ -1,160 +0,0 @@
1
- import Vue from 'vue'
2
- import { isMobileDevice } from '../utils'
3
-
4
- // 🌟 核心魔法:注册一个全局的辅助组件,充当“传送门”(Portal)
5
- if (!Vue.component('dialog-footer')) {
6
- Vue.component('dialog-footer', {
7
- inject: {
8
- dialogCtx: { default: null }
9
- },
10
-
11
- mounted() {
12
- if (this.dialogCtx) {
13
- this.dialogCtx.setFooterVNodes(this.$slots.default)
14
- }
15
- },
16
- updated() {
17
- if (this.dialogCtx) {
18
- this.dialogCtx.setFooterVNodes(this.$slots.default)
19
- }
20
- },
21
- destroyed() {
22
- if (this.dialogCtx) {
23
- this.dialogCtx.setFooterVNodes(null)
24
- }
25
- },
26
- render(h) {
27
- return h('div', { style: { display: 'none' }, class: 'dialog-footer-portal' })
28
- }
29
- })
30
- }
31
-
32
- export function createCommandDialogPlus(options) {
33
- const defaultOptions = {
34
- title: '提示',
35
- width: '50%',
36
- specialWidth: '',
37
- closeOnClickModal: false,
38
- contentComponent: null,
39
- contentProps: {},
40
- showClose: true,
41
- closeOnPressEscape: false,
42
- customClass: ''
43
- }
44
-
45
- const mergedOptions = { ...defaultOptions, ...options }
46
-
47
- const Constructor = Vue.extend({
48
- provide() {
49
- return {
50
- dialogCtx: this
51
- }
52
- },
53
- data() {
54
- return {
55
- visible: false,
56
- footerVNodes: null
57
- }
58
- },
59
- created() {
60
- Object.assign(this, mergedOptions)
61
- },
62
- mounted() {
63
- Vue.nextTick(() => {
64
- this.visible = true
65
- })
66
- },
67
- methods: {
68
- handleBeforeClose(done) {
69
- if (typeof done === 'function') {
70
- done() // 允许 el-dialog 执行关闭动画
71
- } else {
72
- this.visible = false
73
- }
74
- },
75
- handleClose() {
76
- if (this._hasClosed) return
77
- this._hasClosed = true
78
- console.log('你肯定会执行吗啊')
79
- if (typeof this.onClose === 'function') {
80
- this.onClose(this)
81
- }
82
- this.$once('closed', () => {
83
- this.$destroy()
84
- if (this.$el && this.$el.parentNode) {
85
- this.$el.parentNode.removeChild(this.$el)
86
- }
87
- })
88
- },
89
- // 暴露给业务组件的关闭方法
90
- closeDialog() {
91
- this.visible = false
92
- },
93
-
94
- // 兼容以前的 confirm 逻辑(可选保留,为了向后兼容外层传入 onConfirm)
95
- confirmDialog() {
96
- if (typeof this.onConfirm === 'function') {
97
- this.onConfirm()
98
- }
99
- this.visible = false // 同样只修改 visible
100
- },
101
-
102
- // 供 <dialog-footer> 调用的方法
103
- setFooterVNodes(vnodes) {
104
- this.footerVNodes = vnodes
105
- }
106
- },
107
-
108
- render(h) {
109
- // 渲染主体业务组件
110
- const dialogChildren = [
111
- h(this.contentComponent, {
112
- props: this.contentProps,
113
- ref: 'contentComponent',
114
- on: {
115
- // 业务组件可以通过 this.$emit('close') 主动关闭弹窗
116
- close: this.closeDialog,
117
- // 业务组件可以通过 this.$emit('confirm') 触发外层回调并关闭弹窗
118
- confirm: this.confirmDialog
119
- // 【新增】:允许业务组件透传任意自定义事件到外层
120
- // 如果你的业务组件需要向外抛出自定义事件(如 'save-draft'),
121
- // 可以在调用 createCommandDialog 时通过 on 属性传入监听器。
122
- }
123
- })
124
- ]
125
-
126
- if (this.footerVNodes) {
127
- dialogChildren.push(h('template', { slot: 'footer' }, this.footerVNodes))
128
- }
129
-
130
- return h(
131
- 'el-dialog',
132
- {
133
- props: {
134
- title: this.title,
135
- visible: this.visible,
136
- width: isMobileDevice() ? '90%' : this.specialWidth ? this.specialWidth : this.width === '30%' ? '30%' : '50%',
137
- 'close-on-click-modal': this.closeOnClickModal,
138
- showClose: this.showClose,
139
- 'close-on-press-escape': this.closeOnPressEscape,
140
- customClass: this.customClass
141
- },
142
- on: {
143
- 'update:visible': (val) => {
144
- this.visible = val
145
- },
146
- 'before-close': this.handleBeforeClose,
147
- close: this.handleClose,
148
- closed: () => {
149
- this.$emit('closed')
150
- }
151
- }
152
- },
153
- dialogChildren
154
- )
155
- }
156
- })
157
-
158
- const instance = new Constructor().$mount()
159
- document.body.appendChild(instance.$el)
160
- }
@@ -1,170 +0,0 @@
1
- import Vue from 'vue'
2
- import { Button } from 'element-ui'
3
- import { isMobileDevice } from '../utils'
4
- export function createCommandDialog(options) {
5
- const defaultOptions = {
6
- title: '提示',
7
- width: '50%',
8
- specialWidth: '',
9
- closeOnClickModal: false,
10
- contentComponent: null,
11
- contentProps: {},
12
- footerBtns: [],
13
- cancelButtonText: '取消',
14
- confirmButtonText: '确定',
15
- isShowBtn: true,
16
- showClose: true,
17
- closeOnPressEscape: false,
18
- customClass: ''
19
- }
20
-
21
- const mergedOptions = { ...defaultOptions, ...options }
22
-
23
- const Constructor = Vue.extend({
24
- data() {
25
- return {
26
- visible: false // 初始状态为 false
27
- }
28
- },
29
- created() {
30
- // 在 created 钩子中,将配置项直接浅拷贝到 this 实例上
31
- Object.assign(this, mergedOptions)
32
- },
33
- mounted() {
34
- Vue.nextTick(() => {
35
- this.visible = true
36
- })
37
- },
38
- methods: {
39
- handleBeforeClose() {
40
- this.visible = false
41
- },
42
- handleClose(done) {
43
- this.handleBeforeClose()
44
- if (typeof this.onClose === 'function') {
45
- this.onClose(this)
46
- }
47
- this.$once('closed', () => {
48
- this.$destroy()
49
- document.body.removeChild(this.$el)
50
- })
51
- },
52
-
53
- handleCancel() {
54
- this.handleBeforeClose()
55
- if (typeof this.onCancel === 'function') {
56
- this.onCancel()
57
- }
58
- this.handleClose()
59
- },
60
- async handleConfirm() {
61
- // body组件中统一confirm方法(不能用在别的地方)
62
- let shouldClose = true
63
- if (this.$refs.contentComponent.confirm) {
64
- try {
65
- const result = await this.$refs.contentComponent.confirm()
66
- if (result === false) shouldClose = false
67
- } catch (error) {
68
- console.error('弹窗确认时发生错误:', error)
69
- shouldClose = false
70
- }
71
- }
72
- if (typeof this.onConfirm === 'function' && shouldClose) {
73
- this.onConfirm()
74
- }
75
- if (shouldClose) {
76
- this.handleClose()
77
- }
78
- },
79
- // 函数 return false 弹窗不消失; 不返回或者true 弹窗消失
80
- async footerBtnsClick(type) {
81
- if (this.$refs.contentComponent && this.$refs.contentComponent[type]) {
82
- const result = await this.$refs.contentComponent[type]()
83
- if (result !== false) {
84
- this.handleClose()
85
- }
86
- } else {
87
- this.handleClose()
88
- }
89
- }
90
- },
91
-
92
- render(h) {
93
- const footerContent = this.footerBtns.length
94
- ? h('div',
95
- this.footerBtns.map(item => h(Button, {
96
- props: {
97
- type: item.type || 'default',
98
- size: 'small'
99
- },
100
- on: {
101
- click: () => this.footerBtnsClick(item.value)
102
- }
103
- }, item.label)
104
- )
105
- ) : h('div', [
106
- h(Button, {
107
- props: {
108
- type: 'default',
109
- size: 'small'
110
- },
111
- on: {
112
- click: this.handleCancel
113
- }
114
- }, this.cancelButtonText),
115
- h(Button, {
116
- props: {
117
- type: 'primary',
118
- size: 'small'
119
- },
120
- on: {
121
- click: this.handleConfirm
122
- }
123
- }, this.confirmButtonText)
124
- ])
125
-
126
- return h(
127
- 'el-dialog',
128
- {
129
- props: {
130
- title: this.title,
131
- visible: this.visible,
132
- width: isMobileDevice() ? '90%' : this.specialWidth ? this.specialWidth : this.width === '30%' ? '30%' : '50%',
133
- 'close-on-click-modal': this.closeOnClickModal,
134
- showClose: this.showClose,
135
- 'close-on-press-escape': this.closeOnPressEscape,
136
- customClass: this.customClass
137
- },
138
- on: {
139
- 'update:visible': (val) => {
140
- this.visible = val
141
- },
142
- 'before-close': this.handleBeforeClose,
143
- 'close': this.handleClose,
144
- 'closed': () => { this.$emit('closed') }
145
- }
146
- },
147
- [
148
- h(this.contentComponent, {
149
- props: this.contentProps,
150
- ref: 'contentComponent',
151
- scopedSlots: this.$scopedSlots,
152
- on: {
153
- onClose: () => {
154
- this.handleClose()
155
- },
156
- onConfirm: () => {
157
- this.handleConfirm()
158
- }
159
- }
160
- }),
161
- !this.isShowBtn ? '' : h('template', { slot: 'footer' }, [footerContent])
162
- ]
163
- )
164
- }
165
- })
166
-
167
- const instance = new Constructor().$mount()
168
-
169
- document.body.appendChild(instance.$el)
170
- }
@@ -1,154 +0,0 @@
1
- import { createCommandDrawer } from './index.js'
2
-
3
- export default {
4
- title: 'Components/SlDrawer',
5
- parameters: {
6
- docs: {
7
- description: {
8
- component: '命令式抽屉组件,通过 `createCommandDrawer(options)` 函数调用打开。基于 el-drawer 封装,支持传入自定义内容组件、Props 和事件监听。'
9
- }
10
- }
11
- }
12
- }
13
-
14
- const codeBlock = (code) => `
15
- <div style="margin-top:24px;border-top:1px solid #eee;padding-top:16px">
16
- <p style="font-size:14px;font-weight:600;color:#666;margin-bottom:8px;">使用代码:</p>
17
- <pre style="background:#f5f5f5;padding:16px;border-radius:4px;overflow-x:auto;font-size:13px;line-height:1.6;white-space:pre-wrap;word-break:break-all"><code>${escapeHtml(code.trim())}</code></pre>
18
- </div>`
19
-
20
- function escapeHtml(str) {
21
- return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
22
- }
23
-
24
- // 演示用的简单内容组件
25
- const DemoContent = {
26
- props: { message: { type: String, default: '' } },
27
- template: `
28
- <div style="padding:20px">
29
- <p>{{ message }}</p>
30
- <p style="color:#999;font-size:13px;margin-top:12px">这是通过 createCommandDrawer 打开的内容区域。</p>
31
- </div>`
32
- }
33
-
34
- // ---- 基础用法 ----
35
- const defaultCode = `<!-- 使用方式 -->
36
- <script>
37
- import { createCommandDrawer } from '@/components/global/SlDrawer'
38
-
39
- createCommandDrawer({
40
- title: '抽屉标题',
41
- size: '30%',
42
- direction: 'rtl',
43
- contentComponent: YourComponent,
44
- closeDrawer: () => {
45
- console.log('抽屉已关闭')
46
- },
47
- contentProps: {
48
- message: 'Hello'
49
- }
50
- })
51
- </script>`
52
-
53
- export const Default = () => ({
54
- methods: {
55
- openDrawer() {
56
- createCommandDrawer({
57
- title: '用户详情',
58
- size: '30%',
59
- direction: 'rtl',
60
- contentComponent: DemoContent,
61
- closeDrawer: () => {
62
- console.log('抽屉已关闭')
63
- },
64
- contentProps: {
65
- message: '这是通过命令式 API 打开的抽屉'
66
- }
67
- })
68
- }
69
- },
70
- template: `
71
- <div>
72
- <el-button type="primary" @click="openDrawer">打开抽屉</el-button>
73
- ${codeBlock(defaultCode)}
74
- </div>`
75
- })
76
-
77
- Default.storyName = '基础用法'
78
-
79
- // ---- 左侧弹出 ----
80
- const leftCode = `<!-- 左侧弹出 -->
81
- createCommandDrawer({
82
- title: '筛选条件',
83
- size: '25%',
84
- direction: 'ltr',
85
- contentComponent: FilterPanel,
86
- closeDrawer: () => {},
87
- contentProps: { ... }
88
- })`
89
-
90
- export const LeftDirection = () => ({
91
- methods: {
92
- openDrawer() {
93
- createCommandDrawer({
94
- title: '筛选条件',
95
- size: '25%',
96
- direction: 'ltr',
97
- contentComponent: DemoContent,
98
- closeDrawer: () => {
99
- console.log('左侧抽屉已关闭')
100
- },
101
- contentProps: {
102
- message: '从左侧弹出的抽屉'
103
- }
104
- })
105
- }
106
- },
107
- template: `
108
- <div>
109
- <el-button type="success" @click="openDrawer">左侧弹出</el-button>
110
- ${codeBlock(leftCode)}
111
- </div>`
112
- })
113
-
114
- LeftDirection.storyName = '左侧弹出'
115
-
116
- // ---- 大尺寸 ----
117
- const largeCode = `<!-- 大尺寸抽屉 -->
118
- createCommandDrawer({
119
- title: '编辑信息',
120
- size: '50%',
121
- direction: 'rtl',
122
- contentComponent: EditForm,
123
- closeDrawer: () => { this.loadData() },
124
- contentProps: { data: rowData },
125
- contentListeners: {
126
- 'save-success': () => { this.refresh() }
127
- }
128
- })`
129
-
130
- export const LargeSize = () => ({
131
- methods: {
132
- openDrawer() {
133
- createCommandDrawer({
134
- title: '编辑信息',
135
- size: '50%',
136
- direction: 'rtl',
137
- contentComponent: DemoContent,
138
- closeDrawer: () => {
139
- console.log('大尺寸抽屉已关闭')
140
- },
141
- contentProps: {
142
- message: '大尺寸抽屉,适合表单编辑场景'
143
- }
144
- })
145
- }
146
- },
147
- template: `
148
- <div>
149
- <el-button type="warning" @click="openDrawer">大尺寸抽屉(50%)</el-button>
150
- ${codeBlock(largeCode)}
151
- </div>`
152
- })
153
-
154
- LargeSize.storyName = '大尺寸抽屉'
@@ -1,62 +0,0 @@
1
-
2
- import Vue from 'vue'
3
-
4
- export function createCommandDrawer(options) {
5
- const Constructor = Vue.extend({
6
- data() {
7
- return {
8
- visible: true,
9
- ...options
10
- }
11
- },
12
- methods: {
13
- handleClose(done) {
14
- this.visible = false
15
- this.closeDrawer()
16
- done()
17
- }
18
- },
19
- render(h) {
20
- const componentListeners = this.contentListeners || {}
21
- return h(
22
- 'el-drawer',
23
- {
24
- props: {
25
- title: this.title,
26
- size: this.size,
27
- direction: this.direction,
28
- beforeClose: this.handleClose,
29
- visible: this.visible
30
-
31
- },
32
- on: {
33
- input: (val) => {
34
- this.visible = val
35
- }
36
- }
37
- },
38
- [
39
- h(this.contentComponent, {
40
- props: this.contentProps,
41
- on: componentListeners
42
- })
43
- ]
44
- )
45
- }
46
- })
47
-
48
- const instance = new Constructor().$mount()
49
-
50
- document.body.appendChild(instance.$el)
51
-
52
- instance.visible = true
53
- window.addEventListener('keydown', (event) => {
54
- if (event.code === 'Space' || event.key === ' ') {
55
- event.preventDefault()
56
- }
57
- })
58
- instance.$once('close', () => {
59
- instance.$destroy()
60
- document.body.removeChild(instance.$el)
61
- })
62
- }
@@ -1,120 +0,0 @@
1
- import SlForm from './index.vue'
2
-
3
- export default {
4
- title: 'Components/SlForm',
5
- component: SlForm,
6
- parameters: {
7
- docs: {
8
- description: {
9
- component: '动态表单组件,通过 data 配置数组驱动渲染。支持 input、select、datePicker、radio、switch、rangeInput、title、slot 等控件类型。支持表单校验、联动、重置等功能。'
10
- }
11
- }
12
- }
13
- }
14
-
15
- const codeBlock = (code) => `
16
- <div style="margin-top:24px;border-top:1px solid #eee;padding-top:16px">
17
- <p style="font-size:14px;font-weight:600;color:#666;margin-bottom:8px;">使用代码:</p>
18
- <pre style="background:#f5f5f5;padding:16px;border-radius:4px;overflow-x:auto;font-size:13px;line-height:1.6;white-space:pre-wrap;word-break:break-all"><code>${escapeHtml(code.trim())}</code></pre>
19
- </div>`
20
-
21
- function escapeHtml(str) {
22
- return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
23
- }
24
-
25
- // ---- 搜索表单 ----
26
- const searchCode = `<!-- 搜索表单(inline 模式) -->
27
- <sl-form v-model="form" :data="options"
28
- :showlabel="false"
29
- :form-props="{ inline: true, size: 'small' }" />`
30
-
31
- export const SearchForm = () => ({
32
- components: { SlForm },
33
- data() {
34
- return {
35
- form: {},
36
- options: [
37
- { label: '用户名', type: 'input', model: 'userName', privateAttrs: { placeholder: '请输入用户名' } },
38
- { label: '状态', type: 'select', model: 'status', options: [
39
- { label: '启用', value: 1 }, { label: '禁用', value: 0 }
40
- ], props: { placeholder: '请选择状态' } },
41
- { label: '创建时间', type: 'datePicker', model: 'createTime', privateProps: { type: 'daterange', valueFormat: 'yyyy-MM-dd' } }
42
- ]
43
- }
44
- },
45
- template: `
46
- <div>
47
- <sl-form ref="form" v-model="form" :data="options" :showlabel="false" :form-props="{ inline: true, size: 'small' }" />
48
- <div style="margin-top:12px;color:#666;font-size:13px">表单值:{{ form }}</div>
49
- ${codeBlock(searchCode)}
50
- </div>`
51
- })
52
-
53
- SearchForm.storyName = '搜索表单(inline)'
54
-
55
- // ---- 编辑表单 ----
56
- const editCode = `<!-- 编辑表单(非 inline) -->
57
- <sl-form v-model="form" :data="options" item-width="100%"
58
- :form-props="{ inline: false, size: 'small', labelWidth: '120px' }" />`
59
-
60
- export const EditForm = () => ({
61
- components: { SlForm },
62
- data() {
63
- return {
64
- form: { userName: '张三', status: 1 },
65
- options: [
66
- { label: '用户名', type: 'input', model: 'userName', rules: [
67
- { required: true, message: '请输入用户名', trigger: 'blur' }
68
- ]},
69
- { label: '状态', type: 'radio', model: 'status', options: [
70
- { label: '启用', value: 1 }, { label: '禁用', value: 0 }
71
- ], rules: [
72
- { required: true, message: '请选择状态', trigger: 'change' }
73
- ]},
74
- { label: '备注', type: 'input', model: 'remark', privateAttrs: { type: 'textarea', rows: 3 }, remark: '选填,最多200字' },
75
- { label: '开关', type: 'switch', model: 'enable', value: true }
76
- ]
77
- }
78
- },
79
- template: `
80
- <div style="max-width:600px">
81
- <sl-form ref="form" v-model="form" :data="options" item-width="100%" :form-props="{ inline: false, size: 'small', labelWidth: '120px' }" />
82
- <div style="margin-top:12px;color:#666;font-size:13px">表单值:{{ form }}</div>
83
- ${codeBlock(editCode)}
84
- </div>`
85
- })
86
-
87
- EditForm.storyName = '编辑表单'
88
-
89
- // ---- 带标题分组 ----
90
- const titleCode = `<!-- 使用 title 类型分组 -->
91
- <sl-form v-model="form" :data="options" item-width="100%"
92
- :form-props="{ inline: false, size: 'small', labelWidth: '120px' }">
93
- <el-button type="primary" size="small">保存</el-button>
94
- </sl-form>`
95
-
96
- export const WithTitle = () => ({
97
- components: { SlForm },
98
- data() {
99
- return {
100
- form: {},
101
- options: [
102
- { type: 'title', label: '基本信息', model: 'title1' },
103
- { label: '姓名', type: 'input', model: 'name' },
104
- { label: '年龄', type: 'input', model: 'age' },
105
- { type: 'title', label: '联系方式', model: 'title2' },
106
- { label: '手机号', type: 'input', model: 'phone' },
107
- { label: '邮箱', type: 'input', model: 'email' }
108
- ]
109
- }
110
- },
111
- template: `
112
- <div style="max-width:600px">
113
- <sl-form ref="form" v-model="form" :data="options" item-width="100%" :form-props="{ inline: false, size: 'small', labelWidth: '120px' }">
114
- <el-button type="primary" size="small">保存</el-button>
115
- </sl-form>
116
- ${codeBlock(titleCode)}
117
- </div>`
118
- })
119
-
120
- WithTitle.storyName = '带标题分组'