pxd 0.0.13 → 0.0.16
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/dist/components/active-graph/index.vue +331 -0
- package/dist/components/active-graph/index.vue.d.ts +49 -0
- package/dist/components/avatar/index.vue +30 -8
- package/dist/components/avatar/index.vue.d.ts +10 -1
- package/dist/components/avatar-group/index.vue +5 -4
- package/dist/components/avatar-group/index.vue.d.ts +1 -0
- package/dist/components/button/index.vue +11 -7
- package/dist/components/button/index.vue.d.ts +8 -6
- package/dist/components/checkbox/index.vue +7 -6
- package/dist/components/checkbox/index.vue.d.ts +4 -3
- package/dist/components/checkbox-group/index.vue +10 -6
- package/dist/components/checkbox-group/index.vue.d.ts +3 -7
- package/dist/components/config-provider/index.vue +3 -1
- package/dist/components/config-provider/index.vue.d.ts +2 -1
- package/dist/components/description/index.vue +31 -0
- package/dist/components/description/index.vue.d.ts +19 -0
- package/dist/components/error/index.vue +17 -13
- package/dist/components/gauge/index.vue +24 -23
- package/dist/components/gauge/index.vue.d.ts +2 -2
- package/dist/components/hold-button/index.vue +9 -8
- package/dist/components/index.d.ts +8 -1
- package/dist/components/index.js +8 -1
- package/dist/components/input/index.vue +27 -19
- package/dist/components/input/index.vue.d.ts +13 -10
- package/dist/components/kbd/index.vue +1 -1
- package/dist/components/link-button/index.vue +4 -4
- package/dist/components/more-button/index.vue +5 -5
- package/dist/components/more-button/index.vue.d.ts +3 -3
- package/dist/components/note/index.vue +17 -12
- package/dist/components/note/index.vue.d.ts +35 -7
- package/dist/components/popover/index.vue +364 -0
- package/dist/components/popover/index.vue.d.ts +54 -0
- package/dist/components/progress/index.vue +9 -15
- package/dist/components/progress/index.vue.d.ts +2 -2
- package/dist/components/radio/index.vue +14 -16
- package/dist/components/radio/index.vue.d.ts +4 -3
- package/dist/components/radio-group/index.vue +5 -5
- package/dist/components/radio-group/index.vue.d.ts +5 -9
- package/dist/components/scrollable/index.vue +43 -30
- package/dist/components/slider/index.vue +52 -38
- package/dist/components/slider/index.vue.d.ts +5 -4
- package/dist/components/snippet/index.vue +4 -3
- package/dist/components/stack/index.vue +41 -38
- package/dist/components/stack/index.vue.d.ts +14 -3
- package/dist/components/switch/index.vue +65 -0
- package/dist/components/switch/index.vue.d.ts +19 -0
- package/dist/components/switch-group/index.vue +48 -0
- package/dist/components/switch-group/index.vue.d.ts +28 -0
- package/dist/components/teleport/index.vue +68 -0
- package/dist/components/teleport/index.vue.d.ts +20 -0
- package/dist/components/textarea/index.vue +18 -10
- package/dist/components/textarea/index.vue.d.ts +17 -6
- package/dist/components/{color-scheme → theme-switcher}/index.vue +9 -6
- package/dist/components/toggle/index.vue +4 -4
- package/dist/components/toggle/index.vue.d.ts +2 -2
- package/dist/components/tooltip/index.vue +49 -0
- package/dist/components/tooltip/index.vue.d.ts +27 -0
- package/dist/composables/index.d.ts +2 -0
- package/dist/composables/index.js +2 -0
- package/dist/composables/useConfigProviderContext.d.ts +1 -0
- package/dist/composables/useConfigProviderContext.js +3 -1
- package/dist/composables/useDelayChange.d.ts +8 -0
- package/dist/composables/useDelayChange.js +20 -0
- package/dist/composables/useIntersectionObserver.d.ts +7 -0
- package/dist/composables/useIntersectionObserver.js +44 -0
- package/dist/composables/useMediaQuery.d.ts +2 -1
- package/dist/composables/useMediaQuery.js +3 -4
- package/dist/composables/useModelValue.d.ts +2 -1
- package/dist/composables/useRandomValueContext.js +6 -6
- package/dist/composables/useResizeObserver.d.ts +5 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/locales/en-US.d.ts +32 -0
- package/dist/locales/en-US.js +31 -0
- package/dist/locales/index.d.ts +2 -0
- package/dist/locales/index.js +2 -0
- package/dist/locales/zh-CN.d.ts +32 -0
- package/dist/locales/zh-CN.js +31 -0
- package/dist/styles/dst.css +277 -0
- package/dist/styles/styles.css +2 -0
- package/dist/styles/tw.css +361 -355
- package/dist/types/components.d.ts +6 -10
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/shared.d.ts +1 -0
- package/dist/types/shared.js +0 -0
- package/dist/utils/colors.d.ts +1 -0
- package/dist/utils/colors.js +13 -0
- package/dist/utils/dates.d.ts +12 -0
- package/dist/utils/dates.js +40 -0
- package/dist/utils/device.d.ts +1 -0
- package/dist/utils/device.js +1 -0
- package/dist/utils/dom.d.ts +12 -0
- package/dist/utils/dom.js +16 -0
- package/dist/utils/events.d.ts +5 -0
- package/dist/utils/events.js +27 -0
- package/dist/utils/fn.d.ts +4 -0
- package/dist/utils/fn.js +44 -0
- package/dist/utils/random.d.ts +1 -1
- package/dist/utils/random.js +2 -2
- package/dist/utils/uid.d.ts +1 -0
- package/dist/utils/uid.js +4 -0
- package/package.json +27 -11
- package/dist/styles/index.css +0 -2
- package/dist/styles/tokens.css +0 -238
- /package/dist/components/{color-scheme → theme-switcher}/index.vue.d.ts +0 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, shallowRef } from "vue";
|
|
3
|
+
import { useConfigProvider } from "../../composables/useConfigProviderContext";
|
|
4
|
+
import { useDelayChange } from "../../composables/useDelayChange";
|
|
5
|
+
import { getColorByThreshold } from "../../utils/colors";
|
|
6
|
+
import { getAllDatesBetween } from "../../utils/dates";
|
|
7
|
+
defineOptions({
|
|
8
|
+
name: "PActiveGraph"
|
|
9
|
+
});
|
|
10
|
+
const props = defineProps({
|
|
11
|
+
data: { type: Array, required: false, default: () => [] },
|
|
12
|
+
legend: { type: Boolean, required: false, default: true },
|
|
13
|
+
startDate: { type: [String, Date], required: false, default: () => {
|
|
14
|
+
const date = /* @__PURE__ */ new Date();
|
|
15
|
+
date.setFullYear(date.getFullYear() - 1);
|
|
16
|
+
while (date.getDay() !== 0) {
|
|
17
|
+
date.setDate(date.getDate() + 1);
|
|
18
|
+
}
|
|
19
|
+
return date;
|
|
20
|
+
} },
|
|
21
|
+
endDate: { type: [String, Date], required: false, default: () => /* @__PURE__ */ new Date() },
|
|
22
|
+
colors: { type: Object, required: false, default: () => ({
|
|
23
|
+
0: "",
|
|
24
|
+
5: "var(--color-green-300)",
|
|
25
|
+
10: "var(--color-green-500)",
|
|
26
|
+
15: "var(--color-green-700)",
|
|
27
|
+
20: "var(--color-green-900)"
|
|
28
|
+
}) },
|
|
29
|
+
onlyGraph: { type: Boolean, required: false, default: false },
|
|
30
|
+
transpose: { type: Boolean, required: false },
|
|
31
|
+
tooltipText: { type: String, required: false, default: "{COUNT} on {DATE}" }
|
|
32
|
+
});
|
|
33
|
+
const emits = defineEmits(["cellClick"]);
|
|
34
|
+
const config = useConfigProvider();
|
|
35
|
+
const CELL_GAP = 3;
|
|
36
|
+
const CELL_SIZE = 12;
|
|
37
|
+
const rangedDates = computed(() => getAllDatesBetween(props.startDate, props.endDate));
|
|
38
|
+
const dateCountMap = computed(() => {
|
|
39
|
+
return props.data.reduce((acc, cur) => {
|
|
40
|
+
acc[cur.date] = (acc[cur.date] || 0) + cur.count;
|
|
41
|
+
return acc;
|
|
42
|
+
}, {});
|
|
43
|
+
});
|
|
44
|
+
function getLocalizedDay(dayIndex) {
|
|
45
|
+
return config.locale.date.day[dayIndex];
|
|
46
|
+
}
|
|
47
|
+
const tableHeadList = computed(() => {
|
|
48
|
+
if (props.transpose) {
|
|
49
|
+
return Array.from({ length: 7 }, (_, i) => {
|
|
50
|
+
return [1, 3, 5].includes(i) ? getLocalizedDay(i) : "";
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return createMonthHeaders();
|
|
54
|
+
});
|
|
55
|
+
function createMonthHeaders() {
|
|
56
|
+
const dates = rangedDates.value.dates;
|
|
57
|
+
const colCount = Math.ceil(dates.length / 7);
|
|
58
|
+
const result = Array.from({ length: colCount }, () => "");
|
|
59
|
+
const firstDate = new Date(dates[0]);
|
|
60
|
+
result[0] = config.locale.date.month[firstDate.getMonth()];
|
|
61
|
+
const firstDayOfWeek = rangedDates.value.weeks[0];
|
|
62
|
+
let currentMonth = firstDate.getMonth();
|
|
63
|
+
for (let i = 1; i < dates.length; i++) {
|
|
64
|
+
const date = new Date(dates[i]);
|
|
65
|
+
const month = date.getMonth();
|
|
66
|
+
const day = date.getDate();
|
|
67
|
+
if (month !== currentMonth && day === 1) {
|
|
68
|
+
const colIndex = Math.floor((i + 7 - firstDayOfWeek) / 7);
|
|
69
|
+
if (colIndex < colCount) {
|
|
70
|
+
result[colIndex] = config.locale.date.month[month];
|
|
71
|
+
currentMonth = month;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
const tableBodyList = computed(() => {
|
|
78
|
+
return props.transpose ? createTransposedTableData() : createStandardTableData();
|
|
79
|
+
});
|
|
80
|
+
function createTransposedTableData() {
|
|
81
|
+
const dataMap = dateCountMap.value;
|
|
82
|
+
const dateList = rangedDates.value.dates;
|
|
83
|
+
const dateListLength = dateList.length;
|
|
84
|
+
const monthRows = [];
|
|
85
|
+
let currentMonth = -1;
|
|
86
|
+
let currentYear = -1;
|
|
87
|
+
let currentRow = null;
|
|
88
|
+
for (let i = 0; i < dateListLength; i++) {
|
|
89
|
+
const dateStr = dateList[i];
|
|
90
|
+
const date = new Date(dateStr);
|
|
91
|
+
const year = date.getFullYear();
|
|
92
|
+
const month = date.getMonth();
|
|
93
|
+
const dayOfWeek = date.getDay();
|
|
94
|
+
const count = dataMap[dateStr] || 0;
|
|
95
|
+
if (currentRow === null) {
|
|
96
|
+
currentRow = [];
|
|
97
|
+
if (i === 0) {
|
|
98
|
+
for (let j = 0; j < dayOfWeek; j++) {
|
|
99
|
+
currentRow.push({
|
|
100
|
+
hidden: true,
|
|
101
|
+
date: void 0,
|
|
102
|
+
count: 0,
|
|
103
|
+
color: void 0
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
currentRow.push({
|
|
109
|
+
hidden: false,
|
|
110
|
+
date: dateStr,
|
|
111
|
+
count,
|
|
112
|
+
color: getColorByThreshold(count, props.colors)
|
|
113
|
+
});
|
|
114
|
+
if (month !== currentMonth || year !== currentYear) {
|
|
115
|
+
currentMonth = month;
|
|
116
|
+
currentYear = year;
|
|
117
|
+
}
|
|
118
|
+
const isLastItem = i === dateListLength - 1;
|
|
119
|
+
const isRowFull = currentRow.length >= 7;
|
|
120
|
+
if (isRowFull || isLastItem) {
|
|
121
|
+
if (currentRow.length < 7 && isLastItem) {
|
|
122
|
+
while (currentRow.length < 7) {
|
|
123
|
+
currentRow.push({
|
|
124
|
+
hidden: true,
|
|
125
|
+
date: void 0,
|
|
126
|
+
count: 0,
|
|
127
|
+
color: void 0
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
monthRows.push([...currentRow]);
|
|
132
|
+
currentRow = null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return markMonthRows(monthRows);
|
|
136
|
+
}
|
|
137
|
+
function createStandardTableData() {
|
|
138
|
+
const dataMap = dateCountMap.value;
|
|
139
|
+
const dateList = rangedDates.value.dates;
|
|
140
|
+
const dateListLength = dateList.length;
|
|
141
|
+
const firstDayOfWeek = rangedDates.value.weeks[0];
|
|
142
|
+
const result = Array.from({ length: 7 }, (_, i) => {
|
|
143
|
+
const row = [];
|
|
144
|
+
if (i < firstDayOfWeek) {
|
|
145
|
+
row.push({
|
|
146
|
+
hidden: true,
|
|
147
|
+
date: void 0,
|
|
148
|
+
count: 0,
|
|
149
|
+
color: void 0
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
const rowWithHeader = row;
|
|
153
|
+
rowWithHeader.headerText = [1, 3, 5].includes(i) ? getLocalizedDay(i) : " ";
|
|
154
|
+
return rowWithHeader;
|
|
155
|
+
});
|
|
156
|
+
for (let i = 0; i < dateListLength; i++) {
|
|
157
|
+
const dateStr = dateList[i];
|
|
158
|
+
const count = dataMap[dateStr] || 0;
|
|
159
|
+
const dayOfWeek = new Date(dateStr).getDay();
|
|
160
|
+
result[dayOfWeek].push({
|
|
161
|
+
hidden: false,
|
|
162
|
+
date: dateStr,
|
|
163
|
+
count,
|
|
164
|
+
color: getColorByThreshold(count, props.colors)
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
function markMonthRows(rows) {
|
|
170
|
+
const monthMap = {};
|
|
171
|
+
for (let i = 0; i < rows.length; i++) {
|
|
172
|
+
const row = rows[i];
|
|
173
|
+
const firstValidCell = row.find((cell) => !cell.hidden && cell.date);
|
|
174
|
+
if (firstValidCell) {
|
|
175
|
+
const date = new Date(firstValidCell.date);
|
|
176
|
+
const month = date.getMonth();
|
|
177
|
+
const year = date.getFullYear();
|
|
178
|
+
const day = date.getDate();
|
|
179
|
+
const key = `${year}-${month}`;
|
|
180
|
+
if (!monthMap[key] || day === 1) {
|
|
181
|
+
monthMap[key] = true;
|
|
182
|
+
row.isMonthFirstRow = true;
|
|
183
|
+
row.monthName = config.locale.date.month[month];
|
|
184
|
+
row.headerText = row.monthName;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return rows;
|
|
189
|
+
}
|
|
190
|
+
function onCellClick(event) {
|
|
191
|
+
const target = event.target;
|
|
192
|
+
const date = target.dataset.date;
|
|
193
|
+
if (!date) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
emits("cellClick", event, date);
|
|
197
|
+
}
|
|
198
|
+
let tbodyRect;
|
|
199
|
+
const tbodyRef = shallowRef();
|
|
200
|
+
const {
|
|
201
|
+
value: showTooltip,
|
|
202
|
+
set: setShowTooltip,
|
|
203
|
+
setImmediate: setShowTooltipImmediate
|
|
204
|
+
} = useDelayChange(false, 500);
|
|
205
|
+
const tooltipInfo = shallowRef({});
|
|
206
|
+
const formatTooltipText = computed(() => {
|
|
207
|
+
if (props.tooltipText) {
|
|
208
|
+
const { date = "", count = 0 } = tooltipInfo.value;
|
|
209
|
+
return props.tooltipText.replace(/\{DATE\}/g, date).replace(/\{COUNT\}/g, String(count));
|
|
210
|
+
}
|
|
211
|
+
return "";
|
|
212
|
+
});
|
|
213
|
+
function onMouseEnter() {
|
|
214
|
+
tbodyRect = tbodyRef.value.getBoundingClientRect();
|
|
215
|
+
}
|
|
216
|
+
function onMouseLeave() {
|
|
217
|
+
setShowTooltipImmediate(false);
|
|
218
|
+
tooltipInfo.value = {};
|
|
219
|
+
tbodyRect = null;
|
|
220
|
+
}
|
|
221
|
+
function onMouseOver(ev) {
|
|
222
|
+
const targetEl = ev.target;
|
|
223
|
+
if (targetEl.tagName !== "TD") {
|
|
224
|
+
setShowTooltip(false);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const date = targetEl.dataset.date;
|
|
228
|
+
if (!date) {
|
|
229
|
+
setShowTooltipImmediate(false);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
setShowTooltipImmediate(true);
|
|
233
|
+
const rect = targetEl.getBoundingClientRect();
|
|
234
|
+
let top = rect.top - tbodyRect.top - CELL_SIZE;
|
|
235
|
+
if (props.onlyGraph) {
|
|
236
|
+
top -= CELL_SIZE;
|
|
237
|
+
}
|
|
238
|
+
tooltipInfo.value = {
|
|
239
|
+
date,
|
|
240
|
+
count: dateCountMap.value[date] || 0,
|
|
241
|
+
left: rect.left - tbodyRect.left + CELL_GAP,
|
|
242
|
+
top
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
</script>
|
|
246
|
+
|
|
247
|
+
<template>
|
|
248
|
+
<div class="pxd-active-graph relative" :class="[onlyGraph ? 'py-[3px] pr-[3px]' : 'pr-5']">
|
|
249
|
+
<table
|
|
250
|
+
role="grid"
|
|
251
|
+
aria-readonly="true"
|
|
252
|
+
class="border-separate"
|
|
253
|
+
style="border-spacing: 3px;"
|
|
254
|
+
@pointerenter="onMouseEnter"
|
|
255
|
+
@pointerleave="onMouseLeave"
|
|
256
|
+
>
|
|
257
|
+
<thead v-if="!onlyGraph" class="text-xs">
|
|
258
|
+
<tr class="h-3">
|
|
259
|
+
<th style="width: 30px;min-width: 30px;" />
|
|
260
|
+
|
|
261
|
+
<th
|
|
262
|
+
v-for="col in tableHeadList"
|
|
263
|
+
:key="col"
|
|
264
|
+
class="relative font-normal text-gray-900"
|
|
265
|
+
>
|
|
266
|
+
<span class="absolute -top-1 left-0 whitespace-nowrap">{{ col }}</span>
|
|
267
|
+
</th>
|
|
268
|
+
</tr>
|
|
269
|
+
</thead>
|
|
270
|
+
|
|
271
|
+
<tbody
|
|
272
|
+
ref="tbodyRef"
|
|
273
|
+
class="text-xs"
|
|
274
|
+
@click="onCellClick"
|
|
275
|
+
@pointerover="onMouseOver"
|
|
276
|
+
>
|
|
277
|
+
<tr v-for="(row, i) of tableBodyList" :key="i" class="h-3">
|
|
278
|
+
<td class="relative leading-none text-gray-900 overflow-hidden">
|
|
279
|
+
<span class="absolute top-0 right-1">
|
|
280
|
+
{{ row.headerText }}
|
|
281
|
+
</span>
|
|
282
|
+
</td>
|
|
283
|
+
|
|
284
|
+
<td
|
|
285
|
+
v-for="col of row"
|
|
286
|
+
:key="col.date"
|
|
287
|
+
class="pxd-active-graph--item rounded-xs w-3 min-w-3 bg-gray-alpha-200 motion-safe:transition-colors"
|
|
288
|
+
:data-date="col.date"
|
|
289
|
+
:class="{ 'pointer-events-none opacity-0': col.hidden }"
|
|
290
|
+
:style="`background: ${col.color}`"
|
|
291
|
+
/>
|
|
292
|
+
</tr>
|
|
293
|
+
|
|
294
|
+
<template v-if="props.legend">
|
|
295
|
+
<tr class="pxd-active-graph--placeholder pointer-events-none h-0.5" />
|
|
296
|
+
<tr class="pxd-active-graph--legend pointer-events-none">
|
|
297
|
+
<td class="relative h-3 text-gray-700">
|
|
298
|
+
<span class="absolute top-1/2 right-1 -translate-y-1/2">{{ config.locale.compare.less }}</span>
|
|
299
|
+
</td>
|
|
300
|
+
|
|
301
|
+
<td
|
|
302
|
+
v-for="color in props.colors"
|
|
303
|
+
:key="color"
|
|
304
|
+
class="w-3 h-3 rounded-xs bg-gray-alpha-200 motion-safe:transition-colors"
|
|
305
|
+
:style="`background-color: ${color}`"
|
|
306
|
+
/>
|
|
307
|
+
|
|
308
|
+
<td class="relative h-3 text-gray-700 w-3">
|
|
309
|
+
<span
|
|
310
|
+
class="absolute top-1/2 left-px -translate-y-1/2"
|
|
311
|
+
style="width: 30px;min-width: 30px;"
|
|
312
|
+
>{{ config.locale.compare.more }}</span>
|
|
313
|
+
</td>
|
|
314
|
+
</tr>
|
|
315
|
+
</template>
|
|
316
|
+
</tbody>
|
|
317
|
+
</table>
|
|
318
|
+
|
|
319
|
+
<Transition name="pxd-transition--fade">
|
|
320
|
+
<div
|
|
321
|
+
v-if="showTooltip"
|
|
322
|
+
class="pxd-active-graph--tooltip left-0 top-0 bg-gray-1000 pointer-events-none text-gray-100 absolute z-10 px-2 py-1 text-[13px] rounded-sm w-max"
|
|
323
|
+
:style="`transform: translate(${tooltipInfo.left}px, ${tooltipInfo.top}px);`"
|
|
324
|
+
>
|
|
325
|
+
<slot name="tooltip" :data="tooltipInfo">
|
|
326
|
+
{{ formatTooltipText }}
|
|
327
|
+
</slot>
|
|
328
|
+
</div>
|
|
329
|
+
</Transition>
|
|
330
|
+
</div>
|
|
331
|
+
</template>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
data?: Array<{
|
|
3
|
+
date: string;
|
|
4
|
+
count: number;
|
|
5
|
+
}>;
|
|
6
|
+
legend?: boolean;
|
|
7
|
+
startDate?: string | Date;
|
|
8
|
+
endDate?: string | Date;
|
|
9
|
+
colors?: Record<string, string>;
|
|
10
|
+
onlyGraph?: boolean;
|
|
11
|
+
transpose?: boolean;
|
|
12
|
+
tooltipText?: string;
|
|
13
|
+
}
|
|
14
|
+
/** 提示框信息 */
|
|
15
|
+
interface TooltipInfo {
|
|
16
|
+
date: string;
|
|
17
|
+
count: number;
|
|
18
|
+
left: number;
|
|
19
|
+
top: number;
|
|
20
|
+
}
|
|
21
|
+
declare var __VLS_5: {
|
|
22
|
+
data: TooltipInfo;
|
|
23
|
+
};
|
|
24
|
+
type __VLS_Slots = {} & {
|
|
25
|
+
tooltip?: (props: typeof __VLS_5) => any;
|
|
26
|
+
};
|
|
27
|
+
declare const __VLS_component: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
28
|
+
cellClick: (args_0: MouseEvent, args_1: string) => any;
|
|
29
|
+
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
30
|
+
onCellClick?: (args_0: MouseEvent, args_1: string) => any;
|
|
31
|
+
}>, {
|
|
32
|
+
data: Array<{
|
|
33
|
+
date: string;
|
|
34
|
+
count: number;
|
|
35
|
+
}>;
|
|
36
|
+
legend: boolean;
|
|
37
|
+
startDate: string | Date;
|
|
38
|
+
endDate: string | Date;
|
|
39
|
+
colors: Record<string, string>;
|
|
40
|
+
onlyGraph: boolean;
|
|
41
|
+
tooltipText: string;
|
|
42
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
43
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
44
|
+
export default _default;
|
|
45
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
46
|
+
new (): {
|
|
47
|
+
$slots: S;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
@@ -1,19 +1,38 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, inject,
|
|
2
|
+
import { computed, inject, shallowRef } from "vue";
|
|
3
3
|
import { getCssUnitValue } from "../../utils/format";
|
|
4
4
|
defineOptions({
|
|
5
5
|
name: "PAvatar"
|
|
6
6
|
});
|
|
7
7
|
const props = defineProps({
|
|
8
8
|
src: { type: String, required: false },
|
|
9
|
+
alt: { type: String, required: false },
|
|
9
10
|
size: { type: [Number, String], required: false },
|
|
10
11
|
loading: { type: Boolean, required: false }
|
|
11
12
|
});
|
|
12
|
-
defineEmits(["error"]);
|
|
13
|
-
const
|
|
13
|
+
const emits = defineEmits(["load", "error", "loadstart"]);
|
|
14
|
+
const loadingStatus = shallowRef("idle");
|
|
14
15
|
const groupSize = inject("groupSize", 32);
|
|
15
16
|
const computedSize = computed(() => getCssUnitValue(props.size || groupSize));
|
|
16
|
-
const computedLoading = computed(() => props.loading ||
|
|
17
|
+
const computedLoading = computed(() => props.loading || loadingStatus.value === "error");
|
|
18
|
+
function onLoadError(event) {
|
|
19
|
+
loadingStatus.value = "error";
|
|
20
|
+
emits("error", event);
|
|
21
|
+
}
|
|
22
|
+
function onLoadSuccess(event) {
|
|
23
|
+
loadingStatus.value = "loaded";
|
|
24
|
+
emits("load", event);
|
|
25
|
+
}
|
|
26
|
+
function onLoadStart(event) {
|
|
27
|
+
loadingStatus.value = "loading";
|
|
28
|
+
emits("loadstart", event);
|
|
29
|
+
}
|
|
30
|
+
function getLoadingStatus() {
|
|
31
|
+
return loadingStatus.value;
|
|
32
|
+
}
|
|
33
|
+
defineExpose({
|
|
34
|
+
getLoadingStatus
|
|
35
|
+
});
|
|
17
36
|
</script>
|
|
18
37
|
|
|
19
38
|
<template>
|
|
@@ -25,14 +44,17 @@ const computedLoading = computed(() => props.loading || isLoadFailed.value);
|
|
|
25
44
|
<img
|
|
26
45
|
v-if="!computedLoading"
|
|
27
46
|
:src="src"
|
|
28
|
-
alt="
|
|
47
|
+
:alt="alt"
|
|
29
48
|
loading="lazy"
|
|
30
49
|
decoding="async"
|
|
31
50
|
aria-hidden="true"
|
|
32
51
|
fetchpriority="low"
|
|
33
52
|
crossorigin="anonymous"
|
|
34
53
|
class="relative block rounded-inherit overflow-hidden w-full h-full"
|
|
35
|
-
@
|
|
54
|
+
@load="onLoadSuccess"
|
|
55
|
+
@loadstart="onLoadStart"
|
|
56
|
+
@abort="onLoadError"
|
|
57
|
+
@error="onLoadError"
|
|
36
58
|
>
|
|
37
59
|
</slot>
|
|
38
60
|
|
|
@@ -58,12 +80,12 @@ const computedLoading = computed(() => props.loading || isLoadFailed.value);
|
|
|
58
80
|
}
|
|
59
81
|
|
|
60
82
|
&::before {
|
|
61
|
-
background-image: linear-gradient(270deg, var(--gray-alpha-100), var(--gray-alpha-
|
|
83
|
+
background-image: linear-gradient(270deg, var(--color-gray-alpha-100), var(--color-gray-alpha-400), var(--color-gray-alpha-400), var(--color-gray-alpha-100));
|
|
62
84
|
background-size: 400% 100%;
|
|
63
85
|
}
|
|
64
86
|
|
|
65
87
|
&::after {
|
|
66
|
-
border: 1px solid var(--gray-alpha-400)
|
|
88
|
+
border: 1px solid var(--color-gray-alpha-400)
|
|
67
89
|
}
|
|
68
90
|
}
|
|
69
91
|
|
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
interface Props {
|
|
2
2
|
src?: string;
|
|
3
|
+
alt?: string;
|
|
3
4
|
size?: number | string;
|
|
4
5
|
loading?: boolean;
|
|
5
6
|
}
|
|
7
|
+
type LoadingStatus = 'idle' | 'loading' | 'loaded' | 'error';
|
|
8
|
+
declare function getLoadingStatus(): LoadingStatus;
|
|
6
9
|
declare var __VLS_1: {}, __VLS_3: {};
|
|
7
10
|
type __VLS_Slots = {} & {
|
|
8
11
|
default?: (props: typeof __VLS_1) => any;
|
|
9
12
|
} & {
|
|
10
13
|
badge?: (props: typeof __VLS_3) => any;
|
|
11
14
|
};
|
|
12
|
-
declare const __VLS_component: import("vue").DefineComponent<Props, {
|
|
15
|
+
declare const __VLS_component: import("vue").DefineComponent<Props, {
|
|
16
|
+
getLoadingStatus: typeof getLoadingStatus;
|
|
17
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
13
18
|
error: (args_0: Event) => any;
|
|
19
|
+
load: (args_0: Event) => any;
|
|
20
|
+
loadstart: (args_0: Event) => any;
|
|
14
21
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
15
22
|
onError?: (args_0: Event) => any;
|
|
23
|
+
onLoad?: (args_0: Event) => any;
|
|
24
|
+
onLoadstart?: (args_0: Event) => any;
|
|
16
25
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
17
26
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
18
27
|
export default _default;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, provide } from "vue";
|
|
3
|
-
import
|
|
3
|
+
import PAvatar from "../avatar/index.vue";
|
|
4
4
|
defineOptions({
|
|
5
5
|
name: "PAvatarGroup"
|
|
6
6
|
});
|
|
@@ -15,17 +15,18 @@ provide("groupSize", props.size);
|
|
|
15
15
|
|
|
16
16
|
<template>
|
|
17
17
|
<div class="pxd-avatar-group flex flex-wrap items-center">
|
|
18
|
-
<
|
|
18
|
+
<PAvatar
|
|
19
19
|
v-for="(option, index) in slicedOptions"
|
|
20
20
|
:key="index"
|
|
21
21
|
:size="size"
|
|
22
22
|
:src="option.src"
|
|
23
|
+
:alt="option.alt"
|
|
23
24
|
:loading="option.loading"
|
|
24
25
|
class="[&:nth-child(n+2)]:-ml-3"
|
|
25
26
|
/>
|
|
26
27
|
|
|
27
|
-
<
|
|
28
|
+
<PAvatar v-if="slicedOptions.length < options.length" class="text-xs bg-gray-1000 text-gray-100 -ml-3">
|
|
28
29
|
+{{ options.length - slicedOptions.length }}
|
|
29
|
-
</
|
|
30
|
+
</PAvatar>
|
|
30
31
|
</div>
|
|
31
32
|
</template>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { twMerge } from "tailwind-merge";
|
|
3
3
|
import { computed } from "vue";
|
|
4
4
|
import { useComputedSize } from "../../composables/useComputedSize";
|
|
5
|
-
import
|
|
5
|
+
import PSpinner from "../spinner/index.vue";
|
|
6
6
|
defineOptions({
|
|
7
7
|
name: "PButton"
|
|
8
8
|
});
|
|
@@ -15,7 +15,7 @@ const props = defineProps({
|
|
|
15
15
|
loading: { type: Boolean, required: false },
|
|
16
16
|
disabled: { type: Boolean, required: false }
|
|
17
17
|
});
|
|
18
|
-
const emits = defineEmits(["click"]);
|
|
18
|
+
const emits = defineEmits(["click", "dblclick"]);
|
|
19
19
|
const SIZES = {
|
|
20
20
|
xs: "h-6 px-1 rounded-md",
|
|
21
21
|
sm: "h-7.5 px-1.5 rounded-md",
|
|
@@ -32,10 +32,10 @@ const VARIANTS = {
|
|
|
32
32
|
simple: "",
|
|
33
33
|
default: "bg-background text-foreground hover:bg-background-hover active:bg-background-active border-input",
|
|
34
34
|
ghost: "bg-transparent text-foreground hover:bg-gray-alpha-200 active:bg-gray-alpha-300 border-transparent",
|
|
35
|
-
primary: "bg-primary text-gray-100 hover:bg-primary/80 active:bg-
|
|
36
|
-
error: "bg-red-800 text-white hover:bg-red-700 active:bg-red-
|
|
37
|
-
warning: "bg-amber-800 text-black hover:bg-amber-700 active:bg-amber-
|
|
38
|
-
success: "bg-green-800 text-white hover:bg-green-700 active:bg-green-
|
|
35
|
+
primary: "bg-primary text-gray-100 hover:bg-primary/80 active:bg-gray-900 border-transparent",
|
|
36
|
+
error: "bg-red-800 text-white hover:bg-red-700 active:bg-red-900 border-transparent",
|
|
37
|
+
warning: "bg-amber-800 text-black hover:bg-amber-700 active:bg-amber-900 border-transparent",
|
|
38
|
+
success: "bg-green-800 text-white hover:bg-green-700 active:bg-green-900 border-transparent"
|
|
39
39
|
};
|
|
40
40
|
const DISABLED_CLASS_NAMES = "is-disabled bg-gray-100 hover:bg-gray-100 active:bg-gray-100 cursor-not-allowed text-gray-700 border-gray-300";
|
|
41
41
|
const computedSize = useComputedSize(props.size, SIZES);
|
|
@@ -63,6 +63,9 @@ const computedClasses = computed(() => {
|
|
|
63
63
|
function onButtonClick(event) {
|
|
64
64
|
emits("click", event);
|
|
65
65
|
}
|
|
66
|
+
function onButtonDblClick(event) {
|
|
67
|
+
emits("dblclick", event);
|
|
68
|
+
}
|
|
66
69
|
</script>
|
|
67
70
|
|
|
68
71
|
<template>
|
|
@@ -72,8 +75,9 @@ function onButtonClick(event) {
|
|
|
72
75
|
:class="computedClasses"
|
|
73
76
|
:disabled="computedDisabled"
|
|
74
77
|
@click="onButtonClick"
|
|
78
|
+
@dblclick.prevent="onButtonDblClick"
|
|
75
79
|
>
|
|
76
|
-
<
|
|
80
|
+
<PSpinner v-if="loading" />
|
|
77
81
|
|
|
78
82
|
<slot name="prefix" />
|
|
79
83
|
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import type { ButtonProps } from '../../types/components';
|
|
2
|
-
declare var
|
|
2
|
+
declare var __VLS_14: {}, __VLS_16: {}, __VLS_18: {};
|
|
3
3
|
type __VLS_Slots = {} & {
|
|
4
|
-
prefix?: (props: typeof
|
|
4
|
+
prefix?: (props: typeof __VLS_14) => any;
|
|
5
5
|
} & {
|
|
6
|
-
default?: (props: typeof
|
|
6
|
+
default?: (props: typeof __VLS_16) => any;
|
|
7
7
|
} & {
|
|
8
|
-
suffix?: (props: typeof
|
|
8
|
+
suffix?: (props: typeof __VLS_18) => any;
|
|
9
9
|
};
|
|
10
10
|
declare const __VLS_component: import("vue").DefineComponent<ButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
11
|
click: (args_0: MouseEvent) => any;
|
|
12
|
+
dblclick: (args_0: MouseEvent) => any;
|
|
12
13
|
}, string, import("vue").PublicProps, Readonly<ButtonProps> & Readonly<{
|
|
13
14
|
onClick?: (args_0: MouseEvent) => any;
|
|
15
|
+
onDblclick?: (args_0: MouseEvent) => any;
|
|
14
16
|
}>, {
|
|
15
|
-
variant: import("../../types
|
|
16
|
-
as: import("../../types
|
|
17
|
+
variant: import("../../types").ComponentVariantWithDefault | "ghost" | "simple";
|
|
18
|
+
as: import("../../types").ComponentAs;
|
|
17
19
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
18
20
|
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
19
21
|
export default _default;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import
|
|
2
|
+
import CheckIcon from "@gdsicon/vue/check";
|
|
3
|
+
import MinusIcon from "@gdsicon/vue/minus";
|
|
3
4
|
import { twMerge } from "tailwind-merge";
|
|
4
5
|
import { computed, inject } from "vue";
|
|
5
6
|
import { useModelValue } from "../../composables/useModelValue";
|
|
6
|
-
import {
|
|
7
|
+
import { getUniqueId } from "../../utils/uid";
|
|
7
8
|
defineOptions({
|
|
8
9
|
name: "PCheckbox",
|
|
9
10
|
model: {
|
|
@@ -12,7 +13,7 @@ defineOptions({
|
|
|
12
13
|
}
|
|
13
14
|
});
|
|
14
15
|
const props = defineProps({
|
|
15
|
-
label: { type: [String, Number], required: false },
|
|
16
|
+
label: { type: [String, Number, Array, null], required: false },
|
|
16
17
|
value: { type: [String, Number, Boolean], required: false, default: true },
|
|
17
18
|
disabled: { type: Boolean, required: false },
|
|
18
19
|
required: { type: Boolean, required: false },
|
|
@@ -20,7 +21,7 @@ const props = defineProps({
|
|
|
20
21
|
indeterminate: { type: Boolean, required: false }
|
|
21
22
|
});
|
|
22
23
|
const emits = defineEmits(["update:modelValue"]);
|
|
23
|
-
const
|
|
24
|
+
const uniqueId = getUniqueId();
|
|
24
25
|
const modelValue = useModelValue(props, emits);
|
|
25
26
|
const checkboxGroupProps = inject("checkboxGroupProps", {
|
|
26
27
|
disabled: false,
|
|
@@ -79,10 +80,10 @@ defineExpose({
|
|
|
79
80
|
<label
|
|
80
81
|
class="pxd-checkbox inline-flex items-center group/checkbox"
|
|
81
82
|
:class="{ 'is-disabled cursor-not-allowed text-gray-500': computedDisabled }"
|
|
82
|
-
:for="
|
|
83
|
+
:for="uniqueId"
|
|
83
84
|
>
|
|
84
85
|
<input
|
|
85
|
-
:id="
|
|
86
|
+
:id="uniqueId"
|
|
86
87
|
:value="value"
|
|
87
88
|
type="checkbox"
|
|
88
89
|
class="smallest peer"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import type { ComponentLabel } from '../../types/components';
|
|
1
2
|
type ValueType = string | number | boolean;
|
|
2
3
|
interface Props {
|
|
3
|
-
label?:
|
|
4
|
+
label?: ComponentLabel;
|
|
4
5
|
value?: ValueType;
|
|
5
6
|
disabled?: boolean;
|
|
6
7
|
required?: boolean;
|
|
@@ -15,9 +16,9 @@ type __VLS_Slots = {} & {
|
|
|
15
16
|
declare const __VLS_component: import("vue").DefineComponent<Props, {
|
|
16
17
|
getCheckedState: typeof getCheckedState;
|
|
17
18
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
18
|
-
"update:modelValue": (args_0: ValueType | ValueType[]) => any;
|
|
19
|
+
"update:modelValue": (args_0: NonNullable<ValueType | ValueType[]>) => any;
|
|
19
20
|
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
20
|
-
"onUpdate:modelValue"?: (args_0: ValueType | ValueType[]) => any;
|
|
21
|
+
"onUpdate:modelValue"?: (args_0: NonNullable<ValueType | ValueType[]>) => any;
|
|
21
22
|
}>, {
|
|
22
23
|
value: ValueType;
|
|
23
24
|
modelValue: ValueType | ValueType[];
|