UNPKG

bootstrap-vue-next

Version:

Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development

1 lines 12 kB
{"version":3,"file":"BButton-DNmtqoqR.mjs","names":[],"sources":["../src/components/BButton/BButtonGroup.vue","../src/components/BButton/BButtonGroup.vue","../src/components/BButton/BButtonToolbar.vue","../src/components/BButton/BButtonToolbar.vue"],"sourcesContent":["<template>\n <component :is=\"props.tag\" :class=\"computedClasses\" role=\"group\" :aria-label=\"props.ariaLabel\">\n <slot />\n </component>\n</template>\n\n<script setup lang=\"ts\">\nimport {useDefaults} from '../../composables/useDefaults'\nimport type {BButtonGroupProps} from '../../types/ComponentProps'\nimport {computed, provide} from 'vue'\nimport {buttonGroupKey} from '../../utils/keys'\nimport type {BButtonGroupSlots} from '../../types'\n\nprovide(buttonGroupKey, true)\n\nconst _props = withDefaults(defineProps<BButtonGroupProps>(), {\n ariaLabel: 'Group',\n size: 'md',\n tag: 'div',\n vertical: false,\n})\nconst props = useDefaults(_props, 'BButtonGroup')\ndefineSlots<BButtonGroupSlots>()\n\nconst computedClasses = computed(() => ({\n 'btn-group': !props.vertical,\n [`btn-group-${props.size}`]: props.size !== 'md',\n 'btn-group-vertical': props.vertical,\n}))\n</script>\n","<template>\n <component :is=\"props.tag\" :class=\"computedClasses\" role=\"group\" :aria-label=\"props.ariaLabel\">\n <slot />\n </component>\n</template>\n\n<script setup lang=\"ts\">\nimport {useDefaults} from '../../composables/useDefaults'\nimport type {BButtonGroupProps} from '../../types/ComponentProps'\nimport {computed, provide} from 'vue'\nimport {buttonGroupKey} from '../../utils/keys'\nimport type {BButtonGroupSlots} from '../../types'\n\nprovide(buttonGroupKey, true)\n\nconst _props = withDefaults(defineProps<BButtonGroupProps>(), {\n ariaLabel: 'Group',\n size: 'md',\n tag: 'div',\n vertical: false,\n})\nconst props = useDefaults(_props, 'BButtonGroup')\ndefineSlots<BButtonGroupSlots>()\n\nconst computedClasses = computed(() => ({\n 'btn-group': !props.vertical,\n [`btn-group-${props.size}`]: props.size !== 'md',\n 'btn-group-vertical': props.vertical,\n}))\n</script>\n","<template>\n <div\n ref=\"toolbarRef\"\n :class=\"computedClasses\"\n class=\"btn-toolbar\"\n :role=\"props.role\"\n :aria-label=\"props.ariaLabel\"\n @keydown=\"handleKeyNav\"\n >\n <slot />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type {BButtonToolbarSlots, BButtonToolbarProps} from '../../types'\nimport {useDefaults} from '../../composables/useDefaults'\nimport {computed, nextTick, useTemplateRef} from 'vue'\nimport {CODE_DOWN, CODE_END, CODE_HOME, CODE_LEFT, CODE_RIGHT, CODE_UP} from '../../utils/constants'\nimport {getActiveElement, getSafeWindow} from '../../utils/dom'\n\nconst _props = withDefaults(defineProps<BButtonToolbarProps>(), {\n ariaLabel: 'Group',\n justify: false,\n keyNav: false,\n role: 'toolbar',\n})\nconst props = useDefaults(_props, 'BButtonToolbar')\ndefineSlots<BButtonToolbarSlots>()\n\nconst toolbarRef = useTemplateRef<HTMLElement>('toolbarRef')\n\nconst computedClasses = computed(() => ({\n 'justify-content-between': props.justify,\n}))\n\n// Get all focusable elements within the toolbar\nconst getFocusableElements = (): HTMLElement[] => {\n if (!toolbarRef.value) return []\n\n const selector =\n 'button:not(:disabled), [href]:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]:not([tabindex=\"-1\"]):not(:disabled)'\n const elements = Array.from(toolbarRef.value.querySelectorAll(selector)) as HTMLElement[]\n\n // Filter out elements that are not visible or have display:none\n return elements.filter((el) => {\n const style = getSafeWindow()?.getComputedStyle(el)\n return style && style.display !== 'none' && style.visibility !== 'hidden'\n })\n}\n\nconst isDisabled = (element: HTMLElement): boolean =>\n element.hasAttribute('disabled') || element.getAttribute('aria-disabled') === 'true'\n\nconst focusFirst = () => {\n nextTick(() => {\n const elements = getFocusableElements()\n const firstEnabled = elements.find((el) => !isDisabled(el))\n firstEnabled?.focus()\n })\n}\n\nconst focusLast = () => {\n nextTick(() => {\n const elements = getFocusableElements()\n const lastEnabled = elements.reverse().find((el) => !isDisabled(el))\n lastEnabled?.focus()\n })\n}\n\nconst focusPrev = () => {\n nextTick(() => {\n const elements = getFocusableElements()\n const activeElement = getActiveElement() as HTMLElement\n const currentIndex = elements.indexOf(activeElement)\n\n if (currentIndex > 0) {\n // Look backwards for the first non-disabled element\n for (let i = currentIndex - 1; i >= 0; i--) {\n const el = elements[i]\n if (el !== undefined && !isDisabled(el)) {\n elements[i]?.focus()\n break\n }\n }\n }\n })\n}\n\nconst focusNext = () => {\n nextTick(() => {\n const elements = getFocusableElements()\n const activeElement = getActiveElement() as HTMLElement\n const currentIndex = elements.indexOf(activeElement)\n\n if (currentIndex < elements.length - 1) {\n // Look forwards for the first non-disabled element\n for (let i = currentIndex + 1; i < elements.length; i++) {\n const el = elements[i]\n if (el !== undefined && !isDisabled(el)) {\n elements[i]?.focus()\n break\n }\n }\n }\n })\n}\n\nconst handleKeyNav = (event: KeyboardEvent) => {\n if (!props.keyNav) return\n\n const {code, shiftKey} = event\n\n if (code === CODE_LEFT || code === CODE_UP) {\n event.preventDefault()\n if (shiftKey) {\n focusFirst()\n } else {\n focusPrev()\n }\n } else if (code === CODE_RIGHT || code === CODE_DOWN) {\n event.preventDefault()\n if (shiftKey) {\n focusLast()\n } else {\n focusNext()\n }\n } else if (code === CODE_HOME) {\n event.preventDefault()\n focusFirst()\n } else if (code === CODE_END) {\n event.preventDefault()\n focusLast()\n }\n}\n</script>\n","<template>\n <div\n ref=\"toolbarRef\"\n :class=\"computedClasses\"\n class=\"btn-toolbar\"\n :role=\"props.role\"\n :aria-label=\"props.ariaLabel\"\n @keydown=\"handleKeyNav\"\n >\n <slot />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport type {BButtonToolbarSlots, BButtonToolbarProps} from '../../types'\nimport {useDefaults} from '../../composables/useDefaults'\nimport {computed, nextTick, useTemplateRef} from 'vue'\nimport {CODE_DOWN, CODE_END, CODE_HOME, CODE_LEFT, CODE_RIGHT, CODE_UP} from '../../utils/constants'\nimport {getActiveElement, getSafeWindow} from '../../utils/dom'\n\nconst _props = withDefaults(defineProps<BButtonToolbarProps>(), {\n ariaLabel: 'Group',\n justify: false,\n keyNav: false,\n role: 'toolbar',\n})\nconst props = useDefaults(_props, 'BButtonToolbar')\ndefineSlots<BButtonToolbarSlots>()\n\nconst toolbarRef = useTemplateRef<HTMLElement>('toolbarRef')\n\nconst computedClasses = computed(() => ({\n 'justify-content-between': props.justify,\n}))\n\n// Get all focusable elements within the toolbar\nconst getFocusableElements = (): HTMLElement[] => {\n if (!toolbarRef.value) return []\n\n const selector =\n 'button:not(:disabled), [href]:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]:not([tabindex=\"-1\"]):not(:disabled)'\n const elements = Array.from(toolbarRef.value.querySelectorAll(selector)) as HTMLElement[]\n\n // Filter out elements that are not visible or have display:none\n return elements.filter((el) => {\n const style = getSafeWindow()?.getComputedStyle(el)\n return style && style.display !== 'none' && style.visibility !== 'hidden'\n })\n}\n\nconst isDisabled = (element: HTMLElement): boolean =>\n element.hasAttribute('disabled') || element.getAttribute('aria-disabled') === 'true'\n\nconst focusFirst = () => {\n nextTick(() => {\n const elements = getFocusableElements()\n const firstEnabled = elements.find((el) => !isDisabled(el))\n firstEnabled?.focus()\n })\n}\n\nconst focusLast = () => {\n nextTick(() => {\n const elements = getFocusableElements()\n const lastEnabled = elements.reverse().find((el) => !isDisabled(el))\n lastEnabled?.focus()\n })\n}\n\nconst focusPrev = () => {\n nextTick(() => {\n const elements = getFocusableElements()\n const activeElement = getActiveElement() as HTMLElement\n const currentIndex = elements.indexOf(activeElement)\n\n if (currentIndex > 0) {\n // Look backwards for the first non-disabled element\n for (let i = currentIndex - 1; i >= 0; i--) {\n const el = elements[i]\n if (el !== undefined && !isDisabled(el)) {\n elements[i]?.focus()\n break\n }\n }\n }\n })\n}\n\nconst focusNext = () => {\n nextTick(() => {\n const elements = getFocusableElements()\n const activeElement = getActiveElement() as HTMLElement\n const currentIndex = elements.indexOf(activeElement)\n\n if (currentIndex < elements.length - 1) {\n // Look forwards for the first non-disabled element\n for (let i = currentIndex + 1; i < elements.length; i++) {\n const el = elements[i]\n if (el !== undefined && !isDisabled(el)) {\n elements[i]?.focus()\n break\n }\n }\n }\n })\n}\n\nconst handleKeyNav = (event: KeyboardEvent) => {\n if (!props.keyNav) return\n\n const {code, shiftKey} = event\n\n if (code === CODE_LEFT || code === CODE_UP) {\n event.preventDefault()\n if (shiftKey) {\n focusFirst()\n } else {\n focusPrev()\n }\n } else if (code === CODE_RIGHT || code === CODE_DOWN) {\n event.preventDefault()\n if (shiftKey) {\n focusLast()\n } else {\n focusNext()\n }\n } else if (code === CODE_HOME) {\n event.preventDefault()\n focusFirst()\n } else if (code === CODE_END) {\n event.preventDefault()\n focusLast()\n }\n}\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAaA,UAAQ,gBAAgB,KAAI;EAQ5B,MAAM,QAAQ,YANC,SAMmB,eAAc;EAGhD,MAAM,kBAAkB,gBAAgB;GACtC,aAAa,CAAC,MAAM;IACnB,aAAa,MAAM,SAAS,MAAM,SAAS;GAC5C,sBAAsB,MAAM;GAC7B,EAAC;;uBA3BA,YAEY,wBAFI,MAAA,MAAK,CAAC,IAAG,EAAA;IAAG,OAAK,eAAE,gBAAA,MAAe;IAAE,MAAK;IAAS,cAAY,MAAA,MAAK,CAAC;;2BAC1E,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;EEwBZ,MAAM,QAAQ,YANC,SAMmB,iBAAgB;EAGlD,MAAM,aAAa,eAA4B,aAAY;EAE3D,MAAM,kBAAkB,gBAAgB,EACtC,2BAA2B,MAAM,SAClC,EAAC;EAGF,MAAM,6BAA4C;AAChD,OAAI,CAAC,WAAW,MAAO,QAAO,EAAC;AAO/B,UAHiB,MAAM,KAAK,WAAW,MAAM,iBAD3C,uKACqE,CAAC,CAGxD,QAAQ,OAAO;IAC7B,MAAM,QAAQ,eAAe,EAAE,iBAAiB,GAAE;AAClD,WAAO,SAAS,MAAM,YAAY,UAAU,MAAM,eAAe;KAClE;;EAGH,MAAM,cAAc,YAClB,QAAQ,aAAa,WAAW,IAAI,QAAQ,aAAa,gBAAgB,KAAK;EAEhF,MAAM,mBAAmB;AACvB,kBAAe;AACI,0BAAqB,CACR,MAAM,OAAO,CAAC,WAAW,GAAG,CAAA,EAC5C,OAAM;KACrB;;EAGH,MAAM,kBAAkB;AACtB,kBAAe;AACI,0BAAqB,CACT,SAAS,CAAC,MAAM,OAAO,CAAC,WAAW,GAAG,CAAA,EACtD,OAAM;KACpB;;EAGH,MAAM,kBAAkB;AACtB,kBAAe;IACb,MAAM,WAAW,sBAAqB;IACtC,MAAM,gBAAgB,kBAAkB;IACxC,MAAM,eAAe,SAAS,QAAQ,cAAa;AAEnD,QAAI,eAAe,EAEjB,MAAK,IAAI,IAAI,eAAe,GAAG,KAAK,GAAG,KAAK;KAC1C,MAAM,KAAK,SAAS;AACpB,SAAI,OAAO,KAAA,KAAa,CAAC,WAAW,GAAG,EAAE;AACvC,eAAS,IAAI,OAAM;AACnB;;;KAIP;;EAGH,MAAM,kBAAkB;AACtB,kBAAe;IACb,MAAM,WAAW,sBAAqB;IACtC,MAAM,gBAAgB,kBAAkB;IACxC,MAAM,eAAe,SAAS,QAAQ,cAAa;AAEnD,QAAI,eAAe,SAAS,SAAS,EAEnC,MAAK,IAAI,IAAI,eAAe,GAAG,IAAI,SAAS,QAAQ,KAAK;KACvD,MAAM,KAAK,SAAS;AACpB,SAAI,OAAO,KAAA,KAAa,CAAC,WAAW,GAAG,EAAE;AACvC,eAAS,IAAI,OAAM;AACnB;;;KAIP;;EAGH,MAAM,gBAAgB,UAAyB;AAC7C,OAAI,CAAC,MAAM,OAAQ;GAEnB,MAAM,EAAC,MAAM,aAAY;AAEzB,OAAI,SAAA,eAAsB,SAAA,WAAkB;AAC1C,UAAM,gBAAe;AACrB,QAAI,SACF,aAAW;QAEX,YAAU;cAEH,SAAA,gBAAuB,SAAA,aAAoB;AACpD,UAAM,gBAAe;AACrB,QAAI,SACF,YAAU;QAEV,YAAU;cAEH,SAAA,QAAoB;AAC7B,UAAM,gBAAe;AACrB,gBAAW;cACF,SAAA,OAAmB;AAC5B,UAAM,gBAAe;AACrB,eAAU;;;;uBAlIZ,mBASM,OAAA;aARA;IAAJ,KAAI;IACH,OAAK,eAAA,CAAE,gBAAA,OACF,cAAa,CAAA;IAClB,MAAM,MAAA,MAAK,CAAC;IACZ,cAAY,MAAA,MAAK,CAAC;IAClB,WAAS;OAEV,WAAQ,KAAA,QAAA,UAAA,CAAA,EAAA,IAAA,WAAA"}