{{ field.value }}
-
+
v-model
diff --git a/documentation/components_documentation.js b/documentation/components_documentation.js
index 475b2fb6af7c8fd27fdaf4aee4afe35178b06fed..8a1f80e5645be5fe733bb3ba989ee6a01cdc9d1c 100644
--- a/documentation/components_documentation.js
+++ b/documentation/components_documentation.js
@@ -26,6 +26,7 @@ export { default as GlColumnChartDocumentation } from '../src/components/charts/
export { default as GlDiscreteScatterChartDocumentation } from '../src/components/charts/discrete_scatter/discrete_scatter.documentation';
export { default as GlSkeletonLoadingDocumentation } from '../src/components/base/skeleton_loading/skeleton_loading.documentation';
export { default as GlBadgeDocumentation } from '../src/components/base/badge/badge.documentation';
+export { default as GlDeprecatedBadgeDocumentation } from '../src/components/base/deprecated_badge/badge.documentation';
export { default as GlDeprecatedButtonDocumentation } from '../src/components/base/deprecated_button/deprecated_button.documentation';
export { default as GlButtonDocumentation } from '../src/components/base/button/button.documentation';
export { default as GlLinkDocumentation } from '../src/components/base/link/link.documentation';
diff --git a/index.js b/index.js
index 0cdb10454a091e2de57304df5208d2011bc06656..5305f446bc9d4dba57693b843ce7e1f720dbccad 100644
--- a/index.js
+++ b/index.js
@@ -28,6 +28,7 @@ export { default as GlProgressBar } from './src/components/base/progress_bar/pro
export { default as GlToken } from './src/components/base/token/token.vue';
export { default as GlSkeletonLoading } from './src/components/base/skeleton_loading/skeleton_loading.vue';
export { default as GlBadge } from './src/components/base/badge/badge.vue';
+export { default as GlDeprecatedBadge } from './src/components/base/deprecated_badge/badge.vue';
export { default as GlBanner } from './src/components/base/banner/banner.vue';
export { default as GlDeprecatedButton } from './src/components/base/deprecated_button/deprecated_button.vue';
export { default as GlButton } from './src/components/base/button/button.vue';
diff --git a/src/components/base/badge/badge.documentation.js b/src/components/base/badge/badge.documentation.js
index 5c263cd7e0427a10a2bb77284f25cde39c1d9662..7e2afade91f16d448d49406a8bc5be7b4bb23008 100644
--- a/src/components/base/badge/badge.documentation.js
+++ b/src/components/base/badge/badge.documentation.js
@@ -4,8 +4,19 @@ export default {
examples,
bootstrapComponent: 'b-badge',
bootstrapPropsInfo: {
+ href: {
+ additionalInfo:
+ 'Denotes the target URL of the link for standard a links. Providing this makes the badge actionable (clickable).',
+ },
+ },
+ propsInfo: {
variant: {
- enum: 'variantOptions',
+ additionalInfo: 'The variant of the badge.',
+ enum: 'badgeVariantOptions',
+ },
+ size: {
+ additionalInfo: 'The size of the badge.',
+ enum: 'badgeSizeOptions',
},
},
};
diff --git a/src/components/base/badge/badge.md b/src/components/base/badge/badge.md
new file mode 100644
index 0000000000000000000000000000000000000000..cab3374e7a7574e17709a9faf9271803f9a582e0
--- /dev/null
+++ b/src/components/base/badge/badge.md
@@ -0,0 +1,28 @@
+# GlBadge
+
+
+
+Badges highlight metadata of objects, the kind of information that always needs
+some context and isn’t useful on its own. For example, they can be used to
+indicate an issue’s status, a member’s role, or if a branch is protected.
+
+## Usage
+
+```html
+Hello, world!
+```
+
+> Note: Native support for icons in badges will be added in a future version.
+
+## Edge cases
+
+While this component is based on
+[`BBadge`](https://bootstrap-vue.js.org/docs/components/badge) from
+`bootstrap-vue`, it is not a drop-in replacement. Specifically, this component:
+
+ - Has a different set of valid `variant`s. See the examples or props
+ documentation for those values.
+ - Always sets the `pill` prop of the underlying `BBadge` to `true`. Any passed
+ in `pill` prop value is ignored.
+ - Does _not_ scale itself to match the size of its immediate parent, like
+ `BBadge` does.
diff --git a/src/components/base/badge/badge.scss b/src/components/base/badge/badge.scss
index a8df0960cc542a662a42e8399df4243163426a71..f8d78be9efb8e96696ee2bbb403db66ad7602bd1 100644
--- a/src/components/base/badge/badge.scss
+++ b/src/components/base/badge/badge.scss
@@ -1,51 +1,125 @@
-@import './badge-neutral';
-@import './badge-info';
-@import './badge-success';
-@import './badge-warning';
-@import './badge-danger';
+@mixin gl-badge-variant(
+ $variant,
+ $color,
+ $bg,
+ $hover-color,
+ $border-color,
+ $active-color,
+ $active-bg
+) {
+ .gl-badge.badge-#{$variant} {
+ background-color: $bg;
+ color: $color;
+ }
+
+ a.gl-badge.badge-#{$variant} {
+ &:hover {
+ color: $hover-color;
+ // Needed to override bootstrap's badge variant background
+ background-color: $bg;
+ box-shadow: inset 0 0 0 $gl-border-size-1 $border-color;
+ }
+
+ &:focus {
+ color: $hover-color;
+ // Needed to override bootstrap's badge variant background
+ background-color: $bg;
+ @include gl-focus($gl-border-size-1, $white-transparent);
+ }
+
+ &.active,
+ &:active {
+ color: $active-color;
+ background-color: $active-bg;
+ @include gl-focus($gl-border-size-1, $white-transparent);
+ }
+ }
+}
+
+/* Basic badge styles */
.gl-badge {
@include gl-display-inline-flex;
@include gl-align-items-center;
- @include gl-h-6;
- @include gl-font-weight-bold;
@include gl-font-sm;
+ @include gl-font-weight-normal;
@include gl-line-height-normal;
- @include gl-px-b6;
+ @include gl-py-2;
+ @include gl-px-3;
@include gl-outline-none;
- @include gl-border-solid;
- @include gl-border-2;
- // Sizes
&.sm {
- @include gl-h-5;
+ @include gl-py-0;
}
- &.lg {
- @include gl-h-7;
- @include gl-font-base;
+ &.md {
+ @include gl-py-2;
}
- &.normal {
- @include gl-font-weight-normal;
+ &.lg {
+ @include gl-py-3;
+ @include gl-font-base;
}
}
-a,
-button {
- &.gl-badge {
- &:focus {
- @include gl-focus-glow;
- @include gl-outline-none;
- }
+/* Variants */
- &:hover {
- @include gl-drop-shadow;
- }
+@include gl-badge-variant(
+ $variant: muted,
+ $color: $gray-500,
+ $bg: $gray-50,
+ $hover-color: $gray-600,
+ $border-color: $gray-200,
+ $active-color: $gray-800,
+ $active-bg: $gray-100
+);
- &.active,
- &:active {
- @include gl-inset-shadow;
- }
- }
-}
+@include gl-badge-variant(
+ $variant: neutral,
+ $color: $gray-700,
+ $bg: $gray-100,
+ $hover-color: $gray-800,
+ $border-color: $gray-200,
+ $active-color: $gray-900,
+ $active-bg: $gray-200
+);
+
+@include gl-badge-variant(
+ $variant: info,
+ $color: $blue-700,
+ $bg: $blue-100,
+ $hover-color: $blue-800,
+ $border-color: $blue-200,
+ $active-color: $blue-900,
+ $active-bg: $blue-200
+);
+
+@include gl-badge-variant(
+ $variant: success,
+ $color: $green-700,
+ $bg: $green-100,
+ $hover-color: $green-800,
+ $border-color: $green-200,
+ $active-color: $green-900,
+ $active-bg: $green-200
+);
+
+@include gl-badge-variant(
+ $variant: warning,
+ $color: $orange-700,
+ $bg: $orange-100,
+ $hover-color: $orange-800,
+ $border-color: $orange-200,
+ $active-color: $orange-900,
+ $active-bg: $orange-200
+);
+
+@include gl-badge-variant(
+ $variant: danger,
+ $color: $red-700,
+ $bg: $red-100,
+ $hover-color: $red-800,
+ $border-color: $red-200,
+ $active-color: $red-900,
+ $active-bg: $red-200
+);
diff --git a/src/components/base/badge/badge.stories.js b/src/components/base/badge/badge.stories.js
index bb5b7bf16d2f6433fcacba3badb35f9719b6f960..8ddadac7055d30a10e471f9e2ef4418ee1760493 100644
--- a/src/components/base/badge/badge.stories.js
+++ b/src/components/base/badge/badge.stories.js
@@ -1,14 +1,59 @@
-import { withKnobs } from '@storybook/addon-knobs';
+import { withKnobs, text, select } from '@storybook/addon-knobs';
import { documentedStoriesOf } from '../../../../documentation/documented_stories';
+import readme from './badge.md';
+import GlBadge from './badge.vue';
+import { badgeSizeOptions, badgeVariantOptions } from '../../../utils/constants';
+
+const components = {
+ GlBadge,
+};
const template = `
-
- Testbadge
-
+ {{ content }}
`;
-documentedStoriesOf('base|badge', '')
+const generateProps = ({
+ variant = GlBadge.props.variant.default,
+ size = GlBadge.props.size.default,
+ href = '',
+ content = 'TestBadge',
+} = {}) => ({
+ variant: {
+ type: String,
+ default: select('variant', Object.values(badgeVariantOptions), variant),
+ },
+ size: {
+ type: String,
+ default: select('size', Object.values(badgeSizeOptions), size),
+ },
+ href: {
+ type: String,
+ default: text('href', href),
+ },
+ content: {
+ type: String,
+ default: text('content', content),
+ },
+});
+
+documentedStoriesOf('base|badge', readme)
.addDecorator(withKnobs)
.add('default', () => ({
+ components,
+ props: generateProps(),
+ template,
+ }))
+ .add('actionable warning', () => ({
+ components,
+ props: generateProps({ href: '#foo', variant: badgeVariantOptions.warning }),
+ template,
+ }))
+ .add('large danger', () => ({
+ components,
+ props: generateProps({ size: badgeSizeOptions.lg, variant: badgeVariantOptions.danger }),
template,
}));
diff --git a/src/components/base/badge/badge.vue b/src/components/base/badge/badge.vue
index dc52202d48d3913c311b6f74d70de9dcfccbf448..69d1b5debc0499ae1b8fc504c18351fc2ce69db6 100644
--- a/src/components/base/badge/badge.vue
+++ b/src/components/base/badge/badge.vue
@@ -1,16 +1,35 @@
-
+
diff --git a/src/components/base/badge/examples/badge.action.example.vue b/src/components/base/badge/examples/badge.action.example.vue
index 505ae95bd10c65ec8229d331b649b2500716631d..e6350168dd8d0109b7aa2da49aa4ec1028282ec7 100644
--- a/src/components/base/badge/examples/badge.action.example.vue
+++ b/src/components/base/badge/examples/badge.action.example.vue
@@ -1,12 +1,10 @@
- Primary
- Secondary
+ Muted
+ Neutral
+ Info
Success
Danger
Warning
- Info
- Light
- Dark
diff --git a/src/components/base/badge/examples/badge.basic.example.vue b/src/components/base/badge/examples/badge.basic.example.vue
index e45da4c80a5f2b9d51741a447bfee865fdefa9b6..51e26ff06b4f23009679fc96f446f35f3f7d0e08 100644
--- a/src/components/base/badge/examples/badge.basic.example.vue
+++ b/src/components/base/badge/examples/badge.basic.example.vue
@@ -1,3 +1,3 @@
- Testbadge
+ Testbadge
diff --git a/src/components/base/badge/examples/badge.button.example.vue b/src/components/base/badge/examples/badge.button.example.vue
index f56fb6ba32f74349b1e8e80928b469a3d1311462..9d0db29f43388ca9a563be55395d93fbc991cbc8 100644
--- a/src/components/base/badge/examples/badge.button.example.vue
+++ b/src/components/base/badge/examples/badge.button.example.vue
@@ -1,7 +1,8 @@
-
- To-Do 42
-
+
+ To-Do
+ 42
+
diff --git a/src/components/base/badge/examples/badge.scaling.example.vue b/src/components/base/badge/examples/badge.scaling.example.vue
deleted file mode 100644
index 9cc9dedf812e62c6886e17e2830a8e5ff6d3ab42..0000000000000000000000000000000000000000
--- a/src/components/base/badge/examples/badge.scaling.example.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
Example heading New
- Example heading New
- Example heading New
- Example heading New
- Example heading New
-
-
diff --git a/src/components/base/badge/examples/badge.sizes.example.vue b/src/components/base/badge/examples/badge.sizes.example.vue
new file mode 100644
index 0000000000000000000000000000000000000000..c83b479ec78fe62a623a0842e9648c866d013479
--- /dev/null
+++ b/src/components/base/badge/examples/badge.sizes.example.vue
@@ -0,0 +1,7 @@
+
+
+ Small
+ Medium
+ Large
+
+
diff --git a/src/components/base/badge/examples/badge.variants.example.vue b/src/components/base/badge/examples/badge.variants.example.vue
index bf154923f2b6bc36c4b628189955fe1020d73328..2709fc8018724a1a386ac4290f4422a5f9bf9609 100644
--- a/src/components/base/badge/examples/badge.variants.example.vue
+++ b/src/components/base/badge/examples/badge.variants.example.vue
@@ -1,12 +1,10 @@
- Primary
- Secondary
+ Muted
+ Neutral
+ Info
Success
Danger
Warning
- Info
- Light
- Dark
diff --git a/src/components/base/badge/examples/index.js b/src/components/base/badge/examples/index.js
index 87baa0bc53a47c52775d37d5691c4e626830673d..08484a03119b245499b03da0f7c6d4fc385131a5 100644
--- a/src/components/base/badge/examples/index.js
+++ b/src/components/base/badge/examples/index.js
@@ -1,6 +1,6 @@
import BadgeBasicExample from './badge.basic.example.vue';
+import BadgeSizesExample from './badge.sizes.example.vue';
import BadgeVariantsExample from './badge.variants.example.vue';
-import BadgeScalingExample from './badge.scaling.example.vue';
import BadgeActionableExample from './badge.action.example.vue';
import BadgeButtonExample from './badge.button.example.vue';
@@ -21,10 +21,10 @@ export default [
component: BadgeVariantsExample,
},
{
- id: 'badge-scaling',
- name: 'Scaling',
- description: 'Automatic Scaling of Badges',
- component: BadgeScalingExample,
+ id: 'badge-sizes',
+ name: 'Sizes',
+ description: 'Different Badge Sizes',
+ component: BadgeSizesExample,
},
{
id: 'badge-actions',
diff --git a/src/components/base/deprecated_badge/badge.documentation.js b/src/components/base/deprecated_badge/badge.documentation.js
new file mode 100644
index 0000000000000000000000000000000000000000..5c263cd7e0427a10a2bb77284f25cde39c1d9662
--- /dev/null
+++ b/src/components/base/deprecated_badge/badge.documentation.js
@@ -0,0 +1,11 @@
+import examples from './examples';
+
+export default {
+ examples,
+ bootstrapComponent: 'b-badge',
+ bootstrapPropsInfo: {
+ variant: {
+ enum: 'variantOptions',
+ },
+ },
+};
diff --git a/src/components/base/deprecated_badge/badge.md b/src/components/base/deprecated_badge/badge.md
new file mode 100644
index 0000000000000000000000000000000000000000..5530e841d7e962a09dc712b0fb400971f2f97218
--- /dev/null
+++ b/src/components/base/deprecated_badge/badge.md
@@ -0,0 +1,5 @@
+# GlDeprecatedBadge
+
+
+
+> Note: `GlDeprecatedBadge` is _deprecated_ and should not be used. It exists only to ease migration to `GlBadge`, which should be used instead.
diff --git a/src/components/base/deprecated_badge/badge.stories.js b/src/components/base/deprecated_badge/badge.stories.js
new file mode 100644
index 0000000000000000000000000000000000000000..6e75929d360ec2e9c4fa1a00096b3a90b3749fe0
--- /dev/null
+++ b/src/components/base/deprecated_badge/badge.stories.js
@@ -0,0 +1,15 @@
+import { withKnobs } from '@storybook/addon-knobs';
+import { documentedStoriesOf } from '../../../../documentation/documented_stories';
+import readme from './badge.md';
+
+const template = `
+
+ Testbadge
+
+ `;
+
+documentedStoriesOf('base|deprecated-badge', readme)
+ .addDecorator(withKnobs)
+ .add('default', () => ({
+ template,
+ }));
diff --git a/src/components/base/deprecated_badge/badge.vue b/src/components/base/deprecated_badge/badge.vue
new file mode 100644
index 0000000000000000000000000000000000000000..dc52202d48d3913c311b6f74d70de9dcfccbf448
--- /dev/null
+++ b/src/components/base/deprecated_badge/badge.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/src/components/base/deprecated_badge/examples/badge.action.example.vue b/src/components/base/deprecated_badge/examples/badge.action.example.vue
new file mode 100644
index 0000000000000000000000000000000000000000..7249e663f85d771bc4cfaec09a00281e358b62cc
--- /dev/null
+++ b/src/components/base/deprecated_badge/examples/badge.action.example.vue
@@ -0,0 +1,12 @@
+
+
+ Primary
+ Secondary
+ Success
+ Danger
+ Warning
+ Info
+ Light
+ Dark
+
+
diff --git a/src/components/base/deprecated_badge/examples/badge.basic.example.vue b/src/components/base/deprecated_badge/examples/badge.basic.example.vue
new file mode 100644
index 0000000000000000000000000000000000000000..4102233053135f4227617a3af28717722efb9904
--- /dev/null
+++ b/src/components/base/deprecated_badge/examples/badge.basic.example.vue
@@ -0,0 +1,3 @@
+
+ Testbadge
+
diff --git a/src/components/base/deprecated_badge/examples/badge.button.example.vue b/src/components/base/deprecated_badge/examples/badge.button.example.vue
new file mode 100644
index 0000000000000000000000000000000000000000..8d1552637cf3eca09545532273547ab92af72341
--- /dev/null
+++ b/src/components/base/deprecated_badge/examples/badge.button.example.vue
@@ -0,0 +1,7 @@
+
+
+
+ To-Do 42
+
+
+
diff --git a/src/components/base/deprecated_badge/examples/badge.scaling.example.vue b/src/components/base/deprecated_badge/examples/badge.scaling.example.vue
new file mode 100644
index 0000000000000000000000000000000000000000..09fe27dada5b508e8db7ff05ce18850c88c80748
--- /dev/null
+++ b/src/components/base/deprecated_badge/examples/badge.scaling.example.vue
@@ -0,0 +1,9 @@
+
+
+
Example heading New
+ Example heading New
+ Example heading New
+ Example heading New
+ Example heading New
+
+
diff --git a/src/components/base/deprecated_badge/examples/badge.variants.example.vue b/src/components/base/deprecated_badge/examples/badge.variants.example.vue
new file mode 100644
index 0000000000000000000000000000000000000000..b6c0fe08bc332522cf202dcdd9198e50b70c4d56
--- /dev/null
+++ b/src/components/base/deprecated_badge/examples/badge.variants.example.vue
@@ -0,0 +1,12 @@
+
+
+ Primary
+ Secondary
+ Success
+ Danger
+ Warning
+ Info
+ Light
+ Dark
+
+
diff --git a/src/components/base/deprecated_badge/examples/index.js b/src/components/base/deprecated_badge/examples/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..ec17e6c4915cf49d298fed63209cd1cd0724e719
--- /dev/null
+++ b/src/components/base/deprecated_badge/examples/index.js
@@ -0,0 +1,43 @@
+import BadgeBasicExample from './badge.basic.example.vue';
+import BadgeVariantsExample from './badge.variants.example.vue';
+import BadgeScalingExample from './badge.scaling.example.vue';
+import BadgeActionableExample from './badge.action.example.vue';
+import BadgeButtonExample from './badge.button.example.vue';
+
+export default [
+ {
+ name: 'Basic',
+ items: [
+ {
+ id: 'deprecated-badge-basic',
+ name: 'Basic',
+ description: 'Basic Badge',
+ component: BadgeBasicExample,
+ },
+ {
+ id: 'deprecated-badge-variants',
+ name: 'Variants',
+ description: 'Different Badge Variants',
+ component: BadgeVariantsExample,
+ },
+ {
+ id: 'deprecated-badge-scaling',
+ name: 'Scaling',
+ description: 'Automatic Scaling of Badges',
+ component: BadgeScalingExample,
+ },
+ {
+ id: 'deprecated-badge-actions',
+ name: 'Actionable',
+ description: 'Badges with Actions',
+ component: BadgeActionableExample,
+ },
+ {
+ id: 'deprecated-badge-button',
+ name: 'Inside Button',
+ description: 'Show Badge inside Button',
+ component: BadgeButtonExample,
+ },
+ ],
+ },
+];
diff --git a/src/scss/components.scss b/src/scss/components.scss
index c2d08b54c266bdfbc41a7f0a32703a111c86a1f1..c85b6f3acd4323523fbb4bd2d0b04acc0a2352af 100644
--- a/src/scss/components.scss
+++ b/src/scss/components.scss
@@ -9,6 +9,7 @@
@import '../components/base/avatar_labeled/avatar_labeled';
@import '../components/base/avatar_link/avatar_link';
@import '../components/base/avatars_inline/avatars_inline';
+@import '../components/base/badge/badge';
@import '../components/base/breadcrumb/breadcrumb';
@import '../components/base/datepicker/datepicker';
@import '../components/base/banner/banner';
diff --git a/src/utils/constants.js b/src/utils/constants.js
index c5b1309916d5137292fd1daff2e09d3da52eba03..8155ba1ee553897eea9b92fbec7b7513b563643b 100644
--- a/src/utils/constants.js
+++ b/src/utils/constants.js
@@ -20,6 +20,21 @@ export const variantOptions = {
dark: 'dark',
};
+export const badgeSizeOptions = {
+ sm: 'sm',
+ md: 'md',
+ lg: 'lg',
+};
+
+export const badgeVariantOptions = {
+ muted: 'muted',
+ neutral: 'neutral',
+ info: 'info',
+ success: 'success',
+ warning: 'warning',
+ danger: 'danger',
+};
+
export const variantCssColorMap = {
info: 'gl-text-blue-500',
success: 'gl-text-green-500',
diff --git a/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-badge-actionable-warning-1-snap.png b/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-badge-actionable-warning-1-snap.png
new file mode 100644
index 0000000000000000000000000000000000000000..179a4aba0ca48a4b5e44eed76d58e4d234ea687f
Binary files /dev/null and b/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-badge-actionable-warning-1-snap.png differ
diff --git a/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-badge-default-1-snap.png b/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-badge-default-1-snap.png
index dbc81925bc03a2c08c535b7b74e37be3c737fa27..adaf63fd1bd1ba9746b8cd3e196737d12c7bca9e 100644
Binary files a/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-badge-default-1-snap.png and b/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-badge-default-1-snap.png differ
diff --git a/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-badge-large-danger-1-snap.png b/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-badge-large-danger-1-snap.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd8d5f001c46e0377045f893d440587e4242c1f6
Binary files /dev/null and b/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-badge-large-danger-1-snap.png differ
diff --git a/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-deprecated-badge-default-1-snap.png b/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-deprecated-badge-default-1-snap.png
new file mode 100644
index 0000000000000000000000000000000000000000..dbc81925bc03a2c08c535b7b74e37be3c737fa27
Binary files /dev/null and b/tests/__image_snapshots__/storyshots-spec-js-image-storyshots-base-deprecated-badge-default-1-snap.png differ