@bagelink/vue 1.9.81 → 1.9.86
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/Avatar.vue.d.ts +1 -0
- package/dist/components/Avatar.vue.d.ts.map +1 -1
- package/dist/components/Badge.vue.d.ts +0 -1
- package/dist/components/Badge.vue.d.ts.map +1 -1
- package/dist/components/Btn.vue.d.ts.map +1 -1
- package/dist/components/Dropdown.vue.d.ts.map +1 -1
- package/dist/components/Loading.vue.d.ts +2 -1
- package/dist/components/Loading.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RadioGroup.vue.d.ts +12 -3
- package/dist/components/form/inputs/RadioGroup.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
- package/dist/form-flow/FormFlow.vue.d.ts.map +1 -1
- package/dist/form-flow/form-flow.d.ts +9 -9
- package/dist/form-flow/form-flow.d.ts.map +1 -1
- package/dist/index.cjs +165 -87
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +26221 -26015
- package/dist/plugins/useToast.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/dist/utils/filterRef.d.ts +15 -0
- package/dist/utils/filterRef.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/Avatar.vue +6 -2
- package/src/components/Badge.vue +14 -1084
- package/src/components/Btn.vue +37 -37
- package/src/components/Dropdown.vue +1 -1
- package/src/components/Loading.vue +15 -7
- package/src/components/form/inputs/RadioGroup.vue +24 -13
- package/src/components/form/inputs/RichText/index.vue +325 -221
- package/src/form-flow/FormFlow.vue +9 -0
- package/src/form-flow/form-flow.ts +13 -3
- package/src/index.ts +1 -1
- package/src/plugins/useToast.ts +14 -0
- package/src/styles/bagel.css +1 -0
- package/src/styles/base-colors.css +1429 -46
- package/src/styles/text.css +1755 -1755
- package/src/styles/toast-overrides.css +10 -0
- package/src/utils/filterRef.ts +133 -0
- package/src/styles/btnColors.css +0 -847
package/src/components/Btn.vue
CHANGED
|
@@ -59,6 +59,18 @@ const emit = defineEmits<{
|
|
|
59
59
|
|
|
60
60
|
const { $t } = useI18n()
|
|
61
61
|
|
|
62
|
+
const computedPairClass = computed(() => {
|
|
63
|
+
const theme = props.color || props.theme
|
|
64
|
+
if (!theme) {
|
|
65
|
+
// Only flat/border buttons get a default for visibility
|
|
66
|
+
if (props.flat || props.border || props.outline) {
|
|
67
|
+
return 'pair-black'
|
|
68
|
+
}
|
|
69
|
+
return undefined
|
|
70
|
+
}
|
|
71
|
+
return `pair-${theme}`
|
|
72
|
+
})
|
|
73
|
+
|
|
62
74
|
const isMobileScreen = ref(false)
|
|
63
75
|
|
|
64
76
|
function checkMobile() {
|
|
@@ -140,7 +152,7 @@ const slots: SetupContext['slots'] = useSlots()
|
|
|
140
152
|
|
|
141
153
|
<template>
|
|
142
154
|
<component
|
|
143
|
-
:is="isComponent" v-ripple="ripple" v-bind="bind" :disabled="disabled" class="bgl_btn" :class="{
|
|
155
|
+
:is="isComponent" v-ripple="ripple" v-bind="bind" :disabled="disabled" class="bgl_btn" :class="[{
|
|
144
156
|
'bgl_btn-icon': icon && !slots.default && !value,
|
|
145
157
|
thin,
|
|
146
158
|
'bgl_btn_xsSize': size === 'xs' || size === 'extra-small',
|
|
@@ -155,11 +167,9 @@ const slots: SetupContext['slots'] = useSlots()
|
|
|
155
167
|
'bgl_btn_alignStartMobile': alignTxtMobile === 'start',
|
|
156
168
|
'bgl_btn_alignEndMobile': alignTxtMobile === 'end',
|
|
157
169
|
round,
|
|
158
|
-
'
|
|
159
|
-
'
|
|
160
|
-
|
|
161
|
-
[`bgl_btn-${theme}`]: theme,
|
|
162
|
-
}" :tabindex="disabled ? -1 : 0" @click.stop="handleClick" @keydown.enter="handleClick" @keydown.space="handleClick"
|
|
170
|
+
'bgl_flatPill': flat,
|
|
171
|
+
'bgl_pill-border': border || outline,
|
|
172
|
+
}, computedPairClass]" :tabindex="disabled ? -1 : 0" @click.stop="handleClick" @keydown.enter="handleClick" @keydown.space="handleClick"
|
|
163
173
|
>
|
|
164
174
|
<Loading v-if="loading" class="h-100p" size="15" />
|
|
165
175
|
<div v-else class="bgl_btn-flex">
|
|
@@ -180,15 +190,14 @@ const slots: SetupContext['slots'] = useSlots()
|
|
|
180
190
|
</template>
|
|
181
191
|
|
|
182
192
|
<style scoped>
|
|
183
|
-
@import '../styles/
|
|
193
|
+
/* @import '../styles/base-colors.css'; */
|
|
184
194
|
|
|
185
195
|
.bgl_btn {
|
|
186
196
|
padding-left: var(--btn-padding);
|
|
187
197
|
padding-right: var(--btn-padding);
|
|
188
198
|
transition: var(--bgl-transition);
|
|
189
|
-
background: var(--btn-bg);
|
|
190
|
-
color: var(--btn-color);
|
|
191
199
|
text-decoration: none;
|
|
200
|
+
/* Colors now handled by pair-* classes */
|
|
192
201
|
}
|
|
193
202
|
|
|
194
203
|
.bgl_btn.bgl_btn-icon {
|
|
@@ -227,20 +236,7 @@ a {
|
|
|
227
236
|
filter: var(--bgl-active-filter);
|
|
228
237
|
}
|
|
229
238
|
|
|
230
|
-
.
|
|
231
|
-
background: transparent;
|
|
232
|
-
color: var(--btn-flat-color);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
.bgl_btn_flat:hover:not(:disabled),
|
|
236
|
-
.bgl_btn-icon.bgl_btn_flat:hover:not(:disabled) {
|
|
237
|
-
background: var(--bgl-gray-tint);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
.bgl_btn.bgl_btn_flat:active:not(:disabled),
|
|
241
|
-
.bgl_btn-icon.bgl_btn_flat:active:not(:disabled) {
|
|
242
|
-
background: var(--bgl-gray-tint-dark);
|
|
243
|
-
}
|
|
239
|
+
/* Flat hover/active styles now handled by base-colors.css */
|
|
244
240
|
|
|
245
241
|
.bgl_btn.round {
|
|
246
242
|
border-radius: 1000px !important;
|
|
@@ -254,20 +250,7 @@ a {
|
|
|
254
250
|
transform: rotateY(0deg);
|
|
255
251
|
}
|
|
256
252
|
|
|
257
|
-
.
|
|
258
|
-
.bgl_btn-icon.bgl_btn_flat.bgl_btn-border {
|
|
259
|
-
border: 1px solid var(--btn-flat-color);
|
|
260
|
-
background: transparent;
|
|
261
|
-
color: var(--btn-flat-color);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
.bgl_btn-border:hover {
|
|
265
|
-
color: var(--btn-flat-color);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
.bgl_btn-border:active:not(:disabled) {
|
|
269
|
-
filter: brightness(80%);
|
|
270
|
-
}
|
|
253
|
+
/* Border active styles now handled by base-colors.css */
|
|
271
254
|
|
|
272
255
|
.bgl_btn:disabled,
|
|
273
256
|
.bgl_btn[disabled=true] {
|
|
@@ -399,4 +382,21 @@ a {
|
|
|
399
382
|
justify-content: flex-end;
|
|
400
383
|
}
|
|
401
384
|
}
|
|
385
|
+
|
|
386
|
+
/* Ensure external color classes always override pair classes */
|
|
387
|
+
.bgl_btn.color-white {
|
|
388
|
+
color: white !important;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.bgl_btn.color-black {
|
|
392
|
+
color: black !important;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.bgl_btn.text-white {
|
|
396
|
+
color: white !important;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.bgl_btn.text-black {
|
|
400
|
+
color: black !important;
|
|
401
|
+
}
|
|
402
402
|
</style>
|
|
@@ -191,7 +191,7 @@ const computedPopperHideTriggers = computed((): TriggerEvent[] => {
|
|
|
191
191
|
|
|
192
192
|
const computedAutoHide = computed(() => autoHide)
|
|
193
193
|
|
|
194
|
-
const container = computed(() =>
|
|
194
|
+
const container = computed(() => 'body')
|
|
195
195
|
|
|
196
196
|
const computedDelay = computed((): number | { show: number, hide: number } | undefined => {
|
|
197
197
|
if (delay !== undefined) { return delay }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import type { ThemeType } from '@bagelink/vue'
|
|
2
3
|
import type { SizeUnit, SizeType } from '../types/BtnOptions'
|
|
3
4
|
import { computed } from 'vue'
|
|
4
5
|
import { standardSize } from '../utils/sizeParsing'
|
|
@@ -10,7 +11,7 @@ const { type: theme = 'ring', size = 50, thickness, duration = 1.2, color, progr
|
|
|
10
11
|
thickness?: SizeUnit
|
|
11
12
|
duration?: number | string
|
|
12
13
|
type?: LoadingType
|
|
13
|
-
color?: string
|
|
14
|
+
color?: ThemeType | string
|
|
14
15
|
progress?: number
|
|
15
16
|
}>()
|
|
16
17
|
|
|
@@ -22,6 +23,14 @@ const computedBorder = computed(() => {
|
|
|
22
23
|
return standardSize(borderValue)
|
|
23
24
|
})
|
|
24
25
|
|
|
26
|
+
const computedColor = computed(() => {
|
|
27
|
+
if (!color) return 'var(--bgl-black)'
|
|
28
|
+
if (color.startsWith('#') || color.startsWith('rgb') || color.startsWith('var(')) {
|
|
29
|
+
return color // Custom color string
|
|
30
|
+
}
|
|
31
|
+
return `var(--bgl-${color})` // Convert theme color to CSS variable
|
|
32
|
+
})
|
|
33
|
+
|
|
25
34
|
// SVG progress calculations
|
|
26
35
|
const svgStrokeWidth = computed(() => {
|
|
27
36
|
const borderNumeric = Number.parseFloat(computedBorder.value)
|
|
@@ -40,14 +49,14 @@ const svgCircumference = computed(() => Math.PI * 2 * svgRadius.value)
|
|
|
40
49
|
<!-- Bar Theme -->
|
|
41
50
|
<template v-if="theme === 'bar'">
|
|
42
51
|
<slot />
|
|
43
|
-
<div class="lds-bar" :style="{ animationDuration, color }" />
|
|
52
|
+
<div class="lds-bar" :style="{ animationDuration, color: computedColor }" />
|
|
44
53
|
</template>
|
|
45
54
|
|
|
46
55
|
<!-- Ellipsis Theme -->
|
|
47
56
|
<template v-if="theme === 'ellipsis'">
|
|
48
57
|
<slot />
|
|
49
58
|
<div class="lds-ellipsis" :style="{ '--size': computedSize }">
|
|
50
|
-
<div v-for="n in 4" :key="n" :style="{ color, '--size': computedSize }" />
|
|
59
|
+
<div v-for="n in 4" :key="n" :style="{ 'color': computedColor, '--size': computedSize }" />
|
|
51
60
|
</div>
|
|
52
61
|
</template>
|
|
53
62
|
|
|
@@ -56,11 +65,11 @@ const svgCircumference = computed(() => Math.PI * 2 * svgRadius.value)
|
|
|
56
65
|
<template v-if="progress !== undefined">
|
|
57
66
|
<svg :width="computedSize" :height="computedSize" viewBox="0 0 100 100">
|
|
58
67
|
<circle
|
|
59
|
-
cx="50" cy="50" :r="svgRadius" fill="none" :stroke="
|
|
68
|
+
cx="50" cy="50" :r="svgRadius" fill="none" :stroke="computedColor"
|
|
60
69
|
:stroke-width="svgStrokeWidth" stroke-opacity="0.2"
|
|
61
70
|
/>
|
|
62
71
|
<circle
|
|
63
|
-
cx="50" cy="50" :r="svgRadius" fill="none" :stroke="
|
|
72
|
+
cx="50" cy="50" :r="svgRadius" fill="none" :stroke="computedColor"
|
|
64
73
|
:stroke-width="svgStrokeWidth" stroke-linecap="round"
|
|
65
74
|
:stroke-dasharray="`${(progress / 100) * svgCircumference} ${svgCircumference}`"
|
|
66
75
|
transform="rotate(-90 50 50)"
|
|
@@ -69,7 +78,7 @@ const svgCircumference = computed(() => Math.PI * 2 * svgRadius.value)
|
|
|
69
78
|
</template>
|
|
70
79
|
<div
|
|
71
80
|
v-for="n in 4" v-else :key="n" class="ring-segment" :style="{
|
|
72
|
-
color,
|
|
81
|
+
'color': computedColor,
|
|
73
82
|
'width': computedSize,
|
|
74
83
|
'height': computedSize,
|
|
75
84
|
'borderWidth': computedBorder,
|
|
@@ -96,7 +105,6 @@ const svgCircumference = computed(() => Math.PI * 2 * svgRadius.value)
|
|
|
96
105
|
.lds-bar {
|
|
97
106
|
height: var(--thickness, 4px);
|
|
98
107
|
width: 100%;
|
|
99
|
-
max-width: 130px;
|
|
100
108
|
--c: no-repeat linear-gradient(currentColor 0 0);
|
|
101
109
|
background: var(--c), var(--c), #ddd;
|
|
102
110
|
background-size: 60% 100%;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts" generic="ContextObjType extends { [key: string]: any }">
|
|
2
|
+
import type { Option } from '@bagelink/vue'
|
|
2
3
|
import { Btn } from '@bagelink/vue'
|
|
3
4
|
import { computed, ref, watch } from 'vue'
|
|
4
5
|
|
|
5
|
-
export interface RadioOption<T> {
|
|
6
|
+
export interface RadioOption<T = any> {
|
|
6
7
|
imgAlt?: string
|
|
7
8
|
imgSrc?: string
|
|
8
9
|
subLabel?: string
|
|
@@ -12,7 +13,9 @@ export interface RadioOption<T> {
|
|
|
12
13
|
value: any
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
type
|
|
16
|
+
type NormalizedRadioOption<T> = Required<Pick<RadioOption<T>, 'value'>> & Omit<RadioOption<T>, 'value'>
|
|
17
|
+
|
|
18
|
+
type RadioOptionsSource<T> = (Option | RadioOption<T>)[] | (() => Promise<(Option | RadioOption<T>)[]>)
|
|
16
19
|
|
|
17
20
|
const props = withDefaults(
|
|
18
21
|
defineProps<{
|
|
@@ -41,6 +44,13 @@ const props = withDefaults(
|
|
|
41
44
|
|
|
42
45
|
const emit = defineEmits(['delete', 'focus', 'blur', 'change'])
|
|
43
46
|
|
|
47
|
+
function normalizeOption<T>(opt: Option | RadioOption<T>): NormalizedRadioOption<T> {
|
|
48
|
+
if (typeof opt === 'string') { return { label: opt, value: opt } }
|
|
49
|
+
if (typeof opt === 'number') { return { label: `${opt}`, value: opt } }
|
|
50
|
+
if (typeof opt === 'boolean') { return { label: `${opt}`, value: opt } }
|
|
51
|
+
return opt as NormalizedRadioOption<T>
|
|
52
|
+
}
|
|
53
|
+
|
|
44
54
|
const name = computed(
|
|
45
55
|
() => (
|
|
46
56
|
props.groupName
|
|
@@ -49,8 +59,11 @@ const name = computed(
|
|
|
49
59
|
)
|
|
50
60
|
)
|
|
51
61
|
const selectedOption = defineModel('modelValue')
|
|
52
|
-
const loadedOptions = ref<
|
|
53
|
-
const visibleOptions = computed(() =>
|
|
62
|
+
const loadedOptions = ref<(Option | RadioOption<ContextObjType>)[]>([])
|
|
63
|
+
const visibleOptions = computed<NormalizedRadioOption<ContextObjType>[]>(() => {
|
|
64
|
+
const raw = Array.isArray(props.options) ? props.options : loadedOptions.value
|
|
65
|
+
return raw.map(opt => normalizeOption<ContextObjType>(opt))
|
|
66
|
+
})
|
|
54
67
|
|
|
55
68
|
async function loadOptionsIfNeeded() {
|
|
56
69
|
if (typeof props.options === 'function') {
|
|
@@ -93,8 +106,7 @@ function handleChange() {
|
|
|
93
106
|
<div :class="containerClasses">
|
|
94
107
|
<label
|
|
95
108
|
v-for="(opt, index) in visibleOptions" :key="opt.id || `${name}-${index}`"
|
|
96
|
-
class="border rounded flex active-list-item hover"
|
|
97
|
-
:for="opt.id || `${name}-${index}`"
|
|
109
|
+
class="border rounded flex active-list-item hover" :for="opt.id || `${name}-${index}`"
|
|
98
110
|
:class="{ 'p-05 gap-025': thin, 'py-1 gap-075': !thin, 'ps-05': !hideRadio, 'bg-gray-light': !bgColor && !flat, 'align-items-start': align === 'start' || align === 'top', 'align-items-center': align === 'center', 'align-items-end': align === 'end' || align === 'bottom', invertedActive }"
|
|
99
111
|
:style="{ backgroundColor: bgColor, borderColor }"
|
|
100
112
|
>
|
|
@@ -104,9 +116,7 @@ function handleChange() {
|
|
|
104
116
|
'mt-025': align === 'start' || align === 'top',
|
|
105
117
|
'mb-025': align === 'end' || align === 'bottom',
|
|
106
118
|
'hideRadio': hideRadio,
|
|
107
|
-
}" @focus="handleFocus"
|
|
108
|
-
@blur="handleBlur"
|
|
109
|
-
@change="handleChange"
|
|
119
|
+
}" @focus="handleFocus" @blur="handleBlur" @change="handleChange"
|
|
110
120
|
>
|
|
111
121
|
<div
|
|
112
122
|
class="flex w-100 gap-1 flex-wrap m_gap-05 m_gap-row-025"
|
|
@@ -114,8 +124,8 @@ function handleChange() {
|
|
|
114
124
|
:style="{ color: textColor }"
|
|
115
125
|
>
|
|
116
126
|
<img
|
|
117
|
-
v-if="opt.imgSrc" class="
|
|
118
|
-
:alt="opt.imgAlt"
|
|
127
|
+
v-if="opt.imgSrc" class="py-025 radius-05 m_w40 object-fit" height="40" width="40"
|
|
128
|
+
:src="opt.imgSrc" :alt="opt.imgAlt"
|
|
119
129
|
>
|
|
120
130
|
<div class="">
|
|
121
131
|
<div v-if="opt.label" class="m-0 m_txt-14 line-height-14" v-html="opt.label" />
|
|
@@ -132,11 +142,12 @@ function handleChange() {
|
|
|
132
142
|
.hideRadio.radio-input-list {
|
|
133
143
|
display: none !important;
|
|
134
144
|
}
|
|
145
|
+
|
|
135
146
|
.radio-input-list {
|
|
136
147
|
width: auto;
|
|
137
148
|
transform: scale(1.2);
|
|
138
|
-
|
|
139
|
-
|
|
149
|
+
margin-inline-end: 0.5rem;
|
|
150
|
+
margin-top: 0;
|
|
140
151
|
}
|
|
141
152
|
|
|
142
153
|
.radio-input-list.hidden {
|