ct-component-plus 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.
Files changed (87) hide show
  1. package/README.md +3 -0
  2. package/package.json +37 -0
  3. package/packages/components/button/index.js +9 -0
  4. package/packages/components/button/src/button.vue +172 -0
  5. package/packages/components/cascader/index.js +8 -0
  6. package/packages/components/cascader/src/cascader.vue +224 -0
  7. package/packages/components/cascader/src/ct-cascader.vue +261 -0
  8. package/packages/components/cascader/src/index.js +51 -0
  9. package/packages/components/checkbox/index.js +8 -0
  10. package/packages/components/checkbox/src/checkbox.vue +48 -0
  11. package/packages/components/checkbox/src/index.js +13 -0
  12. package/packages/components/date-picker/index.js +9 -0
  13. package/packages/components/date-picker/src/clear-icon.vue +3 -0
  14. package/packages/components/date-picker/src/date-icon.vue +3 -0
  15. package/packages/components/date-picker/src/date-picker.vue +77 -0
  16. package/packages/components/date-picker/src/index.js +34 -0
  17. package/packages/components/dialog/index.js +9 -0
  18. package/packages/components/dialog/src/dialog.vue +104 -0
  19. package/packages/components/empty/index.js +9 -0
  20. package/packages/components/empty/src/empty.vue +98 -0
  21. package/packages/components/index.js +71 -0
  22. package/packages/components/input/index.js +8 -0
  23. package/packages/components/input/src/index.js +14 -0
  24. package/packages/components/input/src/input.vue +107 -0
  25. package/packages/components/input-range/index.js +8 -0
  26. package/packages/components/input-range/src/index.js +30 -0
  27. package/packages/components/input-range/src/input-range.vue +234 -0
  28. package/packages/components/menu/index.js +8 -0
  29. package/packages/components/menu/src/assets/plus_line.svg +1 -0
  30. package/packages/components/menu/src/item.vue +47 -0
  31. package/packages/components/menu/src/link.vue +29 -0
  32. package/packages/components/menu/src/logo.vue +26 -0
  33. package/packages/components/menu/src/menu-item.vue +104 -0
  34. package/packages/components/menu/src/menu.vue +192 -0
  35. package/packages/components/menu/src/utils/index.js +5 -0
  36. package/packages/components/message/icon/ErrorIcon.vue +25 -0
  37. package/packages/components/message/icon/InfoIcon.vue +25 -0
  38. package/packages/components/message/icon/SuccessIcon.vue +25 -0
  39. package/packages/components/message/icon/WarningIcon.vue +25 -0
  40. package/packages/components/message/index.js +9 -0
  41. package/packages/components/message/src/method.js +55 -0
  42. package/packages/components/message-box/index.js +8 -0
  43. package/packages/components/message-box/src/message-box.vue +108 -0
  44. package/packages/components/pagination/index.js +8 -0
  45. package/packages/components/pagination/src/pagination.vue +37 -0
  46. package/packages/components/radio/index.js +8 -0
  47. package/packages/components/radio/src/index.js +13 -0
  48. package/packages/components/radio/src/radio.vue +48 -0
  49. package/packages/components/search-box/index.js +25 -0
  50. package/packages/components/search-box/src/index.js +30 -0
  51. package/packages/components/search-box/src/search-box.vue +240 -0
  52. package/packages/components/search-box/src/slot.vue +5 -0
  53. package/packages/components/select/index.js +8 -0
  54. package/packages/components/select/src/arrow-down.vue +3 -0
  55. package/packages/components/select/src/clear-icon.vue +3 -0
  56. package/packages/components/select/src/empty.vue +14 -0
  57. package/packages/components/select/src/index.js +52 -0
  58. package/packages/components/select/src/select.vue +331 -0
  59. package/packages/components/table/index.js +8 -0
  60. package/packages/components/table/src/TableSort.vue +179 -0
  61. package/packages/components/table/src/index.js +47 -0
  62. package/packages/components/table/src/table.vue +249 -0
  63. package/packages/components/tabs/index.js +8 -0
  64. package/packages/components/tabs/src/tabs.vue +226 -0
  65. package/packages/components/year-select/index.js +8 -0
  66. package/packages/components/year-select/src/index.js +45 -0
  67. package/packages/components/year-select/src/year-select.vue +274 -0
  68. package/packages/constants/aria.ts +17 -0
  69. package/packages/constants/index.ts +1 -0
  70. package/packages/directives/click-outside/index.ts +118 -0
  71. package/packages/directives/index.js +1 -0
  72. package/packages/echarts/bar/index.js +64 -0
  73. package/packages/echarts/base.js +96 -0
  74. package/packages/echarts/line/index.js +107 -0
  75. package/packages/hooks/index.js +6 -0
  76. package/packages/hooks/use-buried/index.js +47 -0
  77. package/packages/hooks/use-checked-all/index.js +37 -0
  78. package/packages/hooks/use-echarts/index.js +2 -0
  79. package/packages/hooks/use-echarts/use-bar/index.js +67 -0
  80. package/packages/hooks/use-echarts/use-line/index.js +83 -0
  81. package/packages/hooks/use-namespace/index.js +66 -0
  82. package/packages/hooks/use-search-component/index.js +29 -0
  83. package/packages/style/element.less +600 -0
  84. package/packages/style/init.less +114 -0
  85. package/packages/utils/index.js +2 -0
  86. package/packages/utils/operate.js +78 -0
  87. package/packages/utils/types.js +35 -0
@@ -0,0 +1,249 @@
1
+ <template>
2
+ <div :class="[ns.b()]">
3
+ <div :class="[ns.e('container')]">
4
+ <el-table
5
+ ref="tableRef"
6
+ :class="[ns.e('body')]"
7
+ :data="showData"
8
+ :span-method="spanMethod"
9
+ @selection-change="handleSelectChange"
10
+ row-key="rowKey"
11
+ v-bind="$attrs"
12
+ >
13
+ <el-table-column
14
+ v-if="isMultiSelect"
15
+ type="selection"
16
+ width="88"
17
+ :reserve-selection="true"
18
+ ></el-table-column>
19
+ <el-table-column
20
+ v-for="(column, index) in columnData"
21
+ :key="column.value + '-' + column.label"
22
+ :label="column.label + ''"
23
+ :prop="column.value || ''"
24
+ :width="judgeWidth(column, index)"
25
+ :min-width="judgeMinWidth(column, index)"
26
+ :sort-orders="['ascending', 'descending']"
27
+ :sortable="column.sortable ? 'custom' : false"
28
+ :align="column.align || 'center'"
29
+ :fixed="column.fixed || false"
30
+ >
31
+ <template #header v-if="column.slotHeader">
32
+ <slot :name="column.value + 'Header'"></slot>
33
+ </template>
34
+ <template #default="scope">
35
+ <slot
36
+ :name="column.value"
37
+ :value="scope.row[column.value]"
38
+ v-bind="scope"
39
+ :column="column"
40
+ >
41
+ <span>{{ scope.row[column.value] }}</span>
42
+ </slot>
43
+ <el-table-column
44
+ v-for="(column1, index) in column.children"
45
+ :key="column1.value + '-' + column1.label"
46
+ :label="column1.label + ''"
47
+ :prop="column1.value"
48
+ :width="judgeWidth(column1, index)"
49
+ :min-width="judgeMinWidth(column1, index)"
50
+ :sort-orders="['ascending', 'descending']"
51
+ :sortable="column1.sortable ? 'custom' : false"
52
+ :align="column1.align || 'center'"
53
+ :fixed="column1.fixed || false"
54
+ show-overflow-tooltip
55
+ >
56
+ <template #default="scope">
57
+ <slot
58
+ :name="column1.value"
59
+ :value="scope.row[column1.value]"
60
+ v-bind="scope"
61
+ :column="column1"
62
+ >
63
+ <span>{{ scope.row[column1.value] }}</span>
64
+ </slot>
65
+ </template>
66
+ </el-table-column>
67
+ </template>
68
+ </el-table-column>
69
+ </el-table>
70
+ <ct-pagination
71
+ :class="ns.e('pagination')"
72
+ :pageSize="pageSize"
73
+ :total="total"
74
+ :current-page="pageNo"
75
+ v-if="pageSize"
76
+ @current-change="handleCurrentChange"
77
+ ></ct-pagination>
78
+ </div>
79
+ <Teleport :to="`#${teleportDom}`" v-if="teleportDom && teleportStatus">
80
+ <table-sort v-model:sort-obj="sortObj" :sort-list="sortList"></table-sort>
81
+ </Teleport>
82
+ </div>
83
+ </template>
84
+
85
+ <script setup>
86
+ import {
87
+ computed,
88
+ defineAsyncComponent,
89
+ nextTick,
90
+ onMounted,
91
+ reactive,
92
+ ref,
93
+ watch,
94
+ } from "vue";
95
+ import { useNamespace } from "../../../hooks";
96
+ import { copyObj } from "../../../utils";
97
+ import { tableEmits, tableProps } from "./index";
98
+ import TableSort from "./TableSort.vue";
99
+ const props = defineProps(tableProps);
100
+ const emit = defineEmits(tableEmits);
101
+
102
+ const ns = useNamespace("table");
103
+ const tableRef = ref(null);
104
+ const total = computed(() => {
105
+ return props.tableProps.tableData?.length;
106
+ });
107
+ const pageSize = computed(() => {
108
+ return Number(props.pagination);
109
+ });
110
+ const pageNo = ref(1);
111
+ const handleCurrentChange = (val) => {
112
+ pageNo.value = val;
113
+ };
114
+ const showData = computed(() => {
115
+ const table = props.tableProps.tableData.map((item, index) => {
116
+ return {
117
+ ...item,
118
+ rowKey: `ct-row-${index}`,
119
+ };
120
+ });
121
+ if (props.pagination) {
122
+ return table.slice(
123
+ (pageNo.value - 1) * pageSize.value,
124
+ pageNo.value * pageSize.value
125
+ );
126
+ } else {
127
+ return table || [];
128
+ }
129
+ });
130
+ const columnData = computed(() => {
131
+ return props.tableProps.columnData || [];
132
+ });
133
+ const judgeWidth = (column, index) => {
134
+ // 判断处理column的width
135
+ const columnWidth = props.columnWidth;
136
+ return (
137
+ column.fixedWidth ||
138
+ (columnWidth &&
139
+ typeof columnWidth[index] === "object" &&
140
+ columnWidth[index].fixed) ||
141
+ ""
142
+ );
143
+ };
144
+ const judgeMinWidth = (column, index) => {
145
+ // 判断处理column的min-width
146
+ const columnWidth = props.columnWidth;
147
+ if (column.width) {
148
+ return column.width;
149
+ }
150
+ if (columnWidth && columnWidth[index]) {
151
+ return typeof columnWidth[index] === "object"
152
+ ? columnWidth[index].width
153
+ : columnWidth[index];
154
+ }
155
+ return "auto";
156
+ };
157
+
158
+ let spanObj = {};
159
+ watch(
160
+ () => props.mergeList,
161
+ (newVal, oldVal) => {
162
+ let res = {};
163
+ if (Array.isArray(newVal)) {
164
+ newVal.forEach((item) => {
165
+ const { row, col, span } = item;
166
+ const spanRow = span ? span[0] : 0;
167
+ const spanCol = span ? span[1] : 0;
168
+ // 处理一项合并单元格数据,设置对应的行和列的合并数据,以及涉及到的其他行和列都需要被合并
169
+ for (let i = 1; i <= spanRow; i++) {
170
+ for (let j = 1; j <= spanCol; j++) {
171
+ // 除了起始行、起始列,其他行和列都是需要被合并的,即都需要设置为[0,0]
172
+ let res = i === 1 && j === 1 ? span : [0, 0];
173
+ const rowKey = row + i - 1;
174
+ const colKey = col + j - 1;
175
+ if (res[rowKey]) {
176
+ res[rowKey][colKey] = res;
177
+ } else {
178
+ res[rowKey] = {
179
+ [colKey]: res,
180
+ };
181
+ }
182
+ }
183
+ }
184
+ });
185
+ }
186
+ spanObj = res;
187
+ },
188
+ { immediate: true }
189
+ );
190
+ const spanMethod = ({ rowIndex, columnIndex }) => {
191
+ const rowKey = rowIndex + 1;
192
+ const colKey = columnIndex + 1;
193
+
194
+ if (spanObj[rowKey]) {
195
+ if (spanObj[rowKey][colKey]) {
196
+ return spanObj[rowKey][colKey];
197
+ }
198
+ }
199
+ return [1, 1];
200
+ };
201
+
202
+ const selectedArr = computed({
203
+ get() {
204
+ return props.multiSelect || [];
205
+ },
206
+ set(val) {
207
+ emit("update:multiSelect", val);
208
+ },
209
+ });
210
+ watch(
211
+ () => props.multiSelect,
212
+ (val, oldVal) => {
213
+ if (val && val.length == 0) {
214
+ tableRef.value.clearSelection();
215
+ }
216
+ }
217
+ );
218
+ function handleSelectChange(val) {
219
+ selectedArr.value = copyObj(val);
220
+ }
221
+
222
+ const teleportStatus = ref(false);
223
+ const sortObj = computed({
224
+ get() {
225
+ return props.defaultSort;
226
+ },
227
+ set(val) {
228
+ emit("update:defaultSort", val);
229
+ },
230
+ });
231
+ const sortList = computed(() => {
232
+ return columnData.value.filter((item) => item.sortable);
233
+ });
234
+ onMounted(() => {
235
+ teleportStatus.value = true; //直到dom挂载完毕再挂载teleport组件
236
+ });
237
+
238
+ defineExpose({ tableRef });
239
+ </script>
240
+ <style lang='less' scoped>
241
+ .ct-table__body {
242
+ width: 100%;
243
+ }
244
+ .ct-table__pagination {
245
+ margin-top: 24px;
246
+ display: flex;
247
+ justify-content: flex-end;
248
+ }
249
+ </style>
@@ -0,0 +1,8 @@
1
+ import CtTabs from './src/tabs.vue';
2
+
3
+ /* istanbul ignore next */
4
+ CtTabs.install = function (Vue) {
5
+ Vue.component('CtTabs', CtTabs);
6
+ };
7
+
8
+ export default CtTabs;
@@ -0,0 +1,226 @@
1
+ <template>
2
+ <div :class="[ns.b(), ns.m(type), ns.is('nav', nav)]" ref="_ref">
3
+ <div
4
+ v-for="(item, index) in list"
5
+ :key="index"
6
+ :class="[
7
+ ns.e('item'),
8
+ ns.is('disabled', item.disabled),
9
+ ns.is('active', modelValue === item.value),
10
+ ]"
11
+ @click="handleClick(item, index)"
12
+ >
13
+ <slot>
14
+ <span :class="ns.e('item-text')">{{ item.label }}</span>
15
+ </slot>
16
+ </div>
17
+ </div>
18
+ </template>
19
+
20
+ <script setup>
21
+ import { onMounted, ref } from "vue";
22
+ import { useNamespace } from "../../../hooks";
23
+ const ns = useNamespace("tabs");
24
+ const props = defineProps({
25
+ nav: {
26
+ type: Boolean,
27
+ default: false,
28
+ },
29
+ type: {
30
+ type: String,
31
+ default: "default",
32
+ },
33
+ modelValue: {
34
+ type: [String, Number],
35
+ default: "",
36
+ },
37
+ list: {
38
+ type: Array,
39
+ default: () => [],
40
+ },
41
+ beforeLeave: Function,
42
+ });
43
+ const emit = defineEmits(["click", "change", "update:modelValue"]);
44
+ const _ref = ref(null);
45
+
46
+ const handleClick = async (item, index) => {
47
+ if (item.disabled) return;
48
+ try {
49
+ emit("click", item.value, index, item);
50
+ if (item.value === props.modelValue) return;
51
+ // 可以继续的标志
52
+ let canContinue = true;
53
+ if (props.beforeLeave) {
54
+ canContinue = await props.beforeLeave(item.value, index, item);
55
+ }
56
+ if (canContinue !== false) {
57
+ emit("update:modelValue", item.value);
58
+ emit("change", item.value, index, item);
59
+ }
60
+ } catch (error) {
61
+ console.error(error);
62
+ return;
63
+ }
64
+ };
65
+ onMounted(() => {
66
+ if (!props.modelValue && props.list.length) {
67
+ handleClick(props.list[0], 0);
68
+ }
69
+ });
70
+ defineExpose({
71
+ ref: _ref,
72
+ });
73
+ </script>
74
+ <style lang='less'>
75
+ .ct-tabs {
76
+ display: inline-flex;
77
+ align-items: center;
78
+ @R: .ct-tabs;
79
+ --tabs-button-border-radius: var(--ct-border-radius);
80
+ &__item {
81
+ cursor: pointer;
82
+ &.is-disabled {
83
+ cursor: not-allowed;
84
+ }
85
+ }
86
+ &--default {
87
+ @{R}__item {
88
+ position: relative;
89
+ padding: 12px 0;
90
+ margin-right: 32px;
91
+ line-height: 20px;
92
+ &:last-child {
93
+ margin-right: 0;
94
+ }
95
+ &.is-active {
96
+ font-weight: 600;
97
+ color: var(--ct-color-primary);
98
+ &::after {
99
+ content: "";
100
+ position: absolute;
101
+ bottom: 0;
102
+ left: 0;
103
+ width: 100%;
104
+ height: 2px;
105
+ background-color: var(--ct-color-primary);
106
+ }
107
+ }
108
+ &.is-disabled {
109
+ color: var(--ct-color-disabled);
110
+ }
111
+ &:not(.is-disabled):hover {
112
+ color: var(--ct-color-primary);
113
+ }
114
+ }
115
+ }
116
+ &--block {
117
+ @{R}__item {
118
+ padding: 5px 12px;
119
+ margin-right: 8px;
120
+ background-color: var(--ct-color-bg);
121
+ border-radius: 3px;
122
+ line-height: 18px;
123
+ &:last-child {
124
+ margin-right: 0;
125
+ }
126
+ &.is-active {
127
+ font-weight: 600;
128
+ background-color: var(--ct-color-primary-bg);
129
+ color: var(--ct-color-primary);
130
+ }
131
+ &.is-disabled {
132
+ color: var(--ct-color-disabled);
133
+ }
134
+ &:not(.is-disabled):hover {
135
+ background-color: var(--ct-color-primary-bg);
136
+ }
137
+ }
138
+ }
139
+ &--button {
140
+ box-sizing: border-box;
141
+ border-radius: var(--tabs-button-border-radius);
142
+ @{R}__item {
143
+ padding: 5px 12px;
144
+ border: 1px solid #a4afbb;
145
+ border-right-width: 0;
146
+ &:first-child {
147
+ border-radius: var(--tabs-button-border-radius) 0 0
148
+ var(--tabs-button-border-radius);
149
+ }
150
+ &:last-child {
151
+ border-right-width: 1px;
152
+ border-radius: 0 var(--tabs-button-border-radius)
153
+ var(--tabs-button-border-radius) 0;
154
+ }
155
+ &.is-active {
156
+ font-weight: 600;
157
+ background-color: var(--ct-color-primary);
158
+ color: #fff;
159
+ border-color: var(--ct-color-primary);
160
+ border-right-width: 0;
161
+ & + div {
162
+ border-left-color: transparent;
163
+ }
164
+ }
165
+ &.is-disabled {
166
+ color: var(--ct-color-disabled);
167
+ }
168
+ &:not(.is-disabled):not(.is-active):hover {
169
+ color: var(--ct-color-primary);
170
+ }
171
+ }
172
+ }
173
+ &--button-bg {
174
+ background-color: var(--ct-color-bg);
175
+ border-radius: var(--tabs-button-border-radius);
176
+ @{R}__item {
177
+ position: relative;
178
+ padding: 5px 12px;
179
+ background-color: var(--ct-color-bg);
180
+ border-radius: 3px;
181
+ line-height: 18px;
182
+ &::before {
183
+ content: "";
184
+ position: absolute;
185
+ top: 50%;
186
+ left: 0;
187
+ transform: translateY(-50%);
188
+ width: 1px;
189
+ height: 16px;
190
+ background-color: var(--ct-color-separator);
191
+ }
192
+ &:first-child {
193
+ &::before {
194
+ display: none;
195
+ }
196
+ }
197
+ &.is-active {
198
+ font-weight: 600;
199
+ background-color: var(--ct-color-primary);
200
+ color: #fff;
201
+ &::before {
202
+ display: none;
203
+ }
204
+ }
205
+ &.is-disabled {
206
+ color: var(--ct-color-disabled);
207
+ }
208
+ &:not(.is-disabled):not(.is-active):hover {
209
+ color: var(--ct-color-primary);
210
+ }
211
+ }
212
+ }
213
+ &.is-nav {
214
+ font-size: 18px;
215
+ font-weight: 600;
216
+ line-height: 22px;
217
+ @{R}__item {
218
+ padding: 23px 0;
219
+ margin-right: 36px;
220
+ &:last-child {
221
+ margin-right: 0;
222
+ }
223
+ }
224
+ }
225
+ }
226
+ </style>
@@ -0,0 +1,8 @@
1
+ import CtYearSelect from './src/year-select.vue';
2
+
3
+ /* istanbul ignore next */
4
+ CtYearSelect.install = function (Vue) {
5
+ Vue.component('CtYearSelect', CtYearSelect);
6
+ };
7
+
8
+ export default CtYearSelect;
@@ -0,0 +1,45 @@
1
+ import { buriedParamsKey, searchComponentProps } from '../../../hooks';
2
+
3
+ export const yearSelectEmits = [
4
+ "update:modelValue",
5
+ buriedParamsKey,
6
+ 'change',
7
+ 'change-select',
8
+ 'visible-change',
9
+ 'blur',
10
+ 'focus'
11
+ ];
12
+ export const yearSelectProps = {
13
+ ...searchComponentProps,
14
+ modelValue: [Number, String, Array],
15
+ disabled: Boolean,
16
+ multiple: {
17
+ type: Boolean,
18
+ default: true
19
+ },
20
+ startPlaceholder: String,
21
+ endPlaceholder: String,
22
+ range: {
23
+ type: Array,
24
+ default() {
25
+ return [1950, new Date().getFullYear()];
26
+ },
27
+ validator(valueArr) {
28
+ if (valueArr.length !== 2) {
29
+ throw `请输入合理的年份取值范围:${valueArr}`;
30
+ }
31
+ let count = 0;
32
+ valueArr.forEach((item) => {
33
+ count += /\d{4}/.test(item) ? 1 : 0;
34
+ });
35
+ if (count !== 2) {
36
+ throw `请确保传入的两个范围都是年份:${valueArr}`;
37
+ }
38
+ return true;
39
+ },
40
+ },
41
+ separator: {
42
+ type: [String, Object],
43
+ default: "至",
44
+ },
45
+ }