diff --git a/exports/badge.d.ts b/exports/badge.d.ts index ebd7f25de..12f6a2b7a 100644 --- a/exports/badge.d.ts +++ b/exports/badge.d.ts @@ -1 +1,2 @@ -export * from './components/badge/Badge'; \ No newline at end of file +export * from './components/badge/Badge'; +export * from './components/badge/BadgeDirective'; \ No newline at end of file diff --git a/exports/badge.js b/exports/badge.js index 5cf477dda..8178606fd 100644 --- a/exports/badge.js +++ b/exports/badge.js @@ -1,2 +1,3 @@ 'use strict'; -module.exports = require('./components/badge/Badge.vue'); \ No newline at end of file +module.exports.Badge = require('./components/badge/Badge.vue'); +module.exports.BadgeDirective = require('./components/badge/BadgeDirective.js'); \ No newline at end of file diff --git a/src/assets/styles/primevue.css b/src/assets/styles/primevue.css index 6cbb2fcb6..ac544b3a0 100644 --- a/src/assets/styles/primevue.css +++ b/src/assets/styles/primevue.css @@ -1,4 +1,5 @@ @import '../../components/common/Common.css'; +@import '../../components/badge/Badge.css'; @import '../../components/button/Button.css'; @import '../../components/checkbox/Checkbox.css'; @import '../../components/colorpicker/ColorPicker.css'; diff --git a/src/components/badge/Badge.css b/src/components/badge/Badge.css new file mode 100644 index 000000000..4a86ae80e --- /dev/null +++ b/src/components/badge/Badge.css @@ -0,0 +1,33 @@ +.p-badge { + display: inline-block; + border-radius: 10px; + text-align: center; + padding: 0 .5rem; +} + +.p-overlay-badge { + position: relative; + display: inline-block; +} + +.p-overlay-badge .p-badge { + position: absolute; + top: 0; + right: 0; + transform: translate(50%,-50%); + transform-origin: 100% 0; + margin: 0; +} + +.p-badge-dot { + width: .5rem; + min-width: .5rem; + height: .5rem; + border-radius: 50%; + padding: 0; +} + +.p-badge-no-gutter { + padding: 0; + border-radius: 50%; +} \ No newline at end of file diff --git a/src/components/badge/Badge.vue b/src/components/badge/Badge.vue index da300cacb..021544ff8 100644 --- a/src/components/badge/Badge.vue +++ b/src/components/badge/Badge.vue @@ -22,6 +22,8 @@ export default { }, badgeClass() { return ['p-badge p-component', { + 'p-badge-no-gutter': this.value && String(this.value).length === 1, + 'p-badge-dot': !this.value, 'p-badge-lg': this.size === 'large', 'p-badge-xl': this.size === 'xlarge', 'p-badge-info': this.severity === 'info', @@ -32,25 +34,4 @@ export default { } } } - - - + \ No newline at end of file diff --git a/src/components/badge/BadgeDirective.d.ts b/src/components/badge/BadgeDirective.d.ts new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/badge/BadgeDirective.js b/src/components/badge/BadgeDirective.js new file mode 100644 index 000000000..279bf2547 --- /dev/null +++ b/src/components/badge/BadgeDirective.js @@ -0,0 +1,55 @@ +import DomHandler from '../utils/DomHandler'; +import UniqueComponentId from '../utils/UniqueComponentId'; + +const BadgeDirective = { + beforeMount(el, options) { + const id = UniqueComponentId() + '_badge'; + el.$_pbadgeId = id; + + let badge = document.createElement('span'); + badge.id = id; + badge.className = 'p-badge p-component'; + + for (let modifier in options.modifiers) { + DomHandler.addClass(badge, 'p-badge-' + modifier); + } + + if (options.value != null) { + badge.appendChild(document.createTextNode(options.value)); + + if (String(options.value).length === 1) { + DomHandler.addClass(badge, 'p-badge-no-gutter'); + } + } + else { + DomHandler.addClass(badge, 'p-badge-dot'); + } + + DomHandler.addClass(el, 'p-overlay-badge'); + el.appendChild(badge); + }, + updated(el, options) { + DomHandler.addClass(el, 'p-overlay-badge'); + + if (options.oldValue !== options.value) { + let badge = document.getElementById(el.$_pbadgeId); + + if (options.value && DomHandler.hasClass('p-badge-dot')) { + DomHandler.removeClass(badge, 'p-badge-dot'); + + if (String(options.value).length === 1) + DomHandler.addClass(badge, 'p-badge-no-gutter'); + else + DomHandler.removeClass(badge, 'p-badge-no-gutter'); + } + else if (!options.value && !DomHandler.hasClass('p-badge-dot')) { + DomHandler.addClass(badge, 'p-badge-dot'); + } + + badge.innerHTML = ''; + badge.appendChild(document.createTextNode(options.value)); + } + } +}; + +export default BadgeDirective; diff --git a/src/components/button/Button.vue b/src/components/button/Button.vue index ac3ddb215..b290f30a2 100755 --- a/src/components/button/Button.vue +++ b/src/components/button/Button.vue @@ -3,7 +3,7 @@ {{label||' '}} - {{badge}} + {{badge}} @@ -51,6 +51,12 @@ export default { 'p-button-icon-bottom': this.iconPos === 'bottom' && this.label } ] + }, + badgeStyleClass() { + return [ + 'p-badge p-component', this.badgeClass, { + 'p-badge-no-gutter': this.badge && String(this.badge).length === 1 + }] } }, directives: { diff --git a/src/main.js b/src/main.js index 403721c6f..f6b7369dc 100644 --- a/src/main.js +++ b/src/main.js @@ -9,6 +9,7 @@ import AccordionTab from './components/accordiontab/AccordionTab'; import Avatar from './components/avatar/Avatar'; import AvatarGroup from './components/avatargroup/AvatarGroup'; import Badge from './components/badge/Badge'; +import BadgeDirective from './components/badge/BadgeDirective'; import BlockUI from './components/blockui/BlockUI'; import Breadcrumb from './components/breadcrumb/Breadcrumb'; import Button from './components/button/Button'; @@ -116,6 +117,7 @@ app.use(ToastService); app.use(ConfirmationService); app.use(router); +app.directive('badge', BadgeDirective); app.directive('tooltip', Tooltip); app.directive('ripple', Ripple); diff --git a/src/views/badge/BadgeDemo.vue b/src/views/badge/BadgeDemo.vue index ced7c0c8d..1cac61011 100644 --- a/src/views/badge/BadgeDemo.vue +++ b/src/views/badge/BadgeDemo.vue @@ -16,10 +16,10 @@ -
Positioned Badge
- - - +
Positioned Badge
+ + +
Button Badge