pxd 0.0.61 → 0.0.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/components/_internal/dismiss-container.d.vue.ts +28 -0
- package/dist/components/_internal/dismiss-container.vue +162 -0
- package/dist/components/_internal/popover-arrow.d.vue.ts +9 -0
- package/dist/components/_internal/popover-arrow.vue +38 -0
- package/dist/components/active-graph/index.vue +4 -4
- package/dist/components/avatar/index.vue +5 -7
- package/dist/components/avatar-group/index.d.vue.ts +0 -1
- package/dist/components/avatar-group/index.vue +1 -1
- package/dist/components/backtop/index.vue +1 -1
- package/dist/components/badge/index.d.vue.ts +5 -1
- package/dist/components/badge/index.vue +18 -4
- package/dist/components/badge/types.d.ts +5 -0
- package/dist/components/book/index.vue +1 -1
- package/dist/components/browser/index.vue +1 -1
- package/dist/components/bubble/index.d.vue.ts +22 -0
- package/dist/components/bubble/index.vue +59 -0
- package/dist/components/bubble/types.d.ts +6 -0
- package/dist/components/button/index.d.vue.ts +0 -2
- package/dist/components/button/index.vue +30 -21
- package/dist/components/button/types.d.ts +3 -2
- package/dist/components/button-group/index.d.vue.ts +14 -0
- package/dist/components/button-group/index.vue +26 -0
- package/dist/components/button-group/types.d.ts +9 -0
- package/dist/components/carousel/index.d.vue.ts +3 -3
- package/dist/components/carousel/index.vue +146 -113
- package/dist/components/carousel/types.d.ts +1 -1
- package/dist/components/carousel-item/index.vue +22 -17
- package/dist/components/checkbox/index.vue +6 -6
- package/dist/components/checkbox-group/index.d.vue.ts +1 -1
- package/dist/components/chip/index.d.vue.ts +1 -5
- package/dist/components/chip/index.vue +4 -4
- package/dist/components/color-selector/index.d.vue.ts +12 -0
- package/dist/components/color-selector/index.vue +64 -0
- package/dist/components/color-selector/types.d.ts +12 -0
- package/dist/components/command-menu/index.d.vue.ts +6 -6
- package/dist/components/command-menu/index.vue +23 -32
- package/dist/components/command-menu/types.d.ts +1 -1
- package/dist/components/command-menu-group/index.vue +15 -6
- package/dist/components/command-menu-group/types.d.ts +1 -1
- package/dist/components/countdown/index.d.vue.ts +11 -11
- package/dist/components/drawer/index.d.vue.ts +8 -8
- package/dist/components/drawer/index.vue +13 -10
- package/dist/components/drawer/types.d.ts +4 -3
- package/dist/components/ellipsis-text/index.d.vue.ts +4 -1
- package/dist/components/ellipsis-text/index.vue +84 -107
- package/dist/components/ellipsis-text/types.d.ts +2 -1
- package/dist/components/error/index.vue +1 -1
- package/dist/components/fader/index.vue +5 -9
- package/dist/components/gauge/index.vue +34 -29
- package/dist/components/grid/index.vue +1 -1
- package/dist/components/grid-item/index.vue +1 -1
- package/dist/components/hold-button/index.d.vue.ts +8 -10
- package/dist/components/hold-button/index.vue +20 -29
- package/dist/components/hold-button/types.d.ts +5 -6
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.js +7 -0
- package/dist/components/input/index.d.vue.ts +8 -8
- package/dist/components/input/index.vue +5 -4
- package/dist/components/intersection-observer/index.vue +4 -4
- package/dist/components/kbd/index.vue +1 -1
- package/dist/components/link-button/index.d.vue.ts +4 -4
- package/dist/components/link-button/index.vue +9 -8
- package/dist/components/link-button/types.d.ts +0 -3
- package/dist/components/list/index.d.vue.ts +10 -15
- package/dist/components/list/index.vue +58 -131
- package/dist/components/list/types.d.ts +4 -4
- package/dist/components/list-item/index.d.vue.ts +2 -2
- package/dist/components/list-item/index.vue +44 -39
- package/dist/components/loading-bar/index.vue +8 -7
- package/dist/components/material/index.vue +24 -46
- package/dist/components/menu/index.d.vue.ts +6 -8
- package/dist/components/menu/index.vue +18 -24
- package/dist/components/menu/types.d.ts +1 -2
- package/dist/components/message/composables/use-group-expand.d.ts +13 -0
- package/dist/components/message/composables/use-group-expand.js +50 -0
- package/dist/components/message/composables/use-message-timer.d.ts +9 -0
- package/dist/components/message/composables/use-message-timer.js +61 -0
- package/dist/components/message/composables/use-promise-message.d.ts +4 -0
- package/dist/components/message/composables/use-promise-message.js +49 -0
- package/dist/components/message/index.d.vue.ts +6 -33
- package/dist/components/message/index.vue +33 -185
- package/dist/components/message/types.d.ts +2 -2
- package/dist/components/message-item/index.vue +26 -2
- package/dist/components/modal/index.d.vue.ts +7 -7
- package/dist/components/modal/index.vue +7 -3
- package/dist/components/modal/types.d.ts +7 -3
- package/dist/components/note/index.vue +2 -2
- package/dist/components/number-input/index.d.vue.ts +5 -4
- package/dist/components/number-input/index.vue +3 -0
- package/dist/components/number-input/types.d.ts +1 -0
- package/dist/components/overlay/index.d.vue.ts +6 -3
- package/dist/components/overlay/index.vue +63 -68
- package/dist/components/overlay/types.d.ts +5 -4
- package/dist/components/pagination/index.vue +2 -2
- package/dist/components/pin-input/index.d.vue.ts +1 -1
- package/dist/components/pin-input/index.vue +7 -6
- package/dist/components/placeholder/index.vue +1 -1
- package/dist/components/popover/index.d.vue.ts +7 -8
- package/dist/components/popover/index.vue +149 -239
- package/dist/components/popover/types.d.ts +5 -5
- package/dist/components/progress/index.vue +1 -1
- package/dist/components/radio/index.vue +2 -2
- package/dist/components/resizable/index.vue +43 -51
- package/dist/components/resizable/types.d.ts +1 -1
- package/dist/components/resizable-handle/index.d.vue.ts +4 -1
- package/dist/components/resizable-handle/index.vue +29 -3
- package/dist/components/resizable-panel/index.vue +3 -7
- package/dist/components/scalable-text/index.d.vue.ts +9 -0
- package/dist/components/scalable-text/index.vue +147 -0
- package/dist/components/scalable-text/types.d.ts +12 -0
- package/dist/components/scrollable/index.d.vue.ts +2 -2
- package/dist/components/scrollable/index.vue +4 -3
- package/dist/components/separator/index.d.vue.ts +6 -0
- package/dist/components/separator/index.vue +18 -0
- package/dist/components/separator/types.d.ts +5 -0
- package/dist/components/skeleton/index.d.vue.ts +1 -1
- package/dist/components/slider/index.d.vue.ts +1 -1
- package/dist/components/slider/index.vue +39 -7
- package/dist/components/snippet/index.vue +16 -13
- package/dist/components/spinner/index.vue +3 -1
- package/dist/components/stack/index.d.vue.ts +1 -1
- package/dist/components/stack/index.vue +1 -1
- package/dist/components/switch/index.d.vue.ts +1 -1
- package/dist/components/switch/index.vue +4 -3
- package/dist/components/switch-item/index.vue +1 -1
- package/dist/components/tabs/index.d.vue.ts +12 -0
- package/dist/components/tabs/index.vue +270 -0
- package/dist/components/tabs/types.d.ts +12 -0
- package/dist/components/tabs-item/index.d.vue.ts +4 -0
- package/dist/components/tabs-item/index.vue +16 -0
- package/dist/components/tabs-item/types.d.ts +10 -0
- package/dist/components/text/index.vue +1 -1
- package/dist/components/textarea/index.d.vue.ts +2 -2
- package/dist/components/textarea/index.vue +1 -1
- package/dist/components/time-picker/index.d.vue.ts +3 -5
- package/dist/components/time-picker/index.vue +53 -45
- package/dist/components/time-picker/types.d.ts +1 -2
- package/dist/components/toggle/index.d.vue.ts +0 -2
- package/dist/components/toggle/index.vue +6 -6
- package/dist/components/toggle-button/index.vue +8 -6
- package/dist/components/tooltip/index.d.vue.ts +1 -1
- package/dist/components/tooltip/index.vue +19 -11
- package/dist/components/tooltip/types.d.ts +2 -2
- package/dist/components/virtual-list/index.d.vue.ts +8 -8
- package/dist/components/virtual-list/index.vue +27 -5
- package/dist/components/virtual-list/types.d.ts +3 -0
- package/dist/composables/index.d.ts +4 -1
- package/dist/composables/index.js +4 -1
- package/dist/composables/use-browser-observer.js +2 -2
- package/dist/composables/use-client-online.js +2 -2
- package/dist/composables/use-color-scheme.js +2 -2
- package/dist/composables/use-countdown.js +3 -2
- package/dist/composables/use-deferred-value.js +2 -2
- package/dist/composables/use-delay-destroy.js +11 -6
- package/dist/composables/use-document-hidden.js +2 -2
- package/dist/composables/use-focus-trap.js +2 -2
- package/dist/composables/use-list-filter.d.ts +11 -0
- package/dist/composables/use-list-filter.js +56 -0
- package/dist/composables/use-list-navigation.d.ts +27 -0
- package/dist/composables/use-list-navigation.js +159 -0
- package/dist/composables/use-lock-scroll.js +12 -12
- package/dist/composables/use-media-query.js +2 -2
- package/dist/composables/use-outside-click.d.ts +1 -1
- package/dist/composables/use-outside-click.js +8 -11
- package/dist/composables/use-overlay-manager.d.ts +18 -0
- package/dist/composables/use-overlay-manager.js +80 -0
- package/dist/composables/use-popover-responsive.d.ts +6 -8
- package/dist/composables/use-popover-responsive.js +9 -12
- package/dist/composables/use-repeat-action.js +2 -2
- package/dist/composables/use-swipe-gesture.d.ts +65 -0
- package/dist/composables/use-swipe-gesture.js +99 -0
- package/dist/composables/use-virtual-list.d.ts +5 -3
- package/dist/composables/use-virtual-list.js +25 -14
- package/dist/composables/use-window-size.js +2 -2
- package/dist/constants/size.d.ts +12 -0
- package/dist/constants/size.js +12 -0
- package/dist/contexts/button.d.ts +5 -0
- package/dist/contexts/button.js +5 -0
- package/dist/contexts/carousel.d.ts +2 -1
- package/dist/contexts/list.d.ts +23 -3
- package/dist/contexts/list.js +6 -2
- package/dist/contexts/resizable.d.ts +3 -11
- package/dist/contexts/tabs.d.ts +15 -0
- package/dist/contexts/tabs.js +2 -0
- package/dist/locales/en-us.d.ts +4 -4
- package/dist/locales/en-us.js +4 -4
- package/dist/locales/zh-cn.d.ts +4 -4
- package/dist/locales/zh-cn.js +4 -4
- package/dist/plugins/dayjs-millisecond-token.js +1 -1
- package/dist/styles/source.css +133 -128
- package/dist/styles/styles.css +2 -2
- package/dist/styles/tw.css +133 -128
- package/dist/types/shared/props.d.ts +1 -0
- package/dist/types/shared/utils.d.ts +1 -4
- package/dist/utils/date.d.ts +3 -3
- package/dist/utils/dom.d.ts +1 -0
- package/dist/utils/dom.js +4 -0
- package/dist/utils/event.d.ts +2 -1
- package/dist/utils/event.js +7 -1
- package/dist/utils/format.d.ts +3 -3
- package/dist/utils/format.js +5 -4
- package/dist/utils/fuzzy-search.d.ts +7 -0
- package/dist/utils/fuzzy-search.js +61 -0
- package/dist/utils/get.d.ts +2 -0
- package/dist/utils/get.js +15 -1
- package/dist/utils/index.d.ts +10 -11
- package/dist/utils/index.js +2 -3
- package/dist/utils/ref.d.ts +2 -2
- package/dist/utils/{throttle.d.ts → timing.d.ts} +1 -0
- package/dist/utils/{throttle.js → timing.js} +4 -2
- package/package.json +40 -37
- package/volar.d.ts +7 -0
- package/dist/components/overlay/overlay-stack.d.ts +0 -3
- package/dist/components/overlay/overlay-stack.js +0 -17
- package/dist/composables/use-pointer-gesture.d.ts +0 -180
- package/dist/composables/use-pointer-gesture.js +0 -406
- package/dist/utils/debounce.d.ts +0 -1
- package/dist/utils/debounce.js +0 -1
- package/dist/utils/regexp.d.ts +0 -8
- package/dist/utils/regexp.js +0 -8
- package/dist/utils/responsive.d.ts +0 -3
- package/dist/utils/responsive.js +0 -14
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
+
import { prepareWithSegments, layoutWithLines } from "@chenglou/pretext";
|
|
3
|
+
import { prepareRichInline, measureRichInlineStats } from "@chenglou/pretext/rich-inline";
|
|
2
4
|
import { twMerge } from "tailwind-merge";
|
|
3
5
|
import { shallowRef, computed, nextTick, watch } from "vue";
|
|
4
6
|
import { useResizeObserver } from "../../composables/use-browser-observer";
|
|
@@ -16,15 +18,16 @@ const props = defineProps({
|
|
|
16
18
|
position: { type: String, required: false, default: "end" },
|
|
17
19
|
moreText: { type: String, required: false, default: "Expand" },
|
|
18
20
|
lessText: { type: String, required: false, default: "Collapse" },
|
|
19
|
-
|
|
21
|
+
moreActionClass: { type: String, required: false },
|
|
22
|
+
lessActionClass: { type: String, required: false }
|
|
20
23
|
});
|
|
21
24
|
const emits = defineEmits(["toggle"]);
|
|
22
25
|
const isExpanded = shallowRef(false);
|
|
23
|
-
const
|
|
26
|
+
const isOverflow = shallowRef(false);
|
|
24
27
|
const ellipsisText = shallowRef(props.text);
|
|
25
|
-
const containerRef = shallowRef();
|
|
26
28
|
const textRef = shallowRef();
|
|
27
29
|
const actionRef = shallowRef();
|
|
30
|
+
const containerRef = shallowRef();
|
|
28
31
|
const maxRows = computed(() => {
|
|
29
32
|
const rows = Number(props.rows ?? 1);
|
|
30
33
|
return Number.isFinite(rows) && rows > 0 ? Math.floor(rows) : 1;
|
|
@@ -32,7 +35,7 @@ const maxRows = computed(() => {
|
|
|
32
35
|
const computedActionClass = computed(() => {
|
|
33
36
|
return twMerge(
|
|
34
37
|
"pxd-ellipsis-text--action cursor-pointer whitespace-nowrap text-blue-900",
|
|
35
|
-
props.
|
|
38
|
+
isExpanded.value ? props.lessActionClass : props.moreActionClass
|
|
36
39
|
);
|
|
37
40
|
});
|
|
38
41
|
const displayText = computed(() => {
|
|
@@ -55,18 +58,6 @@ function toggleAction() {
|
|
|
55
58
|
emits("toggle", isExpanded.value);
|
|
56
59
|
updateEllipsis();
|
|
57
60
|
}
|
|
58
|
-
const TEXT_STYLE_KEYS = [
|
|
59
|
-
"fontFamily",
|
|
60
|
-
"fontSize",
|
|
61
|
-
"fontWeight",
|
|
62
|
-
"fontStyle",
|
|
63
|
-
"fontVariant",
|
|
64
|
-
"letterSpacing",
|
|
65
|
-
"lineHeight",
|
|
66
|
-
"textTransform",
|
|
67
|
-
"textRendering",
|
|
68
|
-
"wordSpacing"
|
|
69
|
-
];
|
|
70
61
|
function parseSize(value) {
|
|
71
62
|
const parsed = Number.parseFloat(value);
|
|
72
63
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
@@ -83,74 +74,39 @@ function getLineHeightPx(style) {
|
|
|
83
74
|
}
|
|
84
75
|
return parsed;
|
|
85
76
|
}
|
|
86
|
-
function
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
77
|
+
function getFontShorthand(style) {
|
|
78
|
+
const fontStyle = style.fontStyle || "normal";
|
|
79
|
+
const fontWeight = style.fontWeight || "400";
|
|
80
|
+
const fontSize = style.fontSize || "16px";
|
|
81
|
+
const fontFamily = style.fontFamily || "sans-serif";
|
|
82
|
+
return `${fontStyle} ${fontWeight} ${fontSize} ${fontFamily}`;
|
|
83
|
+
}
|
|
84
|
+
function getAvailableWidth(container) {
|
|
85
|
+
const containerStyle = getStyle(container);
|
|
86
|
+
const paddingLeft = parseSize(containerStyle.paddingLeft);
|
|
87
|
+
const paddingRight = parseSize(containerStyle.paddingRight);
|
|
88
|
+
return Math.max(0, container.clientWidth - paddingLeft - paddingRight);
|
|
89
|
+
}
|
|
90
|
+
function measureLineCount(text, textFont, maxWidth, actionText, actionFont) {
|
|
91
|
+
const items = [{ text, font: textFont }];
|
|
92
|
+
if (actionText) {
|
|
93
|
+
items.push({ text: actionText, font: actionFont || textFont, break: "never" });
|
|
94
|
+
}
|
|
95
|
+
return measureRichInlineStats(prepareRichInline(items), maxWidth).lineCount;
|
|
96
|
+
}
|
|
97
|
+
function joinChars(chars, start, end) {
|
|
98
|
+
return chars.slice(start, end).join("");
|
|
96
99
|
}
|
|
97
100
|
function buildCandidate(chars, keep, dots, position) {
|
|
98
101
|
if (keep <= 0) {
|
|
99
102
|
return dots;
|
|
100
103
|
}
|
|
101
104
|
if (position === "start") {
|
|
102
|
-
return `${dots}${
|
|
105
|
+
return `${dots}${joinChars(chars, chars.length - keep, chars.length)}`;
|
|
103
106
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const head = chars.slice(0, headLen).join("");
|
|
108
|
-
const tail = chars.slice(chars.length - tailLen).join("");
|
|
109
|
-
return `${head}${dots}${tail}`;
|
|
110
|
-
}
|
|
111
|
-
return `${chars.slice(0, keep).join("")}${dots}`;
|
|
112
|
-
}
|
|
113
|
-
function createMeasureElements(parent) {
|
|
114
|
-
const mc = document.createElement("span");
|
|
115
|
-
const mt = document.createElement("span");
|
|
116
|
-
const ma = document.createElement("span");
|
|
117
|
-
mc.append(mt, ma);
|
|
118
|
-
mc.style.position = "absolute";
|
|
119
|
-
mc.style.visibility = "hidden";
|
|
120
|
-
mc.style.pointerEvents = "none";
|
|
121
|
-
mc.style.zIndex = "-1";
|
|
122
|
-
mc.style.left = "0";
|
|
123
|
-
mc.style.top = "0";
|
|
124
|
-
mc.style.overflow = "visible";
|
|
125
|
-
mc.style.whiteSpace = "pre-wrap";
|
|
126
|
-
mc.style.wordBreak = "break-word";
|
|
127
|
-
mc.style.display = "block";
|
|
128
|
-
mc.style.boxSizing = "border-box";
|
|
129
|
-
parent.appendChild(mc);
|
|
130
|
-
return { container: mc, text: mt, action: ma };
|
|
131
|
-
}
|
|
132
|
-
function syncMeasureStyles(elements, container, textEl, actionEl) {
|
|
133
|
-
const containerStyle = getStyle(container);
|
|
134
|
-
const paddingLeft = parseSize(containerStyle.paddingLeft);
|
|
135
|
-
const paddingRight = parseSize(containerStyle.paddingRight);
|
|
136
|
-
const availableWidth = Math.max(0, container.clientWidth - paddingLeft - paddingRight);
|
|
137
|
-
elements.container.style.width = `${availableWidth}px`;
|
|
138
|
-
const textStyle = getStyle(textEl ?? container);
|
|
139
|
-
applyTextStyles(textStyle, elements.text);
|
|
140
|
-
const actionStyle = actionEl ? getStyle(actionEl) : textStyle;
|
|
141
|
-
applyTextStyles(actionStyle, elements.action);
|
|
142
|
-
}
|
|
143
|
-
function fits(elements, text, actionText, maxHeight) {
|
|
144
|
-
elements.text.textContent = text;
|
|
145
|
-
if (actionText) {
|
|
146
|
-
elements.action.textContent = actionText;
|
|
147
|
-
elements.action.style.display = "inline";
|
|
148
|
-
} else {
|
|
149
|
-
elements.action.textContent = "";
|
|
150
|
-
elements.action.style.display = "none";
|
|
151
|
-
}
|
|
152
|
-
const height = elements.container.getBoundingClientRect().height;
|
|
153
|
-
return height <= maxHeight + 0.5;
|
|
107
|
+
const headLen = Math.ceil(keep / 2);
|
|
108
|
+
const tailLen = keep - headLen;
|
|
109
|
+
return `${joinChars(chars, 0, headLen)}${dots}${joinChars(chars, chars.length - tailLen, chars.length)}`;
|
|
154
110
|
}
|
|
155
111
|
async function updateEllipsis() {
|
|
156
112
|
if (isServer()) {
|
|
@@ -164,7 +120,7 @@ async function updateEllipsis() {
|
|
|
164
120
|
const sourceText = props.text ?? "";
|
|
165
121
|
if (container.clientWidth <= 0) {
|
|
166
122
|
ellipsisText.value = sourceText;
|
|
167
|
-
|
|
123
|
+
isOverflow.value = false;
|
|
168
124
|
return;
|
|
169
125
|
}
|
|
170
126
|
if (isExpanded.value || !sourceText) {
|
|
@@ -173,41 +129,58 @@ async function updateEllipsis() {
|
|
|
173
129
|
}
|
|
174
130
|
const style = getStyle(textRef.value ?? container);
|
|
175
131
|
const lineHeight = getLineHeightPx(style);
|
|
176
|
-
|
|
177
|
-
if (maxHeight <= 0) {
|
|
132
|
+
if (lineHeight <= 0) {
|
|
178
133
|
ellipsisText.value = sourceText;
|
|
179
|
-
|
|
134
|
+
isOverflow.value = false;
|
|
180
135
|
return;
|
|
181
136
|
}
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
137
|
+
const availableWidth = getAvailableWidth(container);
|
|
138
|
+
const textFont = getFontShorthand(style);
|
|
139
|
+
if (measureLineCount(sourceText, textFont, availableWidth) <= maxRows.value) {
|
|
140
|
+
ellipsisText.value = sourceText;
|
|
141
|
+
isOverflow.value = false;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
isOverflow.value = true;
|
|
145
|
+
const actionText = props.action ? props.moreText : "";
|
|
146
|
+
const actionFont = actionRef.value ? getFontShorthand(getStyle(actionRef.value)) : textFont;
|
|
147
|
+
const dots = props.dots ?? "";
|
|
148
|
+
if (props.position === "end") {
|
|
149
|
+
const prepared = prepareWithSegments(sourceText, textFont);
|
|
150
|
+
const { lines } = layoutWithLines(prepared, availableWidth, lineHeight);
|
|
151
|
+
const baseText = lines.slice(0, maxRows.value).map((l) => l.text).join("");
|
|
152
|
+
const baseChars = [...baseText];
|
|
153
|
+
let low2 = 0;
|
|
154
|
+
let high2 = baseChars.length;
|
|
155
|
+
let best2 = "";
|
|
156
|
+
while (low2 <= high2) {
|
|
157
|
+
const mid = Math.floor((low2 + high2) / 2);
|
|
158
|
+
const candidate = `${joinChars(baseChars, 0, mid)}${dots}`;
|
|
159
|
+
if (measureLineCount(candidate, textFont, availableWidth, actionText, actionFont) <= maxRows.value) {
|
|
160
|
+
best2 = candidate;
|
|
161
|
+
low2 = mid + 1;
|
|
203
162
|
} else {
|
|
204
|
-
|
|
163
|
+
high2 = mid - 1;
|
|
205
164
|
}
|
|
206
165
|
}
|
|
207
|
-
ellipsisText.value =
|
|
208
|
-
|
|
209
|
-
|
|
166
|
+
ellipsisText.value = best2 || dots;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const chars = [...sourceText];
|
|
170
|
+
let low = 0;
|
|
171
|
+
let high = chars.length;
|
|
172
|
+
let best = "";
|
|
173
|
+
while (low <= high) {
|
|
174
|
+
const mid = Math.floor((low + high) / 2);
|
|
175
|
+
const candidate = buildCandidate(chars, mid, dots, props.position);
|
|
176
|
+
if (measureLineCount(candidate, textFont, availableWidth, actionText, actionFont) <= maxRows.value) {
|
|
177
|
+
best = candidate;
|
|
178
|
+
low = mid + 1;
|
|
179
|
+
} else {
|
|
180
|
+
high = mid - 1;
|
|
181
|
+
}
|
|
210
182
|
}
|
|
183
|
+
ellipsisText.value = best || dots;
|
|
211
184
|
}
|
|
212
185
|
watch(
|
|
213
186
|
() => props,
|
|
@@ -224,6 +197,10 @@ watch(
|
|
|
224
197
|
}
|
|
225
198
|
);
|
|
226
199
|
useResizeObserver(containerRef, updateEllipsis);
|
|
200
|
+
defineExpose({
|
|
201
|
+
isExpanded,
|
|
202
|
+
isOverflow
|
|
203
|
+
});
|
|
227
204
|
</script>
|
|
228
205
|
|
|
229
206
|
<template>
|
|
@@ -231,7 +208,7 @@ useResizeObserver(containerRef, updateEllipsis);
|
|
|
231
208
|
<span ref="textRef" class="pxd-ellipsis-text--text">{{ displayText.content }}</span>
|
|
232
209
|
|
|
233
210
|
<span
|
|
234
|
-
v-if="action && (
|
|
211
|
+
v-if="action && (isOverflow || isExpanded)"
|
|
235
212
|
ref="actionRef"
|
|
236
213
|
:class="computedActionClass"
|
|
237
214
|
@click="toggleAction"
|
|
@@ -4,7 +4,7 @@ import { useResizeObserver } from "../../composables/use-browser-observer";
|
|
|
4
4
|
import { cachedOff, cachedOn } from "../../utils/event";
|
|
5
5
|
import { getCssUnitValue } from "../../utils/format";
|
|
6
6
|
import { unrefElement } from "../../utils/ref";
|
|
7
|
-
import { throttleByRaf } from "../../utils/
|
|
7
|
+
import { throttleByRaf } from "../../utils/timing";
|
|
8
8
|
defineOptions({
|
|
9
9
|
name: "PFader",
|
|
10
10
|
inheritAttrs: false
|
|
@@ -95,12 +95,8 @@ onBeforeUnmount(() => {
|
|
|
95
95
|
content: '';
|
|
96
96
|
position: absolute;
|
|
97
97
|
border-radius: inherit;
|
|
98
|
-
background: linear-gradient(var(--dir), transparent, var(--fader-color
|
|
99
|
-
mask-image: linear-gradient(
|
|
100
|
-
var(--dir-revert),
|
|
101
|
-
var(--fader-color, var(--color-gray-100)) 50%,
|
|
102
|
-
transparent
|
|
103
|
-
);
|
|
98
|
+
background: linear-gradient(var(--dir), transparent, var(--fader-color));
|
|
99
|
+
mask-image: linear-gradient(var(--dir-revert), var(--fader-color) 50%, transparent);
|
|
104
100
|
transition-property: opacity;
|
|
105
101
|
opacity: 0;
|
|
106
102
|
}
|
|
@@ -116,7 +112,7 @@ onBeforeUnmount(() => {
|
|
|
116
112
|
&::before,
|
|
117
113
|
&::after {
|
|
118
114
|
top: 0;
|
|
119
|
-
width: var(--fader-size
|
|
115
|
+
width: var(--fader-size);
|
|
120
116
|
height: 100%;
|
|
121
117
|
}
|
|
122
118
|
|
|
@@ -138,7 +134,7 @@ onBeforeUnmount(() => {
|
|
|
138
134
|
&::after {
|
|
139
135
|
left: 0;
|
|
140
136
|
width: 100%;
|
|
141
|
-
height: var(--fader-size
|
|
137
|
+
height: var(--fader-size);
|
|
142
138
|
}
|
|
143
139
|
|
|
144
140
|
&::before {
|
|
@@ -27,6 +27,7 @@ const SIZES = {
|
|
|
27
27
|
const PROGRESS_BAR_GAP = 5;
|
|
28
28
|
const MIN_VISIBLE_TRACK = PROGRESS_BAR_GAP * 2;
|
|
29
29
|
const RADIUS = 42;
|
|
30
|
+
const STROKE_WIDTH = 10;
|
|
30
31
|
const CIRCUMFERENCE = 2 * Math.PI * RADIUS;
|
|
31
32
|
const GAP_LENGTH = PROGRESS_BAR_GAP / 100 * CIRCUMFERENCE;
|
|
32
33
|
const defaultColors = {
|
|
@@ -47,8 +48,8 @@ const progressArc = computed(() => {
|
|
|
47
48
|
return progress.value / 100 * CIRCUMFERENCE;
|
|
48
49
|
}
|
|
49
50
|
const baseArc = progress.value / 100 * CIRCUMFERENCE;
|
|
50
|
-
const
|
|
51
|
-
return Math.max(0, baseArc -
|
|
51
|
+
const roundCapTrim = STROKE_WIDTH;
|
|
52
|
+
return Math.max(0, baseArc - roundCapTrim);
|
|
52
53
|
});
|
|
53
54
|
const progressStatus = computed(() => {
|
|
54
55
|
const _progress = progress.value;
|
|
@@ -106,38 +107,42 @@ const progressColors = computed(() => {
|
|
|
106
107
|
v-bind="$attrs"
|
|
107
108
|
>
|
|
108
109
|
<svg
|
|
109
|
-
class="pxd-gauge--svg block size-(--gauge-size)
|
|
110
|
+
class="pxd-gauge--svg block size-(--gauge-size) overflow-visible"
|
|
110
111
|
aria-hidden="true"
|
|
111
112
|
fill="none"
|
|
112
113
|
viewBox="0 0 100 100"
|
|
113
114
|
>
|
|
114
|
-
<
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
115
|
+
<g transform="rotate(-83 50 50)">
|
|
116
|
+
<circle
|
|
117
|
+
v-if="shouldShowTrack"
|
|
118
|
+
cx="50"
|
|
119
|
+
cy="50"
|
|
120
|
+
fill="none"
|
|
121
|
+
:r="RADIUS"
|
|
122
|
+
:stroke-width="STROKE_WIDTH"
|
|
123
|
+
stroke-linecap="round"
|
|
124
|
+
:stroke-dashoffset="trackOffset"
|
|
125
|
+
:stroke="progressColors.secondary"
|
|
126
|
+
class="pxd-gauge--track motion-safe:transition-appearance"
|
|
127
|
+
:stroke-dasharray="
|
|
128
|
+
progressStatus.hasProgress ? `${trackArc} ${CIRCUMFERENCE}` : void 0
|
|
129
|
+
"
|
|
130
|
+
/>
|
|
127
131
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
132
|
+
<circle
|
|
133
|
+
v-if="progressStatus.hasProgress || progressStatus.isComplete"
|
|
134
|
+
cx="50"
|
|
135
|
+
cy="50"
|
|
136
|
+
fill="none"
|
|
137
|
+
:r="RADIUS"
|
|
138
|
+
:stroke-width="STROKE_WIDTH"
|
|
139
|
+
stroke-dashoffset="0"
|
|
140
|
+
stroke-linecap="round"
|
|
141
|
+
:stroke="progressColors.primary"
|
|
142
|
+
class="pxd-gauge--bar motion-safe:transition-appearance"
|
|
143
|
+
:stroke-dasharray="`${progressArc} ${CIRCUMFERENCE}`"
|
|
144
|
+
/>
|
|
145
|
+
</g>
|
|
141
146
|
</svg>
|
|
142
147
|
|
|
143
148
|
<div
|
|
@@ -8,22 +8,20 @@ type __VLS_Slots = {} & {
|
|
|
8
8
|
suffix?: (props: typeof __VLS_18) => any;
|
|
9
9
|
};
|
|
10
10
|
declare const __VLS_base: import("vue").DefineComponent<HoldButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
-
|
|
12
|
-
pointerup: (args_0: PointerEvent) => any;
|
|
13
|
-
finished: (args_0: boolean) => any;
|
|
11
|
+
cancel: () => any;
|
|
14
12
|
confirm: () => any;
|
|
15
|
-
|
|
13
|
+
release: (confirmed: boolean) => any;
|
|
14
|
+
pointerup: (args_0: PointerEvent) => any;
|
|
15
|
+
pointerdown: (args_0: PointerEvent) => any;
|
|
16
16
|
}, string, import("vue").PublicProps, Readonly<HoldButtonProps> & Readonly<{
|
|
17
|
-
|
|
18
|
-
onPointerup?: ((args_0: PointerEvent) => any) | undefined;
|
|
19
|
-
onFinished?: ((args_0: boolean) => any) | undefined;
|
|
17
|
+
onCancel?: (() => any) | undefined;
|
|
20
18
|
onConfirm?: (() => any) | undefined;
|
|
21
|
-
|
|
19
|
+
onRelease?: ((confirmed: boolean) => any) | undefined;
|
|
20
|
+
onPointerup?: ((args_0: PointerEvent) => any) | undefined;
|
|
21
|
+
onPointerdown?: ((args_0: PointerEvent) => any) | undefined;
|
|
22
22
|
}>, {
|
|
23
|
-
durations: number | string;
|
|
24
23
|
vibrate: boolean;
|
|
25
24
|
scalable: boolean;
|
|
26
|
-
maskColor: string;
|
|
27
25
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
28
26
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
29
27
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,51 +1,44 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, onBeforeUnmount, shallowRef } from "vue";
|
|
2
|
+
import { computed, onBeforeUnmount, shallowRef, useAttrs } from "vue";
|
|
3
3
|
import { getStyle } from "../../utils/dom";
|
|
4
4
|
import { off, once } from "../../utils/event";
|
|
5
5
|
import PButton from "../button/index.vue";
|
|
6
6
|
defineOptions({
|
|
7
|
-
name: "PHoldButton"
|
|
7
|
+
name: "PHoldButton",
|
|
8
|
+
inheritAttrs: false
|
|
8
9
|
});
|
|
9
10
|
const props = defineProps({
|
|
10
11
|
vibrate: { type: Boolean, required: false, default: true },
|
|
12
|
+
disabled: { type: Boolean, required: false },
|
|
11
13
|
scalable: { type: Boolean, required: false, default: true },
|
|
12
|
-
durations: { type: [Number, String], required: false
|
|
13
|
-
maskColor: { type: String, required: false, default: "var(--color-gray-alpha-600)" },
|
|
14
|
+
durations: { type: [Number, String], required: false },
|
|
14
15
|
cancelable: { type: Boolean, required: false },
|
|
15
|
-
|
|
16
|
-
size: { type: String, required: false },
|
|
17
|
-
shape: { type: String, required: false },
|
|
18
|
-
align: { type: String, required: false },
|
|
19
|
-
icon: { type: Boolean, required: false },
|
|
20
|
-
loading: { type: Boolean, required: false },
|
|
21
|
-
disabled: { type: Boolean, required: false },
|
|
22
|
-
fullWidth: { type: Boolean, required: false }
|
|
16
|
+
progressColor: { type: String, required: false }
|
|
23
17
|
});
|
|
24
|
-
const emits = defineEmits(["
|
|
18
|
+
const emits = defineEmits(["cancel", "confirm", "release", "pointerup", "pointerdown"]);
|
|
19
|
+
const attrs = useAttrs();
|
|
25
20
|
const status = shallowRef("idle");
|
|
26
21
|
const computedAttrs = computed(() => {
|
|
27
|
-
const { scalable, durations, maskColor, cancelable, ...rest } = props;
|
|
28
22
|
return {
|
|
29
23
|
class: [
|
|
30
|
-
"pxd-hold-button relative motion-safe:transition-
|
|
24
|
+
"pxd-hold-button relative motion-safe:transition-appearance",
|
|
31
25
|
{
|
|
32
|
-
scalable,
|
|
26
|
+
scalable: props.scalable,
|
|
33
27
|
effective: status.value !== "canceled"
|
|
34
28
|
}
|
|
35
29
|
],
|
|
36
|
-
...
|
|
30
|
+
...attrs
|
|
37
31
|
};
|
|
38
32
|
});
|
|
39
33
|
const computedStyle = computed(() => {
|
|
40
|
-
const { durations,
|
|
34
|
+
const { durations, progressColor } = props;
|
|
41
35
|
let _durations = Number(durations);
|
|
42
36
|
if (Number.isNaN(_durations) || _durations < 0) {
|
|
43
|
-
console.warn("Invalid durations value provided to PHoldButton, defaulting to 2000");
|
|
44
37
|
_durations = 2e3;
|
|
45
38
|
}
|
|
46
39
|
return {
|
|
47
40
|
"--hold-button-durations": `${_durations}ms`,
|
|
48
|
-
"--hold-button-
|
|
41
|
+
"--hold-button-progress-color": progressColor
|
|
49
42
|
};
|
|
50
43
|
});
|
|
51
44
|
function onTriggerVibrate() {
|
|
@@ -75,7 +68,7 @@ function onPointerLeave(e) {
|
|
|
75
68
|
}
|
|
76
69
|
if (status.value === "loading" || status.value === "confirmed") {
|
|
77
70
|
status.value = "canceled";
|
|
78
|
-
emits("
|
|
71
|
+
emits("cancel");
|
|
79
72
|
}
|
|
80
73
|
}
|
|
81
74
|
function onPointerDown(event) {
|
|
@@ -93,7 +86,7 @@ function onPointerUp(event) {
|
|
|
93
86
|
}
|
|
94
87
|
const isConfirmed = status.value === "confirmed";
|
|
95
88
|
status.value = "idle";
|
|
96
|
-
emits("
|
|
89
|
+
emits("release", isConfirmed);
|
|
97
90
|
emits("pointerup", event);
|
|
98
91
|
onTriggerVibrate();
|
|
99
92
|
cleanPointerReleaseEvents();
|
|
@@ -139,8 +132,8 @@ onBeforeUnmount(() => {
|
|
|
139
132
|
<template #suffix>
|
|
140
133
|
<slot name="suffix" />
|
|
141
134
|
<div
|
|
142
|
-
class="pxd-hold-button--overlay pointer-events-none absolute -inset-px rounded-inherit bg-(--hold-button-
|
|
143
|
-
:class="{
|
|
135
|
+
class="pxd-hold-button--overlay pointer-events-none absolute -inset-px rounded-inherit bg-(--hold-button-progress-color) default-transition-timing-function!"
|
|
136
|
+
:class="{ confirmed: status === 'confirmed' }"
|
|
144
137
|
:style="computedStyle"
|
|
145
138
|
@transitionend="onTransitionEnd"
|
|
146
139
|
/>
|
|
@@ -154,10 +147,8 @@ onBeforeUnmount(() => {
|
|
|
154
147
|
transform: scale(0.97);
|
|
155
148
|
}
|
|
156
149
|
|
|
157
|
-
&:hover {
|
|
158
|
-
|
|
159
|
-
will-change: clip-path;
|
|
160
|
-
}
|
|
150
|
+
&:hover .pxd-hold-button--overlay {
|
|
151
|
+
will-change: clip-path;
|
|
161
152
|
}
|
|
162
153
|
|
|
163
154
|
.pxd-hold-button--overlay {
|
|
@@ -168,7 +159,7 @@ onBeforeUnmount(() => {
|
|
|
168
159
|
clip-path 0.1s,
|
|
169
160
|
opacity 0s;
|
|
170
161
|
|
|
171
|
-
&.
|
|
162
|
+
&.confirmed {
|
|
172
163
|
--opacity: 0.68;
|
|
173
164
|
}
|
|
174
165
|
}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import type { ButtonProps } from '../button/types'
|
|
2
|
-
|
|
3
1
|
export type HoldButtonStatus = 'idle' | 'loading' | 'canceled' | 'confirmed'
|
|
4
2
|
|
|
5
|
-
export interface HoldButtonProps
|
|
3
|
+
export interface HoldButtonProps {
|
|
6
4
|
vibrate?: boolean
|
|
5
|
+
disabled?: boolean
|
|
7
6
|
scalable?: boolean
|
|
8
7
|
durations?: number | string
|
|
9
|
-
maskColor?: string
|
|
10
8
|
cancelable?: boolean
|
|
9
|
+
progressColor?: string
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
export interface HoldButtonEmits {
|
|
13
|
+
cancel: []
|
|
14
14
|
confirm: []
|
|
15
|
-
|
|
16
|
-
finished: [boolean]
|
|
15
|
+
release: [confirmed: boolean]
|
|
17
16
|
pointerup: [PointerEvent]
|
|
18
17
|
pointerdown: [PointerEvent]
|
|
19
18
|
}
|
|
@@ -5,7 +5,9 @@ export { default as Backtop } from './backtop/index.vue';
|
|
|
5
5
|
export { default as Badge } from './badge/index.vue';
|
|
6
6
|
export { default as Book } from './book/index.vue';
|
|
7
7
|
export { default as Browser } from './browser/index.vue';
|
|
8
|
+
export { default as Bubble } from './bubble/index.vue';
|
|
8
9
|
export { default as Button } from './button/index.vue';
|
|
10
|
+
export { default as ButtonGroup } from './button-group/index.vue';
|
|
9
11
|
export { default as Carousel } from './carousel/index.vue';
|
|
10
12
|
export { default as CarouselItem } from './carousel-item/index.vue';
|
|
11
13
|
export { default as Checkbox } from './checkbox/index.vue';
|
|
@@ -15,6 +17,7 @@ export { default as Choicebox } from './choicebox/index.vue';
|
|
|
15
17
|
export { default as ChoiceboxItem } from './choicebox-item/index.vue';
|
|
16
18
|
export { default as Collapse } from './collapse/index.vue';
|
|
17
19
|
export { default as CollapseGroup } from './collapse-group/index.vue';
|
|
20
|
+
export { default as ColorSelector } from './color-selector/index.vue';
|
|
18
21
|
export { default as CommandMenu } from './command-menu/index.vue';
|
|
19
22
|
export { default as CommandMenuGroup } from './command-menu-group/index.vue';
|
|
20
23
|
export { default as ConfigProvider } from './config-provider/index.vue';
|
|
@@ -60,7 +63,9 @@ export { default as RadioGroup } from './radio-group/index.vue';
|
|
|
60
63
|
export { default as Resizable } from './resizable/index.vue';
|
|
61
64
|
export { default as ResizableHandle } from './resizable-handle/index.vue';
|
|
62
65
|
export { default as ResizablePanel } from './resizable-panel/index.vue';
|
|
66
|
+
export { default as ScalableText } from './scalable-text/index.vue';
|
|
63
67
|
export { default as Scrollable } from './scrollable/index.vue';
|
|
68
|
+
export { default as Separator } from './separator/index.vue';
|
|
64
69
|
export { default as Skeleton } from './skeleton/index.vue';
|
|
65
70
|
export { default as Slider } from './slider/index.vue';
|
|
66
71
|
export { default as Snippet } from './snippet/index.vue';
|
|
@@ -69,6 +74,8 @@ export { default as Stack } from './stack/index.vue';
|
|
|
69
74
|
export { default as StatusDot } from './status-dot/index.vue';
|
|
70
75
|
export { default as Switch } from './switch/index.vue';
|
|
71
76
|
export { default as SwitchItem } from './switch-item/index.vue';
|
|
77
|
+
export { default as Tabs } from './tabs/index.vue';
|
|
78
|
+
export { default as TabsItem } from './tabs-item/index.vue';
|
|
72
79
|
export { default as Teleport } from './teleport/index.vue';
|
|
73
80
|
export { default as Text } from './text/index.vue';
|
|
74
81
|
export { default as Textarea } from './textarea/index.vue';
|