@bagelink/vue 1.15.245 → 1.15.249
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Btn.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/OTP.vue.d.ts +4 -0
- package/dist/components/form/inputs/OTP.vue.d.ts.map +1 -1
- package/dist/components/layout/AppLayout.vue.d.ts.map +1 -1
- package/dist/components/layout/Tabs.vue.d.ts.map +1 -1
- package/dist/components/layout/TabsNav.vue.d.ts.map +1 -1
- package/dist/index.cjs +21 -21
- package/dist/index.mjs +3025 -3025
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/Btn.vue +14 -3
- package/src/components/form/inputs/OTP.vue +13 -5
- package/src/components/layout/AppLayout.vue +10 -2
- package/src/components/layout/Tabs.vue +6 -4
- package/src/components/layout/TabsNav.vue +5 -4
package/package.json
CHANGED
package/src/components/Btn.vue
CHANGED
|
@@ -229,9 +229,10 @@ const slots: SetupContext['slots'] = useSlots()
|
|
|
229
229
|
}, computedPairClass]" :style="gradientStyle" :tabindex="disabled ? -1 : 0" @click.stop="handleClick" @keydown.enter="handleClick" @keydown.space="handleClick"
|
|
230
230
|
>
|
|
231
231
|
<!-- Keep label/icons mounted while loading so the button width/height don't jump.
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
<
|
|
232
|
+
Hide them hard (visibility + opacity) so the icon never shows through the spinner.
|
|
233
|
+
absolute-fill + flex-center (not center-xy) so the spinner stays centered in RTL too. -->
|
|
234
|
+
<Loading v-if="loading" class="btn-loading absolute-fill flex-center pointer-events-none" size="15" color="currentColor" />
|
|
235
|
+
<div class="bgl_btn-flex" :class="{ 'btn-loading-hide': loading }">
|
|
235
236
|
<Icon
|
|
236
237
|
v-if="icon" :icon="icon" class="transition-400" :size="iconSizeComputed"
|
|
237
238
|
:mobile-size="iconMobileSize"
|
|
@@ -299,6 +300,16 @@ justify-content: center;
|
|
|
299
300
|
height: 100%;
|
|
300
301
|
}
|
|
301
302
|
|
|
303
|
+
/* Hide content while the spinner overlays — visibility alone can still flash
|
|
304
|
+
icons (esp. icon-only flat buttons); opacity + z-index keeps the spinner on top. */
|
|
305
|
+
.bgl_btn-flex.btn-loading-hide {
|
|
306
|
+
visibility: hidden;
|
|
307
|
+
opacity: 0;
|
|
308
|
+
}
|
|
309
|
+
.bgl_btn .btn-loading {
|
|
310
|
+
z-index: 1;
|
|
311
|
+
}
|
|
312
|
+
|
|
302
313
|
/* Loading.ring applies a thickness offset transform that pulls the spinner off-center */
|
|
303
314
|
.bgl_btn :deep(.lds-ring) {
|
|
304
315
|
transform: none;
|
|
@@ -10,6 +10,10 @@ const props = defineProps<{
|
|
|
10
10
|
error?: string
|
|
11
11
|
/** Color of the entered digits. Accepts any CSS color or theme var (e.g. "primary", "var(--bgl-primary)", "#e11d48"). */
|
|
12
12
|
color?: string
|
|
13
|
+
/** Size of each digit box (width & height). Accepts any CSS length (e.g. "2.5rem", "40px"). Default: 3rem. */
|
|
14
|
+
size?: string
|
|
15
|
+
/** Digit box size below 910px. Falls back to `size` (or 3rem) when omitted. */
|
|
16
|
+
mobileSize?: string
|
|
13
17
|
} & BagelInputShellProps>()
|
|
14
18
|
|
|
15
19
|
const emit = defineEmits(['update:modelValue', 'complete'])
|
|
@@ -23,9 +27,11 @@ const digitColor = computed(() => {
|
|
|
23
27
|
})
|
|
24
28
|
|
|
25
29
|
const shellStyle = computed(() => {
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
-
|
|
30
|
+
const style = { ...(baseShellStyle.value ?? {}) } as Record<string, string>
|
|
31
|
+
if (digitColor.value) { style['--bgl-otp-digit-color'] = digitColor.value }
|
|
32
|
+
if (props.size) { style['--bgl-otp-digit-size'] = props.size }
|
|
33
|
+
if (props.mobileSize) { style['--bgl-otp-digit-mobile-size'] = props.mobileSize }
|
|
34
|
+
return Object.keys(style).length > 0 ? style : undefined
|
|
29
35
|
})
|
|
30
36
|
|
|
31
37
|
// ── Single-input model ──────────────────────────────────────────────────────
|
|
@@ -156,7 +162,7 @@ outline: none;
|
|
|
156
162
|
.otp-hidden-input::selection { background: transparent; }
|
|
157
163
|
|
|
158
164
|
.digit-box {
|
|
159
|
-
height: 3rem;
|
|
165
|
+
height: var(--bgl-otp-digit-size, 3rem);
|
|
160
166
|
aspect-ratio: 1;
|
|
161
167
|
flex: 0 0 auto;
|
|
162
168
|
color: var(--bgl-otp-digit-color, inherit);
|
|
@@ -168,7 +174,7 @@ background: var(--bgl-gray-light);
|
|
|
168
174
|
border-radius: 5px;
|
|
169
175
|
margin: 5px;
|
|
170
176
|
text-align: center;
|
|
171
|
-
font-size:
|
|
177
|
+
font-size: calc(var(--bgl-otp-digit-size, 3rem) * 0.8);
|
|
172
178
|
font-variant-numeric: tabular-nums;
|
|
173
179
|
user-select: none;
|
|
174
180
|
transition: outline-color 0.2s ease, box-shadow 0.2s ease;
|
|
@@ -210,6 +216,8 @@ outline-offset: -1px;
|
|
|
210
216
|
|
|
211
217
|
@media screen and (max-width: 910px) {
|
|
212
218
|
.digit-box {
|
|
219
|
+
height: var(--bgl-otp-digit-mobile-size, var(--bgl-otp-digit-size, 3rem));
|
|
220
|
+
font-size: calc(var(--bgl-otp-digit-mobile-size, var(--bgl-otp-digit-size, 3rem)) * 0.8);
|
|
213
221
|
padding: 0.25rem;
|
|
214
222
|
}
|
|
215
223
|
}
|
|
@@ -260,6 +260,10 @@ function handleVisible(side: ResizableSide): boolean {
|
|
|
260
260
|
let dragSide: ResizableSide | null = null
|
|
261
261
|
let dragStartX = 0
|
|
262
262
|
let dragStartW = 0
|
|
263
|
+
/** True while the user is drag-resizing a start/end rail. Suppresses the
|
|
264
|
+
* grid-template-columns transition so the track tracks the pointer 1:1
|
|
265
|
+
* instead of lagging behind a 300ms ease. */
|
|
266
|
+
const isRegionDragging = ref(false)
|
|
263
267
|
|
|
264
268
|
function onResizeMove(e: PointerEvent) {
|
|
265
269
|
if (!dragSide) { return }
|
|
@@ -280,6 +284,8 @@ function onResizeMove(e: PointerEvent) {
|
|
|
280
284
|
}
|
|
281
285
|
function onResizeUp() {
|
|
282
286
|
dragSide = null
|
|
287
|
+
isRegionDragging.value = false
|
|
288
|
+
document.body.style.cursor = ''
|
|
283
289
|
document.body.style.userSelect = ''
|
|
284
290
|
window.removeEventListener('pointermove', onResizeMove)
|
|
285
291
|
window.removeEventListener('pointerup', onResizeUp)
|
|
@@ -288,6 +294,8 @@ function onResizeDown(side: ResizableSide, e: PointerEvent) {
|
|
|
288
294
|
dragSide = side
|
|
289
295
|
dragStartX = e.clientX
|
|
290
296
|
dragStartW = parsePx(regions.value[side].size, 0)
|
|
297
|
+
isRegionDragging.value = true
|
|
298
|
+
document.body.style.cursor = 'ew-resize'
|
|
291
299
|
document.body.style.userSelect = 'none'
|
|
292
300
|
window.addEventListener('pointermove', onResizeMove)
|
|
293
301
|
window.addEventListener('pointerup', onResizeUp)
|
|
@@ -341,7 +349,7 @@ const slotBind = computed(() => ({ isOpen, isMobile, toggleMenu, closeOnMobile }
|
|
|
341
349
|
</script>
|
|
342
350
|
|
|
343
351
|
<template>
|
|
344
|
-
<div class="app-layout vh-100 relative" :class="{ 'app-layout--resizing': isResizing }" :style="rootVars">
|
|
352
|
+
<div class="app-layout vh-100 relative" :class="{ 'app-layout--resizing': isResizing || isRegionDragging }" :style="rootVars">
|
|
345
353
|
<!-- top region: a full-width band above the start/end rails. Everything
|
|
346
354
|
below insets by --bgl-region-top so the nav is never overlapped. -->
|
|
347
355
|
<div v-if="regions.top.present" class="region-band region-band--top">
|
|
@@ -352,7 +360,7 @@ const slotBind = computed(() => ({ isOpen, isMobile, toggleMenu, closeOnMobile }
|
|
|
352
360
|
track size (rowStyle → grid-template-columns); each rail just fills its
|
|
353
361
|
track. Overlay rails (mobile drawer, floating chat) collapse their track
|
|
354
362
|
to 0 and their fixed child floats above instead. -->
|
|
355
|
-
<div class="app-row relative" :class="{ 'app-layout--resizing': isResizing }" :style="rowStyle">
|
|
363
|
+
<div class="app-row relative" :class="{ 'app-layout--resizing': isResizing || isRegionDragging }" :style="rowStyle">
|
|
356
364
|
<!-- Mobile sidebar drawer backdrop -->
|
|
357
365
|
<div v-if="startOverlayOpen" class="overlay" @click="closeOnMobile" />
|
|
358
366
|
|
|
@@ -54,10 +54,12 @@ const tabComponent = defineComponent({
|
|
|
54
54
|
const currentTabIndex = props.tabs.findIndex(
|
|
55
55
|
tab => tabValue(tab) === currentTab.value
|
|
56
56
|
)
|
|
57
|
-
if (currentTabIndex === -1)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
if (currentTabIndex === -1) return null
|
|
58
|
+
// Nav-only usage (no default slot / no panel children) — render nothing.
|
|
59
|
+
const slotChildren = slots.default?.()?.[1]?.children as VNode[] | undefined
|
|
60
|
+
const panel = slotChildren?.[currentTabIndex]
|
|
61
|
+
if (!panel) return null
|
|
62
|
+
return h('div', panel)
|
|
61
63
|
},
|
|
62
64
|
})
|
|
63
65
|
</script>
|
|
@@ -29,10 +29,11 @@ const props = defineProps<{
|
|
|
29
29
|
|
|
30
30
|
const emit = defineEmits(['update:modelValue'])
|
|
31
31
|
const { currentTab } = useTabs(props.group)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
// Prefer controlled modelValue; otherwise the first tab's string value.
|
|
33
|
+
// (Parentheses required — `||` binds tighter than `?:` and used to assign the
|
|
34
|
+
// whole tab object when modelValue was set, breaking findIndex / isActive.)
|
|
35
|
+
currentTab.value = props.modelValue
|
|
36
|
+
|| (typeof props.tabs[0] === 'string' ? props.tabs[0] : props.tabs[0]?.value)
|
|
36
37
|
|
|
37
38
|
const tabsWrap = ref<HTMLElement | undefined>(undefined)
|
|
38
39
|
const tabEls = ref<HTMLElement[]>([])
|