bootstrap-vue-next 0.46.4 → 1.0.1
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/{BFormFile-BVrDprWL.js → BFormFile-C2DnrbK7.js} +30 -10
- package/dist/BFormFile-C2DnrbK7.js.map +1 -0
- package/dist/{BFormOtp-C3vmDnzs.js → BFormOtp-ClDACqXM.js} +2 -2
- package/dist/{BFormOtp-C3vmDnzs.js.map → BFormOtp-ClDACqXM.js.map} +1 -1
- package/dist/{BFormRating-AEiF8K8T.js → BFormRating-iKFgSFet.js} +81 -66
- package/dist/BFormRating-iKFgSFet.js.map +1 -0
- package/dist/bootstrap-vue-next.css +28 -22
- package/dist/bootstrap-vue-next.mjs +3 -3
- package/dist/components/BFormFile/useAriaLiveMessage.d.mts +10 -0
- package/dist/components/BFormFile/useAriaLiveMessage.d.ts +10 -0
- package/dist/components/BFormRating/BFormRating.vue.d.mts +3 -3
- package/dist/components/BFormRating/BFormRating.vue.d.ts +3 -3
- package/dist/src/components/BFormFile/index.mjs +1 -1
- package/dist/src/components/BFormOtp/index.mjs +1 -1
- package/dist/src/components/BFormRating/index.mjs +1 -1
- package/dist/src/components/index.mjs +3 -3
- package/dist/src/composables/orchestratorShared/index.mjs +4 -0
- package/dist/src/composables/orchestratorShared/index.mjs.map +1 -1
- package/dist/types/ComponentProps.d.mts +3 -3
- package/dist/types/ComponentProps.d.ts +3 -3
- package/dist/types/ComponentSlots.d.mts +1 -1
- package/dist/types/ComponentSlots.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/BFormRating/_form-rating.scss +30 -25
- package/dist/BFormFile-BVrDprWL.js.map +0 -1
- package/dist/BFormRating-AEiF8K8T.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BFormRating-iKFgSFet.js","names":[],"sources":["../src/components/BFormRating/BFormRating.vue","../src/components/BFormRating/BFormRating.vue"],"sourcesContent":["<template>\n <output\n :id=\"computedId\"\n :class=\"computedClasses\"\n :dir=\"computedRtl ? 'rtl' : 'ltr'\"\n :form=\"props.form ? props.form : undefined\"\n role=\"slider\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"computedLength\"\n :aria-valuenow=\"displayValue\"\n :aria-valuetext=\"props.labelValueCurrent(displayValue, computedLength)\"\n :aria-disabled=\"props.disabled ? true : undefined\"\n :aria-readonly=\"props.readonly ? true : undefined\"\n :tabindex=\"props.disabled ? undefined : '0'\"\n @keydown=\"onKeydown\"\n >\n <input\n v-if=\"props.name && !props.disabled\"\n key=\"hidden\"\n type=\"hidden\"\n :name=\"props.name\"\n :form=\"props.form\"\n :value=\"modelValue\"\n />\n <span\n v-if=\"props.showClear && !props.readonly && !props.disabled\"\n class=\"rating-clear-button\"\n @click=\"clearRating\"\n >\n <slot name=\"icon-clear\">\n <svg\n viewBox=\"0 0 16 16\"\n role=\"img\"\n :aria-label=\"props.clearLabel\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"clear-icon\"\n >\n <g>\n <path :d=\"iconPaths.clear\" />\n </g>\n </svg>\n </slot>\n </span>\n <span\n v-for=\"(itemIndex, index) in computedLength\"\n :key=\"itemIndex\"\n class=\"rating-item flex-grow-1\"\n @click=\"selectRating(itemIndex)\"\n >\n <slot :item-index=\"itemIndex\" :is-filled=\"isIconFull(index)\" :is-half=\"isIconHalf(index)\">\n <span class=\"b-form-rating-item\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n :width=\"computedSize\"\n :height=\"computedSize\"\n fill=\"currentColor\"\n :class=\"[iconColors[index]?.class]\"\n :style=\"iconColors[index]?.style\"\n viewBox=\"0 0 16 16\"\n >\n <path :d=\"getIcon(index)\" />\n </svg>\n </span>\n </slot>\n </span>\n\n <span\n v-if=\"props.showValue || props.showValueMax\"\n :style=\"{fontSize: computedSize}\"\n class=\"rating-value-text\"\n >\n {{ displayValueText }}\n </span>\n </output>\n</template>\n\n<script setup lang=\"ts\">\nimport {computed, ref} from 'vue'\nimport {useToNumber} from '@vueuse/core'\nimport {useDefaults} from '../../composables/useDefaults'\nimport {useId} from '../../composables/useId'\nimport {useRtl} from '../../composables/useRtl'\nimport type {BFormRatingProps, BFormRatingSlots, Size} from '../../types'\n\nconst lengthDefault = 5\nconst _props = withDefaults(defineProps<Omit<BFormRatingProps, 'modelValue'>>(), {\n clearLabel: 'Clear rating',\n color: '',\n id: undefined,\n inline: false,\n labelValueCurrent: (current: number, max: number) => `${current} of ${max}`,\n locale: undefined,\n noBorder: false,\n precision: 0,\n readonly: false,\n disabled: false,\n form: undefined,\n name: undefined,\n showClear: false,\n showValue: false,\n showValueMax: false,\n size: undefined,\n length: lengthDefault,\n variant: undefined,\n})\nconst props = useDefaults(_props, 'BFormRating')\ndefineSlots<BFormRatingSlots>()\n\nconst modelValue = defineModel<Exclude<BFormRatingProps['modelValue'], undefined>>({default: 0})\n\nconst computedId = useId(() => props.id, 'form-rating')\n\nconst {isRtl, locale: globalLocale} = useRtl()\n\nconst computedLocale = computed(() => {\n const loc = (props.locale ?? globalLocale?.value) || undefined\n const nf = new Intl.NumberFormat(loc)\n return nf.resolvedOptions().locale\n})\n\nconst computedRtl = computed(() => {\n const locale = computedLocale.value\n try {\n const localeObj = new Intl.Locale(locale)\n const {textInfo} = localeObj as Intl.Locale & {textInfo?: {direction: string}}\n if (textInfo) {\n return textInfo.direction === 'rtl'\n }\n } catch {\n // Fallback\n }\n return isRtl?.value ?? false\n})\n\nconst computedClasses = computed(() => [\n 'form-control',\n 'b-form-rating',\n 'align-items-center',\n {\n 'is-readonly': props.readonly,\n 'is-disabled': props.disabled,\n 'no-border': props.noBorder,\n 'd-flex': !props.inline,\n 'd-inline-flex': props.inline,\n 'b-form-rating-inline': props.inline,\n },\n])\n\nconst isIconFull = (index: number): boolean => displayValue.value - index >= 1\nconst isIconHalf = (index: number): boolean => {\n const diff = displayValue.value - index\n return diff >= 0.5 && diff < 1\n}\nconst iconPaths = {\n full: 'M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z',\n half: 'M5.354 5.119 7.538.792A.52.52 0 0 1 8 .5c.183 0 .366.097.465.292l2.184 4.327 4.898.696A.54.54 0 0 1 16 6.32a.55.55 0 0 1-.17.445l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256a.5.5 0 0 1-.146.05c-.342.06-.668-.254-.6-.642l.83-4.73L.173 6.765a.55.55 0 0 1-.172-.403.6.6 0 0 1 .085-.302.51.51 0 0 1 .37-.245zM8 12.027a.5.5 0 0 1 .232.056l3.686 1.894-.694-3.957a.56.56 0 0 1 .162-.505l2.907-2.77-4.052-.576a.53.53 0 0 1-.393-.288L8.001 2.223 8 2.226z',\n empty:\n 'M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.522 3.356-.83 4.73zm4.905-2.767-3.686 1.894.694-3.957a.56.56 0 0 0-.163-.505L1.71 6.745l4.052-.576a.53.53 0 0 0 .393-.288L8 2.223l1.847 3.658a.53.53 0 0 0 .393.288l4.052.575-2.906 2.77a.56.56 0 0 0-.163.506l.694 3.957-3.686-1.894a.5.5 0 0 0-.461 0z',\n clear:\n 'M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708',\n} as const\nconst getIcon = (index: number): string => {\n if (isIconFull(index)) return iconPaths.full\n if (isIconHalf(index)) return iconPaths.half\n return iconPaths.empty\n}\n\nconst hoverValue = ref<number | null>(null)\n\nconst displayValue = computed(() =>\n hoverValue.value !== null ? hoverValue.value : modelValue.value\n)\n\nconst lengthNumber = useToNumber(() => props.length, {nanToZero: true, method: 'parseInt'})\nconst computedLength = computed(() => (lengthNumber.value > 0 ? lengthNumber.value : lengthDefault))\n\nconst computedSize = computed(() => {\n const resolved = {\n sm: 0.875,\n default: 1,\n lg: 1.25,\n } satisfies Record<Size | 'default', number>\n return `${resolved[props.size ?? 'default']}rem`\n})\n\nconst computedFormatter = computed(() => {\n const preciseValue = props.precision > 0 ? props.precision : 0\n return new Intl.NumberFormat(computedLocale.value, {\n style: 'decimal',\n useGrouping: false,\n minimumFractionDigits: preciseValue,\n maximumFractionDigits: preciseValue,\n notation: 'standard',\n })\n})\n\nconst displayValueText = computed(() => {\n const val = props.precision > 0 ? roundedValue.value : displayValue.value\n const formattedValue = computedFormatter.value.format(val)\n if (props.showValueMax) {\n const formattedMax = computedFormatter.value.format(computedLength.value)\n return `${formattedValue}/${formattedMax}`\n }\n if (props.showValue) {\n return formattedValue\n }\n return ''\n})\n\nconst roundedValue = computed(() => {\n const val = displayValue.value\n const factor = 10 ** props.precision\n return Math.round((val + Number.EPSILON) * factor) / factor\n})\n\nconst iconColors = computed(() =>\n Array.from({length: computedLength.value}, () => {\n if (props.disabled) {\n return {class: 'is-disabled', style: {}}\n }\n if (props.variant) {\n return {class: `text-${props.variant}`, style: {}}\n }\n if (props.color) {\n return {class: '', style: {color: props.color}}\n }\n return {class: '', style: {}}\n })\n)\n\n//add keyboard support\nconst onKeydown = (e: KeyboardEvent) => {\n if (props.readonly || props.disabled) return\n\n let newValue = modelValue.value\n\n const isRtlMode = computedRtl.value\n\n switch (e.key) {\n case 'ArrowRight':\n newValue = isRtlMode\n ? Math.max(newValue - 1, 0)\n : Math.min(newValue + 1, computedLength.value)\n break\n case 'ArrowUp':\n newValue = Math.min(newValue + 1, computedLength.value)\n break\n case 'ArrowLeft':\n newValue = isRtlMode\n ? Math.min(newValue + 1, computedLength.value)\n : Math.max(newValue - 1, 0)\n break\n case 'ArrowDown':\n newValue = Math.max(newValue - 1, 0)\n break\n default:\n return\n }\n\n e.preventDefault()\n modelValue.value = newValue\n}\n\nconst selectRating = (itemIndex: number) => {\n if (props.readonly || props.disabled) return\n modelValue.value = hoverValue.value !== null ? hoverValue.value : itemIndex\n}\n\n// clear\nconst clearRating = () => {\n hoverValue.value = null\n modelValue.value = 0\n}\n\ndefineExpose({\n hoverValue,\n})\n</script>\n","<template>\n <output\n :id=\"computedId\"\n :class=\"computedClasses\"\n :dir=\"computedRtl ? 'rtl' : 'ltr'\"\n :form=\"props.form ? props.form : undefined\"\n role=\"slider\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"computedLength\"\n :aria-valuenow=\"displayValue\"\n :aria-valuetext=\"props.labelValueCurrent(displayValue, computedLength)\"\n :aria-disabled=\"props.disabled ? true : undefined\"\n :aria-readonly=\"props.readonly ? true : undefined\"\n :tabindex=\"props.disabled ? undefined : '0'\"\n @keydown=\"onKeydown\"\n >\n <input\n v-if=\"props.name && !props.disabled\"\n key=\"hidden\"\n type=\"hidden\"\n :name=\"props.name\"\n :form=\"props.form\"\n :value=\"modelValue\"\n />\n <span\n v-if=\"props.showClear && !props.readonly && !props.disabled\"\n class=\"rating-clear-button\"\n @click=\"clearRating\"\n >\n <slot name=\"icon-clear\">\n <svg\n viewBox=\"0 0 16 16\"\n role=\"img\"\n :aria-label=\"props.clearLabel\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"clear-icon\"\n >\n <g>\n <path :d=\"iconPaths.clear\" />\n </g>\n </svg>\n </slot>\n </span>\n <span\n v-for=\"(itemIndex, index) in computedLength\"\n :key=\"itemIndex\"\n class=\"rating-item flex-grow-1\"\n @click=\"selectRating(itemIndex)\"\n >\n <slot :item-index=\"itemIndex\" :is-filled=\"isIconFull(index)\" :is-half=\"isIconHalf(index)\">\n <span class=\"b-form-rating-item\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n :width=\"computedSize\"\n :height=\"computedSize\"\n fill=\"currentColor\"\n :class=\"[iconColors[index]?.class]\"\n :style=\"iconColors[index]?.style\"\n viewBox=\"0 0 16 16\"\n >\n <path :d=\"getIcon(index)\" />\n </svg>\n </span>\n </slot>\n </span>\n\n <span\n v-if=\"props.showValue || props.showValueMax\"\n :style=\"{fontSize: computedSize}\"\n class=\"rating-value-text\"\n >\n {{ displayValueText }}\n </span>\n </output>\n</template>\n\n<script setup lang=\"ts\">\nimport {computed, ref} from 'vue'\nimport {useToNumber} from '@vueuse/core'\nimport {useDefaults} from '../../composables/useDefaults'\nimport {useId} from '../../composables/useId'\nimport {useRtl} from '../../composables/useRtl'\nimport type {BFormRatingProps, BFormRatingSlots, Size} from '../../types'\n\nconst lengthDefault = 5\nconst _props = withDefaults(defineProps<Omit<BFormRatingProps, 'modelValue'>>(), {\n clearLabel: 'Clear rating',\n color: '',\n id: undefined,\n inline: false,\n labelValueCurrent: (current: number, max: number) => `${current} of ${max}`,\n locale: undefined,\n noBorder: false,\n precision: 0,\n readonly: false,\n disabled: false,\n form: undefined,\n name: undefined,\n showClear: false,\n showValue: false,\n showValueMax: false,\n size: undefined,\n length: lengthDefault,\n variant: undefined,\n})\nconst props = useDefaults(_props, 'BFormRating')\ndefineSlots<BFormRatingSlots>()\n\nconst modelValue = defineModel<Exclude<BFormRatingProps['modelValue'], undefined>>({default: 0})\n\nconst computedId = useId(() => props.id, 'form-rating')\n\nconst {isRtl, locale: globalLocale} = useRtl()\n\nconst computedLocale = computed(() => {\n const loc = (props.locale ?? globalLocale?.value) || undefined\n const nf = new Intl.NumberFormat(loc)\n return nf.resolvedOptions().locale\n})\n\nconst computedRtl = computed(() => {\n const locale = computedLocale.value\n try {\n const localeObj = new Intl.Locale(locale)\n const {textInfo} = localeObj as Intl.Locale & {textInfo?: {direction: string}}\n if (textInfo) {\n return textInfo.direction === 'rtl'\n }\n } catch {\n // Fallback\n }\n return isRtl?.value ?? false\n})\n\nconst computedClasses = computed(() => [\n 'form-control',\n 'b-form-rating',\n 'align-items-center',\n {\n 'is-readonly': props.readonly,\n 'is-disabled': props.disabled,\n 'no-border': props.noBorder,\n 'd-flex': !props.inline,\n 'd-inline-flex': props.inline,\n 'b-form-rating-inline': props.inline,\n },\n])\n\nconst isIconFull = (index: number): boolean => displayValue.value - index >= 1\nconst isIconHalf = (index: number): boolean => {\n const diff = displayValue.value - index\n return diff >= 0.5 && diff < 1\n}\nconst iconPaths = {\n full: 'M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z',\n half: 'M5.354 5.119 7.538.792A.52.52 0 0 1 8 .5c.183 0 .366.097.465.292l2.184 4.327 4.898.696A.54.54 0 0 1 16 6.32a.55.55 0 0 1-.17.445l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256a.5.5 0 0 1-.146.05c-.342.06-.668-.254-.6-.642l.83-4.73L.173 6.765a.55.55 0 0 1-.172-.403.6.6 0 0 1 .085-.302.51.51 0 0 1 .37-.245zM8 12.027a.5.5 0 0 1 .232.056l3.686 1.894-.694-3.957a.56.56 0 0 1 .162-.505l2.907-2.77-4.052-.576a.53.53 0 0 1-.393-.288L8.001 2.223 8 2.226z',\n empty:\n 'M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.522 3.356-.83 4.73zm4.905-2.767-3.686 1.894.694-3.957a.56.56 0 0 0-.163-.505L1.71 6.745l4.052-.576a.53.53 0 0 0 .393-.288L8 2.223l1.847 3.658a.53.53 0 0 0 .393.288l4.052.575-2.906 2.77a.56.56 0 0 0-.163.506l.694 3.957-3.686-1.894a.5.5 0 0 0-.461 0z',\n clear:\n 'M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708',\n} as const\nconst getIcon = (index: number): string => {\n if (isIconFull(index)) return iconPaths.full\n if (isIconHalf(index)) return iconPaths.half\n return iconPaths.empty\n}\n\nconst hoverValue = ref<number | null>(null)\n\nconst displayValue = computed(() =>\n hoverValue.value !== null ? hoverValue.value : modelValue.value\n)\n\nconst lengthNumber = useToNumber(() => props.length, {nanToZero: true, method: 'parseInt'})\nconst computedLength = computed(() => (lengthNumber.value > 0 ? lengthNumber.value : lengthDefault))\n\nconst computedSize = computed(() => {\n const resolved = {\n sm: 0.875,\n default: 1,\n lg: 1.25,\n } satisfies Record<Size | 'default', number>\n return `${resolved[props.size ?? 'default']}rem`\n})\n\nconst computedFormatter = computed(() => {\n const preciseValue = props.precision > 0 ? props.precision : 0\n return new Intl.NumberFormat(computedLocale.value, {\n style: 'decimal',\n useGrouping: false,\n minimumFractionDigits: preciseValue,\n maximumFractionDigits: preciseValue,\n notation: 'standard',\n })\n})\n\nconst displayValueText = computed(() => {\n const val = props.precision > 0 ? roundedValue.value : displayValue.value\n const formattedValue = computedFormatter.value.format(val)\n if (props.showValueMax) {\n const formattedMax = computedFormatter.value.format(computedLength.value)\n return `${formattedValue}/${formattedMax}`\n }\n if (props.showValue) {\n return formattedValue\n }\n return ''\n})\n\nconst roundedValue = computed(() => {\n const val = displayValue.value\n const factor = 10 ** props.precision\n return Math.round((val + Number.EPSILON) * factor) / factor\n})\n\nconst iconColors = computed(() =>\n Array.from({length: computedLength.value}, () => {\n if (props.disabled) {\n return {class: 'is-disabled', style: {}}\n }\n if (props.variant) {\n return {class: `text-${props.variant}`, style: {}}\n }\n if (props.color) {\n return {class: '', style: {color: props.color}}\n }\n return {class: '', style: {}}\n })\n)\n\n//add keyboard support\nconst onKeydown = (e: KeyboardEvent) => {\n if (props.readonly || props.disabled) return\n\n let newValue = modelValue.value\n\n const isRtlMode = computedRtl.value\n\n switch (e.key) {\n case 'ArrowRight':\n newValue = isRtlMode\n ? Math.max(newValue - 1, 0)\n : Math.min(newValue + 1, computedLength.value)\n break\n case 'ArrowUp':\n newValue = Math.min(newValue + 1, computedLength.value)\n break\n case 'ArrowLeft':\n newValue = isRtlMode\n ? Math.min(newValue + 1, computedLength.value)\n : Math.max(newValue - 1, 0)\n break\n case 'ArrowDown':\n newValue = Math.max(newValue - 1, 0)\n break\n default:\n return\n }\n\n e.preventDefault()\n modelValue.value = newValue\n}\n\nconst selectRating = (itemIndex: number) => {\n if (props.readonly || props.disabled) return\n modelValue.value = hoverValue.value !== null ? hoverValue.value : itemIndex\n}\n\n// clear\nconst clearRating = () => {\n hoverValue.value = null\n modelValue.value = 0\n}\n\ndefineExpose({\n hoverValue,\n})\n</script>\n"],"mappings":"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"}
|
|
@@ -144,17 +144,15 @@
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
.b-form-rating {
|
|
147
|
-
|
|
148
|
-
justify-content: space-between;
|
|
149
|
-
padding: 0.375rem 0.75rem;
|
|
150
|
-
border-radius: 0.375rem;
|
|
151
|
-
border: 1px solid var(--bs-secondary-border-subtle, #dee2e6);
|
|
152
|
-
background-color: var(--bs-body-bg);
|
|
153
|
-
gap: 0.25rem;
|
|
154
|
-
flex: 1 1 auto;
|
|
155
|
-
width: 1%;
|
|
147
|
+
text-align: center;
|
|
156
148
|
min-width: 0;
|
|
157
149
|
}
|
|
150
|
+
.b-form-rating:not(.b-form-rating-inline) {
|
|
151
|
+
width: 100%;
|
|
152
|
+
}
|
|
153
|
+
.b-form-rating.b-form-rating-inline {
|
|
154
|
+
width: auto;
|
|
155
|
+
}
|
|
158
156
|
.b-form-rating.no-border {
|
|
159
157
|
border: none;
|
|
160
158
|
}
|
|
@@ -173,36 +171,44 @@
|
|
|
173
171
|
transform: scale(1.5);
|
|
174
172
|
}
|
|
175
173
|
|
|
176
|
-
.
|
|
177
|
-
|
|
174
|
+
.rating-item {
|
|
175
|
+
align-items: center;
|
|
176
|
+
display: flex;
|
|
177
|
+
justify-content: center;
|
|
178
178
|
user-select: none;
|
|
179
179
|
padding: 0 0.25em;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
.is-readonly .
|
|
183
|
-
|
|
184
|
-
cursor: default;
|
|
182
|
+
.b-form-rating:not(.is-readonly):not(.is-disabled) .rating-item {
|
|
183
|
+
cursor: pointer;
|
|
185
184
|
}
|
|
186
185
|
|
|
187
|
-
.
|
|
188
|
-
|
|
189
|
-
|
|
186
|
+
.is-readonly .rating-item,
|
|
187
|
+
.is-disabled .rating-item {
|
|
188
|
+
cursor: default;
|
|
190
189
|
}
|
|
191
190
|
|
|
192
|
-
.
|
|
193
|
-
|
|
191
|
+
.rating-clear-button {
|
|
192
|
+
align-items: center;
|
|
193
|
+
cursor: pointer;
|
|
194
|
+
display: inline-flex;
|
|
195
|
+
flex-shrink: 0;
|
|
196
|
+
padding: 0 0.25em;
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
.rating-value-text {
|
|
200
|
+
flex-shrink: 0;
|
|
197
201
|
color: var(--bs-body-color);
|
|
198
|
-
margin: 0
|
|
202
|
+
margin: 0;
|
|
203
|
+
padding: 0 0.25em;
|
|
199
204
|
}
|
|
200
205
|
|
|
201
|
-
.b-form-rating-
|
|
206
|
+
.b-form-rating-item {
|
|
207
|
+
display: inline-flex;
|
|
202
208
|
transition: transform 0.2s ease;
|
|
203
209
|
}
|
|
204
210
|
|
|
205
|
-
.b-form-rating:not(.is-readonly):not(.is-disabled) .
|
|
211
|
+
.b-form-rating:not(.is-readonly):not(.is-disabled) .rating-item:hover .b-form-rating-item {
|
|
206
212
|
transform: scale(1.5);
|
|
207
213
|
}
|
|
208
214
|
|
|
@@ -17,7 +17,7 @@ import { n as BOrchestrator_default, t as BApp_default } from "./BApp-Bg5xEz8H.j
|
|
|
17
17
|
import { useProvideDefaults } from "./src/composables/useProvideDefaults/index.mjs";
|
|
18
18
|
import { useRegistry } from "./src/composables/useRegistry/index.mjs";
|
|
19
19
|
import { t as BAutocomplete_default } from "./BAutocomplete-BFbbKtpz.js";
|
|
20
|
-
import { t as BFormOtp_default } from "./BFormOtp-
|
|
20
|
+
import { t as BFormOtp_default } from "./BFormOtp-ClDACqXM.js";
|
|
21
21
|
import { n as BDatePicker_default, t as BDateRangePicker_default } from "./BDatePicker-AVTYcVLy.js";
|
|
22
22
|
import { t as BTimeField_default } from "./BTimeField-CbRGjaI6.js";
|
|
23
23
|
import { n as BDateRangeField_default, r as BDateField_default, t as BTimeRangeField_default } from "./BDateField-Bj-Jz7u4.js";
|
|
@@ -43,10 +43,10 @@ import { t as BFormSelectOption_default } from "./BFormSelectOption-C8orMj24.js"
|
|
|
43
43
|
import { n as BFormDatalist_default, t as BFormFloatingLabel_default } from "./BForm-CcbrqF35.js";
|
|
44
44
|
import { i as BFormInvalidFeedback_default, n as BFormText_default, r as BFormRow_default, t as BFormValidFeedback_default } from "./BFormValidFeedback-BTNOXbQ6.js";
|
|
45
45
|
import { n as BFormCheckbox_default, t as BFormCheckboxGroup_default } from "./BFormCheckbox-BMhyR-J5.js";
|
|
46
|
-
import { t as BFormFile_default } from "./BFormFile-
|
|
46
|
+
import { t as BFormFile_default } from "./BFormFile-C2DnrbK7.js";
|
|
47
47
|
import { t as BFormGroup_default } from "./BFormGroup-D3R7DxxF.js";
|
|
48
48
|
import { n as BFormRadio_default, t as BFormRadioGroup_default } from "./BFormRadio-DRViMh6V.js";
|
|
49
|
-
import { t as BFormRating_default } from "./BFormRating-
|
|
49
|
+
import { t as BFormRating_default } from "./BFormRating-iKFgSFet.js";
|
|
50
50
|
import { n as BFormSelectOptionGroup_default, t as BFormSelect_default } from "./BFormSelect-DdjH8482.js";
|
|
51
51
|
import { t as BFormSpinbutton_default } from "./BFormSpinbutton-fkVMbQC3.js";
|
|
52
52
|
import { t as BFormTags_default } from "./BFormTags-CUcyRTCK.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { MaybeRef, Ref } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* Manages an ARIA live region message with a clear-then-set pattern.
|
|
4
|
+
*
|
|
5
|
+
* Screen readers only announce `aria-live` content on a transition from empty
|
|
6
|
+
* to non-empty text. By clearing the message first and then setting it in the
|
|
7
|
+
* next tick we guarantee that every file selection produces that empty→non-empty
|
|
8
|
+
* transition, even when the same file is selected again.
|
|
9
|
+
*/
|
|
10
|
+
export declare const useAriaLiveMessage: (selectedFiles: Ref<readonly File[]>, formatter: MaybeRef<((files: readonly File[]) => string) | undefined>) => Readonly<Ref<string, string>>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { MaybeRef, Ref } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* Manages an ARIA live region message with a clear-then-set pattern.
|
|
4
|
+
*
|
|
5
|
+
* Screen readers only announce `aria-live` content on a transition from empty
|
|
6
|
+
* to non-empty text. By clearing the message first and then setting it in the
|
|
7
|
+
* next tick we guarantee that every file selection produces that empty→non-empty
|
|
8
|
+
* transition, even when the same file is selected again.
|
|
9
|
+
*/
|
|
10
|
+
export declare const useAriaLiveMessage: (selectedFiles: Ref<readonly File[]>, formatter: MaybeRef<((files: readonly File[]) => string) | undefined>) => Readonly<Ref<string, string>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BFormRatingProps, BFormRatingSlots } from '../../types';
|
|
1
|
+
import { BFormRatingProps, BFormRatingSlots, Size } from '../../types';
|
|
2
2
|
type __VLS_Props = Omit<BFormRatingProps, 'modelValue'>;
|
|
3
3
|
type __VLS_Slots = BFormRatingSlots;
|
|
4
4
|
type __VLS_ModelProps = {
|
|
@@ -17,19 +17,19 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {
|
|
|
17
17
|
id: string;
|
|
18
18
|
name: string;
|
|
19
19
|
readonly: boolean;
|
|
20
|
-
size:
|
|
20
|
+
size: Size;
|
|
21
21
|
color: string;
|
|
22
22
|
variant: "primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark" | string;
|
|
23
23
|
precision: number;
|
|
24
24
|
showValue: boolean;
|
|
25
25
|
inline: boolean;
|
|
26
|
+
length: import('../../types/CommonTypes').Numberish;
|
|
26
27
|
locale: string;
|
|
27
28
|
clearLabel: string;
|
|
28
29
|
labelValueCurrent: (current: number, max: number) => string;
|
|
29
30
|
noBorder: boolean;
|
|
30
31
|
showClear: boolean;
|
|
31
32
|
showValueMax: boolean;
|
|
32
|
-
stars: number;
|
|
33
33
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
34
34
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
35
35
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BFormRatingProps, BFormRatingSlots } from '../../types';
|
|
1
|
+
import { BFormRatingProps, BFormRatingSlots, Size } from '../../types';
|
|
2
2
|
type __VLS_Props = Omit<BFormRatingProps, 'modelValue'>;
|
|
3
3
|
type __VLS_Slots = BFormRatingSlots;
|
|
4
4
|
type __VLS_ModelProps = {
|
|
@@ -17,19 +17,19 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {
|
|
|
17
17
|
id: string;
|
|
18
18
|
name: string;
|
|
19
19
|
readonly: boolean;
|
|
20
|
-
size:
|
|
20
|
+
size: Size;
|
|
21
21
|
color: string;
|
|
22
22
|
variant: "primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark" | string;
|
|
23
23
|
precision: number;
|
|
24
24
|
showValue: boolean;
|
|
25
25
|
inline: boolean;
|
|
26
|
+
length: import('../../types/CommonTypes').Numberish;
|
|
26
27
|
locale: string;
|
|
27
28
|
clearLabel: string;
|
|
28
29
|
labelValueCurrent: (current: number, max: number) => string;
|
|
29
30
|
noBorder: boolean;
|
|
30
31
|
showClear: boolean;
|
|
31
32
|
showValueMax: boolean;
|
|
32
|
-
stars: number;
|
|
33
33
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
34
34
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
35
35
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as BFormFile_default } from "../../../BFormFile-
|
|
1
|
+
import { t as BFormFile_default } from "../../../BFormFile-C2DnrbK7.js";
|
|
2
2
|
export { BFormFile_default as BFormFile };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as BFormOtp_default } from "../../../BFormOtp-
|
|
1
|
+
import { t as BFormOtp_default } from "../../../BFormOtp-ClDACqXM.js";
|
|
2
2
|
export { BFormOtp_default as BFormOtp };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as BFormRating_default } from "../../../BFormRating-
|
|
1
|
+
import { t as BFormRating_default } from "../../../BFormRating-iKFgSFet.js";
|
|
2
2
|
export { BFormRating_default as BFormRating };
|
|
@@ -11,7 +11,7 @@ import { t as BButton_default } from "../../BButton-KZu5jczf.js";
|
|
|
11
11
|
import { t as BAlert_default } from "../../BAlert-C9Mi4RDx.js";
|
|
12
12
|
import { n as BOrchestrator_default, t as BApp_default } from "../../BApp-Bg5xEz8H.js";
|
|
13
13
|
import { t as BAutocomplete_default } from "../../BAutocomplete-BFbbKtpz.js";
|
|
14
|
-
import { t as BFormOtp_default } from "../../BFormOtp-
|
|
14
|
+
import { t as BFormOtp_default } from "../../BFormOtp-ClDACqXM.js";
|
|
15
15
|
import { n as BDatePicker_default, t as BDateRangePicker_default } from "../../BDatePicker-AVTYcVLy.js";
|
|
16
16
|
import { t as BTimeField_default } from "../../BTimeField-CbRGjaI6.js";
|
|
17
17
|
import { n as BDateRangeField_default, r as BDateField_default, t as BTimeRangeField_default } from "../../BDateField-Bj-Jz7u4.js";
|
|
@@ -37,10 +37,10 @@ import { t as BFormSelectOption_default } from "../../BFormSelectOption-C8orMj24
|
|
|
37
37
|
import { n as BFormDatalist_default, t as BFormFloatingLabel_default } from "../../BForm-CcbrqF35.js";
|
|
38
38
|
import { i as BFormInvalidFeedback_default, n as BFormText_default, r as BFormRow_default, t as BFormValidFeedback_default } from "../../BFormValidFeedback-BTNOXbQ6.js";
|
|
39
39
|
import { n as BFormCheckbox_default, t as BFormCheckboxGroup_default } from "../../BFormCheckbox-BMhyR-J5.js";
|
|
40
|
-
import { t as BFormFile_default } from "../../BFormFile-
|
|
40
|
+
import { t as BFormFile_default } from "../../BFormFile-C2DnrbK7.js";
|
|
41
41
|
import { t as BFormGroup_default } from "../../BFormGroup-D3R7DxxF.js";
|
|
42
42
|
import { n as BFormRadio_default, t as BFormRadioGroup_default } from "../../BFormRadio-DRViMh6V.js";
|
|
43
|
-
import { t as BFormRating_default } from "../../BFormRating-
|
|
43
|
+
import { t as BFormRating_default } from "../../BFormRating-iKFgSFet.js";
|
|
44
44
|
import { n as BFormSelectOptionGroup_default, t as BFormSelect_default } from "../../BFormSelect-DdjH8482.js";
|
|
45
45
|
import { t as BFormSpinbutton_default } from "../../BFormSpinbutton-fkVMbQC3.js";
|
|
46
46
|
import { t as BFormTags_default } from "../../BFormTags-CUcyRTCK.js";
|
|
@@ -11,6 +11,10 @@ var buildController = (id, store) => {
|
|
|
11
11
|
id,
|
|
12
12
|
ref: null,
|
|
13
13
|
async show() {
|
|
14
|
+
if (controller.get()?.value.props.modelValue) {
|
|
15
|
+
const event = await basePromise;
|
|
16
|
+
return Object.assign(Object.create(event), { [Symbol.asyncDispose]: controller.destroy });
|
|
17
|
+
}
|
|
14
18
|
const refWithMethods = controller.ref;
|
|
15
19
|
if (refWithMethods !== null && "show" in refWithMethods && typeof refWithMethods.show === "function") refWithMethods.show();
|
|
16
20
|
else controller.set({ modelValue: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/composables/orchestratorShared/index.ts"],"sourcesContent":["import {type ComponentPublicInstance, inject, nextTick, provide, readonly, type Ref, ref} from 'vue'\nimport type {ComponentController, ControllerKey, PromiseWithController} from '../../types'\nimport type {BvTriggerableEvent} from '../../utils'\nimport {orchestratorRegistryKey, type OrchestratorStoreObject} from '../../utils/keys'\n\n/* oxlint-disable-next-line no-explicit-any */\n/* eslint-disable-next-line @typescript-eslint/no-explicit-any */\nexport type ValueInMapRecord<MapRecord> = MapRecord extends Map<any, infer I> ? I : never\n\nexport const buildController = <\n TComponent,\n TStore extends Readonly<Ref<OrchestratorStoreObject[keyof OrchestratorStoreObject]>>,\n>(\n id: ControllerKey,\n store: TStore\n): PromiseWithController<TComponent, ValueInMapRecord<TStore['value']>> => {\n let resolveFunc: (value: BvTriggerableEvent) => void = () => {}\n\n const basePromise = new Promise<BvTriggerableEvent>((resolve) => {\n resolveFunc = resolve\n })\n\n type RefWithMethods = ComponentPublicInstance<TComponent> & {\n show?: () => void\n hide?: (trigger?: string, noEmit?: boolean) => void\n toggle?: () => void\n }\n const findItem = () => store.value.get(id)\n\n const controller = {\n id,\n ref: null as RefWithMethods | null,\n async show() {\n const refWithMethods = controller.ref\n if (\n refWithMethods !== null &&\n 'show' in refWithMethods &&\n typeof refWithMethods.show === 'function'\n ) {\n refWithMethods.show()\n } else {\n controller.set({modelValue: true})\n }\n const event = await basePromise\n return Object.assign(Object.create(event), {\n [Symbol.asyncDispose]: controller.destroy,\n })\n },\n hide(trigger?: string) {\n const refWithMethods = controller.ref\n if (\n refWithMethods !== null &&\n 'hide' in refWithMethods &&\n typeof refWithMethods.hide === 'function'\n ) {\n refWithMethods.hide(trigger, true)\n } else {\n controller.set({modelValue: false})\n }\n },\n toggle() {\n const currentItem = controller.get()\n const refWithMethods = controller.ref\n if (\n refWithMethods !== null &&\n 'toggle' in refWithMethods &&\n typeof refWithMethods.toggle === 'function'\n ) {\n refWithMethods.toggle()\n } else {\n controller.set({modelValue: !currentItem?.value.props.modelValue})\n }\n },\n get: findItem,\n set(val: Partial<ValueInMapRecord<TStore['value']>['value']['props']>) {\n const current = findItem()\n if (current?.value) {\n current.value = {\n ...current.value,\n props: {\n ...current.value.props,\n ...val,\n /* oxlint-disable no-explicit-any */\n /* eslint-disable @typescript-eslint/no-explicit-any */\n } as any,\n }\n }\n },\n async destroy() {\n const item = findItem()\n if (!item) return\n try {\n if (item.value.props.modelValue) {\n await basePromise\n await nextTick()\n controller.hide('destroy')\n }\n } finally {\n store.value.delete(id)\n }\n },\n [Symbol.asyncDispose]() {\n return controller.destroy()\n },\n } as ComponentController<TComponent, ValueInMapRecord<TStore['value']>>\n\n return {\n controller,\n resolve: resolveFunc,\n }\n}\n\nexport const _newOrchestratorRegistry = (): {\n store: Readonly<Ref<OrchestratorStoreObject>>\n _isToastAppend: Readonly<Ref<boolean>>\n _setToastAppend: (value: boolean) => void\n _isOrchestratorInstalled: Readonly<Ref<boolean>>\n _setOrchestratorInstalled: (value: boolean) => void\n} => {\n const _isOrchestratorInstalled = ref(false)\n const _isToastAppend = ref(false)\n\n return {\n store: ref({\n modal: new Map(),\n tooltip: new Map(),\n popover: new Map(),\n toast: new Map(),\n }),\n _isOrchestratorInstalled: readonly(_isOrchestratorInstalled),\n _setOrchestratorInstalled: (v) => {\n _isOrchestratorInstalled.value = v\n },\n _isToastAppend: readonly(_isToastAppend),\n _setToastAppend: (v) => {\n _isToastAppend.value = v\n },\n }\n}\n\nexport const useOrchestratorRegistry = () => {\n const orchestratorRegistry = inject(orchestratorRegistryKey, null)\n\n if (orchestratorRegistry) {\n return orchestratorRegistry\n }\n const newOrchestratorRegistry = _newOrchestratorRegistry()\n provide(orchestratorRegistryKey, newOrchestratorRegistry)\n return newOrchestratorRegistry\n}\n\nexport const getOrchestratorControllerId = (propId: string | undefined) => {\n const id: ControllerKey = propId || Symbol('OrchestratorItem')\n\n return {\n /**\n * This id is used for stability in the store, using the createIdWatcher will update the store if the id ever changes\n */\n storeId: id,\n /**\n * Do not pass in the symbol as a prop. Html attribute cannot be a symbol. Thus it's internal\n */\n htmlAttributeId: typeof id === 'string' ? id : undefined,\n }\n}\n"],"mappings":";;;AASA,IAAa,mBAIX,IACA,UACyE;CACzE,IAAI,oBAAyD,CAAC;CAE9D,MAAM,cAAc,IAAI,SAA6B,YAAY;EAC/D,cAAc;CAChB,CAAC;CAOD,MAAM,iBAAiB,MAAM,MAAM,IAAI,EAAE;CAEzC,MAAM,aAAa;EACjB;EACA,KAAK;EACL,MAAM,OAAO;
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/composables/orchestratorShared/index.ts"],"sourcesContent":["import {type ComponentPublicInstance, inject, nextTick, provide, readonly, type Ref, ref} from 'vue'\nimport type {ComponentController, ControllerKey, PromiseWithController} from '../../types'\nimport type {BvTriggerableEvent} from '../../utils'\nimport {orchestratorRegistryKey, type OrchestratorStoreObject} from '../../utils/keys'\n\n/* oxlint-disable-next-line no-explicit-any */\n/* eslint-disable-next-line @typescript-eslint/no-explicit-any */\nexport type ValueInMapRecord<MapRecord> = MapRecord extends Map<any, infer I> ? I : never\n\nexport const buildController = <\n TComponent,\n TStore extends Readonly<Ref<OrchestratorStoreObject[keyof OrchestratorStoreObject]>>,\n>(\n id: ControllerKey,\n store: TStore\n): PromiseWithController<TComponent, ValueInMapRecord<TStore['value']>> => {\n let resolveFunc: (value: BvTriggerableEvent) => void = () => {}\n\n const basePromise = new Promise<BvTriggerableEvent>((resolve) => {\n resolveFunc = resolve\n })\n\n type RefWithMethods = ComponentPublicInstance<TComponent> & {\n show?: () => void\n hide?: (trigger?: string, noEmit?: boolean) => void\n toggle?: () => void\n }\n const findItem = () => store.value.get(id)\n\n const controller = {\n id,\n ref: null as RefWithMethods | null,\n async show() {\n const currentModelValue = controller.get()?.value.props.modelValue\n if (currentModelValue) {\n const event = await basePromise\n return Object.assign(Object.create(event), {\n [Symbol.asyncDispose]: controller.destroy,\n })\n }\n const refWithMethods = controller.ref\n if (\n refWithMethods !== null &&\n 'show' in refWithMethods &&\n typeof refWithMethods.show === 'function'\n ) {\n refWithMethods.show()\n } else {\n controller.set({modelValue: true})\n }\n const event = await basePromise\n return Object.assign(Object.create(event), {\n [Symbol.asyncDispose]: controller.destroy,\n })\n },\n hide(trigger?: string) {\n const refWithMethods = controller.ref\n if (\n refWithMethods !== null &&\n 'hide' in refWithMethods &&\n typeof refWithMethods.hide === 'function'\n ) {\n refWithMethods.hide(trigger, true)\n } else {\n controller.set({modelValue: false})\n }\n },\n toggle() {\n const currentItem = controller.get()\n const refWithMethods = controller.ref\n if (\n refWithMethods !== null &&\n 'toggle' in refWithMethods &&\n typeof refWithMethods.toggle === 'function'\n ) {\n refWithMethods.toggle()\n } else {\n controller.set({modelValue: !currentItem?.value.props.modelValue})\n }\n },\n get: findItem,\n set(val: Partial<ValueInMapRecord<TStore['value']>['value']['props']>) {\n const current = findItem()\n if (current?.value) {\n current.value = {\n ...current.value,\n props: {\n ...current.value.props,\n ...val,\n /* oxlint-disable no-explicit-any */\n /* eslint-disable @typescript-eslint/no-explicit-any */\n } as any,\n }\n }\n },\n async destroy() {\n const item = findItem()\n if (!item) return\n try {\n if (item.value.props.modelValue) {\n await basePromise\n await nextTick()\n controller.hide('destroy')\n }\n } finally {\n store.value.delete(id)\n }\n },\n [Symbol.asyncDispose]() {\n return controller.destroy()\n },\n } as ComponentController<TComponent, ValueInMapRecord<TStore['value']>>\n\n return {\n controller,\n resolve: resolveFunc,\n }\n}\n\nexport const _newOrchestratorRegistry = (): {\n store: Readonly<Ref<OrchestratorStoreObject>>\n _isToastAppend: Readonly<Ref<boolean>>\n _setToastAppend: (value: boolean) => void\n _isOrchestratorInstalled: Readonly<Ref<boolean>>\n _setOrchestratorInstalled: (value: boolean) => void\n} => {\n const _isOrchestratorInstalled = ref(false)\n const _isToastAppend = ref(false)\n\n return {\n store: ref({\n modal: new Map(),\n tooltip: new Map(),\n popover: new Map(),\n toast: new Map(),\n }),\n _isOrchestratorInstalled: readonly(_isOrchestratorInstalled),\n _setOrchestratorInstalled: (v) => {\n _isOrchestratorInstalled.value = v\n },\n _isToastAppend: readonly(_isToastAppend),\n _setToastAppend: (v) => {\n _isToastAppend.value = v\n },\n }\n}\n\nexport const useOrchestratorRegistry = () => {\n const orchestratorRegistry = inject(orchestratorRegistryKey, null)\n\n if (orchestratorRegistry) {\n return orchestratorRegistry\n }\n const newOrchestratorRegistry = _newOrchestratorRegistry()\n provide(orchestratorRegistryKey, newOrchestratorRegistry)\n return newOrchestratorRegistry\n}\n\nexport const getOrchestratorControllerId = (propId: string | undefined) => {\n const id: ControllerKey = propId || Symbol('OrchestratorItem')\n\n return {\n /**\n * This id is used for stability in the store, using the createIdWatcher will update the store if the id ever changes\n */\n storeId: id,\n /**\n * Do not pass in the symbol as a prop. Html attribute cannot be a symbol. Thus it's internal\n */\n htmlAttributeId: typeof id === 'string' ? id : undefined,\n }\n}\n"],"mappings":";;;AASA,IAAa,mBAIX,IACA,UACyE;CACzE,IAAI,oBAAyD,CAAC;CAE9D,MAAM,cAAc,IAAI,SAA6B,YAAY;EAC/D,cAAc;CAChB,CAAC;CAOD,MAAM,iBAAiB,MAAM,MAAM,IAAI,EAAE;CAEzC,MAAM,aAAa;EACjB;EACA,KAAK;EACL,MAAM,OAAO;GAEX,IAD0B,WAAW,IAAI,CAAC,EAAE,MAAM,MAAM,YACjC;IACrB,MAAM,QAAQ,MAAM;IACpB,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,GAAG,GACxC,OAAO,eAAe,WAAW,QACpC,CAAC;GACH;GACA,MAAM,iBAAiB,WAAW;GAClC,IACE,mBAAmB,QACnB,UAAU,kBACV,OAAO,eAAe,SAAS,YAE/B,eAAe,KAAK;QAEpB,WAAW,IAAI,EAAC,YAAY,KAAI,CAAC;GAEnC,MAAM,QAAQ,MAAM;GACpB,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,GAAG,GACxC,OAAO,eAAe,WAAW,QACpC,CAAC;EACH;EACA,KAAK,SAAkB;GACrB,MAAM,iBAAiB,WAAW;GAClC,IACE,mBAAmB,QACnB,UAAU,kBACV,OAAO,eAAe,SAAS,YAE/B,eAAe,KAAK,SAAS,IAAI;QAEjC,WAAW,IAAI,EAAC,YAAY,MAAK,CAAC;EAEtC;EACA,SAAS;GACP,MAAM,cAAc,WAAW,IAAI;GACnC,MAAM,iBAAiB,WAAW;GAClC,IACE,mBAAmB,QACnB,YAAY,kBACZ,OAAO,eAAe,WAAW,YAEjC,eAAe,OAAO;QAEtB,WAAW,IAAI,EAAC,YAAY,CAAC,aAAa,MAAM,MAAM,WAAU,CAAC;EAErE;EACA,KAAK;EACL,IAAI,KAAmE;GACrE,MAAM,UAAU,SAAS;GACzB,IAAI,SAAS,OACX,QAAQ,QAAQ;IACd,GAAG,QAAQ;IACX,OAAO;KACL,GAAG,QAAQ,MAAM;KACjB,GAAG;IAGL;GACF;EAEJ;EACA,MAAM,UAAU;GACd,MAAM,OAAO,SAAS;GACtB,IAAI,CAAC,MAAM;GACX,IAAI;IACF,IAAI,KAAK,MAAM,MAAM,YAAY;KAC/B,MAAM;KACN,MAAM,SAAS;KACf,WAAW,KAAK,SAAS;IAC3B;GACF,UAAU;IACR,MAAM,MAAM,OAAO,EAAE;GACvB;EACF;EACA,CAAC,OAAO,gBAAgB;GACtB,OAAO,WAAW,QAAQ;EAC5B;CACF;CAEA,OAAO;EACL;EACA,SAAS;CACX;AACF;AAEA,IAAa,iCAMR;CACH,MAAM,2BAA2B,IAAI,KAAK;CAC1C,MAAM,iBAAiB,IAAI,KAAK;CAEhC,OAAO;EACL,OAAO,IAAI;GACT,uBAAO,IAAI,IAAI;GACf,yBAAS,IAAI,IAAI;GACjB,yBAAS,IAAI,IAAI;GACjB,uBAAO,IAAI,IAAI;EACjB,CAAC;EACD,0BAA0B,SAAS,wBAAwB;EAC3D,4BAA4B,MAAM;GAChC,yBAAyB,QAAQ;EACnC;EACA,gBAAgB,SAAS,cAAc;EACvC,kBAAkB,MAAM;GACtB,eAAe,QAAQ;EACzB;CACF;AACF;AAEA,IAAa,gCAAgC;CAC3C,MAAM,uBAAuB,OAAO,yBAAyB,IAAI;CAEjE,IAAI,sBACF,OAAO;CAET,MAAM,0BAA0B,yBAAyB;CACzD,QAAQ,yBAAyB,uBAAuB;CACxD,OAAO;AACT;AAEA,IAAa,+BAA+B,WAA+B;CACzE,MAAM,KAAoB,UAAU,OAAO,kBAAkB;CAE7D,OAAO;;;;EAIL,SAAS;;;;EAIT,iBAAiB,OAAO,OAAO,WAAW,KAAK,KAAA;CACjD;AACF"}
|
|
@@ -325,7 +325,7 @@ export interface BFormDatalistBaseProps {
|
|
|
325
325
|
textField?: string;
|
|
326
326
|
valueField?: string;
|
|
327
327
|
}
|
|
328
|
-
export interface BFormDatalistProps<Item = Record<string, unknown> | string | number | boolean, ValueKey extends Item extends Record<string, unknown> ? keyof Item : string = Item extends Record<string, unknown> ? keyof Item : never> {
|
|
328
|
+
export interface BFormDatalistProps<Item = Record<string, unknown> | string | number | boolean, ValueKey extends (Item extends Record<string, unknown> ? keyof Item : string) = Item extends Record<string, unknown> ? keyof Item : never> {
|
|
329
329
|
disabled?: boolean;
|
|
330
330
|
disabledField?: keyof Item & string;
|
|
331
331
|
id?: string;
|
|
@@ -470,8 +470,8 @@ export interface BFormRatingProps {
|
|
|
470
470
|
showClear?: boolean;
|
|
471
471
|
showValue?: boolean;
|
|
472
472
|
showValueMax?: boolean;
|
|
473
|
-
size?:
|
|
474
|
-
|
|
473
|
+
size?: Size;
|
|
474
|
+
length?: Numberish;
|
|
475
475
|
variant?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark' | string;
|
|
476
476
|
}
|
|
477
477
|
export interface BFormSelectBaseProps {
|
|
@@ -325,7 +325,7 @@ export interface BFormDatalistBaseProps {
|
|
|
325
325
|
textField?: string;
|
|
326
326
|
valueField?: string;
|
|
327
327
|
}
|
|
328
|
-
export interface BFormDatalistProps<Item = Record<string, unknown> | string | number | boolean, ValueKey extends Item extends Record<string, unknown> ? keyof Item : string = Item extends Record<string, unknown> ? keyof Item : never> {
|
|
328
|
+
export interface BFormDatalistProps<Item = Record<string, unknown> | string | number | boolean, ValueKey extends (Item extends Record<string, unknown> ? keyof Item : string) = Item extends Record<string, unknown> ? keyof Item : never> {
|
|
329
329
|
disabled?: boolean;
|
|
330
330
|
disabledField?: keyof Item & string;
|
|
331
331
|
id?: string;
|
|
@@ -470,8 +470,8 @@ export interface BFormRatingProps {
|
|
|
470
470
|
showClear?: boolean;
|
|
471
471
|
showValue?: boolean;
|
|
472
472
|
showValueMax?: boolean;
|
|
473
|
-
size?:
|
|
474
|
-
|
|
473
|
+
size?: Size;
|
|
474
|
+
length?: Numberish;
|
|
475
475
|
variant?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'light' | 'dark' | string;
|
|
476
476
|
}
|
|
477
477
|
export interface BFormSelectBaseProps {
|
|
@@ -272,7 +272,7 @@ export type BFormRadioGroupSlots = {
|
|
|
272
272
|
export type BFormRatingSlots = {
|
|
273
273
|
'icon-clear'?: (props: Record<string, never>) => any;
|
|
274
274
|
'default'?: (props: {
|
|
275
|
-
|
|
275
|
+
itemIndex: number;
|
|
276
276
|
isFilled: boolean;
|
|
277
277
|
isHalf: boolean;
|
|
278
278
|
}) => any;
|
|
@@ -272,7 +272,7 @@ export type BFormRadioGroupSlots = {
|
|
|
272
272
|
export type BFormRatingSlots = {
|
|
273
273
|
'icon-clear'?: (props: Record<string, never>) => any;
|
|
274
274
|
'default'?: (props: {
|
|
275
|
-
|
|
275
|
+
itemIndex: number;
|
|
276
276
|
isFilled: boolean;
|
|
277
277
|
isHalf: boolean;
|
|
278
278
|
}) => any;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "bootstrap-vue-next",
|
|
3
3
|
"displayName": "BootstrapVueNext",
|
|
4
4
|
"description": "Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "1.0.1",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./dist/bootstrap-vue-next.mjs",
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
$clear-icon-size: 1em !default;
|
|
2
2
|
|
|
3
3
|
.b-form-rating {
|
|
4
|
-
|
|
5
|
-
//align-items: center;
|
|
6
|
-
justify-content: space-between;
|
|
7
|
-
padding: 0.375rem 0.75rem;
|
|
8
|
-
border-radius: 0.375rem;
|
|
9
|
-
border: 1px solid var(--bs-secondary-border-subtle, #dee2e6);
|
|
10
|
-
background-color: var(--bs-body-bg);
|
|
11
|
-
gap: 0.25rem;
|
|
12
|
-
|
|
13
|
-
// Allow it to flex properly in input groups
|
|
14
|
-
flex: 1 1 auto;
|
|
15
|
-
width: 1%;
|
|
4
|
+
text-align: center;
|
|
16
5
|
min-width: 0;
|
|
17
6
|
|
|
7
|
+
&:not(.b-form-rating-inline) {
|
|
8
|
+
width: 100%;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
&.b-form-rating-inline {
|
|
12
|
+
width: auto;
|
|
13
|
+
}
|
|
14
|
+
|
|
18
15
|
&.no-border {
|
|
19
16
|
border: none;
|
|
20
17
|
}
|
|
@@ -37,35 +34,43 @@ $clear-icon-size: 1em !default;
|
|
|
37
34
|
}
|
|
38
35
|
}
|
|
39
36
|
|
|
40
|
-
.
|
|
41
|
-
|
|
37
|
+
.rating-item {
|
|
38
|
+
align-items: center;
|
|
39
|
+
display: flex;
|
|
40
|
+
justify-content: center;
|
|
42
41
|
user-select: none;
|
|
43
42
|
padding: 0 0.25em;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
.is-readonly .
|
|
47
|
-
|
|
48
|
-
cursor: default;
|
|
45
|
+
.b-form-rating:not(.is-readonly):not(.is-disabled) .rating-item {
|
|
46
|
+
cursor: pointer;
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
.
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
.is-readonly .rating-item,
|
|
50
|
+
.is-disabled .rating-item {
|
|
51
|
+
cursor: default;
|
|
54
52
|
}
|
|
55
53
|
|
|
56
|
-
.
|
|
57
|
-
|
|
54
|
+
.rating-clear-button {
|
|
55
|
+
align-items: center;
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
flex-shrink: 0;
|
|
59
|
+
padding: 0 0.25em;
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
.rating-value-text {
|
|
63
|
+
flex-shrink: 0;
|
|
61
64
|
color: var(--bs-body-color);
|
|
62
|
-
margin: 0
|
|
65
|
+
margin: 0;
|
|
66
|
+
padding: 0 0.25em;
|
|
63
67
|
}
|
|
64
68
|
|
|
65
|
-
.b-form-rating-
|
|
69
|
+
.b-form-rating-item {
|
|
70
|
+
display: inline-flex;
|
|
66
71
|
transition: transform 0.2s ease;
|
|
67
72
|
}
|
|
68
73
|
|
|
69
|
-
.b-form-rating:not(.is-readonly):not(.is-disabled) .
|
|
74
|
+
.b-form-rating:not(.is-readonly):not(.is-disabled) .rating-item:hover .b-form-rating-item {
|
|
70
75
|
transform: scale(1.5);
|
|
71
76
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BFormFile-BVrDprWL.js","names":[],"sources":["../src/components/BFormFile/BFormFile.vue","../src/components/BFormFile/BFormFile.vue"],"sourcesContent":["<template>\n <div ref=\"rootRef\" v-bind=\"processedAttrs.rootAttrs\" class=\"b-form-file-root\">\n <!-- Optional label -->\n <label\n v-if=\"hasLabelSlot || props.label\"\n class=\"form-label\"\n :class=\"props.labelClass\"\n :for=\"computedId\"\n >\n <slot name=\"label\">\n {{ props.label }}\n </slot>\n </label>\n\n <!-- Drop zone wrapper -->\n <div\n v-if=\"!props.plain\"\n ref=\"dropZoneRef\"\n v-bind=\"processedAttrs.dropZoneAttrs\"\n class=\"b-form-file-wrapper\"\n :class=\"{\n 'b-form-file-dragging': isOverDropZone && !props.noDrop,\n 'b-form-file-has-files': hasFiles,\n }\"\n >\n <!-- Custom file control (mimics Bootstrap native input) -->\n <div\n class=\"b-form-file-control\"\n :class=\"computedClasses\"\n :aria-disabled=\"props.disabled\"\n @click=\"handleControlClick\"\n >\n <!-- Custom browse button (now on LEFT to match Bootstrap v5) -->\n <button\n v-if=\"!props.noButton\"\n :id=\"computedId\"\n ref=\"browseButtonRef\"\n type=\"button\"\n class=\"b-form-file-button\"\n :disabled=\"props.disabled\"\n :aria-label=\"props.ariaLabel\"\n :aria-labelledby=\"props.ariaLabelledby\"\n @click.stop=\"openFileDialog\"\n >\n {{ effectiveBrowseText }}\n </button>\n\n <!-- File name display -->\n <div class=\"b-form-file-text\">\n <slot name=\"file-name\" :files=\"selectedFiles\" :names=\"fileNames\">\n <span v-if=\"hasFiles\">{{ formattedFileNames }}</span>\n <span v-else-if=\"hasPlaceholderSlot || props.placeholder\" class=\"text-muted\">\n <slot name=\"placeholder\">{{ props.placeholder }}</slot>\n </span>\n </slot>\n </div>\n </div>\n\n <!-- Drag overlay (only shown when dragging) -->\n <div v-if=\"isOverDropZone && !props.noDrop\" class=\"b-form-file-drag-overlay\">\n <slot name=\"drop-placeholder\">\n <div class=\"b-form-file-drag-text\">\n {{ effectiveDropPlaceholder }}\n </div>\n </slot>\n </div>\n\n <!-- Hidden input for form submission (positioned behind UI with z-index) -->\n <input\n ref=\"customInputRef\"\n v-bind=\"processedAttrs.inputAttrs\"\n type=\"file\"\n :name=\"props.name\"\n :form=\"props.form\"\n :multiple=\"props.multiple || props.directory\"\n :disabled=\"props.disabled\"\n :required=\"props.required\"\n :accept=\"computedAccept || undefined\"\n :capture=\"props.capture\"\n :directory=\"props.directory || undefined\"\n :webkitdirectory=\"props.directory || undefined\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n style=\"\n position: absolute;\n z-index: -5;\n width: 0;\n height: 0;\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n \"\n />\n </div>\n\n <!-- Plain mode - simple native input -->\n <input\n v-else\n :id=\"computedId\"\n ref=\"plainInputRef\"\n v-bind=\"processedAttrs.inputAttrs\"\n type=\"file\"\n :class=\"computedPlainClasses\"\n :form=\"props.form\"\n :name=\"props.name\"\n :multiple=\"props.multiple || props.directory\"\n :disabled=\"props.disabled\"\n :capture=\"props.capture\"\n :accept=\"computedAccept || undefined\"\n :required=\"props.required || undefined\"\n :aria-label=\"props.ariaLabel\"\n :aria-labelledby=\"props.ariaLabelledby\"\n :aria-required=\"props.required || undefined\"\n :directory=\"props.directory || undefined\"\n :webkitdirectory=\"props.directory || undefined\"\n @change=\"onPlainChange\"\n />\n\n <!-- External file display (when showFileNames is true and not plain) -->\n <div v-if=\"showExternalDisplay\" class=\"b-form-file-display mt-2\">\n <slot name=\"file-name\" :files=\"selectedFiles\" :names=\"fileNames\">\n <div v-if=\"hasFiles\" class=\"small text-muted\">\n {{ formattedFileNames }}\n </div>\n <div v-else-if=\"hasPlaceholderSlot || props.placeholder\" class=\"small text-muted\">\n <slot name=\"placeholder\">\n {{ props.placeholder }}\n </slot>\n </div>\n </slot>\n </div>\n\n <!-- ARIA live region for screen reader announcements -->\n <div v-if=\"!props.plain\" class=\"visually-hidden\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ ariaLiveMessage }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport {useDropZone, useFileDialog} from '@vueuse/core'\nimport {computed, nextTick, onMounted, ref, type Ref, useAttrs, useTemplateRef, watch} from 'vue'\nimport {useDefaults} from '../../composables/useDefaults'\nimport {useId} from '../../composables/useId'\nimport {useStateClass} from '../../composables/useStateClass'\nimport {isEmptySlot} from '../../utils/dom'\nimport type {BFormFileProps, BFormFileSlots} from '../../types'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst _props = withDefaults(defineProps<Omit<BFormFileProps, 'modelValue'>>(), {\n ariaLabel: undefined,\n ariaLabelledby: undefined,\n accept: '',\n autofocus: false,\n browseText: undefined,\n capture: undefined,\n directory: false,\n disabled: false,\n dropPlaceholder: undefined,\n fileNameFormatter: undefined,\n ariaLiveFormatter: undefined,\n form: undefined,\n id: undefined,\n label: '',\n labelClass: undefined,\n multiple: false,\n name: undefined,\n noButton: false,\n noDrop: false,\n plain: false,\n placeholder: 'No file chosen',\n required: false,\n showFileNames: false,\n size: undefined,\n state: null,\n})\nconst props = useDefaults(_props, 'BFormFile')\nconst slots = defineSlots<BFormFileSlots>()\n\nconst emit = defineEmits<{\n change: [value: Event]\n}>()\n\nconst modelValue = defineModel<Exclude<BFormFileProps['modelValue'], undefined>>({\n default: null,\n})\n\nconst attrs = useAttrs()\n\nconst processedAttrs = computed(() => {\n // In plain mode, pass all attributes to the input element\n if (props.plain) {\n return {\n rootAttrs: {},\n dropZoneAttrs: {},\n inputAttrs: attrs,\n }\n }\n // In custom mode, split attributes:\n // - class/style go to root (for layout/positioning)\n // - title goes to drop zone (for tooltip on interactive element)\n // - everything else goes to hidden input (for form functionality)\n const {class: rootClass, style: rootStyle, title: dropZoneTitle, ...inputAttrs} = attrs\n const rootAttrs: Record<string, unknown> = {}\n const dropZoneAttrs: Record<string, unknown> = {}\n if (rootClass !== undefined) rootAttrs.class = rootClass\n if (rootStyle !== undefined) rootAttrs.style = rootStyle\n if (dropZoneTitle !== undefined) dropZoneAttrs.title = dropZoneTitle\n return {\n rootAttrs,\n dropZoneAttrs,\n inputAttrs,\n }\n})\n\nconst computedId = useId(() => props.id)\nconst stateClass = useStateClass(() => props.state)\n\n// Refs\nconst rootRef = useTemplateRef('rootRef')\nconst dropZoneRef = useTemplateRef('dropZoneRef')\nconst browseButtonRef = useTemplateRef('browseButtonRef')\nconst plainInputRef = useTemplateRef<HTMLInputElement>('plainInputRef')\nconst customInputRef = useTemplateRef<HTMLInputElement>('customInputRef')\n\n// Computed accept for file type validation\nconst computedAccept = computed(() =>\n typeof props.accept === 'string' ? props.accept : props.accept.join(',')\n)\n\n// VueUse file dialog (uses our hidden input element)\nconst {\n open,\n reset: resetDialog,\n onChange: onDialogChange,\n} = useFileDialog({\n accept: computedAccept.value,\n multiple: props.multiple || props.directory,\n directory: props.directory,\n input: customInputRef as unknown as Ref<HTMLInputElement>,\n})\n\n// VueUse drop zone (replaces manual drag/drop)\n// Note: We don't pass dataTypes because the accept attribute handles validation\n// and there is no reliable way to get MIME types from in all browsers\n// https://github.com/vueuse/vueuse/issues/4523\nconst {isOverDropZone} = useDropZone(dropZoneRef, {\n onDrop: (files) => {\n if (files && !props.noDrop) {\n handleFiles(files)\n }\n },\n multiple: props.multiple || props.directory,\n})\n\n// Computed properties\nconst hasLabelSlot = computed(() => !isEmptySlot(slots.label))\nconst hasPlaceholderSlot = computed(() => !isEmptySlot(slots.placeholder))\n\nconst computedClasses = computed(() => [\n stateClass.value,\n {\n [`form-control-${props.size}`]: props.size !== undefined,\n },\n])\n\nconst computedPlainClasses = computed(() => [\n 'form-control',\n stateClass.value,\n {\n [`form-control-${props.size}`]: props.size !== undefined,\n },\n])\n\n// Selected files (from dialog or managed state)\nconst internalFiles = ref<readonly File[]>([])\n\nconst selectedFiles = computed<readonly File[]>(() => internalFiles.value)\n\nconst hasFiles = computed(() => selectedFiles.value.length > 0)\n\nconst fileNames = computed(() => selectedFiles.value.map((file) => file.name))\n\nconst formattedFileNames = computed(() => {\n if (!hasFiles.value) return ''\n if (props.fileNameFormatter) {\n return props.fileNameFormatter(selectedFiles.value)\n }\n const names = fileNames.value\n if (names.length === 1) return names[0]\n return `${names.length} files selected`\n})\n\nconst showExternalDisplay = computed(\n () => !props.plain && props.showFileNames && (hasFiles.value || props.placeholder)\n)\n\n// ARIA live region message for accessibility\nconst ariaLiveMessage = computed(() => {\n if (!hasFiles.value) return ''\n if (props.ariaLiveFormatter) {\n return props.ariaLiveFormatter(selectedFiles.value)\n }\n const count = selectedFiles.value.length\n if (count === 1) {\n return `File selected: ${selectedFiles.value[0]?.name}`\n }\n return `${count} files selected`\n})\n\nconst effectiveBrowseText = computed(() => props.browseText ?? 'Browse')\nconst effectiveDropPlaceholder = computed(() => props.dropPlaceholder ?? 'Drop files here...')\n\n// Validate file against accept criteria\nconst isFileAccepted = (file: File): boolean => {\n if (!computedAccept.value) return true\n\n const acceptTypes = computedAccept.value.split(',').map((type) => type.trim())\n\n return acceptTypes.some((acceptType) => {\n // Extension match (e.g., .pdf)\n if (acceptType.startsWith('.')) {\n return file.name.toLowerCase().endsWith(acceptType.toLowerCase())\n }\n // Exact MIME type match (e.g., image/png)\n if (!acceptType.includes('*')) {\n return file.type === acceptType\n }\n // Wildcard MIME type match (e.g., image/* or */*)\n const slashIndex = acceptType.indexOf('/')\n if (slashIndex === -1) {\n // Malformed wildcard pattern (no '/'): do not match anything\n return false\n }\n const category = acceptType.slice(0, slashIndex)\n // */* should match any MIME type\n if (category === '*') {\n return true\n }\n return file.type.startsWith(`${category}/`)\n })\n}\n\n// File handling\nconst handleFiles = (files: File[] | FileList, nativeEvent?: Event) => {\n let fileArray: File[] = []\n\n if (nativeEvent) {\n // Plain mode: read from the event target (browser already filtered via accept)\n const input = nativeEvent.target as HTMLInputElement\n fileArray = input.files ? Array.from(input.files) : []\n } else {\n // Custom mode (drag & drop or file dialog): manually filter and set on hidden input\n fileArray = Array.from(files).filter((file) => isFileAccepted(file))\n if (customInputRef.value && typeof DataTransfer !== 'undefined') {\n try {\n const dataTransfer = new DataTransfer()\n fileArray.forEach((file) => dataTransfer.items.add(file))\n customInputRef.value.files = dataTransfer.files\n } catch {\n // In environments where DataTransfer is not fully supported, skip syncing files on the input\n }\n }\n }\n\n // Update internal state\n internalFiles.value = fileArray\n\n // Update model value\n if (fileArray.length === 0) {\n modelValue.value = null\n } else if (props.directory || props.multiple) {\n modelValue.value = fileArray\n } else {\n const [firstFile] = fileArray\n if (firstFile) {\n modelValue.value = firstFile\n }\n }\n\n // Emit change event in nextTick to ensure DOM updates\n // In plain mode: forward the native event (has target.files)\n // In custom mode: create CustomEvent with files in detail\n nextTick(() => {\n if (nativeEvent) {\n // Plain mode: forward native event\n emit('change', nativeEvent)\n } else {\n // Custom mode: create CustomEvent with files\n const changeEvent = new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: {\n files: fileArray,\n target: {files: fileArray},\n },\n })\n // Also attach files directly for easier access\n Object.defineProperty(changeEvent, 'files', {\n value: fileArray,\n enumerable: true,\n })\n emit('change', changeEvent)\n }\n })\n}\n\n// Open file dialog\nconst openFileDialog = () => {\n if (!props.disabled) {\n open({\n accept: computedAccept.value,\n multiple: props.multiple || props.directory,\n directory: props.directory,\n })\n }\n}\n\n// Handle click on control wrapper (make entire control clickable like Bootstrap v5)\nconst handleControlClick = () => {\n // Don't trigger if clicking the button itself (button has its own handler with .stop)\n // Don't trigger if disabled\n if (!props.disabled) {\n openFileDialog()\n }\n}\n\n// Plain mode change handler\nconst onPlainChange = (e: Event) => {\n const input = e.target as HTMLInputElement\n if (input.files) {\n handleFiles(input.files, e) // Pass native event\n }\n}\n\n// Watch dialog files from useFileDialog\nonDialogChange((files) => {\n if (files) {\n handleFiles(files)\n }\n})\n\n// Reset method\nconst reset = () => {\n internalFiles.value = []\n modelValue.value = null\n resetDialog() // This resets the hidden input in custom mode\n if (plainInputRef.value) {\n plainInputRef.value.value = ''\n }\n}\n\n// Focus management\nconst focus = () => {\n if (props.plain) {\n plainInputRef.value?.focus()\n } else {\n browseButtonRef.value?.focus()\n }\n}\n\nconst blur = () => {\n if (props.plain) {\n plainInputRef.value?.blur()\n } else {\n browseButtonRef.value?.blur()\n }\n}\n\n// Autofocus support - initial focus on mount\nonMounted(() => {\n if (props.autofocus) {\n nextTick(() => {\n focus()\n })\n }\n})\n\n// Autofocus support - runtime prop changes\nwatch(\n () => props.autofocus,\n (autofocus) => {\n if (autofocus) {\n focus()\n }\n }\n)\n\n// Watch modelValue changes from parent\nwatch(modelValue, (newValue) => {\n if (newValue === null) {\n internalFiles.value = []\n if (plainInputRef.value) {\n plainInputRef.value.value = ''\n }\n } else if (Array.isArray(newValue)) {\n internalFiles.value = newValue as readonly File[]\n } else {\n internalFiles.value = [newValue] as readonly File[]\n }\n})\n\ndefineExpose({\n blur,\n element: computed(() => (props.plain ? plainInputRef.value : browseButtonRef.value)),\n focus,\n reset,\n})\n</script>\n","<template>\n <div ref=\"rootRef\" v-bind=\"processedAttrs.rootAttrs\" class=\"b-form-file-root\">\n <!-- Optional label -->\n <label\n v-if=\"hasLabelSlot || props.label\"\n class=\"form-label\"\n :class=\"props.labelClass\"\n :for=\"computedId\"\n >\n <slot name=\"label\">\n {{ props.label }}\n </slot>\n </label>\n\n <!-- Drop zone wrapper -->\n <div\n v-if=\"!props.plain\"\n ref=\"dropZoneRef\"\n v-bind=\"processedAttrs.dropZoneAttrs\"\n class=\"b-form-file-wrapper\"\n :class=\"{\n 'b-form-file-dragging': isOverDropZone && !props.noDrop,\n 'b-form-file-has-files': hasFiles,\n }\"\n >\n <!-- Custom file control (mimics Bootstrap native input) -->\n <div\n class=\"b-form-file-control\"\n :class=\"computedClasses\"\n :aria-disabled=\"props.disabled\"\n @click=\"handleControlClick\"\n >\n <!-- Custom browse button (now on LEFT to match Bootstrap v5) -->\n <button\n v-if=\"!props.noButton\"\n :id=\"computedId\"\n ref=\"browseButtonRef\"\n type=\"button\"\n class=\"b-form-file-button\"\n :disabled=\"props.disabled\"\n :aria-label=\"props.ariaLabel\"\n :aria-labelledby=\"props.ariaLabelledby\"\n @click.stop=\"openFileDialog\"\n >\n {{ effectiveBrowseText }}\n </button>\n\n <!-- File name display -->\n <div class=\"b-form-file-text\">\n <slot name=\"file-name\" :files=\"selectedFiles\" :names=\"fileNames\">\n <span v-if=\"hasFiles\">{{ formattedFileNames }}</span>\n <span v-else-if=\"hasPlaceholderSlot || props.placeholder\" class=\"text-muted\">\n <slot name=\"placeholder\">{{ props.placeholder }}</slot>\n </span>\n </slot>\n </div>\n </div>\n\n <!-- Drag overlay (only shown when dragging) -->\n <div v-if=\"isOverDropZone && !props.noDrop\" class=\"b-form-file-drag-overlay\">\n <slot name=\"drop-placeholder\">\n <div class=\"b-form-file-drag-text\">\n {{ effectiveDropPlaceholder }}\n </div>\n </slot>\n </div>\n\n <!-- Hidden input for form submission (positioned behind UI with z-index) -->\n <input\n ref=\"customInputRef\"\n v-bind=\"processedAttrs.inputAttrs\"\n type=\"file\"\n :name=\"props.name\"\n :form=\"props.form\"\n :multiple=\"props.multiple || props.directory\"\n :disabled=\"props.disabled\"\n :required=\"props.required\"\n :accept=\"computedAccept || undefined\"\n :capture=\"props.capture\"\n :directory=\"props.directory || undefined\"\n :webkitdirectory=\"props.directory || undefined\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n style=\"\n position: absolute;\n z-index: -5;\n width: 0;\n height: 0;\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n \"\n />\n </div>\n\n <!-- Plain mode - simple native input -->\n <input\n v-else\n :id=\"computedId\"\n ref=\"plainInputRef\"\n v-bind=\"processedAttrs.inputAttrs\"\n type=\"file\"\n :class=\"computedPlainClasses\"\n :form=\"props.form\"\n :name=\"props.name\"\n :multiple=\"props.multiple || props.directory\"\n :disabled=\"props.disabled\"\n :capture=\"props.capture\"\n :accept=\"computedAccept || undefined\"\n :required=\"props.required || undefined\"\n :aria-label=\"props.ariaLabel\"\n :aria-labelledby=\"props.ariaLabelledby\"\n :aria-required=\"props.required || undefined\"\n :directory=\"props.directory || undefined\"\n :webkitdirectory=\"props.directory || undefined\"\n @change=\"onPlainChange\"\n />\n\n <!-- External file display (when showFileNames is true and not plain) -->\n <div v-if=\"showExternalDisplay\" class=\"b-form-file-display mt-2\">\n <slot name=\"file-name\" :files=\"selectedFiles\" :names=\"fileNames\">\n <div v-if=\"hasFiles\" class=\"small text-muted\">\n {{ formattedFileNames }}\n </div>\n <div v-else-if=\"hasPlaceholderSlot || props.placeholder\" class=\"small text-muted\">\n <slot name=\"placeholder\">\n {{ props.placeholder }}\n </slot>\n </div>\n </slot>\n </div>\n\n <!-- ARIA live region for screen reader announcements -->\n <div v-if=\"!props.plain\" class=\"visually-hidden\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ ariaLiveMessage }}\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport {useDropZone, useFileDialog} from '@vueuse/core'\nimport {computed, nextTick, onMounted, ref, type Ref, useAttrs, useTemplateRef, watch} from 'vue'\nimport {useDefaults} from '../../composables/useDefaults'\nimport {useId} from '../../composables/useId'\nimport {useStateClass} from '../../composables/useStateClass'\nimport {isEmptySlot} from '../../utils/dom'\nimport type {BFormFileProps, BFormFileSlots} from '../../types'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst _props = withDefaults(defineProps<Omit<BFormFileProps, 'modelValue'>>(), {\n ariaLabel: undefined,\n ariaLabelledby: undefined,\n accept: '',\n autofocus: false,\n browseText: undefined,\n capture: undefined,\n directory: false,\n disabled: false,\n dropPlaceholder: undefined,\n fileNameFormatter: undefined,\n ariaLiveFormatter: undefined,\n form: undefined,\n id: undefined,\n label: '',\n labelClass: undefined,\n multiple: false,\n name: undefined,\n noButton: false,\n noDrop: false,\n plain: false,\n placeholder: 'No file chosen',\n required: false,\n showFileNames: false,\n size: undefined,\n state: null,\n})\nconst props = useDefaults(_props, 'BFormFile')\nconst slots = defineSlots<BFormFileSlots>()\n\nconst emit = defineEmits<{\n change: [value: Event]\n}>()\n\nconst modelValue = defineModel<Exclude<BFormFileProps['modelValue'], undefined>>({\n default: null,\n})\n\nconst attrs = useAttrs()\n\nconst processedAttrs = computed(() => {\n // In plain mode, pass all attributes to the input element\n if (props.plain) {\n return {\n rootAttrs: {},\n dropZoneAttrs: {},\n inputAttrs: attrs,\n }\n }\n // In custom mode, split attributes:\n // - class/style go to root (for layout/positioning)\n // - title goes to drop zone (for tooltip on interactive element)\n // - everything else goes to hidden input (for form functionality)\n const {class: rootClass, style: rootStyle, title: dropZoneTitle, ...inputAttrs} = attrs\n const rootAttrs: Record<string, unknown> = {}\n const dropZoneAttrs: Record<string, unknown> = {}\n if (rootClass !== undefined) rootAttrs.class = rootClass\n if (rootStyle !== undefined) rootAttrs.style = rootStyle\n if (dropZoneTitle !== undefined) dropZoneAttrs.title = dropZoneTitle\n return {\n rootAttrs,\n dropZoneAttrs,\n inputAttrs,\n }\n})\n\nconst computedId = useId(() => props.id)\nconst stateClass = useStateClass(() => props.state)\n\n// Refs\nconst rootRef = useTemplateRef('rootRef')\nconst dropZoneRef = useTemplateRef('dropZoneRef')\nconst browseButtonRef = useTemplateRef('browseButtonRef')\nconst plainInputRef = useTemplateRef<HTMLInputElement>('plainInputRef')\nconst customInputRef = useTemplateRef<HTMLInputElement>('customInputRef')\n\n// Computed accept for file type validation\nconst computedAccept = computed(() =>\n typeof props.accept === 'string' ? props.accept : props.accept.join(',')\n)\n\n// VueUse file dialog (uses our hidden input element)\nconst {\n open,\n reset: resetDialog,\n onChange: onDialogChange,\n} = useFileDialog({\n accept: computedAccept.value,\n multiple: props.multiple || props.directory,\n directory: props.directory,\n input: customInputRef as unknown as Ref<HTMLInputElement>,\n})\n\n// VueUse drop zone (replaces manual drag/drop)\n// Note: We don't pass dataTypes because the accept attribute handles validation\n// and there is no reliable way to get MIME types from in all browsers\n// https://github.com/vueuse/vueuse/issues/4523\nconst {isOverDropZone} = useDropZone(dropZoneRef, {\n onDrop: (files) => {\n if (files && !props.noDrop) {\n handleFiles(files)\n }\n },\n multiple: props.multiple || props.directory,\n})\n\n// Computed properties\nconst hasLabelSlot = computed(() => !isEmptySlot(slots.label))\nconst hasPlaceholderSlot = computed(() => !isEmptySlot(slots.placeholder))\n\nconst computedClasses = computed(() => [\n stateClass.value,\n {\n [`form-control-${props.size}`]: props.size !== undefined,\n },\n])\n\nconst computedPlainClasses = computed(() => [\n 'form-control',\n stateClass.value,\n {\n [`form-control-${props.size}`]: props.size !== undefined,\n },\n])\n\n// Selected files (from dialog or managed state)\nconst internalFiles = ref<readonly File[]>([])\n\nconst selectedFiles = computed<readonly File[]>(() => internalFiles.value)\n\nconst hasFiles = computed(() => selectedFiles.value.length > 0)\n\nconst fileNames = computed(() => selectedFiles.value.map((file) => file.name))\n\nconst formattedFileNames = computed(() => {\n if (!hasFiles.value) return ''\n if (props.fileNameFormatter) {\n return props.fileNameFormatter(selectedFiles.value)\n }\n const names = fileNames.value\n if (names.length === 1) return names[0]\n return `${names.length} files selected`\n})\n\nconst showExternalDisplay = computed(\n () => !props.plain && props.showFileNames && (hasFiles.value || props.placeholder)\n)\n\n// ARIA live region message for accessibility\nconst ariaLiveMessage = computed(() => {\n if (!hasFiles.value) return ''\n if (props.ariaLiveFormatter) {\n return props.ariaLiveFormatter(selectedFiles.value)\n }\n const count = selectedFiles.value.length\n if (count === 1) {\n return `File selected: ${selectedFiles.value[0]?.name}`\n }\n return `${count} files selected`\n})\n\nconst effectiveBrowseText = computed(() => props.browseText ?? 'Browse')\nconst effectiveDropPlaceholder = computed(() => props.dropPlaceholder ?? 'Drop files here...')\n\n// Validate file against accept criteria\nconst isFileAccepted = (file: File): boolean => {\n if (!computedAccept.value) return true\n\n const acceptTypes = computedAccept.value.split(',').map((type) => type.trim())\n\n return acceptTypes.some((acceptType) => {\n // Extension match (e.g., .pdf)\n if (acceptType.startsWith('.')) {\n return file.name.toLowerCase().endsWith(acceptType.toLowerCase())\n }\n // Exact MIME type match (e.g., image/png)\n if (!acceptType.includes('*')) {\n return file.type === acceptType\n }\n // Wildcard MIME type match (e.g., image/* or */*)\n const slashIndex = acceptType.indexOf('/')\n if (slashIndex === -1) {\n // Malformed wildcard pattern (no '/'): do not match anything\n return false\n }\n const category = acceptType.slice(0, slashIndex)\n // */* should match any MIME type\n if (category === '*') {\n return true\n }\n return file.type.startsWith(`${category}/`)\n })\n}\n\n// File handling\nconst handleFiles = (files: File[] | FileList, nativeEvent?: Event) => {\n let fileArray: File[] = []\n\n if (nativeEvent) {\n // Plain mode: read from the event target (browser already filtered via accept)\n const input = nativeEvent.target as HTMLInputElement\n fileArray = input.files ? Array.from(input.files) : []\n } else {\n // Custom mode (drag & drop or file dialog): manually filter and set on hidden input\n fileArray = Array.from(files).filter((file) => isFileAccepted(file))\n if (customInputRef.value && typeof DataTransfer !== 'undefined') {\n try {\n const dataTransfer = new DataTransfer()\n fileArray.forEach((file) => dataTransfer.items.add(file))\n customInputRef.value.files = dataTransfer.files\n } catch {\n // In environments where DataTransfer is not fully supported, skip syncing files on the input\n }\n }\n }\n\n // Update internal state\n internalFiles.value = fileArray\n\n // Update model value\n if (fileArray.length === 0) {\n modelValue.value = null\n } else if (props.directory || props.multiple) {\n modelValue.value = fileArray\n } else {\n const [firstFile] = fileArray\n if (firstFile) {\n modelValue.value = firstFile\n }\n }\n\n // Emit change event in nextTick to ensure DOM updates\n // In plain mode: forward the native event (has target.files)\n // In custom mode: create CustomEvent with files in detail\n nextTick(() => {\n if (nativeEvent) {\n // Plain mode: forward native event\n emit('change', nativeEvent)\n } else {\n // Custom mode: create CustomEvent with files\n const changeEvent = new CustomEvent('change', {\n bubbles: true,\n cancelable: false,\n detail: {\n files: fileArray,\n target: {files: fileArray},\n },\n })\n // Also attach files directly for easier access\n Object.defineProperty(changeEvent, 'files', {\n value: fileArray,\n enumerable: true,\n })\n emit('change', changeEvent)\n }\n })\n}\n\n// Open file dialog\nconst openFileDialog = () => {\n if (!props.disabled) {\n open({\n accept: computedAccept.value,\n multiple: props.multiple || props.directory,\n directory: props.directory,\n })\n }\n}\n\n// Handle click on control wrapper (make entire control clickable like Bootstrap v5)\nconst handleControlClick = () => {\n // Don't trigger if clicking the button itself (button has its own handler with .stop)\n // Don't trigger if disabled\n if (!props.disabled) {\n openFileDialog()\n }\n}\n\n// Plain mode change handler\nconst onPlainChange = (e: Event) => {\n const input = e.target as HTMLInputElement\n if (input.files) {\n handleFiles(input.files, e) // Pass native event\n }\n}\n\n// Watch dialog files from useFileDialog\nonDialogChange((files) => {\n if (files) {\n handleFiles(files)\n }\n})\n\n// Reset method\nconst reset = () => {\n internalFiles.value = []\n modelValue.value = null\n resetDialog() // This resets the hidden input in custom mode\n if (plainInputRef.value) {\n plainInputRef.value.value = ''\n }\n}\n\n// Focus management\nconst focus = () => {\n if (props.plain) {\n plainInputRef.value?.focus()\n } else {\n browseButtonRef.value?.focus()\n }\n}\n\nconst blur = () => {\n if (props.plain) {\n plainInputRef.value?.blur()\n } else {\n browseButtonRef.value?.blur()\n }\n}\n\n// Autofocus support - initial focus on mount\nonMounted(() => {\n if (props.autofocus) {\n nextTick(() => {\n focus()\n })\n }\n})\n\n// Autofocus support - runtime prop changes\nwatch(\n () => props.autofocus,\n (autofocus) => {\n if (autofocus) {\n focus()\n }\n }\n)\n\n// Watch modelValue changes from parent\nwatch(modelValue, (newValue) => {\n if (newValue === null) {\n internalFiles.value = []\n if (plainInputRef.value) {\n plainInputRef.value.value = ''\n }\n } else if (Array.isArray(newValue)) {\n internalFiles.value = newValue as readonly File[]\n } else {\n internalFiles.value = [newValue] as readonly File[]\n }\n})\n\ndefineExpose({\n blur,\n element: computed(() => (props.plain ? plainInputRef.value : browseButtonRef.value)),\n focus,\n reset,\n})\n</script>\n"],"mappings":"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"}
|