@greypan/web-ui 10.2.1 → 11.1.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.
- package/README.CN.md +132 -68
- package/README.md +112 -43
- package/dist/assets/menu-portal.js.map +1 -1
- package/dist/assets/modal-surface.js.map +1 -1
- package/dist/assets/overlay-motion.js +1 -1
- package/dist/assets/overlay-motion.js.map +1 -1
- package/dist/assets/selection-control.js +1 -1
- package/dist/assets/selection-control.js.map +1 -1
- package/dist/classes/glass.js +6 -0
- package/dist/classes/glass.js.map +1 -0
- package/dist/classes/glow.js +6 -0
- package/dist/classes/glow.js.map +1 -0
- package/dist/classes/style.css +1 -0
- package/dist/components/autocomplete/index.d.ts +13 -6
- package/dist/components/autocomplete/index.js +34 -14
- package/dist/components/autocomplete/index.js.map +1 -1
- package/dist/components/autocomplete/style.js +1 -1
- package/dist/components/autocomplete/style.js.map +1 -1
- package/dist/components/avatar/index.js +2 -2
- package/dist/components/avatar/index.js.map +1 -1
- package/dist/components/avatar/style.js +1 -1
- package/dist/components/avatar/style.js.map +1 -1
- package/dist/components/back-top/index.d.ts +4 -0
- package/dist/components/back-top/index.js +60 -22
- package/dist/components/back-top/index.js.map +1 -1
- package/dist/components/back-top/style.js +1 -1
- package/dist/components/back-top/style.js.map +1 -1
- package/dist/components/badge/index.d.ts +3 -0
- package/dist/components/badge/index.js +30 -15
- package/dist/components/badge/index.js.map +1 -1
- package/dist/components/badge/style.js +1 -1
- package/dist/components/badge/style.js.map +1 -1
- package/dist/components/button/index.d.ts +4 -0
- package/dist/components/button/index.js +32 -19
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/button/style.js +1 -1
- package/dist/components/button/style.js.map +1 -1
- package/dist/components/button-group/index.d.ts +3 -0
- package/dist/components/button-group/index.js +15 -2
- package/dist/components/button-group/index.js.map +1 -1
- package/dist/components/button-group/style.js +1 -1
- package/dist/components/button-group/style.js.map +1 -1
- package/dist/components/checkbox/index.d.ts +1 -1
- package/dist/components/checkbox/index.js +7 -7
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox/style.js +1 -1
- package/dist/components/checkbox/style.js.map +1 -1
- package/dist/components/checkbox-group/index.js +1 -1
- package/dist/components/checkbox-group/index.js.map +1 -1
- package/dist/components/collapse/index.d.ts +8 -6
- package/dist/components/collapse/index.js +45 -25
- package/dist/components/collapse/index.js.map +1 -1
- package/dist/components/collapse/style.js +1 -1
- package/dist/components/collapse/style.js.map +1 -1
- package/dist/components/context-menu/index.d.ts +60 -60
- package/dist/components/context-menu/index.js +2 -2
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/context-menu/scrim.js.map +1 -1
- package/dist/components/context-menu/style.js.map +1 -1
- package/dist/components/dialog/index.d.ts +5 -4
- package/dist/components/dialog/index.js +6 -3
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/dialog/style.js +1 -1
- package/dist/components/dialog/style.js.map +1 -1
- package/dist/components/drawer/index.d.ts +8 -8
- package/dist/components/drawer/index.js +2 -2
- package/dist/components/drawer/index.js.map +1 -1
- package/dist/components/drawer/style.js.map +1 -1
- package/dist/components/dropdown/index.d.ts +22 -6
- package/dist/components/dropdown/index.js +147 -18
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropdown-item/index.js.map +1 -1
- package/dist/components/dropdown-item/style.js +1 -1
- package/dist/components/dropdown-item/style.js.map +1 -1
- package/dist/components/editable-text/index.d.ts +2 -2
- package/dist/components/editable-text/index.js +7 -3
- package/dist/components/editable-text/index.js.map +1 -1
- package/dist/components/editable-text/style.js +1 -1
- package/dist/components/editable-text/style.js.map +1 -1
- package/dist/components/empty/index.d.ts +3 -3
- package/dist/components/empty/index.js.map +1 -1
- package/dist/components/image-preview/index.d.ts +5 -5
- package/dist/components/image-preview/index.js +9 -9
- package/dist/components/image-preview/index.js.map +1 -1
- package/dist/components/image-preview/style.js.map +1 -1
- package/dist/components/input/index.d.ts +1 -0
- package/dist/components/input/index.js +6 -3
- package/dist/components/input/index.js.map +1 -1
- package/dist/components/input/style.js +1 -1
- package/dist/components/input/style.js.map +1 -1
- package/dist/components/input-number/index.d.ts +31 -1
- package/dist/components/input-number/index.js +281 -22
- package/dist/components/input-number/index.js.map +1 -1
- package/dist/components/input-number/style.js +1 -1
- package/dist/components/input-number/style.js.map +1 -1
- package/dist/components/layout/index.d.ts +7 -7
- package/dist/components/layout/index.js +47 -42
- package/dist/components/layout/index.js.map +1 -1
- package/dist/components/layout/style.js +1 -1
- package/dist/components/layout/style.js.map +1 -1
- package/dist/components/middle-ellipsis/index.d.ts +9 -2
- package/dist/components/middle-ellipsis/index.js +68 -10
- package/dist/components/middle-ellipsis/index.js.map +1 -1
- package/dist/components/middle-ellipsis/truncate.d.ts +1 -1
- package/dist/components/middle-ellipsis/truncate.js.map +1 -1
- package/dist/components/option/style.js +1 -1
- package/dist/components/option/style.js.map +1 -1
- package/dist/components/popover/index.d.ts +1 -1
- package/dist/components/popover/index.js +1 -1
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/popover/style.js +1 -1
- package/dist/components/popover/style.js.map +1 -1
- package/dist/components/radio/index.d.ts +6 -1
- package/dist/components/radio/index.js +34 -24
- package/dist/components/radio/index.js.map +1 -1
- package/dist/components/radio/interaction.d.ts +4 -0
- package/dist/components/radio/interaction.js +17 -0
- package/dist/components/radio/interaction.js.map +1 -0
- package/dist/components/radio/style.js +1 -1
- package/dist/components/radio/style.js.map +1 -1
- package/dist/components/radio-group/index.d.ts +23 -1
- package/dist/components/radio-group/index.js +220 -29
- package/dist/components/radio-group/index.js.map +1 -1
- package/dist/components/segmented/index.d.ts +2 -0
- package/dist/components/segmented/index.js +74 -18
- package/dist/components/segmented/index.js.map +1 -1
- package/dist/components/segmented/style.js +1 -1
- package/dist/components/segmented/style.js.map +1 -1
- package/dist/components/segmented-trigger/index.js +3 -2
- package/dist/components/segmented-trigger/index.js.map +1 -1
- package/dist/components/segmented-trigger/style.js +1 -1
- package/dist/components/segmented-trigger/style.js.map +1 -1
- package/dist/components/select/index.d.ts +8 -0
- package/dist/components/select/index.js +77 -26
- package/dist/components/select/index.js.map +1 -1
- package/dist/components/select/style.js +1 -1
- package/dist/components/select/style.js.map +1 -1
- package/dist/components/slider/index.d.ts +15 -0
- package/dist/components/slider/index.js +175 -39
- package/dist/components/slider/index.js.map +1 -1
- package/dist/components/slider/style.js +1 -1
- package/dist/components/slider/style.js.map +1 -1
- package/dist/components/spinner/index.d.ts +15 -0
- package/dist/components/spinner/index.js +79 -22
- package/dist/components/spinner/index.js.map +1 -1
- package/dist/components/spinner/style.js +1 -1
- package/dist/components/spinner/style.js.map +1 -1
- package/dist/components/svg-draw-lines/index.js +48 -12
- package/dist/components/svg-draw-lines/index.js.map +1 -1
- package/dist/components/switch/index.d.ts +11 -3
- package/dist/components/switch/index.js +58 -54
- package/dist/components/switch/index.js.map +1 -1
- package/dist/components/switch/style.js +1 -1
- package/dist/components/switch/style.js.map +1 -1
- package/dist/components/textarea/index.js +3 -3
- package/dist/components/textarea/index.js.map +1 -1
- package/dist/components/textarea/style.js +1 -1
- package/dist/components/textarea/style.js.map +1 -1
- package/dist/components/theme/index.d.ts +1 -0
- package/dist/components/theme/index.js +26 -15
- package/dist/components/theme/index.js.map +1 -1
- package/dist/components/theme/style.js +1 -1
- package/dist/components/theme/style.js.map +1 -1
- package/dist/components/toast/style.js +1 -1
- package/dist/components/toast/style.js.map +1 -1
- package/dist/components/toast/toast.js +2 -2
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/tooltip/index.d.ts +2 -1
- package/dist/components/tooltip/index.js +10 -5
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/components/tooltip/style.js.map +1 -1
- package/dist/scrollbars/index.d.ts +8 -8
- package/dist/scrollbars/index.js.map +1 -1
- package/dist/scrollbars/internal.js.map +1 -1
- package/dist/shared/element-height/index.js.map +1 -1
- package/dist/shared/focus/pointer-focus.js +12 -10
- package/dist/shared/focus/pointer-focus.js.map +1 -1
- package/dist/shared/gesture/drag-gesture.js +4 -4
- package/dist/shared/gesture/drag-gesture.js.map +1 -1
- package/dist/shared/group-management/index.js +43 -18
- package/dist/shared/group-management/index.js.map +1 -1
- package/dist/shared/label-emptiness/index.js.map +1 -1
- package/dist/shared/menu-behavior/index.js.map +1 -1
- package/dist/shared/menu-portal/menu-portal.js +1 -1
- package/dist/shared/menu-portal/menu-portal.js.map +1 -1
- package/dist/shared/menu-portal/menu-tree.js.map +1 -1
- package/dist/shared/option-portal/combobox-shell.js.map +1 -1
- package/dist/shared/option-portal/index.js.map +1 -1
- package/dist/shared/overlay/anchored-panel.js.map +1 -1
- package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
- package/dist/shared/overlay/nested-drawer-layers.js.map +1 -1
- package/dist/shared/overlay/open-overlay.js.map +1 -1
- package/dist/shared/overlay/overlay-root.js +1 -1
- package/dist/shared/overlay/overlay-root.js.map +1 -1
- package/dist/shared/overlay/overlay.js +7 -1
- package/dist/shared/overlay/overlay.js.map +1 -1
- package/dist/shared/overlay/portal.js.map +1 -1
- package/dist/shared/overlay/presence.js.map +1 -1
- package/dist/shared/scroll-lock/scroll-lock.js.map +1 -1
- package/dist/shared/theme/root-sync.js.map +1 -1
- package/package.json +5 -2
- package/dist/assets/glass.js +0 -6
- package/dist/assets/glass.js.map +0 -1
- package/dist/icons/generated/heroicons-arrow-down-16-solid.d.ts +0 -6
- package/dist/icons/generated/heroicons-arrow-up-16-solid.d.ts +0 -6
- package/dist/icons/generated/jam-volume.d.ts +0 -8
- package/dist/icons/generated/jam-watch-f.d.ts +0 -8
- package/dist/icons/generated/ooui-check.d.ts +0 -6
- package/dist/icons/generated/radix-icons-check.d.ts +0 -6
- package/dist/icons/generated/si-check-alt-fill.d.ts +0 -6
|
@@ -3,17 +3,18 @@ import "../icon/index.js";
|
|
|
3
3
|
import t from "../../icons/generated/lucide-arrow-up-to-line.js";
|
|
4
4
|
import { normalizeLiteral as n, normalizeNumber as r } from "../../shared/normalize/index.js";
|
|
5
5
|
import "../button/index.js";
|
|
6
|
-
import i from "
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
6
|
+
import { prefersReducedMotion as i } from "../../shared/theme/reduced-motion.js";
|
|
7
|
+
import a from "./style.js";
|
|
8
|
+
import { LitElement as o, html as s, nothing as c, unsafeCSS as l } from "lit";
|
|
9
|
+
import { customElement as u, property as d, state as f } from "lit/decorators.js";
|
|
10
|
+
import { getRootScrollTop as p } from "@greypan/browser-kit";
|
|
10
11
|
//#region src/components/back-top/index.ts
|
|
11
|
-
var
|
|
12
|
+
var m = class extends o {
|
|
12
13
|
constructor(...e) {
|
|
13
|
-
super(...e), this._scrollBehavior = "smooth", this.visible = !1, this.scrollTarget = window, this._threshold = 200;
|
|
14
|
+
super(...e), this._scrollBehavior = "smooth", this.visible = !1, this.scrollTarget = window, this.ariaLabel = null, this._threshold = 200, this.slottedTextObserver = new MutationObserver(() => this.requestUpdate()), this.onSlotChange = () => this.requestUpdate();
|
|
14
15
|
}
|
|
15
16
|
static {
|
|
16
|
-
this.styles =
|
|
17
|
+
this.styles = l(a);
|
|
17
18
|
}
|
|
18
19
|
get scrollBehavior() {
|
|
19
20
|
return this._scrollBehavior;
|
|
@@ -30,10 +31,13 @@ var f = class extends a {
|
|
|
30
31
|
this._threshold = r(e, 0, 1e4, 200), this.requestUpdate("threshold", t);
|
|
31
32
|
}
|
|
32
33
|
connectedCallback() {
|
|
33
|
-
super.connectedCallback(), this.
|
|
34
|
+
super.connectedCallback(), this.slottedTextObserver.observe(this, {
|
|
35
|
+
characterData: !0,
|
|
36
|
+
subtree: !0
|
|
37
|
+
}), this.computeVisible(), this.onScrollTarget();
|
|
34
38
|
}
|
|
35
39
|
disconnectedCallback() {
|
|
36
|
-
super.disconnectedCallback(), this.eventController?.abort();
|
|
40
|
+
this.slottedTextObserver.disconnect(), super.disconnectedCallback(), this.eventController?.abort();
|
|
37
41
|
}
|
|
38
42
|
willUpdate(e) {
|
|
39
43
|
super.willUpdate(e), (e.has("threshold") || e.has("scrollTarget")) && this.computeVisible(), e.has("scrollTarget") && (this.toggleAttribute("container-mode", this.target !== window), this.onScrollTarget());
|
|
@@ -51,23 +55,54 @@ var f = class extends a {
|
|
|
51
55
|
}
|
|
52
56
|
computeVisible() {
|
|
53
57
|
let e = this.target;
|
|
54
|
-
if (e === window) this.visible =
|
|
58
|
+
if (e === window) this.visible = p() >= this.threshold;
|
|
55
59
|
else if (e instanceof HTMLElement) this.visible = e.scrollTop >= this.threshold;
|
|
56
60
|
else throw Error("Prop scrollTarget must be HTMLElement or Window.");
|
|
57
61
|
}
|
|
58
62
|
toTop() {
|
|
59
|
-
this.target
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
let e = this.target;
|
|
64
|
+
if (!i(this)) {
|
|
65
|
+
e.scrollTo({
|
|
66
|
+
top: 0,
|
|
67
|
+
behavior: this.scrollBehavior
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
let t = e instanceof HTMLElement ? e : document.documentElement, n = t.style.getPropertyValue("scroll-behavior"), r = t.style.getPropertyPriority("scroll-behavior");
|
|
72
|
+
t.style.setProperty("scroll-behavior", "auto", "important");
|
|
73
|
+
try {
|
|
74
|
+
e.scrollTo({
|
|
75
|
+
top: 0,
|
|
76
|
+
behavior: "auto"
|
|
77
|
+
});
|
|
78
|
+
} finally {
|
|
79
|
+
n ? t.style.setProperty("scroll-behavior", n, r) : t.style.removeProperty("scroll-behavior");
|
|
80
|
+
}
|
|
63
81
|
}
|
|
64
82
|
onEnter(e) {
|
|
65
83
|
(e.key === "Enter" || e.key === " ") && (e.preventDefault(), this.toTop());
|
|
66
84
|
}
|
|
85
|
+
hasDefaultSlotContent() {
|
|
86
|
+
return [...this.childNodes].some((e) => {
|
|
87
|
+
if (e.nodeType === Node.ELEMENT_NODE) {
|
|
88
|
+
let t = e;
|
|
89
|
+
return !t.hasAttribute("slot") || t.getAttribute("slot") === "";
|
|
90
|
+
}
|
|
91
|
+
return e.nodeType === Node.TEXT_NODE && !!e.textContent?.trim();
|
|
92
|
+
});
|
|
93
|
+
}
|
|
67
94
|
render() {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
95
|
+
let e = this.ariaLabel?.trim() || (this.hasDefaultSlotContent() ? c : "Back to top");
|
|
96
|
+
return s`
|
|
97
|
+
<div
|
|
98
|
+
class="back-top-inner"
|
|
99
|
+
role="button"
|
|
100
|
+
aria-label=${e}
|
|
101
|
+
tabindex="0"
|
|
102
|
+
@click=${this.toTop}
|
|
103
|
+
@keydown=${this.onEnter}
|
|
104
|
+
>
|
|
105
|
+
<slot @slotchange=${this.onSlotChange}>
|
|
71
106
|
<web-ui-button variant="glass" tabindex="-1" icon>
|
|
72
107
|
<web-ui-icon .icon=${t}></web-ui-icon>
|
|
73
108
|
</web-ui-button>
|
|
@@ -76,18 +111,21 @@ var f = class extends a {
|
|
|
76
111
|
`;
|
|
77
112
|
}
|
|
78
113
|
};
|
|
79
|
-
e([
|
|
114
|
+
e([d({
|
|
80
115
|
reflect: !0,
|
|
81
116
|
attribute: "scroll-behavior",
|
|
82
117
|
useDefault: !0
|
|
83
|
-
})],
|
|
118
|
+
})], m.prototype, "scrollBehavior", null), e([d({
|
|
84
119
|
type: Boolean,
|
|
85
120
|
reflect: !0
|
|
86
|
-
})],
|
|
121
|
+
})], m.prototype, "visible", void 0), e([d({ attribute: !1 })], m.prototype, "scrollTarget", void 0), e([d({
|
|
122
|
+
type: String,
|
|
123
|
+
attribute: "aria-label"
|
|
124
|
+
})], m.prototype, "ariaLabel", void 0), e([d({
|
|
87
125
|
type: Number,
|
|
88
126
|
reflect: !0
|
|
89
|
-
})],
|
|
127
|
+
})], m.prototype, "threshold", null), e([f()], m.prototype, "eventController", void 0), m = e([u("web-ui-back-top")], m);
|
|
90
128
|
//#endregion
|
|
91
|
-
export {
|
|
129
|
+
export { m as WebUiBackTop };
|
|
92
130
|
|
|
93
131
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/back-top/index.ts"],"sourcesContent":["import '@/components/button'\nimport '@/components/icon'\n\nimport { getRootScrollTop } from '@greypan/browser-kit'\nimport { html, LitElement, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { lucideArrowUpToLine } from '@/icons'\nimport { normalizeLiteral, normalizeNumber } from '@/shared/normalize'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-back-top')\nexport class WebUiBackTop extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ reflect: true, attribute: 'scroll-behavior', useDefault: true })\n get scrollBehavior(): 'smooth' | 'auto' {\n return this._scrollBehavior\n }\n set scrollBehavior(value: string) {\n const old = this._scrollBehavior\n this._scrollBehavior = normalizeLiteral(value, ['smooth', 'auto'] as const, 'smooth')\n this.requestUpdate('scrollBehavior', old)\n }\n private _scrollBehavior: 'smooth' | 'auto' = 'smooth'\n @property({ type: Boolean, reflect: true }) visible = false\n @property({ attribute: false }) scrollTarget: HTMLElement | Window = window\n\n @property({ type: Number, reflect: true })\n get threshold(): number {\n return this._threshold\n }\n set threshold(v: number) {\n const old = this._threshold\n this._threshold = normalizeNumber(v, 0, 10000, 200)\n this.requestUpdate('threshold', old)\n }\n private _threshold = 200\n\n @state() private eventController?: AbortController\n\n override connectedCallback() {\n super.connectedCallback()\n this.computeVisible()\n this.onScrollTarget()\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this.eventController?.abort()\n }\n\n protected override willUpdate(props: PropertyValues) {\n super.willUpdate(props)\n\n if (props.has('threshold') || props.has('scrollTarget')) {\n this.computeVisible()\n }\n // 不设 hasUpdated 门控:scrollTarget 可能在首次更新完成前赋值(如框架 onMounted 中),\n // 此时 connectedCallback 已按 window 绑定,必须重绑到新容器;onScrollTarget 幂等,重复调用安全\n if (props.has('scrollTarget')) {\n // 容器模式:scrollTarget
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/back-top/index.ts"],"sourcesContent":["import '@/components/button'\nimport '@/components/icon'\n\nimport { getRootScrollTop } from '@greypan/browser-kit'\nimport { html, LitElement, nothing, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { lucideArrowUpToLine } from '@/icons'\nimport { normalizeLiteral, normalizeNumber } from '@/shared/normalize'\nimport { prefersReducedMotion } from '@/shared/theme/reduced-motion'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-back-top')\nexport class WebUiBackTop extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ reflect: true, attribute: 'scroll-behavior', useDefault: true })\n get scrollBehavior(): 'smooth' | 'auto' {\n return this._scrollBehavior\n }\n set scrollBehavior(value: string) {\n const old = this._scrollBehavior\n this._scrollBehavior = normalizeLiteral(value, ['smooth', 'auto'] as const, 'smooth')\n this.requestUpdate('scrollBehavior', old)\n }\n private _scrollBehavior: 'smooth' | 'auto' = 'smooth'\n @property({ type: Boolean, reflect: true }) visible = false\n @property({ attribute: false }) scrollTarget: HTMLElement | Window = window\n @property({ type: String, attribute: 'aria-label' }) override ariaLabel: string | null = null\n\n @property({ type: Number, reflect: true })\n get threshold(): number {\n return this._threshold\n }\n set threshold(v: number) {\n const old = this._threshold\n this._threshold = normalizeNumber(v, 0, 10000, 200)\n this.requestUpdate('threshold', old)\n }\n private _threshold = 200\n\n @state() private eventController?: AbortController\n // `slotchange` 不覆盖同一个 Text 节点的内容变化,需要同步重新计算 fallback name。\n private readonly slottedTextObserver = new MutationObserver(() => this.requestUpdate())\n private readonly onSlotChange = () => this.requestUpdate()\n\n override connectedCallback() {\n super.connectedCallback()\n this.slottedTextObserver.observe(this, { characterData: true, subtree: true })\n this.computeVisible()\n this.onScrollTarget()\n }\n\n override disconnectedCallback() {\n this.slottedTextObserver.disconnect()\n super.disconnectedCallback()\n this.eventController?.abort()\n }\n\n protected override willUpdate(props: PropertyValues) {\n super.willUpdate(props)\n\n if (props.has('threshold') || props.has('scrollTarget')) {\n this.computeVisible()\n }\n // 不设 hasUpdated 门控:scrollTarget 可能在首次更新完成前赋值(如框架 onMounted 中),\n // 此时 connectedCallback 已按 window 绑定,必须重绑到新容器;onScrollTarget 幂等,重复调用安全\n if (props.has('scrollTarget')) {\n // 容器模式:scrollTarget 为元素时 button 通过 sticky 悬浮于容器底部,而非固定视口角落\n this.toggleAttribute('container-mode', this.target !== window)\n this.onScrollTarget()\n }\n }\n\n private get target() {\n if (!this.scrollTarget) return window\n const isRoot =\n this.scrollTarget === window ||\n this.scrollTarget === document.documentElement ||\n this.scrollTarget === document.body\n return isRoot ? window : this.scrollTarget\n }\n\n private onScrollTarget() {\n this.eventController?.abort()\n this.eventController = new AbortController()\n\n this.target.addEventListener(\n 'scroll',\n () => {\n this.computeVisible()\n },\n { signal: this.eventController.signal, passive: true }\n )\n }\n\n private computeVisible() {\n const target = this.target\n if (target === window) {\n this.visible = getRootScrollTop() >= this.threshold\n } else if (target instanceof HTMLElement) {\n this.visible = target.scrollTop >= this.threshold\n } else {\n throw new Error('Prop scrollTarget must be HTMLElement or Window.')\n }\n }\n\n toTop() {\n const target = this.target\n if (!prefersReducedMotion(this)) {\n target.scrollTo({ top: 0, behavior: this.scrollBehavior })\n return\n }\n\n // `auto` 会跟随 CSS scroll-behavior,因此仅在启动减少动效的滚动时临时覆盖目标元素。\n const scrollElement = target instanceof HTMLElement ? target : document.documentElement\n const previousBehavior = scrollElement.style.getPropertyValue('scroll-behavior')\n const previousPriority = scrollElement.style.getPropertyPriority('scroll-behavior')\n scrollElement.style.setProperty('scroll-behavior', 'auto', 'important')\n try {\n target.scrollTo({ top: 0, behavior: 'auto' })\n } finally {\n if (previousBehavior) scrollElement.style.setProperty('scroll-behavior', previousBehavior, previousPriority)\n else scrollElement.style.removeProperty('scroll-behavior')\n }\n }\n\n // ARIA button 契约要求 Enter 与 Space 均能激活\n private onEnter(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n this.toTop()\n }\n }\n\n private hasDefaultSlotContent() {\n return [...this.childNodes].some(node => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element\n return !element.hasAttribute('slot') || element.getAttribute('slot') === ''\n }\n return node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())\n })\n }\n\n override render() {\n const ariaLabel = this.ariaLabel?.trim() || (this.hasDefaultSlotContent() ? nothing : 'Back to top')\n\n return html`\n <div\n class=\"back-top-inner\"\n role=\"button\"\n aria-label=${ariaLabel}\n tabindex=\"0\"\n @click=${this.toTop}\n @keydown=${this.onEnter}\n >\n <slot @slotchange=${this.onSlotChange}>\n <web-ui-button variant=\"glass\" tabindex=\"-1\" icon>\n <web-ui-icon .icon=${lucideArrowUpToLine}></web-ui-icon>\n </web-ui-button>\n </slot>\n </div>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-back-top': WebUiBackTop\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/back-top/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{display:block}:host([container-mode]){bottom:var(--wui-back-top-bottom,20px);position:sticky}.back-top-inner{pointer-events:none;position:var(--wui-back-top-position,fixed);z-index:var(--wui-back-top-z-index,var(--wui-layer-auxiliary,20));top:var(--wui-back-top-top,auto);right:var(--wui-back-top-right,20px);bottom:var(--wui-back-top-bottom,20px);left:var(--wui-back-top-left,auto);visibility:hidden;opacity:0}.back-top-inner
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{display:block}:host([container-mode]){bottom:var(--wui-back-top-bottom,20px);position:sticky}.back-top-inner{pointer-events:none;position:var(--wui-back-top-position,fixed);z-index:var(--wui-back-top-z-index,var(--wui-layer-auxiliary,20));top:var(--wui-back-top-top,auto);right:var(--wui-back-top-right,20px);bottom:var(--wui-back-top-bottom,20px);left:var(--wui-back-top-left,auto);visibility:hidden;opacity:0}.back-top-inner:focus-visible{border-radius:var(--wui-radius-control,calc(infinity * 1px));outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#0071e3) 40%, transparent));outline-offset:2px}:host([container-mode]) .back-top-inner{width:fit-content;margin-right:var(--wui-back-top-right,20px);margin-left:var(--wui-back-top-left,auto);position:static}:host([visible]) .back-top-inner{pointer-events:auto;visibility:visible;opacity:1}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/back-top/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n}\n\n/* 容器模式:scrollTarget
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/back-top/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n display: block;\n}\n\n/* 容器模式:scrollTarget 为元素时 button 悬浮于容器底部(元素需置于容器内部),\n 横向偏移沿用 --wui-back-top-left/right,纵向沿用 --wui-back-top-bottom;不使用 top */\n:host([container-mode]) {\n position: sticky;\n bottom: var(--wui-back-top-bottom, 20px);\n}\n\n.back-top-inner {\n pointer-events: none;\n\n position: var(--wui-back-top-position, fixed);\n z-index: var(--wui-back-top-z-index, var(--wui-layer-auxiliary, 20));\n top: var(--wui-back-top-top, auto);\n right: var(--wui-back-top-right, 20px);\n bottom: var(--wui-back-top-bottom, 20px);\n left: var(--wui-back-top-left, auto);\n\n visibility: hidden;\n opacity: 0;\n\n &:focus-visible {\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n outline: var(--wui-focus-ring-width, 3px) solid\n var(--wui-color-focus-ring, color-mix(in srgb, var(--wui-color-accent, #0071e3) 40%, transparent));\n outline-offset: 2px;\n }\n}\n\n:host([container-mode]) .back-top-inner {\n position: static;\n width: fit-content;\n margin-right: var(--wui-back-top-right, 20px);\n margin-left: var(--wui-back-top-left, auto);\n}\n\n:host([visible]) .back-top-inner {\n pointer-events: auto;\n visibility: visible;\n opacity: 1;\n}\n"],"mappings":""}
|
|
@@ -16,8 +16,11 @@ export declare class WebUiBadge extends LitElement {
|
|
|
16
16
|
get placement(): 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
17
17
|
private _placement;
|
|
18
18
|
private _hasContent;
|
|
19
|
+
private readonly _contentObserver;
|
|
19
20
|
private readonly _handleSlotChange;
|
|
21
|
+
private _syncHasContent;
|
|
20
22
|
connectedCallback(): void;
|
|
23
|
+
disconnectedCallback(): void;
|
|
21
24
|
render(): import('lit').TemplateResult<1>;
|
|
22
25
|
}
|
|
23
26
|
declare global {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import e from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
2
|
-
import t from "../../
|
|
2
|
+
import t from "../../classes/glass.js";
|
|
3
3
|
import { normalizeLiteral as n, normalizeNumber as r } from "../../shared/normalize/index.js";
|
|
4
4
|
import i from "./style.js";
|
|
5
5
|
import { LitElement as a, html as o, unsafeCSS as s } from "lit";
|
|
@@ -13,10 +13,15 @@ var m = [
|
|
|
13
13
|
"top-left",
|
|
14
14
|
"bottom-right",
|
|
15
15
|
"bottom-left"
|
|
16
|
-
], h = 2 ** 53 - 1
|
|
16
|
+
], h = 2 ** 53 - 1;
|
|
17
|
+
function g(e) {
|
|
18
|
+
for (let t of e) if (t.nodeType === Node.TEXT_NODE && t.textContent?.trim() || t.nodeType === Node.ELEMENT_NODE && t.slot === "") return !0;
|
|
19
|
+
return !1;
|
|
20
|
+
}
|
|
21
|
+
var _ = class extends a {
|
|
17
22
|
constructor(...e) {
|
|
18
|
-
super(...e), this._count = 0, this._max = 99, this.dot = !1, this.showZero = !1, this.badgeHidden = !1, this.offsetX = 0, this.offsetY = 0, this._placement = "top-right", this._hasContent = !1, this._handleSlotChange = () => {
|
|
19
|
-
this.
|
|
23
|
+
super(...e), this._count = 0, this._max = 99, this.dot = !1, this.showZero = !1, this.badgeHidden = !1, this.offsetX = 0, this.offsetY = 0, this._placement = "top-right", this._hasContent = !1, this._contentObserver = new MutationObserver(() => this._syncHasContent()), this._handleSlotChange = () => {
|
|
24
|
+
this._syncHasContent();
|
|
20
25
|
};
|
|
21
26
|
}
|
|
22
27
|
static {
|
|
@@ -55,11 +60,21 @@ var m = [
|
|
|
55
60
|
get placement() {
|
|
56
61
|
return this._placement;
|
|
57
62
|
}
|
|
63
|
+
_syncHasContent() {
|
|
64
|
+
let e = this.renderRoot.querySelector("slot");
|
|
65
|
+
this._hasContent = g(e?.assignedNodes() ?? this.childNodes);
|
|
66
|
+
}
|
|
58
67
|
connectedCallback() {
|
|
59
|
-
super.connectedCallback(), this.
|
|
68
|
+
super.connectedCallback(), this._syncHasContent(), this._contentObserver.observe(this, {
|
|
69
|
+
characterData: !0,
|
|
70
|
+
subtree: !0
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
disconnectedCallback() {
|
|
74
|
+
this._contentObserver.disconnect(), super.disconnectedCallback();
|
|
60
75
|
}
|
|
61
76
|
render() {
|
|
62
|
-
let e = this.badgeHidden ? !1 : this.dot ? !0 : this.count > 0 || this.showZero, t = this.dot ? "" : this.count > this.max ? `${this.max}+` : String(this.count), n = this.dot ? "
|
|
77
|
+
let e = this.badgeHidden ? !1 : this.dot ? !0 : this.count > 0 || this.showZero, t = this.dot ? "" : this.count > this.max ? `${this.max}+` : String(this.count), n = this.dot ? "Unread" : this.count > 0 ? `${this.count} unread messages` : this.showZero ? "No unread messages" : void 0, r = {
|
|
63
78
|
"badge-wrapper": !0,
|
|
64
79
|
"badge-wrapper-fixed": this._hasContent
|
|
65
80
|
}, i = {
|
|
@@ -87,33 +102,33 @@ var m = [
|
|
|
87
102
|
e([l({
|
|
88
103
|
type: Number,
|
|
89
104
|
reflect: !0
|
|
90
|
-
})],
|
|
105
|
+
})], _.prototype, "count", null), e([l({
|
|
91
106
|
type: Number,
|
|
92
107
|
reflect: !0
|
|
93
|
-
})],
|
|
108
|
+
})], _.prototype, "max", null), e([l({
|
|
94
109
|
type: Boolean,
|
|
95
110
|
reflect: !0
|
|
96
|
-
})],
|
|
111
|
+
})], _.prototype, "dot", void 0), e([l({
|
|
97
112
|
type: Boolean,
|
|
98
113
|
reflect: !0,
|
|
99
114
|
attribute: "show-zero"
|
|
100
|
-
})],
|
|
115
|
+
})], _.prototype, "showZero", void 0), e([l({
|
|
101
116
|
type: Boolean,
|
|
102
117
|
reflect: !0,
|
|
103
118
|
attribute: "badge-hidden"
|
|
104
|
-
})],
|
|
119
|
+
})], _.prototype, "badgeHidden", void 0), e([l({
|
|
105
120
|
type: Number,
|
|
106
121
|
reflect: !0,
|
|
107
122
|
attribute: "offset-x"
|
|
108
|
-
})],
|
|
123
|
+
})], _.prototype, "offsetX", void 0), e([l({
|
|
109
124
|
type: Number,
|
|
110
125
|
reflect: !0,
|
|
111
126
|
attribute: "offset-y"
|
|
112
|
-
})],
|
|
127
|
+
})], _.prototype, "offsetY", void 0), e([l({
|
|
113
128
|
type: String,
|
|
114
129
|
reflect: !0
|
|
115
|
-
})],
|
|
130
|
+
})], _.prototype, "placement", null), e([u()], _.prototype, "_hasContent", void 0), _ = e([c("web-ui-badge")], _);
|
|
116
131
|
//#endregion
|
|
117
|
-
export {
|
|
132
|
+
export { _ as WebUiBadge };
|
|
118
133
|
|
|
119
134
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/badge/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { styleMap } from 'lit/directives/style-map.js'\n\nimport glass from '@/
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/badge/index.ts"],"sourcesContent":["import { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { styleMap } from 'lit/directives/style-map.js'\n\nimport glass from '@/classes/glass.css?inline'\nimport { normalizeLiteral, normalizeNumber } from '@/shared/normalize'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_PLACEMENTS = ['top-right', 'top-left', 'bottom-right', 'bottom-left'] as const\nconst MAX_SAFE = Number.MAX_SAFE_INTEGER\n\nfunction hasDefaultSlotContent(nodes: Iterable<Node>): boolean {\n for (const node of nodes) {\n if (node.nodeType === Node.TEXT_NODE && node.textContent?.trim()) return true\n if (node.nodeType === Node.ELEMENT_NODE && (node as Element).slot === '') return true\n }\n return false\n}\n\n@customElement('web-ui-badge')\nexport class WebUiBadge extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n\n @property({ type: Number, reflect: true })\n set count(value: number) {\n const normalized = normalizeNumber(value, 0, MAX_SAFE, 0)\n if (this._count !== normalized) {\n const old = this._count\n this._count = normalized\n this.requestUpdate('count', old)\n }\n if (this.getAttribute('count') !== String(normalized)) {\n this.setAttribute('count', String(normalized))\n }\n }\n\n get count(): number {\n return this._count\n }\n\n private _count = 0\n\n @property({ type: Number, reflect: true })\n set max(value: number) {\n const normalized = normalizeNumber(value, 0, MAX_SAFE, 99)\n if (this._max !== normalized) {\n const old = this._max\n this._max = normalized\n this.requestUpdate('max', old)\n }\n if (this.getAttribute('max') !== String(normalized)) {\n this.setAttribute('max', String(normalized))\n }\n }\n\n get max(): number {\n return this._max\n }\n\n private _max = 99\n\n @property({ type: Boolean, reflect: true }) dot = false\n @property({ type: Boolean, reflect: true, attribute: 'show-zero' }) showZero = false\n @property({ type: Boolean, reflect: true, attribute: 'badge-hidden' }) badgeHidden = false\n @property({ type: Number, reflect: true, attribute: 'offset-x' }) offsetX = 0\n @property({ type: Number, reflect: true, attribute: 'offset-y' }) offsetY = 0\n\n @property({ type: String, reflect: true })\n set placement(value: string) {\n const normalized = normalizeLiteral(value, ALLOWED_PLACEMENTS, 'top-right')\n if (this._placement !== normalized) {\n const old = this._placement\n this._placement = normalized\n this.requestUpdate('placement', old)\n }\n if (this.getAttribute('placement') !== normalized) {\n this.setAttribute('placement', normalized)\n }\n }\n\n get placement(): 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' {\n return this._placement\n }\n\n private _placement: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' = 'top-right'\n\n @state() private _hasContent = false\n\n private readonly _contentObserver = new MutationObserver(() => this._syncHasContent())\n\n private readonly _handleSlotChange = () => {\n this._syncHasContent()\n }\n\n private _syncHasContent(): void {\n const slot = this.renderRoot.querySelector('slot')\n this._hasContent = hasDefaultSlotContent(slot?.assignedNodes() ?? this.childNodes)\n }\n\n override connectedCallback() {\n super.connectedCallback()\n this._syncHasContent()\n this._contentObserver.observe(this, { characterData: true, subtree: true })\n }\n\n override disconnectedCallback() {\n this._contentObserver.disconnect()\n super.disconnectedCallback()\n }\n\n override render() {\n const showBadge = this.badgeHidden ? false : this.dot ? true : this.count > 0 || this.showZero\n const display = this.dot ? '' : this.count > this.max ? `${this.max}+` : String(this.count)\n const ariaLabel = this.dot\n ? 'Unread'\n : this.count > 0\n ? `${this.count} unread messages`\n : this.showZero\n ? 'No unread messages'\n : undefined\n const wrapperClass = { 'badge-wrapper': true, 'badge-wrapper-fixed': this._hasContent }\n const badgeClass = { badge: true, 'badge-dot': this.dot, 'badge-fixed': this._hasContent }\n const badgeStyle = {\n '--badge-offset-x': `${this.offsetX}px`,\n '--badge-offset-y': `${this.offsetY}px`\n }\n\n return html`\n <div class=${classMap(wrapperClass)}>\n <slot @slotchange=${this._handleSlotChange}></slot>\n ${\n showBadge\n ? html`<span\n class=${classMap(badgeClass)}\n style=${styleMap(badgeStyle)}\n role=\"status\"\n aria-label=${ifDefined(ariaLabel)}\n >${display}</span\n >`\n : ''\n }\n </div>\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-badge': WebUiBadge\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/badge/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{-webkit-user-select:none;user-select:none;display:inline-block}.badge-wrapper{display:inline-flex}.badge-wrapper-fixed{position:relative}.badge{z-index:1;min-width:18px;height:18px;padding:0 var(--wui-space-1,4px);border:1px solid var(--wui-color-page,#fff);border-radius:var(--wui-radius-control,calc(infinity * 1px));font-size:var(--wui-font-size-caption,12px);font-weight:var(--wui-font-weight-medium,500);color:var(--wui-color-on-
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{-webkit-user-select:none;user-select:none;display:inline-block}.badge-wrapper{display:inline-flex}.badge-wrapper-fixed{position:relative}.badge{pointer-events:none;z-index:1;min-width:18px;height:18px;padding:0 var(--wui-space-1,4px);border:1px solid var(--wui-color-page,#fff);border-radius:var(--wui-radius-control,calc(infinity * 1px));font-size:var(--wui-font-size-caption,12px);font-weight:var(--wui-font-weight-medium,500);color:var(--wui-color-on-danger,#fff);white-space:nowrap;background-color:var(--wui-color-danger,#dc2626);justify-content:center;align-items:center;line-height:1;display:inline-flex}.badge-fixed{transform:translate(calc(var(--badge-x,50%) + var(--badge-offset-x,0px)), calc(var(--badge-y,-50%) + var(--badge-offset-y,0px)));position:absolute}:host([placement=top-right]) .badge{--badge-x:50%;--badge-y:-50%;top:0;right:0}:host([placement=top-left]) .badge{--badge-x:-50%;--badge-y:-50%;top:0;left:0}:host([placement=bottom-right]) .badge{--badge-x:50%;--badge-y:50%;bottom:0;right:0}:host([placement=bottom-left]) .badge{--badge-x:-50%;--badge-y:50%;bottom:0;left:0}.badge-dot{min-width:8px;height:8px;padding:0;font-size:0}.badge-fixed.badge-dot{--badge-x:40%;--badge-y:-40%}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/badge/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n user-select: none;\n display: inline-block;\n}\n\n.badge-wrapper {\n display: inline-flex;\n}\n\n.badge-wrapper-fixed {\n position: relative;\n}\n\n.badge {\n z-index: 1;\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n min-width: 18px;\n height: 18px;\n padding: 0 var(--wui-space-1, 4px);\n border: 1px solid var(--wui-color-page, #fff);\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n font-size: var(--wui-font-size-caption, 12px);\n font-weight: var(--wui-font-weight-medium, 500);\n line-height: 1;\n color: var(--wui-color-on-
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/badge/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n user-select: none;\n display: inline-block;\n}\n\n.badge-wrapper {\n display: inline-flex;\n}\n\n.badge-wrapper-fixed {\n position: relative;\n}\n\n.badge {\n pointer-events: none;\n\n z-index: 1;\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n min-width: 18px;\n height: 18px;\n padding: 0 var(--wui-space-1, 4px);\n border: 1px solid var(--wui-color-page, #fff);\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n font-size: var(--wui-font-size-caption, 12px);\n font-weight: var(--wui-font-weight-medium, 500);\n line-height: 1;\n color: var(--wui-color-on-danger, #fff);\n white-space: nowrap;\n\n background-color: var(--wui-color-danger, #dc2626);\n}\n\n.badge-fixed {\n position: absolute;\n transform: translate(\n calc(var(--badge-x, 50%) + var(--badge-offset-x, 0px)),\n calc(var(--badge-y, -50%) + var(--badge-offset-y, 0px))\n );\n}\n\n:host([placement='top-right']) .badge {\n --badge-x: 50%;\n --badge-y: -50%;\n top: 0;\n right: 0;\n}\n\n:host([placement='top-left']) .badge {\n --badge-x: -50%;\n --badge-y: -50%;\n top: 0;\n left: 0;\n}\n\n:host([placement='bottom-right']) .badge {\n --badge-x: 50%;\n --badge-y: 50%;\n right: 0;\n bottom: 0;\n}\n\n:host([placement='bottom-left']) .badge {\n --badge-x: -50%;\n --badge-y: 50%;\n bottom: 0;\n left: 0;\n}\n\n.badge-dot {\n min-width: 8px;\n height: 8px;\n padding: 0;\n font-size: 0;\n}\n\n.badge-fixed.badge-dot {\n --badge-x: 40%;\n --badge-y: -40%;\n}\n"],"mappings":""}
|
|
@@ -378,13 +378,17 @@ export declare class WebUiButton extends WebUiButton_base {
|
|
|
378
378
|
set type(value: unknown);
|
|
379
379
|
private _type;
|
|
380
380
|
ariaLabel: string | null;
|
|
381
|
+
ariaDisabled: string | null;
|
|
382
|
+
ariaExpanded: string | null;
|
|
381
383
|
private readonly _groupManagement;
|
|
382
384
|
private get _groupContext();
|
|
383
385
|
private readonly _formAssociation;
|
|
384
386
|
private readonly _formAssociationController;
|
|
385
387
|
private get _isDisabled();
|
|
388
|
+
constructor();
|
|
386
389
|
private get _sizeStyle();
|
|
387
390
|
private handleClick;
|
|
391
|
+
private readonly _handleHostClick;
|
|
388
392
|
render(): import('lit').TemplateResult<1>;
|
|
389
393
|
}
|
|
390
394
|
declare global {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import e from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
2
2
|
import "../icon/index.js";
|
|
3
|
-
import t from "../../
|
|
3
|
+
import t from "../../classes/glass.js";
|
|
4
4
|
import n from "../../icons/generated/lucide-loader-circle.js";
|
|
5
5
|
import { installPointerFocusSuppression as r } from "../../shared/focus/pointer-focus.js";
|
|
6
6
|
import { FormAssociated as i, FormAssociationController as a, defineFormAssociation as o } from "../../shared/form-association/index.js";
|
|
@@ -26,20 +26,6 @@ var b = [
|
|
|
26
26
|
];
|
|
27
27
|
r();
|
|
28
28
|
var S = class extends i(d) {
|
|
29
|
-
constructor(...e) {
|
|
30
|
-
super(...e), this._variant = "glass", this.disabled = !1, this.loading = !1, this.full = !1, this.icon = !1, this.size = "", this._type = "button", this.ariaLabel = null, this._groupManagement = c(this, {
|
|
31
|
-
context: s,
|
|
32
|
-
requestUpdate: () => this.requestUpdate(),
|
|
33
|
-
equals: (e, t) => e?.direction === t?.direction && e?.isLast === t?.isLast
|
|
34
|
-
}).make(), this._formAssociation = o({
|
|
35
|
-
host: this,
|
|
36
|
-
getState: () => null,
|
|
37
|
-
setState: () => {},
|
|
38
|
-
getFormValue: () => null,
|
|
39
|
-
getFormState: () => null,
|
|
40
|
-
restoreState: () => {}
|
|
41
|
-
}).make(), this._formAssociationController = new a(this, this._formAssociation);
|
|
42
|
-
}
|
|
43
29
|
static {
|
|
44
30
|
this.styles = [m(t), m(u)];
|
|
45
31
|
}
|
|
@@ -63,12 +49,31 @@ var S = class extends i(d) {
|
|
|
63
49
|
get _isDisabled() {
|
|
64
50
|
return this.disabled || this.loading || this._formAssociation.isFormDisabled();
|
|
65
51
|
}
|
|
52
|
+
constructor() {
|
|
53
|
+
super(), this._variant = "glass", this.disabled = !1, this.loading = !1, this.full = !1, this.icon = !1, this.size = "", this._type = "button", this.ariaLabel = null, this.ariaDisabled = null, this.ariaExpanded = null, this._groupManagement = c(this, {
|
|
54
|
+
context: s,
|
|
55
|
+
requestUpdate: () => this.requestUpdate(),
|
|
56
|
+
equals: (e, t) => e?.direction === t?.direction && e?.isLast === t?.isLast
|
|
57
|
+
}).make(), this._formAssociation = o({
|
|
58
|
+
host: this,
|
|
59
|
+
getState: () => null,
|
|
60
|
+
setState: () => {},
|
|
61
|
+
getFormValue: () => null,
|
|
62
|
+
getFormState: () => null,
|
|
63
|
+
restoreState: () => {}
|
|
64
|
+
}).make(), this._formAssociationController = new a(this, this._formAssociation), this._handleHostClick = (e) => {
|
|
65
|
+
e.composedPath()[0] !== this || !this._isDisabled && this.ariaDisabled !== "true" || (e.preventDefault(), e.stopPropagation());
|
|
66
|
+
}, this.addEventListener("click", this._handleHostClick);
|
|
67
|
+
}
|
|
66
68
|
get _sizeStyle() {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
if (this._groupContext) return { "--wui-control-size": "var(--wui-internal-button-group-button-size, 30px)" };
|
|
70
|
+
let e = this.size;
|
|
71
|
+
if (typeof e != "string" && typeof e != "number") return {};
|
|
72
|
+
let t = `${e}`.trim();
|
|
73
|
+
return t ? { "--wui-control-size": /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(t) ? `${Number(t)}px` : t } : {};
|
|
69
74
|
}
|
|
70
75
|
handleClick(e) {
|
|
71
|
-
if (this._isDisabled) {
|
|
76
|
+
if (this._isDisabled || this.ariaDisabled === "true") {
|
|
72
77
|
e.preventDefault(), e.stopPropagation();
|
|
73
78
|
return;
|
|
74
79
|
}
|
|
@@ -91,6 +96,8 @@ var S = class extends i(d) {
|
|
|
91
96
|
<button
|
|
92
97
|
type=${this.type}
|
|
93
98
|
aria-label=${v(this.ariaLabel)}
|
|
99
|
+
aria-disabled=${v(this.ariaDisabled)}
|
|
100
|
+
aria-expanded=${v(this.ariaExpanded)}
|
|
94
101
|
class=${_(t)}
|
|
95
102
|
part="button"
|
|
96
103
|
style=${Object.keys(this._sizeStyle).length > 0 ? y(this._sizeStyle) : p}
|
|
@@ -132,7 +139,13 @@ e([g({
|
|
|
132
139
|
})], S.prototype, "type", null), e([g({
|
|
133
140
|
type: String,
|
|
134
141
|
attribute: "aria-label"
|
|
135
|
-
})], S.prototype, "ariaLabel", void 0),
|
|
142
|
+
})], S.prototype, "ariaLabel", void 0), e([g({
|
|
143
|
+
type: String,
|
|
144
|
+
attribute: "aria-disabled"
|
|
145
|
+
})], S.prototype, "ariaDisabled", void 0), e([g({
|
|
146
|
+
type: String,
|
|
147
|
+
attribute: "aria-expanded"
|
|
148
|
+
})], S.prototype, "ariaExpanded", void 0), S = e([h("web-ui-button")], S);
|
|
136
149
|
//#endregion
|
|
137
150
|
export { S as WebUiButton };
|
|
138
151
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/button/index.ts"],"sourcesContent":["import '@/components/icon'\n\nimport { html, LitElement, nothing, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { styleMap } from 'lit/directives/style-map.js'\n\nimport glass from '@/assets/glass.css?inline'\nimport { lucideLoaderCircle } from '@/icons'\nimport { installPointerFocusSuppression } from '@/shared/focus/pointer-focus'\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { buttonGroupContextKey, defineGroupManaged, type ButtonGroupContext } from '@/shared/group-management'\nimport { normalizeLiteral } from '@/shared/normalize'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_VARIANTS = ['primary', 'secondary', 'ghost', 'danger', 'glass'] as const\nconst ALLOWED_TYPES = ['button', 'submit', 'reset'] as const\n\ninstallPointerFocusSuppression()\n\n@customElement('web-ui-button')\nexport class WebUiButton extends FormAssociated(LitElement) {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n\n @property({ type: String, reflect: true })\n get variant(): 'primary' | 'secondary' | 'ghost' | 'danger' | 'glass' {\n return this._variant\n }\n set variant(v: string) {\n const old = this._variant\n this._variant = normalizeLiteral(v, ALLOWED_VARIANTS, 'glass')\n this.requestUpdate('variant', old)\n }\n private _variant: 'primary' | 'secondary' | 'ghost' | 'danger' | 'glass' = 'glass'\n\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) loading = false\n @property({ type: Boolean, reflect: true }) full = false\n @property({ type: Boolean, reflect: true }) icon = false\n @property({ type: String, reflect: true }) size = ''\n\n @property({ type: String, reflect: true })\n get type(): (typeof ALLOWED_TYPES)[number] {\n return this._type\n }\n set type(value: unknown) {\n const old = this._type\n this._type = normalizeLiteral(value, ALLOWED_TYPES, 'button')\n this.requestUpdate('type', old)\n }\n private _type: (typeof ALLOWED_TYPES)[number] = 'button'\n\n // Explicitly delegated accessible naming attributes.\n @property({ type: String, attribute: 'aria-label' }) override ariaLabel: string | null = null\n\n private readonly _groupManagement = defineGroupManaged<ButtonGroupContext>(this, {\n context: buttonGroupContextKey,\n requestUpdate: () => this.requestUpdate(),\n equals: (a, b) => a?.direction === b?.direction && a?.isLast === b?.isLast\n }).make()\n\n private get _groupContext(): ButtonGroupContext | undefined {\n return this._groupManagement.getContext()\n }\n\n /*\n * 按钮不贡献表单值,接 shared form-association 只为拿 ElementInternals 与原生禁用回调:\n * 禁用态由浏览器在宿主 disabled 反射时同步回报,自己镜像一份会漏掉更新时机。\n */\n private readonly _formAssociation = defineFormAssociation<null>({\n host: this,\n getState: () => null,\n setState: () => {},\n getFormValue: () => null,\n getFormState: () => null,\n restoreState: () => {}\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n private get _isDisabled(): boolean {\n return this.disabled || this.loading || this._formAssociation.isFormDisabled()\n }\n\n private get _sizeStyle(): Record<string, string> {\n // size 仅控制按钮高度;icon 模式下 min-width 同步为相同值,天然保持正方形。\n const size = this._groupContext ? '30' : this.size\n return size ? { '--wui-control-size': `${size}px` } : {}\n }\n\n private handleClick(e: Event) {\n if (this._isDisabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n\n const action = this.type\n if (action === 'button') return\n\n /*\n * Shadow 内按钮没有 form owner;等 composed click 的同步监听器全部完成后,\n * 再读取宿主的 live form owner 并转发,调用方仍可用 preventDefault 取消这次原生 activation。\n */\n setTimeout(() => {\n if (e.defaultPrevented) return\n const form = this._formAssociation.getInternals()?.form\n if (!form) return\n if (action === 'submit') form.requestSubmit()\n else form.reset()\n })\n }\n\n override render() {\n const groupContext = this._groupContext\n const btnClass = {\n 'wui-glass': this.variant === 'glass' && !groupContext,\n 'is-grouped': Boolean(groupContext)\n }\n const dividerClass = {\n 'group-divider': true,\n vertical: groupContext?.direction === 'vertical'\n }\n\n return html`\n <button\n type=${this.type}\n aria-label=${ifDefined(this.ariaLabel)}\n class=${classMap(btnClass)}\n part=\"button\"\n style=${Object.keys(this._sizeStyle).length > 0 ? styleMap(this._sizeStyle) : nothing}\n ?disabled=${this._isDisabled}\n @click=${this.handleClick}\n >\n ${\n this.icon\n ? // loading 优先于 icon 内容:icon 模式下只展示 spinner,不投影默认 slot,避免双图标叠加\n this.loading\n ? html`<web-ui-icon .icon=${lucideLoaderCircle} spin></web-ui-icon>`\n : html`<slot></slot>`\n : html`\n ${this.loading ? html`<web-ui-icon .icon=${lucideLoaderCircle} spin></web-ui-icon>` : ''}\n <slot name=\"prefix\"></slot>\n <span class=\"label\"><slot></slot></span>\n <slot name=\"suffix\"></slot>\n `\n }\n </button>\n ${\n groupContext && !groupContext.isLast\n ? html`<span class=${classMap(dividerClass)} aria-hidden=\"true\"></span>`\n : ''\n }\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-button': WebUiButton\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/button/index.ts"],"sourcesContent":["import '@/components/icon'\n\nimport { html, LitElement, nothing, unsafeCSS } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport { styleMap } from 'lit/directives/style-map.js'\n\nimport glass from '@/classes/glass.css?inline'\nimport { lucideLoaderCircle } from '@/icons'\nimport { installPointerFocusSuppression } from '@/shared/focus/pointer-focus'\nimport { FormAssociated, defineFormAssociation, FormAssociationController } from '@/shared/form-association'\nimport { buttonGroupContextKey, defineGroupManaged, type ButtonGroupContext } from '@/shared/group-management'\nimport { normalizeLiteral } from '@/shared/normalize'\n\nimport style from './style.css?inline'\n\nconst ALLOWED_VARIANTS = ['primary', 'secondary', 'ghost', 'danger', 'glass'] as const\nconst ALLOWED_TYPES = ['button', 'submit', 'reset'] as const\n\ninstallPointerFocusSuppression()\n\n@customElement('web-ui-button')\nexport class WebUiButton extends FormAssociated(LitElement) {\n static override styles = [unsafeCSS(glass), unsafeCSS(style)]\n\n @property({ type: String, reflect: true })\n get variant(): 'primary' | 'secondary' | 'ghost' | 'danger' | 'glass' {\n return this._variant\n }\n set variant(v: string) {\n const old = this._variant\n this._variant = normalizeLiteral(v, ALLOWED_VARIANTS, 'glass')\n this.requestUpdate('variant', old)\n }\n private _variant: 'primary' | 'secondary' | 'ghost' | 'danger' | 'glass' = 'glass'\n\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true }) loading = false\n @property({ type: Boolean, reflect: true }) full = false\n @property({ type: Boolean, reflect: true }) icon = false\n @property({ type: String, reflect: true }) size = ''\n\n @property({ type: String, reflect: true })\n get type(): (typeof ALLOWED_TYPES)[number] {\n return this._type\n }\n set type(value: unknown) {\n const old = this._type\n this._type = normalizeLiteral(value, ALLOWED_TYPES, 'button')\n this.requestUpdate('type', old)\n }\n private _type: (typeof ALLOWED_TYPES)[number] = 'button'\n\n // Explicitly delegated ARIA attributes.\n @property({ type: String, attribute: 'aria-label' }) override ariaLabel: string | null = null\n @property({ type: String, attribute: 'aria-disabled' }) override ariaDisabled: string | null = null\n @property({ type: String, attribute: 'aria-expanded' }) override ariaExpanded: string | null = null\n\n private readonly _groupManagement = defineGroupManaged<ButtonGroupContext>(this, {\n context: buttonGroupContextKey,\n requestUpdate: () => this.requestUpdate(),\n equals: (a, b) => a?.direction === b?.direction && a?.isLast === b?.isLast\n }).make()\n\n private get _groupContext(): ButtonGroupContext | undefined {\n return this._groupManagement.getContext()\n }\n\n /*\n * button 不贡献表单值,接 shared form-association 只为拿 ElementInternals 与原生禁用回调:\n * 禁用态由浏览器在宿主 disabled 反射时同步回报,自己镜像一份会漏掉更新时机。\n */\n private readonly _formAssociation = defineFormAssociation<null>({\n host: this,\n getState: () => null,\n setState: () => {},\n getFormValue: () => null,\n getFormState: () => null,\n restoreState: () => {}\n }).make()\n\n private readonly _formAssociationController = new FormAssociationController(this, this._formAssociation)\n\n private get _isDisabled(): boolean {\n return this.disabled || this.loading || this._formAssociation.isFormDisabled()\n }\n\n constructor() {\n super()\n this.addEventListener('click', this._handleHostClick)\n }\n\n private get _sizeStyle(): Record<string, string> {\n // size 仅控制 button 高度;icon 模式下 min-width 同步为相同值,天然保持正方形。\n if (this._groupContext) {\n return { '--wui-control-size': 'var(--wui-internal-button-group-button-size, 30px)' }\n }\n\n const sizeValue: unknown = this.size\n if (typeof sizeValue !== 'string' && typeof sizeValue !== 'number') return {}\n\n const size = `${sizeValue}`.trim()\n if (!size) return {}\n\n // 裸数字按 px 解释;带单位的 CSS 长度原样使用。\n const isBareNumber = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?$/i.test(size)\n const cssSize = isBareNumber ? `${Number(size)}px` : size\n return { '--wui-control-size': cssSize }\n }\n\n private handleClick(e: Event) {\n if (this._isDisabled || this.ariaDisabled === 'true') {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n\n const action = this.type\n if (action === 'button') return\n\n /*\n * Shadow 内 button 没有 form owner;等 composed click 的同步监听器全部完成后,\n * 再读取宿主的 live form owner 并转发,调用方仍可用 preventDefault 取消这次原生 activation。\n */\n setTimeout(() => {\n if (e.defaultPrevented) return\n const form = this._formAssociation.getInternals()?.form\n if (!form) return\n if (action === 'submit') form.requestSubmit()\n else form.reset()\n })\n }\n\n private readonly _handleHostClick = (event: Event) => {\n if (event.composedPath()[0] !== this || (!this._isDisabled && this.ariaDisabled !== 'true')) return\n event.preventDefault()\n event.stopPropagation()\n }\n\n override render() {\n const groupContext = this._groupContext\n const btnClass = {\n 'wui-glass': this.variant === 'glass' && !groupContext,\n 'is-grouped': Boolean(groupContext)\n }\n const dividerClass = {\n 'group-divider': true,\n vertical: groupContext?.direction === 'vertical'\n }\n\n return html`\n <button\n type=${this.type}\n aria-label=${ifDefined(this.ariaLabel)}\n aria-disabled=${ifDefined(this.ariaDisabled)}\n aria-expanded=${ifDefined(this.ariaExpanded)}\n class=${classMap(btnClass)}\n part=\"button\"\n style=${Object.keys(this._sizeStyle).length > 0 ? styleMap(this._sizeStyle) : nothing}\n ?disabled=${this._isDisabled}\n @click=${this.handleClick}\n >\n ${\n this.icon\n ? // loading 优先于 icon 内容:icon 模式下只展示 spinner,不投影默认 slot,避免双 icon 叠加\n this.loading\n ? html`<web-ui-icon .icon=${lucideLoaderCircle} spin></web-ui-icon>`\n : html`<slot></slot>`\n : html`\n ${this.loading ? html`<web-ui-icon .icon=${lucideLoaderCircle} spin></web-ui-icon>` : ''}\n <slot name=\"prefix\"></slot>\n <span class=\"label\"><slot></slot></span>\n <slot name=\"suffix\"></slot>\n `\n }\n </button>\n ${\n groupContext && !groupContext.isLast\n ? html`<span class=${classMap(dividerClass)} aria-hidden=\"true\"></span>`\n : ''\n }\n `\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-button': WebUiButton\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/components/button/style.css?inline
|
|
2
|
-
var e = "*,:before,:after{box-sizing:border-box}:host{justify-content:center;align-items:center;display:inline-flex;position:relative}:host([full]){width:100%;display:block}:host([disabled]){cursor:not-allowed}button{--wui-glass-corner-radius:calc(var(--wui-control-size,36px) / 2);cursor:default;-webkit-user-select:none;user-select:none;gap:var(--wui-button-gap,var(--wui-space-2,8px));box-sizing:border-box;width:var(--wui-button-width,max-content);min-width:var(--wui-control-size,36px);height:var(--wui-control-size,36px);padding:0 var(--wui-button-px,var(--wui-space-3,12px));border-radius:var(--wui-radius-control,calc(infinity * 1px));font:inherit;font-size:var(--wui-font-size,14px);color:var(--wui-button-color);white-space:nowrap;background-color:var(--wui-button-bg);border:none;justify-content:center;align-items:center;line-height:1;display:inline-flex;position:relative;overflow:clip}button:disabled{cursor:not-allowed;opacity:.4}button:focus-visible{outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#
|
|
2
|
+
var e = "*,:before,:after{box-sizing:border-box}:host{justify-content:center;align-items:center;display:inline-flex;position:relative}:host([full]){width:100%;display:block}:host([disabled]){cursor:not-allowed}button{--wui-glass-corner-radius:calc(var(--wui-control-size,36px) / 2);cursor:default;-webkit-user-select:none;user-select:none;gap:var(--wui-button-gap,var(--wui-space-2,8px));box-sizing:border-box;width:var(--wui-button-width,max-content);min-width:var(--wui-control-size,36px);height:var(--wui-control-size,36px);padding:0 var(--wui-button-px,var(--wui-space-3,12px));border-radius:var(--wui-radius-control,calc(infinity * 1px));font:inherit;font-size:var(--wui-font-size,14px);color:var(--wui-button-color);white-space:nowrap;background-color:var(--wui-button-bg);border:none;justify-content:center;align-items:center;line-height:1;display:inline-flex;position:relative;overflow:clip}button:disabled{cursor:not-allowed;opacity:.4}button:focus-visible{outline:var(--wui-focus-ring-width,3px) solid var(--wui-color-focus-ring,color-mix(in srgb, var(--wui-color-accent,#0071e3) 40%, transparent));outline-offset:2px}@media (hover:hover) and (pointer:fine){button:hover:not(:disabled){background-color:var(--wui-button-bg-hover)}}button:active:not(:disabled){background-color:var(--wui-button-bg-active)}:host([full]) button{width:100%;display:flex}:host([icon]) button{padding:0}:host([data-wui-pointer-focus]) button:focus-visible{outline-color:#0000}:host([variant=primary]){--wui-button-color:var(--wui-color-on-accent,#fff);--wui-button-bg:var(--wui-color-accent,#0071e3);--wui-button-bg-hover:color-mix(in srgb, var(--wui-button-bg,#0071e3) 94%, black);--wui-button-bg-active:color-mix(in srgb, var(--wui-button-bg,#0071e3) 90%, black)}:host([variant=secondary]){--wui-button-color:var(--wui-color-text,#1b1b1b);--wui-button-bg:var(--wui-color-surface-control,#dfdfdf);--wui-button-bg-hover:color-mix(in srgb, var(--wui-button-bg,#dfdfdf) 92%, black);--wui-button-bg-active:color-mix(in srgb, var(--wui-button-bg,#dfdfdf) 82%, black)}:host([variant=ghost]){--wui-button-color:var(--wui-color-text,#1b1b1b);--wui-button-bg:transparent;--wui-button-bg-hover:var(--wui-color-state-layer-hover,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, transparent));--wui-button-bg-active:var(--wui-color-state-layer-active,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 15%, transparent))}:host([variant=danger]){--wui-button-color:var(--wui-color-danger,#dc2626);--wui-button-bg:color-mix(in srgb, var(--wui-color-danger,#dc2626) 18%, var(--wui-color-surface,#fff));--wui-button-bg-hover:color-mix(in srgb, var(--wui-color-danger,#dc2626) 26%, var(--wui-color-surface,#fff));--wui-button-bg-active:color-mix(in srgb, var(--wui-color-danger,#dc2626) 45%, var(--wui-color-surface,#fff))}:host([variant=glass]){--wui-button-color:var(--wui-color-text,#1b1b1b);--wui-button-bg:transparent;--wui-button-bg-hover:var(--wui-color-surface-glass-hover,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, var(--wui-color-surface-glass,#fafafa57)));--wui-button-bg-active:var(--wui-color-surface-glass-active,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 15%, var(--wui-color-surface-glass,#fafafa57)))}button.is-grouped{--wui-button-bg:transparent;--wui-button-bg-hover:var(--wui-color-state-layer-hover,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 6%, transparent));--wui-button-bg-active:var(--wui-color-state-layer-active,color-mix(in srgb, var(--wui-color-text,#1b1b1b) 15%, transparent))}.group-divider{z-index:1;width:1px;height:var(--wui-button-group-divider-length,20px);background-color:var(--wui-color-border,#0000001a);position:absolute;top:50%;right:-2px;transform:translateY(-50%)}.group-divider.vertical{width:var(--wui-button-group-divider-length,20px);height:1px;inset:auto auto -2px 50%;transform:translate(-50%)}";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { e as default };
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/button/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n position: relative;\n\n /* inline-flex
|
|
1
|
+
{"version":3,"file":"style.js","names":[],"sources":["../../../src/components/button/style.css?inline"],"sourcesContent":["*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n:host {\n position: relative;\n\n /* inline-flex 让内层 button 在宿主内完全居中,避免继承的行高撑高宿主、导致 icon 偏移 */\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n:host([full]) {\n display: block;\n width: 100%;\n}\n\n:host([disabled]) {\n cursor: not-allowed;\n}\n\nbutton {\n --wui-glass-corner-radius: calc(var(--wui-control-size, 36px) / 2);\n cursor: default;\n user-select: none;\n\n position: relative;\n\n overflow: clip;\n display: inline-flex;\n gap: var(--wui-button-gap, var(--wui-space-2, 8px));\n align-items: center;\n justify-content: center;\n\n box-sizing: border-box;\n width: var(--wui-button-width, max-content);\n min-width: var(--wui-control-size, 36px);\n height: var(--wui-control-size, 36px);\n padding: 0 var(--wui-button-px, var(--wui-space-3, 12px));\n border: none;\n border-radius: var(--wui-radius-control, calc(infinity * 1px));\n\n /* 原生 button 不继承字体;显式继承以对齐宿主排版,避免 UA 默认 Arial 差异 */\n font: inherit;\n font-size: var(--wui-font-size, 14px);\n line-height: 1;\n color: var(--wui-button-color);\n white-space: nowrap;\n\n background-color: var(--wui-button-bg);\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n }\n\n &:focus-visible {\n outline: var(--wui-focus-ring-width, 3px) solid\n var(--wui-color-focus-ring, color-mix(in srgb, var(--wui-color-accent, #0071e3) 40%, transparent));\n outline-offset: 2px;\n }\n}\n\n@media (hover: hover) and (pointer: fine) {\n button:hover:not(:disabled) {\n background-color: var(--wui-button-bg-hover);\n }\n}\n\nbutton:active:not(:disabled) {\n background-color: var(--wui-button-bg-active);\n}\n\n:host([full]) button {\n display: flex;\n width: 100%;\n}\n\n:host([icon]) button {\n padding: 0;\n}\n\n/* pointer-focus helper 把标记写到 shadow host 上;这里抑制 Shadow DOM 内 button 的 focus ring。 */\n:host([data-wui-pointer-focus]) button:focus-visible {\n outline-color: transparent;\n}\n\n:host([variant='primary']) {\n --wui-button-color: var(--wui-color-on-accent, #fff);\n --wui-button-bg: var(--wui-color-accent, #0071e3);\n --wui-button-bg-hover: color-mix(in srgb, var(--wui-button-bg, #0071e3) 94%, black);\n --wui-button-bg-active: color-mix(in srgb, var(--wui-button-bg, #0071e3) 90%, black);\n}\n\n:host([variant='secondary']) {\n --wui-button-color: var(--wui-color-text, #1b1b1b);\n --wui-button-bg: var(--wui-color-surface-control, #dfdfdf);\n --wui-button-bg-hover: color-mix(in srgb, var(--wui-button-bg, #dfdfdf) 92%, black);\n --wui-button-bg-active: color-mix(in srgb, var(--wui-button-bg, #dfdfdf) 82%, black);\n}\n\n:host([variant='ghost']) {\n --wui-button-color: var(--wui-color-text, #1b1b1b);\n --wui-button-bg: transparent;\n --wui-button-bg-hover: var(\n --wui-color-state-layer-hover,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, transparent)\n );\n --wui-button-bg-active: var(\n --wui-color-state-layer-active,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 15%, transparent)\n );\n}\n\n:host([variant='danger']) {\n --wui-button-color: var(--wui-color-danger, #dc2626);\n --wui-button-bg: color-mix(in srgb, var(--wui-color-danger, #dc2626) 18%, var(--wui-color-surface, #fff));\n --wui-button-bg-hover: color-mix(in srgb, var(--wui-color-danger, #dc2626) 26%, var(--wui-color-surface, #fff));\n --wui-button-bg-active: color-mix(in srgb, var(--wui-color-danger, #dc2626) 45%, var(--wui-color-surface, #fff));\n}\n\n/* .wui-glass 样式由 @/classes/glass.css 提供 */\n:host([variant='glass']) {\n --wui-button-color: var(--wui-color-text, #1b1b1b);\n\n /* standalone glass 底色由 .wui-glass 提供;hover/active 需要还原玻璃底,避免被 button 状态色整块替换 */\n --wui-button-bg: transparent;\n --wui-button-bg-hover: var(\n --wui-color-surface-glass-hover,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, var(--wui-color-surface-glass, rgb(250 250 250 / 0.34)))\n );\n --wui-button-bg-active: var(\n --wui-color-surface-glass-active,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 15%, var(--wui-color-surface-glass, rgb(250 250 250 / 0.34)))\n );\n}\n\nbutton.is-grouped {\n --wui-button-bg: transparent;\n --wui-button-bg-hover: var(\n --wui-color-state-layer-hover,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 6%, transparent)\n );\n --wui-button-bg-active: var(\n --wui-color-state-layer-active,\n color-mix(in srgb, var(--wui-color-text, #1b1b1b) 15%, transparent)\n );\n}\n\n.group-divider {\n position: absolute;\n z-index: 1;\n top: 50%;\n right: -2px;\n transform: translateY(-50%);\n\n width: 1px;\n height: var(--wui-button-group-divider-length, 20px);\n\n background-color: var(--wui-color-border, rgb(0 0 0 / 0.1));\n}\n\n.group-divider.vertical {\n top: auto;\n right: auto;\n bottom: -2px;\n left: 50%;\n transform: translateX(-50%);\n\n width: var(--wui-button-group-divider-length, 20px);\n height: 1px;\n}\n"],"mappings":""}
|
|
@@ -5,6 +5,9 @@ export declare class WebUiButtonGroup extends LitElement {
|
|
|
5
5
|
set direction(v: string);
|
|
6
6
|
private _direction;
|
|
7
7
|
private readonly _groupController;
|
|
8
|
+
private _trackResizeObserver;
|
|
9
|
+
connectedCallback(): void;
|
|
10
|
+
disconnectedCallback(): void;
|
|
8
11
|
render(): import('lit').TemplateResult<1>;
|
|
9
12
|
}
|
|
10
13
|
declare global {
|