@bagelink/vue 1.15.82 → 1.15.88
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/Alert.vue.d.ts +6 -1
- package/dist/components/Alert.vue.d.ts.map +1 -1
- package/dist/components/Avatar.vue.d.ts +3 -1
- package/dist/components/Avatar.vue.d.ts.map +1 -1
- package/dist/components/Badge.vue.d.ts +4 -0
- package/dist/components/Badge.vue.d.ts.map +1 -1
- package/dist/components/EmptyState.vue.d.ts.map +1 -1
- package/dist/components/Image.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/ArrayInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RangeInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TextInput.vue.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/kanban/KanbanBoard.vue.d.ts +42 -0
- package/dist/components/kanban/KanbanBoard.vue.d.ts.map +1 -0
- package/dist/components/kanban/kanbanTypes.d.ts +64 -0
- package/dist/components/kanban/kanbanTypes.d.ts.map +1 -0
- package/dist/composables/useGradientVariant.d.ts.map +1 -1
- package/dist/index.cjs +40 -40
- package/dist/index.mjs +8526 -8313
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/Alert.vue +40 -9
- package/src/components/Avatar.vue +8 -5
- package/src/components/Badge.vue +30 -0
- package/src/components/Dropdown.vue +1 -1
- package/src/components/EmptyState.vue +5 -1
- package/src/components/Image.vue +18 -4
- package/src/components/form/inputs/ArrayInput.vue +2 -2
- package/src/components/form/inputs/RangeInput.vue +0 -2
- package/src/components/form/inputs/RichText/components/TableGridSelector.vue +1 -1
- package/src/components/form/inputs/RichText/editor.css +14 -8
- package/src/components/form/inputs/RichText/index.vue +1 -1
- package/src/components/form/inputs/TextInput.vue +6 -2
- package/src/components/form/inputs/Upload/upload.css +7 -1
- package/src/components/index.ts +2 -0
- package/src/components/kanban/KanbanBoard.vue +231 -0
- package/src/components/kanban/kanbanTypes.ts +72 -0
- package/src/composables/useGradientVariant.ts +20 -3
- package/src/styles/appearance.css +108 -0
- package/src/styles/base-colors.css +830 -1
- package/src/styles/buttons.css +44 -2
- package/src/styles/color-variants.css +75 -50
- package/src/styles/colors.css +1115 -1
- package/src/styles/gradients.css +49 -0
- package/src/styles/mobileColors.css +1156 -0
- package/src/styles/motion.css +107 -19
- package/src/styles/theme.css +84 -1
- package/vite.config.ts +2 -2
package/package.json
CHANGED
package/src/components/Alert.vue
CHANGED
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
defineOptions({ name: 'BglAlert' })
|
|
3
3
|
import type { IconType } from '@bagelink/vue'
|
|
4
4
|
import { Icon } from '@bagelink/vue'
|
|
5
|
-
import { computed, ref } from 'vue'
|
|
5
|
+
import { computed, ref, useSlots } from 'vue'
|
|
6
6
|
import Btn from './Btn.vue'
|
|
7
7
|
|
|
8
8
|
type AlertType = 'info' | 'success' | 'warning' | 'error'
|
|
9
9
|
|
|
10
10
|
interface Props {
|
|
11
11
|
message?: string
|
|
12
|
+
/** Bold heading above the message / default slot. */
|
|
13
|
+
title?: string
|
|
12
14
|
thin?: boolean
|
|
13
15
|
/** Border + transparent background (drops the tinted fill). */
|
|
14
16
|
outline?: boolean
|
|
15
|
-
/**
|
|
17
|
+
/** Neutral surface card: standard box background + a subtle neutral
|
|
18
|
+
(non-accent) border. Only the icon/title keep the accent color — use
|
|
19
|
+
when a full tinted fill reads as too loud. */
|
|
16
20
|
frame?: boolean
|
|
17
21
|
dismissable?: boolean
|
|
18
22
|
type?: AlertType
|
|
@@ -25,6 +29,7 @@ interface Props {
|
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
const props = defineProps<Props>()
|
|
32
|
+
const slots = useSlots()
|
|
28
33
|
|
|
29
34
|
const computedType = computed<AlertType>(() => {
|
|
30
35
|
if (props.type) { return props.type }
|
|
@@ -47,11 +52,17 @@ const typeIcon: Record<AlertType, IconType> = {
|
|
|
47
52
|
<template>
|
|
48
53
|
<div v-if="!isDismissed" class="alert" :class="[computedType, { thin, outline, frame }]" :dismissable="dismissable">
|
|
49
54
|
<Icon v-if="icon !== 'none'" class="alert_icon" :icon="icon || typeIcon[computedType]" :size="1.7" />
|
|
50
|
-
<
|
|
51
|
-
<p class="m-0">
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
<div class="alert_content">
|
|
56
|
+
<p v-if="title" class="alert_title m-0">{{ title }}</p>
|
|
57
|
+
<slot>
|
|
58
|
+
<p class="m-0 light">
|
|
59
|
+
{{ message }}
|
|
60
|
+
</p>
|
|
61
|
+
</slot>
|
|
62
|
+
</div>
|
|
63
|
+
<div v-if="slots.actions" class="alert_actions">
|
|
64
|
+
<slot name="actions" />
|
|
65
|
+
</div>
|
|
55
66
|
<Btn flat thin class="alert_close" icon="close" @click="isDismissed = true" />
|
|
56
67
|
</div>
|
|
57
68
|
</template>
|
|
@@ -94,6 +105,23 @@ const typeIcon: Record<AlertType, IconType> = {
|
|
|
94
105
|
color: var(--alert-outline);
|
|
95
106
|
}
|
|
96
107
|
|
|
108
|
+
.alert_content {
|
|
109
|
+
flex: 1;
|
|
110
|
+
min-width: 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.alert_title {
|
|
114
|
+
font-weight: 600;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.alert_actions {
|
|
118
|
+
display: flex;
|
|
119
|
+
align-items: center;
|
|
120
|
+
gap: 0.5rem;
|
|
121
|
+
flex-shrink: 0;
|
|
122
|
+
align-self: center;
|
|
123
|
+
}
|
|
124
|
+
|
|
97
125
|
.alert.thin {
|
|
98
126
|
padding: 1rem;
|
|
99
127
|
}
|
|
@@ -103,9 +131,12 @@ const typeIcon: Record<AlertType, IconType> = {
|
|
|
103
131
|
background: unset;
|
|
104
132
|
}
|
|
105
133
|
|
|
106
|
-
/* frame:
|
|
134
|
+
/* frame: neutral surface card — box bg + subtle border tinted by the accent;
|
|
135
|
+
accent stays on the icon/title only (use when a full tinted fill is too loud). */
|
|
107
136
|
.alert.frame {
|
|
108
|
-
|
|
137
|
+
background: var(--bgl-box-bg);
|
|
138
|
+
border: 1px solid color-mix(in srgb, var(--alert-outline) 35%, var(--bgl-border-color));
|
|
139
|
+
color: inherit;
|
|
109
140
|
}
|
|
110
141
|
|
|
111
142
|
.alert_icon {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
2
|
+
// A consumer `class` lands on the positioning wrapper (the root) like any normal
|
|
3
|
+
// component — so spacing/layout utilities (mb-2, me-2, …) work as expected. To
|
|
4
|
+
// style the inner rounded/clipped element (e.g. a custom background that must
|
|
5
|
+
// stay circular), use the `innerClass` prop — mirrors `triggerClass` on Dropdown.
|
|
6
|
+
defineOptions({ name: 'BglAvatar' })
|
|
6
7
|
import type { IconType, ThemeType } from '@bagelink/vue'
|
|
7
8
|
import { initials, Icon } from '@bagelink/vue'
|
|
8
9
|
import { computed } from 'vue'
|
|
@@ -24,6 +25,8 @@ const props = withDefaults(defineProps<{
|
|
|
24
25
|
status?: boolean | ThemeType
|
|
25
26
|
/** Accessible label / tooltip for the status dot. */
|
|
26
27
|
statusTitle?: string
|
|
28
|
+
/** Class applied to the inner rounded/clipped avatar element (vs. the wrapper). */
|
|
29
|
+
innerClass?: string
|
|
27
30
|
}>(), { size: 50 })
|
|
28
31
|
|
|
29
32
|
const statusColor = computed(() => (props.status === true ? 'green' : props.status || null))
|
|
@@ -48,8 +51,8 @@ const themed = computed(() => props.color
|
|
|
48
51
|
<template>
|
|
49
52
|
<div class="avatar-wrap" :style="{ width: `${size}px`, height: `${size}px` }">
|
|
50
53
|
<div
|
|
51
|
-
v-bind="$attrs"
|
|
52
54
|
class="overflow-hidden txt-center p-0 avatar flex justify-content-center align-items-center"
|
|
55
|
+
:class="innerClass"
|
|
53
56
|
:style="{ width: `${size}px`, height: `${size}px`, borderRadius: radius, ...themed }"
|
|
54
57
|
>
|
|
55
58
|
<Image v-if="src" :src="src" :alt="alt || name" />
|
package/src/components/Badge.vue
CHANGED
|
@@ -52,6 +52,10 @@ const props = defineProps<{
|
|
|
52
52
|
/** Boolean size shorthands: <Badge sm value="New" /> */
|
|
53
53
|
sm?: boolean
|
|
54
54
|
lg?: boolean
|
|
55
|
+
/** Mobile-only size override (≤ 910px). Lets a `lg` desktop badge shrink on
|
|
56
|
+
phones so it doesn't overflow / touch neighbours. e.g.
|
|
57
|
+
<Badge lg mobile-size="sm" />. Mirrors `Icon`'s `mobileSize` prop. */
|
|
58
|
+
mobileSize?: 'sm' | 'md' | 'lg'
|
|
55
59
|
uppercase?: boolean
|
|
56
60
|
}>()
|
|
57
61
|
|
|
@@ -87,6 +91,10 @@ const computedSize = computed(() => {
|
|
|
87
91
|
return 'md'
|
|
88
92
|
})
|
|
89
93
|
|
|
94
|
+
/** Mobile-only size override (≤ 910px). Falls back to undefined when not set,
|
|
95
|
+
so the desktop size keeps applying at all widths. */
|
|
96
|
+
const computedMobileSize = computed(() => props.mobileSize)
|
|
97
|
+
|
|
90
98
|
const computedVariant = computed(() => {
|
|
91
99
|
if (props.variant) { return props.variant }
|
|
92
100
|
if (isGradient.value) { return 'gradient' }
|
|
@@ -111,6 +119,9 @@ const computedClasses = computed(() => {
|
|
|
111
119
|
'gradient': computedVariant.value === 'gradient',
|
|
112
120
|
'pillLarge': computedSize.value === 'lg',
|
|
113
121
|
'pillSmall': computedSize.value === 'sm',
|
|
122
|
+
'm_pillLarge': computedMobileSize.value === 'lg',
|
|
123
|
+
'm_pillMd': computedMobileSize.value === 'md',
|
|
124
|
+
'm_pillSmall': computedMobileSize.value === 'sm',
|
|
114
125
|
}
|
|
115
126
|
|
|
116
127
|
// Add the pair class
|
|
@@ -156,8 +167,27 @@ const computedClasses = computed(() => {
|
|
|
156
167
|
--bgl-pill-font-size: 9px;
|
|
157
168
|
--bgl-pill-height:15px;
|
|
158
169
|
}
|
|
170
|
+
|
|
171
|
+
/* Mobile-only size overrides (≤ 910px). These win over the desktop size class
|
|
172
|
+
because the size is driven entirely by --bgl-pill-font-size / --bgl-pill-height,
|
|
173
|
+
and a later @media rule with equal specificity overrides the base class. */
|
|
174
|
+
@media screen and (max-width: 910px) {
|
|
175
|
+
.m_pillLarge {
|
|
176
|
+
--bgl-pill-font-size: var(--bgl-font-size);
|
|
177
|
+
--bgl-pill-height: auto;
|
|
178
|
+
}
|
|
179
|
+
.m_pillMd {
|
|
180
|
+
--bgl-pill-font-size: 12px;
|
|
181
|
+
--bgl-pill-height: 20px;
|
|
182
|
+
}
|
|
183
|
+
.m_pillSmall {
|
|
184
|
+
--bgl-pill-font-size: 9px;
|
|
185
|
+
--bgl-pill-height: 15px;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
159
188
|
.pillText{
|
|
160
189
|
font-size: var(--bgl-pill-font-size);
|
|
190
|
+
white-space: nowrap;
|
|
161
191
|
}
|
|
162
192
|
.bgl_pill-dot{
|
|
163
193
|
width: 6px;
|
|
@@ -271,7 +271,7 @@ function onDocumentPointerDown(e: PointerEvent) {
|
|
|
271
271
|
// that each Dropdown sets on its popover element to point to the nearest ancestor popover's id.
|
|
272
272
|
const openPopovers = document.querySelectorAll<HTMLElement>('[popover]:popover-open')
|
|
273
273
|
const myId = popoverRef.value?.dataset.bglId
|
|
274
|
-
for (const p of openPopovers) {
|
|
274
|
+
for (const p of Array.from(openPopovers)) {
|
|
275
275
|
if (p === popoverRef.value) continue
|
|
276
276
|
if (p.contains(target) && myId && p.dataset.bglOwner === myId) return
|
|
277
277
|
}
|
|
@@ -39,7 +39,7 @@ const slots = useSlots()
|
|
|
39
39
|
</script>
|
|
40
40
|
|
|
41
41
|
<template>
|
|
42
|
-
<div class="bgl-empty
|
|
42
|
+
<div class="bgl-empty txt-center" :class="[{ 'bgl-empty--compact': compact }, className]">
|
|
43
43
|
<div v-if="slots.icon || icon !== 'none'" class="bgl-empty-icon flex-center">
|
|
44
44
|
<slot name="icon"><Icon :icon="icon" :size="compact ? 1.6 : 2.2" /></slot>
|
|
45
45
|
</div>
|
|
@@ -57,6 +57,10 @@ const slots = useSlots()
|
|
|
57
57
|
|
|
58
58
|
<style scoped>
|
|
59
59
|
.bgl-empty {
|
|
60
|
+
display: flex;
|
|
61
|
+
flex-direction: column;
|
|
62
|
+
align-items: center;
|
|
63
|
+
justify-content: center;
|
|
60
64
|
gap: 0.75rem;
|
|
61
65
|
padding: 2.5rem 1.5rem;
|
|
62
66
|
color: var(--bgl-text-soft, var(--bgl-gray));
|
package/src/components/Image.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
defineOptions({ name: 'BglImage', inheritAttrs: true })
|
|
3
3
|
import { Skeleton, normalizeDimension, Icon, useImageSrc } from '@bagelink/vue'
|
|
4
|
-
import { computed, useSlots } from 'vue'
|
|
4
|
+
import { Comment, computed, useSlots, type StyleValue, type VNode } from 'vue'
|
|
5
5
|
|
|
6
6
|
interface ImageProps {
|
|
7
7
|
src?: string
|
|
@@ -29,9 +29,16 @@ const { imageSrc, loadingError } = useImageSrc(() => props.src ?? props.pathKey
|
|
|
29
29
|
|
|
30
30
|
// ── Framed mode (ratio / gradient / blend / rounded / overlay slot) ──────────
|
|
31
31
|
const slots = useSlots()
|
|
32
|
+
// Only count the default slot as "framed" when it actually renders nodes — an
|
|
33
|
+
// empty/whitespace slot (or none) must NOT force framed mode, otherwise a plain
|
|
34
|
+
// `<Image :src />` renders an absolute-fill img that collapses the box to 0×0.
|
|
35
|
+
const hasOverlay = computed(() => {
|
|
36
|
+
const nodes = slots.default?.({}) as VNode[] | undefined
|
|
37
|
+
return !!nodes?.some((n: VNode) => n.type !== Comment && !(typeof n.children === 'string' && n.children.trim() === ''))
|
|
38
|
+
})
|
|
32
39
|
const framed = computed(() =>
|
|
33
40
|
props.ratio !== undefined || props.gradient !== undefined || props.blend !== undefined
|
|
34
|
-
|| props.rounded !== undefined ||
|
|
41
|
+
|| props.rounded !== undefined || hasOverlay.value)
|
|
35
42
|
|
|
36
43
|
// Resolve `gradient` into a CSS background. Accepts a tone name, a [from,to]
|
|
37
44
|
// pair (tone or color), or a raw CSS gradient/color string.
|
|
@@ -49,6 +56,10 @@ const gradientCss = computed(() => {
|
|
|
49
56
|
})
|
|
50
57
|
|
|
51
58
|
const ratioClass = computed(() => (props.ratio ? `ratio-${props.ratio}` : ''))
|
|
59
|
+
// When the frame has no intrinsic height (no ratio + no explicit height), the
|
|
60
|
+
// absolute-fill img would collapse the box to 0. In that case let the img flow
|
|
61
|
+
// naturally (relative) so the frame sizes to the image.
|
|
62
|
+
const frameHasHeight = computed(() => props.ratio !== undefined || props.height !== undefined)
|
|
52
63
|
const radiusStyle = computed(() => {
|
|
53
64
|
if (props.rounded === undefined || props.rounded === false) return undefined
|
|
54
65
|
return typeof props.rounded === 'number' ? `${props.rounded}px` : 'var(--bgl-card-radius, 12px)'
|
|
@@ -73,8 +84,9 @@ const imgFit = computed(() => props.fit ?? ((props.ratio || props.gradient) ? 'c
|
|
|
73
84
|
v-if="imageSrc"
|
|
74
85
|
:src="imageSrc"
|
|
75
86
|
:alt="alt"
|
|
76
|
-
class="bgl-image-frame-img
|
|
77
|
-
:
|
|
87
|
+
class="bgl-image-frame-img"
|
|
88
|
+
:class="frameHasHeight ? 'absolute-fill' : 'bgl-image-frame-img--flow'"
|
|
89
|
+
:style="{ objectFit: imgFit, mixBlendMode: blend } as StyleValue"
|
|
78
90
|
>
|
|
79
91
|
<Skeleton v-else-if="!gradientCss && !loadingError" class="absolute-fill" />
|
|
80
92
|
<div v-else-if="loadingError && !gradientCss" class="flex-center absolute-fill error-image">
|
|
@@ -140,5 +152,7 @@ background-color: var(--bgl-skeleton-bg);
|
|
|
140
152
|
|
|
141
153
|
.bgl-image-frame { display: block; }
|
|
142
154
|
.bgl-image-frame-img { width: 100%; height: 100%; }
|
|
155
|
+
/* no ratio/height → flow naturally so the frame gets the image's height (avoids 0×0 collapse) */
|
|
156
|
+
.bgl-image-frame-img--flow { position: relative; height: auto; display: block; }
|
|
143
157
|
|
|
144
158
|
</style>
|
|
@@ -4,7 +4,7 @@ import type { Ref, WritableComputedRef } from 'vue'
|
|
|
4
4
|
import type { DraggableEvent } from '../../draggable/useDraggable'
|
|
5
5
|
|
|
6
6
|
import { Btn, resolveI18n, useI18n, pathKeyToURL } from '@bagelink/vue'
|
|
7
|
-
import { computed, ref, watch, useSlots } from 'vue'
|
|
7
|
+
import { computed, ref, watch, useSlots, type VNode } from 'vue'
|
|
8
8
|
import Draggable from '../../draggable/Draggable.vue'
|
|
9
9
|
import type { BagelInputShellProps } from './bagelInputShell'
|
|
10
10
|
import { useBagelInputShell } from './bagelInputShell'
|
|
@@ -141,7 +141,7 @@ const isSimple = computed(() => {
|
|
|
141
141
|
if (props.simple) return true
|
|
142
142
|
if (!slots.default) return false
|
|
143
143
|
const dummyItem = computed({ get: () => undefined as T, set: () => { } })
|
|
144
|
-
const vnodes = slots.default({ item: dummyItem, index: 0 })
|
|
144
|
+
const vnodes = slots.default({ item: dummyItem, index: 0 }) as VNode[]
|
|
145
145
|
return vnodes.filter(vn => typeof vn.type !== 'symbol').length === 1
|
|
146
146
|
})
|
|
147
147
|
|
|
@@ -46,8 +46,6 @@ onMounted(() => {
|
|
|
46
46
|
inheritedRtl.value = getComputedStyle(rootEl.value).direction === 'rtl'
|
|
47
47
|
}
|
|
48
48
|
})
|
|
49
|
-
const isRtl = computed(() => props.rtl ?? inheritedRtl.value)
|
|
50
|
-
|
|
51
49
|
const from = ref<number>(Array.isArray(props.modelValue) ? props.modelValue[0] : (props.modelValue ?? min))
|
|
52
50
|
const to = ref<number>(Array.isArray(props.modelValue) ? props.modelValue[1] : max)
|
|
53
51
|
|
|
@@ -80,7 +80,7 @@ function handleMouseLeave() {
|
|
|
80
80
|
cursor: 'pointer',
|
|
81
81
|
borderRadius: '2px',
|
|
82
82
|
transition: 'background-color 0.1s ease',
|
|
83
|
-
}" @focus="handleCellHover(cell)" @mouseenter="handleCellHover(cell.row, cell.col)" @click="handleCellClick(cell.row, cell.col, hide)"
|
|
83
|
+
}" @focus="handleCellHover(cell.row, cell.col)" @mouseenter="handleCellHover(cell.row, cell.col)" @click="handleCellClick(cell.row, cell.col, hide)"
|
|
84
84
|
/>
|
|
85
85
|
</div>
|
|
86
86
|
|
|
@@ -164,11 +164,15 @@ th {
|
|
|
164
164
|
text-align: end;
|
|
165
165
|
max-width: 100%;
|
|
166
166
|
cursor: pointer;
|
|
167
|
-
transition:
|
|
167
|
+
transition: var(--bgl-transition);
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
.richtext-editor-content .image-figure:hover {
|
|
171
|
-
|
|
171
|
+
filter: var(--bgl-hover-filter);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.richtext-editor-content .image-figure:active {
|
|
175
|
+
filter: var(--bgl-active-filter);
|
|
172
176
|
}
|
|
173
177
|
|
|
174
178
|
.richtext-editor-content .image-figure img {
|
|
@@ -229,9 +233,7 @@ th {
|
|
|
229
233
|
}
|
|
230
234
|
|
|
231
235
|
.richtext-editor-content .video-figure:hover {
|
|
232
|
-
|
|
233
|
-
filter: brightness(90%);
|
|
234
|
-
--bgl-transition-400: all 400ms ease;
|
|
236
|
+
filter: var(--bgl-hover-filter);
|
|
235
237
|
}
|
|
236
238
|
|
|
237
239
|
.richtext-editor-content .video-figure:active {
|
|
@@ -292,13 +294,17 @@ th {
|
|
|
292
294
|
text-align: center;
|
|
293
295
|
max-width: 100%;
|
|
294
296
|
cursor: pointer;
|
|
295
|
-
transition:
|
|
297
|
+
transition: var(--bgl-transition);
|
|
296
298
|
}
|
|
297
299
|
|
|
298
300
|
.richtext-editor-content .embed-figure:hover {
|
|
299
301
|
filter: var(--bgl-hover-filter);
|
|
300
302
|
}
|
|
301
303
|
|
|
304
|
+
.richtext-editor-content .embed-figure:active {
|
|
305
|
+
filter: var(--bgl-active-filter);
|
|
306
|
+
}
|
|
307
|
+
|
|
302
308
|
.richtext-editor-content .embed-figure iframe {
|
|
303
309
|
display: block;
|
|
304
310
|
max-width: 100%;
|
|
@@ -307,12 +313,12 @@ th {
|
|
|
307
313
|
border: 1px solid var(--bgl-border-color, #ddd);
|
|
308
314
|
border-radius: 8px;
|
|
309
315
|
background: white;
|
|
310
|
-
transition:
|
|
316
|
+
transition: var(--bgl-transition);
|
|
311
317
|
pointer-events: none;
|
|
312
318
|
}
|
|
313
319
|
|
|
314
320
|
.richtext-editor-content .embed-figure:hover iframe {
|
|
315
|
-
box-shadow: 0 4px 12px
|
|
321
|
+
box-shadow: 0 4px 12px var(--bgl-shadow);
|
|
316
322
|
}
|
|
317
323
|
|
|
318
324
|
.richtext-editor-content .embed-figure figcaption {
|
|
@@ -2119,7 +2119,7 @@ onUnmounted(() => {
|
|
|
2119
2119
|
function setupTableEditButtons(doc: Document) {
|
|
2120
2120
|
// Simple function to add edit buttons to all tables
|
|
2121
2121
|
function addEditButtonsToTables() {
|
|
2122
|
-
const tables = doc.querySelectorAll('table:not([data-edit-button-added])')
|
|
2122
|
+
const tables = doc.querySelectorAll<HTMLTableElement>('table:not([data-edit-button-added])')
|
|
2123
2123
|
|
|
2124
2124
|
tables.forEach((table, index) => {
|
|
2125
2125
|
// Create edit button as a span element instead of button
|
|
@@ -247,7 +247,9 @@ background: #f5f5f5;
|
|
|
247
247
|
color: var(--bgl-input-color);
|
|
248
248
|
position: absolute;
|
|
249
249
|
inset-inline-end: calc(var(--bgl-input-height) / 3 - 0.25rem);
|
|
250
|
-
|
|
250
|
+
/* center on the input row regardless of input height (dense/small/default) */
|
|
251
|
+
top: calc(var(--bgl-input-height) / 2);
|
|
252
|
+
transform: translateY(-50%);
|
|
251
253
|
line-height: 0;
|
|
252
254
|
}
|
|
253
255
|
|
|
@@ -260,7 +262,9 @@ padding-inline-end: calc(var(--bgl-input-height) / 3 + 1.5rem);
|
|
|
260
262
|
color: var(--bgl-input-color);
|
|
261
263
|
position: absolute;
|
|
262
264
|
inset-inline-start: calc(var(--bgl-input-height) / 3 - 0.25rem);
|
|
263
|
-
|
|
265
|
+
/* center on the input row regardless of input height (dense/small/default) */
|
|
266
|
+
top: calc(var(--bgl-input-height) / 2);
|
|
267
|
+
transform: translateY(-50%);
|
|
264
268
|
line-height: 0;
|
|
265
269
|
}
|
|
266
270
|
|
|
@@ -23,7 +23,13 @@
|
|
|
23
23
|
|
|
24
24
|
.fileUploadWrap.dragover,
|
|
25
25
|
.fileUploadWrap:hover {
|
|
26
|
-
box-shadow: inset 0 0 10px
|
|
26
|
+
box-shadow: inset 0 0 10px var(--bgl-shadow);
|
|
27
|
+
filter: var(--bgl-hover-filter);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.fileUploadWrap.dragover:active,
|
|
31
|
+
.fileUploadWrap:active {
|
|
32
|
+
filter: var(--bgl-active-filter);
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
.fileUploadWrap[style*='height: auto;'] {
|
package/src/components/index.ts
CHANGED
|
@@ -22,6 +22,8 @@ export { default as DragOver } from './DragOver.vue'
|
|
|
22
22
|
export { default as Dropdown } from './Dropdown.vue'
|
|
23
23
|
export { default as EmptyState } from './EmptyState.vue'
|
|
24
24
|
export { default as FieldSetVue } from './FieldSetVue.vue'
|
|
25
|
+
export { default as KanbanBoard } from './kanban/KanbanBoard.vue'
|
|
26
|
+
export type { KanbanBoardProps, KanbanColumn, KanbanCardSchema, KanbanMoveEvent } from './kanban/kanbanTypes'
|
|
25
27
|
export { default as FilterQuery } from './FilterQuery.vue'
|
|
26
28
|
export type { FilterField, QueryOption } from './FilterQuery.types'
|
|
27
29
|
export { default as Flag } from './Flag.vue'
|