@leavepulse/ui 0.22.12 → 0.22.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{LpAddressInput-BWuIOt_4.js → LpAddressInput-DoiamNCt.js} +3 -3
- package/dist/chunks/{LpAutocomplete-DIgXmtCA.js → LpAutocomplete-DExlIZe_.js} +2 -1
- package/dist/chunks/{LpConfirmDialog-B_3ML33f.js → LpConfirmDialog-CmgeAdCh.js} +1 -1
- package/dist/chunks/{LpFileTree-DWx77B1F.js → LpFileTree-Cw50eG_y.js} +2 -2
- package/dist/chunks/{LpInput-BauZRyzm.js → LpInput-DYc9O-db.js} +2 -1
- package/dist/chunks/{LpModal-CF7G_0D_.js → LpModal-CNNSf5pv.js} +8 -9
- package/dist/chunks/{LpNumberField-C5ar-OwE.js → LpNumberField-B3JuQFol.js} +1 -0
- package/dist/chunks/{LpPasswordInput-DIHFw4u0.js → LpPasswordInput-BvF2omhn.js} +1 -1
- package/dist/chunks/{LpPhoneInput-LQvVFGMw.js → LpPhoneInput-BxuDyXp3.js} +2 -1
- package/dist/components/LpAddressInput.vue.js +1 -1
- package/dist/components/LpAutocomplete.vue.js +1 -1
- package/dist/components/LpConfirmDialog.vue.js +1 -1
- package/dist/components/LpFileTree.vue.js +1 -1
- package/dist/components/LpInput.vue.js +1 -1
- package/dist/components/LpModal.vue.js +1 -1
- package/dist/components/LpNumberField.vue.js +1 -1
- package/dist/components/LpPasswordInput.vue.js +1 -1
- package/dist/components/LpPhoneInput.vue.js +1 -1
- package/dist/components/LpShortcutsDialog.vue.js +1 -1
- package/dist/index.js +9 -9
- package/package.json +1 -1
- package/src/components/LpAutocomplete.vue +2 -1
- package/src/components/LpFileTree.vue +6 -4
- package/src/components/LpInput.vue +2 -1
- package/src/components/LpModal.vue +12 -9
- package/src/components/LpNumberField.vue +1 -0
- package/src/components/LpPhoneInput.vue +2 -1
- package/src/tokens/utilities.css +32 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { defineComponent, defineAsyncComponent, computed, ref, onMounted, watch, openBlock, createElementBlock, createVNode, withCtx, createElementVNode, unref, createBlock, createCommentVNode, createTextVNode, toDisplayString, renderSlot, normalizeClass } from "vue";
|
|
2
2
|
import { OSM_TILES, createNominatimProvider, emptyAddress, formatAddress } from "../components/address.js";
|
|
3
3
|
import { flagEmoji, loadCountries } from "../components/countries.js";
|
|
4
|
-
import { _ as _sfc_main$2 } from "./LpAutocomplete-
|
|
4
|
+
import { _ as _sfc_main$2 } from "./LpAutocomplete-DExlIZe_.js";
|
|
5
5
|
import { _ as _sfc_main$3 } from "./LpButton-5VXXCjwF.js";
|
|
6
6
|
import { _ as _sfc_main$1 } from "./LpFormField-Bn-ZwC6z.js";
|
|
7
7
|
import { _ as _sfc_main$4 } from "./LpIcon-CCnX5_2j.js";
|
|
8
|
-
import { _ as _sfc_main$5 } from "./LpInput-
|
|
9
|
-
import { _ as _sfc_main$7 } from "./LpModal-
|
|
8
|
+
import { _ as _sfc_main$5 } from "./LpInput-DYc9O-db.js";
|
|
9
|
+
import { _ as _sfc_main$7 } from "./LpModal-CNNSf5pv.js";
|
|
10
10
|
import { _ as _sfc_main$6 } from "./LpSelect-D5mU4cZO.js";
|
|
11
11
|
const _hoisted_1 = { class: "flex flex-col gap-3" };
|
|
12
12
|
const _hoisted_2 = { class: "flex items-stretch gap-2" };
|
|
@@ -105,6 +105,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
105
105
|
}, {
|
|
106
106
|
default: withCtx(() => [
|
|
107
107
|
createVNode(unref(ComboboxAnchor), {
|
|
108
|
+
"data-lp-ring-owner": "",
|
|
108
109
|
class: normalizeClass(["flex w-full items-center gap-2 rounded-control border bg-surface-soft px-3 text-ink transition-colors duration-[var(--duration-fast)] focus-within:ring-2 focus-within:ring-ring data-[disabled]:cursor-not-allowed data-[disabled]:opacity-55", [
|
|
109
110
|
anchorSize[__props.size],
|
|
110
111
|
isInvalidState.value ? "border-danger focus-within:border-danger focus-within:ring-danger-soft" : "border-line focus-within:border-brand"
|
|
@@ -123,7 +124,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
123
124
|
disabled: __props.disabled,
|
|
124
125
|
"aria-invalid": isInvalidState.value || void 0,
|
|
125
126
|
"auto-focus": "",
|
|
126
|
-
class: "min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted",
|
|
127
|
+
class: "lp-autofill min-w-0 flex-1 self-stretch bg-transparent outline-none placeholder:text-muted",
|
|
127
128
|
onBeforeinput: unref(onBeforeInput),
|
|
128
129
|
onPaste: unref(onPaste),
|
|
129
130
|
onInput,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineComponent, openBlock, createBlock, withCtx, renderSlot, createVNode, createTextVNode, toDisplayString } from "vue";
|
|
2
2
|
import { _ as _sfc_main$2 } from "./LpButton-5VXXCjwF.js";
|
|
3
|
-
import { _ as _sfc_main$1 } from "./LpModal-
|
|
3
|
+
import { _ as _sfc_main$1 } from "./LpModal-CNNSf5pv.js";
|
|
4
4
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
5
5
|
__name: "LpConfirmDialog",
|
|
6
6
|
props: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineComponent, ref, watch, computed, openBlock, createElementBlock, Fragment, renderList, normalizeStyle, createBlock, createVNode, withCtx, createElementVNode, renderSlot, mergeProps, normalizeProps, guardReactiveProps, createTextVNode, toDisplayString, createCommentVNode } from "vue";
|
|
2
|
-
import { formatSize, sortNodes,
|
|
2
|
+
import { computeStats, formatSize, sortNodes, subtreeIds, ancestorIds } from "../components/fileTree.js";
|
|
3
3
|
import { _ as _sfc_main$1 } from "./LpEmptyState-CrfyRJUG.js";
|
|
4
4
|
import { _ as _sfc_main$3 } from "./LpFileTreeNode-DFg4PhOK.js";
|
|
5
5
|
import { _ as _sfc_main$2 } from "./LpScrollArea-D8xyKXcF.js";
|
|
@@ -67,6 +67,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
67
67
|
return { byId: byId2, parentOfId };
|
|
68
68
|
});
|
|
69
69
|
const byId = computed(() => index.value.byId);
|
|
70
|
+
const stats = computed(() => computeStats(props.nodes, checkedIds.value));
|
|
70
71
|
const summary = computed(() => {
|
|
71
72
|
let files = 0;
|
|
72
73
|
let dirs = 0;
|
|
@@ -146,7 +147,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
146
147
|
}
|
|
147
148
|
const requested = /* @__PURE__ */ new Set();
|
|
148
149
|
const roots = computed(() => props.sort ? sortNodes(props.nodes) : props.nodes);
|
|
149
|
-
const stats = computed(() => computeStats(props.nodes, checkedIds.value));
|
|
150
150
|
const visible = computed(() => {
|
|
151
151
|
const out = [];
|
|
152
152
|
function walk(list) {
|
|
@@ -91,6 +91,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
91
91
|
}, {
|
|
92
92
|
default: withCtx(() => [
|
|
93
93
|
createElementVNode("div", {
|
|
94
|
+
"data-lp-ring-owner": "",
|
|
94
95
|
class: normalizeClass([shellClass.value, hasLeading.value ? "pl-2.5" : "", hasTrailing.value ? "pr-1.5" : "", hasField.value ? "" : rootClass.value]),
|
|
95
96
|
style: normalizeStyle(hasField.value ? void 0 : rootStyle.value)
|
|
96
97
|
}, [
|
|
@@ -113,7 +114,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
113
114
|
disabled: __props.disabled,
|
|
114
115
|
"aria-invalid": isInvalidState.value || void 0,
|
|
115
116
|
class: [
|
|
116
|
-
"min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted",
|
|
117
|
+
"lp-autofill min-w-0 flex-1 self-stretch bg-transparent outline-none placeholder:text-muted",
|
|
117
118
|
hasLeading.value ? "pl-2" : padX[__props.size ?? "md"],
|
|
118
119
|
hasTrailing.value ? "" : padX[__props.size ?? "md"]
|
|
119
120
|
],
|
|
@@ -70,16 +70,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
70
70
|
const target = panel.querySelector(selector);
|
|
71
71
|
if (!target || target.hasAttribute("disabled")) continue;
|
|
72
72
|
event.preventDefault();
|
|
73
|
-
target.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (target instanceof HTMLInputElement && target.type === "text") {
|
|
81
|
-
target.select();
|
|
73
|
+
if (!target.closest("[data-lp-ring-owner]")) {
|
|
74
|
+
target.setAttribute("data-lp-focus-ring", "");
|
|
75
|
+
target.addEventListener(
|
|
76
|
+
"blur",
|
|
77
|
+
() => target.removeAttribute("data-lp-focus-ring"),
|
|
78
|
+
{ once: true }
|
|
79
|
+
);
|
|
82
80
|
}
|
|
81
|
+
target.focus();
|
|
83
82
|
return;
|
|
84
83
|
}
|
|
85
84
|
}
|
|
@@ -19,6 +19,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
19
19
|
max: __props.max,
|
|
20
20
|
step: __props.step,
|
|
21
21
|
disabled: __props.disabled,
|
|
22
|
+
"data-lp-ring-owner": "",
|
|
22
23
|
class: "flex h-(--size-control-md) w-full items-center rounded-control border border-line bg-surface-soft transition-colors duration-[var(--duration-fast)] focus-within:border-brand focus-within:ring-2 focus-within:ring-ring data-[disabled]:cursor-not-allowed data-[disabled]:opacity-55",
|
|
23
24
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = (v) => _ctx.$emit("update:modelValue", v ?? null))
|
|
24
25
|
}, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineComponent, ref, openBlock, createBlock, createSlots, withCtx, createElementVNode, createVNode, renderSlot } from "vue";
|
|
2
2
|
import { _ as _sfc_main$2 } from "./LpIcon-CCnX5_2j.js";
|
|
3
|
-
import { _ as _sfc_main$1 } from "./LpInput-
|
|
3
|
+
import { _ as _sfc_main$1 } from "./LpInput-DYc9O-db.js";
|
|
4
4
|
const _hoisted_1 = ["aria-label"];
|
|
5
5
|
const __default__ = { inheritAttrs: false };
|
|
6
6
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
@@ -86,6 +86,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
86
86
|
};
|
|
87
87
|
return (_ctx, _cache) => {
|
|
88
88
|
return openBlock(), createElementBlock("div", {
|
|
89
|
+
"data-lp-ring-owner": "",
|
|
89
90
|
class: normalizeClass(["flex w-full items-stretch rounded-control border bg-surface-soft text-ink transition-colors duration-[var(--duration-fast)] focus-within:ring-2 focus-within:ring-ring", [
|
|
90
91
|
sizeClass[__props.size],
|
|
91
92
|
__props.invalid ? "border-danger focus-within:border-danger focus-within:ring-danger-soft" : "border-line focus-within:border-brand",
|
|
@@ -183,7 +184,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
183
184
|
type: "tel",
|
|
184
185
|
inputmode: "tel",
|
|
185
186
|
autocomplete: "tel",
|
|
186
|
-
class: "min-w-0 flex-1 bg-transparent px-3 outline-none placeholder:text-muted",
|
|
187
|
+
class: "lp-autofill min-w-0 flex-1 self-stretch bg-transparent px-3 outline-none placeholder:text-muted",
|
|
187
188
|
onBeforeinput: _cache[2] || (_cache[2] = //@ts-ignore
|
|
188
189
|
(...args) => unref(onBeforeInput) && unref(onBeforeInput)(...args)),
|
|
189
190
|
onPaste: _cache[3] || (_cache[3] = //@ts-ignore
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineComponent, openBlock, createBlock, withCtx, createElementVNode, createElementBlock, Fragment, renderList, toDisplayString, unref } from "vue";
|
|
2
|
-
import { _ as _sfc_main$1 } from "../chunks/LpModal-
|
|
2
|
+
import { _ as _sfc_main$1 } from "../chunks/LpModal-CNNSf5pv.js";
|
|
3
3
|
import { appleModifierLabel } from "../composables/useHotkeys.js";
|
|
4
4
|
import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
|
|
5
5
|
import '../assets/LpShortcutsDialog-B7H-RZLQ.css';const _hoisted_1 = { class: "shortcut-groups" };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { _ } from "./chunks/LayoutCanvas-Dd20boUG.js";
|
|
2
|
-
import { _ as _2 } from "./chunks/LpAddressInput-
|
|
2
|
+
import { _ as _2 } from "./chunks/LpAddressInput-DoiamNCt.js";
|
|
3
3
|
import { _ as _3 } from "./chunks/LpMapPicker-DFKrd1Ne.js";
|
|
4
4
|
import { OSM_TILES, createNominatimProvider, emptyAddress, formatAddress, project, tileUrl, unproject } from "./components/address.js";
|
|
5
5
|
import { _ as _4 } from "./chunks/LpAlert-BAYHDSS1.js";
|
|
6
6
|
import { _ as _5 } from "./chunks/LpAppShell-D8CAP9oF.js";
|
|
7
|
-
import { _ as _6 } from "./chunks/LpAutocomplete-
|
|
7
|
+
import { _ as _6 } from "./chunks/LpAutocomplete-DExlIZe_.js";
|
|
8
8
|
import { _ as _7 } from "./chunks/LpAvatar-B1Ez0ZAx.js";
|
|
9
9
|
import { _ as _8 } from "./chunks/LpBadge-BPodVcJa.js";
|
|
10
10
|
import { _ as _9 } from "./chunks/LpBreadcrumbs-B7Aqatzw.js";
|
|
@@ -14,7 +14,7 @@ import { _ as _12 } from "./chunks/LpCard-BmrTvWOe.js";
|
|
|
14
14
|
import { _ as _13 } from "./chunks/LpCheckbox-BO0zuuPh.js";
|
|
15
15
|
import { _ as _14 } from "./chunks/LpCodeBlock-CSiOSPs8.js";
|
|
16
16
|
import { default as default2 } from "./components/LpCommandPalette.vue.js";
|
|
17
|
-
import { _ as _15 } from "./chunks/LpConfirmDialog-
|
|
17
|
+
import { _ as _15 } from "./chunks/LpConfirmDialog-CmgeAdCh.js";
|
|
18
18
|
import { _ as _16 } from "./chunks/LpContextMenu-D0mzXqA7.js";
|
|
19
19
|
import { _ as _17 } from "./chunks/LpDatePicker-dY2q4dr4.js";
|
|
20
20
|
import { _ as _18 } from "./chunks/LpDisclosure-DP6yfgfM.js";
|
|
@@ -22,23 +22,23 @@ import { _ as _19 } from "./chunks/LpDivider-CUX46KR0.js";
|
|
|
22
22
|
import { _ as _20 } from "./chunks/LpDrawer-DAJN5rGK.js";
|
|
23
23
|
import { _ as _21 } from "./chunks/LpDropdownMenu-DJpoqRCb.js";
|
|
24
24
|
import { _ as _22 } from "./chunks/LpEmptyState-CrfyRJUG.js";
|
|
25
|
-
import { _ as _23 } from "./chunks/LpFileTree-
|
|
25
|
+
import { _ as _23 } from "./chunks/LpFileTree-Cw50eG_y.js";
|
|
26
26
|
import { ancestorIds, checkStateOf, checkedCount, computeStats, fileIcon, formatModified, formatSize, sortNodes, subtreeIds, subtreeSize } from "./components/fileTree.js";
|
|
27
27
|
import { _ as _24 } from "./chunks/LpFormField-Bn-ZwC6z.js";
|
|
28
28
|
import { _ as _25 } from "./chunks/LpIcon-CCnX5_2j.js";
|
|
29
29
|
import { _ as _26 } from "./chunks/LpInfraNode-qIL3l7IO.js";
|
|
30
|
-
import { _ as _27 } from "./chunks/LpInput-
|
|
30
|
+
import { _ as _27 } from "./chunks/LpInput-DYc9O-db.js";
|
|
31
31
|
import { _ as _28 } from "./chunks/LpLightbox-Ci35Y_xP.js";
|
|
32
32
|
import { fileNameOf } from "./components/lightbox.js";
|
|
33
33
|
import { _ as _29 } from "./chunks/LpLink-DHwOEp4e.js";
|
|
34
34
|
import { _ as _30 } from "./chunks/LpLogViewer-B1aLUVdz.js";
|
|
35
|
-
import { _ as _31 } from "./chunks/LpModal-
|
|
35
|
+
import { _ as _31 } from "./chunks/LpModal-CNNSf5pv.js";
|
|
36
36
|
import { _ as _32 } from "./chunks/LpNotificationBell-DWDEkmdA.js";
|
|
37
|
-
import { _ as _33 } from "./chunks/LpNumberField-
|
|
37
|
+
import { _ as _33 } from "./chunks/LpNumberField-B3JuQFol.js";
|
|
38
38
|
import { _ as _34 } from "./chunks/LpOtpInput-DqaT0Z75.js";
|
|
39
39
|
import { _ as _35 } from "./chunks/LpPagination-CeGuNe_q.js";
|
|
40
|
-
import { _ as _36 } from "./chunks/LpPasswordInput-
|
|
41
|
-
import { _ as _37 } from "./chunks/LpPhoneInput-
|
|
40
|
+
import { _ as _36 } from "./chunks/LpPasswordInput-BvF2omhn.js";
|
|
41
|
+
import { _ as _37 } from "./chunks/LpPhoneInput-BxuDyXp3.js";
|
|
42
42
|
import { flagEmoji, loadCountries, matchCountryByValue } from "./components/countries.js";
|
|
43
43
|
import { _ as _38 } from "./chunks/LpPopover-8268UmlC.js";
|
|
44
44
|
import { _ as _39 } from "./chunks/LpProgress-BhI0IbjC.js";
|
package/package.json
CHANGED
|
@@ -180,6 +180,7 @@ function clear() {
|
|
|
180
180
|
class="relative"
|
|
181
181
|
>
|
|
182
182
|
<ComboboxAnchor
|
|
183
|
+
data-lp-ring-owner
|
|
183
184
|
class="flex w-full items-center gap-2 rounded-control border bg-surface-soft px-3 text-ink transition-colors duration-[var(--duration-fast)] focus-within:ring-2 focus-within:ring-ring data-[disabled]:cursor-not-allowed data-[disabled]:opacity-55"
|
|
184
185
|
:class="[
|
|
185
186
|
anchorSize[size],
|
|
@@ -202,7 +203,7 @@ function clear() {
|
|
|
202
203
|
:disabled="disabled"
|
|
203
204
|
:aria-invalid="isInvalidState || undefined"
|
|
204
205
|
auto-focus
|
|
205
|
-
class="min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted"
|
|
206
|
+
class="lp-autofill min-w-0 flex-1 self-stretch bg-transparent outline-none placeholder:text-muted"
|
|
206
207
|
@beforeinput="onBeforeInput"
|
|
207
208
|
@paste="onPaste"
|
|
208
209
|
@input="onInput"
|
|
@@ -155,6 +155,12 @@ const index = computed(() => {
|
|
|
155
155
|
|
|
156
156
|
const byId = computed(() => index.value.byId)
|
|
157
157
|
|
|
158
|
+
// One pass for the whole tree; every row reads its entry by id instead of
|
|
159
|
+
// walking its own subtree on each render. Declared before `summary`, which
|
|
160
|
+
// reads it and is watched eagerly — a `const` below that watcher is still in
|
|
161
|
+
// its temporal dead zone when the watcher first runs.
|
|
162
|
+
const stats = computed(() => computeStats(props.nodes, checkedIds.value))
|
|
163
|
+
|
|
158
164
|
/**
|
|
159
165
|
* What the ticked set adds up to. Directories are counted but not sized — their
|
|
160
166
|
* bytes arrive through the files inside them, so summing both would double-count.
|
|
@@ -268,10 +274,6 @@ const requested = new Set<string>()
|
|
|
268
274
|
|
|
269
275
|
const roots = computed(() => (props.sort ? sortNodes(props.nodes) : props.nodes))
|
|
270
276
|
|
|
271
|
-
// One pass for the whole tree; every row reads its entry by id instead of
|
|
272
|
-
// walking its own subtree on each render.
|
|
273
|
-
const stats = computed(() => computeStats(props.nodes, checkedIds.value))
|
|
274
|
-
|
|
275
277
|
/** Rows currently visible, in render order — the axis the arrow keys walk. */
|
|
276
278
|
const visible = computed(() => {
|
|
277
279
|
const out: FileNode[] = []
|
|
@@ -118,6 +118,7 @@ defineExpose({
|
|
|
118
118
|
:style="hasField ? rootStyle : undefined"
|
|
119
119
|
>
|
|
120
120
|
<div
|
|
121
|
+
data-lp-ring-owner
|
|
121
122
|
:class="[shellClass, hasLeading ? 'pl-2.5' : '', hasTrailing ? 'pr-1.5' : '', hasField ? '' : rootClass]"
|
|
122
123
|
:style="hasField ? undefined : rootStyle"
|
|
123
124
|
>
|
|
@@ -133,7 +134,7 @@ defineExpose({
|
|
|
133
134
|
:disabled="disabled"
|
|
134
135
|
:aria-invalid="isInvalidState || undefined"
|
|
135
136
|
:class="[
|
|
136
|
-
'min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted',
|
|
137
|
+
'lp-autofill min-w-0 flex-1 self-stretch bg-transparent outline-none placeholder:text-muted',
|
|
137
138
|
hasLeading ? 'pl-2' : padX[size ?? 'md'],
|
|
138
139
|
hasTrailing ? '' : padX[size ?? 'md'],
|
|
139
140
|
]"
|
|
@@ -140,16 +140,19 @@ function onOpenAutoFocus(event: Event) {
|
|
|
140
140
|
// `focus-visible` is the browser's own heuristic and cannot be forced, so
|
|
141
141
|
// the ring is driven off an attribute the kit owns. Removed as soon as the
|
|
142
142
|
// element loses focus, leaving normal focus-visible behaviour in charge.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
143
|
+
//
|
|
144
|
+
// Skipped for a control whose own shell already draws a ring on
|
|
145
|
+
// focus-within: our fields put the border and ring on the wrapper, so
|
|
146
|
+
// adding one to the bare <input> stacks a second ring inside the first.
|
|
147
|
+
if (!target.closest("[data-lp-ring-owner]")) {
|
|
148
|
+
target.setAttribute("data-lp-focus-ring", "")
|
|
149
|
+
target.addEventListener(
|
|
150
|
+
"blur",
|
|
151
|
+
() => target.removeAttribute("data-lp-focus-ring"),
|
|
152
|
+
{ once: true },
|
|
153
|
+
)
|
|
152
154
|
}
|
|
155
|
+
target.focus()
|
|
153
156
|
return
|
|
154
157
|
}
|
|
155
158
|
}
|
|
@@ -28,6 +28,7 @@ defineEmits<{ (e: "update:modelValue", value: number | null): void }>()
|
|
|
28
28
|
:max="max"
|
|
29
29
|
:step="step"
|
|
30
30
|
:disabled="disabled"
|
|
31
|
+
data-lp-ring-owner
|
|
31
32
|
class="flex h-(--size-control-md) w-full items-center rounded-control border border-line bg-surface-soft transition-colors duration-[var(--duration-fast)] focus-within:border-brand focus-within:ring-2 focus-within:ring-ring data-[disabled]:cursor-not-allowed data-[disabled]:opacity-55"
|
|
32
33
|
@update:model-value="(v) => $emit('update:modelValue', v ?? null)"
|
|
33
34
|
>
|
|
@@ -150,6 +150,7 @@ const sizeClass = {
|
|
|
150
150
|
|
|
151
151
|
<template>
|
|
152
152
|
<div
|
|
153
|
+
data-lp-ring-owner
|
|
153
154
|
class="flex w-full items-stretch rounded-control border bg-surface-soft text-ink transition-colors duration-[var(--duration-fast)] focus-within:ring-2 focus-within:ring-ring"
|
|
154
155
|
:class="[
|
|
155
156
|
sizeClass[size],
|
|
@@ -232,7 +233,7 @@ const sizeClass = {
|
|
|
232
233
|
type="tel"
|
|
233
234
|
inputmode="tel"
|
|
234
235
|
autocomplete="tel"
|
|
235
|
-
class="min-w-0 flex-1 bg-transparent px-3 outline-none placeholder:text-muted"
|
|
236
|
+
class="lp-autofill min-w-0 flex-1 self-stretch bg-transparent px-3 outline-none placeholder:text-muted"
|
|
236
237
|
@beforeinput="onBeforeInput"
|
|
237
238
|
@paste="onPaste"
|
|
238
239
|
@input="onInput"
|
package/src/tokens/utilities.css
CHANGED
|
@@ -36,3 +36,35 @@
|
|
|
36
36
|
outline: none;
|
|
37
37
|
box-shadow: 0 0 0 2px var(--color-ring);
|
|
38
38
|
}
|
|
39
|
+
|
|
40
|
+
/*
|
|
41
|
+
* Autofilled fields keep the field's own colours.
|
|
42
|
+
*
|
|
43
|
+
* A browser paints its own background on an autofilled control, and it wins
|
|
44
|
+
* over `background` outright. Our inputs draw their surface and border on the
|
|
45
|
+
* WRAPPER, so that paint lands on the bare <input> inside — a band of colour
|
|
46
|
+
* that stops short of the field's real height and reads as a rendering fault.
|
|
47
|
+
*
|
|
48
|
+
* The background cannot be overridden, so it is covered: a large inset shadow
|
|
49
|
+
* repaints the control in the field's own surface colour, and the text colour
|
|
50
|
+
* is forced back with `-webkit-text-fill-color`, which the autofill style also
|
|
51
|
+
* hijacks. The transition delay keeps Chrome from flashing its yellow during
|
|
52
|
+
* the fade it runs on load.
|
|
53
|
+
*/
|
|
54
|
+
.lp-autofill:-webkit-autofill,
|
|
55
|
+
.lp-autofill:-webkit-autofill:hover,
|
|
56
|
+
.lp-autofill:-webkit-autofill:focus,
|
|
57
|
+
.lp-autofill:-webkit-autofill:active {
|
|
58
|
+
box-shadow: inset 0 0 0 1000px var(--color-surface-soft);
|
|
59
|
+
-webkit-text-fill-color: var(--color-ink);
|
|
60
|
+
caret-color: var(--color-ink);
|
|
61
|
+
transition: background-color 100000s ease-in-out 0s;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* Firefox names it differently and does honour a background here. */
|
|
65
|
+
.lp-autofill:autofill,
|
|
66
|
+
.lp-autofill:-moz-autofill {
|
|
67
|
+
background-color: var(--color-surface-soft);
|
|
68
|
+
color: var(--color-ink);
|
|
69
|
+
filter: none;
|
|
70
|
+
}
|