diff --git a/CHANGELOG.md b/CHANGELOG.md index f5315c30845..f07a2d2983e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,40 @@ > [standard-version](https://github.com/conventional-changelog/standard-version) for commit > guidelines. + + +## [v2.3.0](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.2.2...v2.3.0) + +Released: 2020-01-24 + +### Features v2.3.0 + +- **b-button-close:** add `content` prop + ([#4574](https://github.com/bootstrap-vue/bootstrap-vue/issues/4574)) + ([7379c6d](https://github.com/bootstrap-vue/bootstrap-vue/commit/7379c6dd0bac76307720645080741b3b0ed7ed99)) +- **b-form-tags:** new option to specify input type (closes + [#4644](https://github.com/bootstrap-vue/bootstrap-vue/issues/4644)) + ([#4645](https://github.com/bootstrap-vue/bootstrap-vue/issues/4645)) + ([b899fac](https://github.com/bootstrap-vue/bootstrap-vue/commit/b899faceb4c1fd8562454fa93432e70d7113401b)) +- **b-pagination, b-pagination-nav:** add page button class props and option to show first/last page + numbers (closes [#4597](https://github.com/bootstrap-vue/bootstrap-vue/issues/4597), + [#4533](https://github.com/bootstrap-vue/bootstrap-vue/issues/4533)) + ([#4622](https://github.com/bootstrap-vue/bootstrap-vue/issues/4622)) + ([3a3ee1d](https://github.com/bootstrap-vue/bootstrap-vue/commit/3a3ee1dc9312a1a8c530a5ea42d1d239d5a24351)) +- **icons:** add stacking support + ([#4658](https://github.com/bootstrap-vue/bootstrap-vue/issues/4658)) + ([b185cdb](https://github.com/bootstrap-vue/bootstrap-vue/commit/b185cdb686ddddcde1b98585b1fbc48859fc541a)) + +### Bug Fixes v2.3.0 + +- **v-b-modal:** only unbind/rebind during componentUpdated hook if trigger element or modal ID + changes (closes [#4669](https://github.com/bootstrap-vue/bootstrap-vue/issues/4669)) + ([#4672](https://github.com/bootstrap-vue/bootstrap-vue/issues/4672)) + ([e53a05d](https://github.com/bootstrap-vue/bootstrap-vue/commit/e53a05d960a9de0ca9636ee31e0197e7e554ddbc)) +- **utils:** pass all Array/Object util shortcuts as functions, for handling late loaded polyfills + ([#4647](https://github.com/bootstrap-vue/bootstrap-vue/issues/4647)) + ([f584425](https://github.com/bootstrap-vue/bootstrap-vue/commit/f5844256a03d2f4b8006900419acfa2c5e3803c3)) + ## [v2.2.2](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.2.1...v2.2.2) diff --git a/docs/components/footer.vue b/docs/components/footer.vue index 4629d8eac34..b0a28c839b9 100644 --- a/docs/components/footer.vue +++ b/docs/components/footer.vue @@ -50,6 +50,7 @@ Currently v{{ version }}. Code licensed MIT. Docs generated with Nuxt.js +

@@ -80,6 +81,11 @@ export default { }, data() { return { version } + }, + computed: { + isNetlify() { + return Boolean(process.env.NETLIFY) + } } } diff --git a/docs/content/index.js b/docs/content/index.js index 1b9a489697f..ca7355537af 100644 --- a/docs/content/index.js +++ b/docs/content/index.js @@ -10,14 +10,21 @@ export const directives = importAll(directivesContext) const iconsContext = require.context('~/../src/icons', false, /package.json/) const icons = importAll(iconsContext) || {} -// Since there are over 300 icons, we only return the first BIcon component, plus one -// extra example icon component which we modify the icon name to be `BIcon{IconName}` +// Since there are over 300 icons, we only return `BIcon` and `BIconstack` component, plus +// one extra example icon component which we modify the icon name to be `BIcon{IconName}` // We sort the array to ensure `BIcon` appears first icons[''].components = icons[''].components - .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)) - .slice(0, 2) - .map(c => ({ ...c })) -icons[''].components[1].component = 'BIcon{IconName}' + .filter(c => c.component === 'BIconBlank' || !/^BIcon[A-Z]/.test(c.component)) + .sort((a, b) => (a.component < b.component ? -1 : a.component > b.component ? 1 : 0)) + .map(c => { + c = { ...c } + if (c.component === 'BIconBlank') { + c.component = 'BIcon{IconName}' + // We add a special `srcComponent` to grab the prop `$options` data from + c.srcComponent = 'BIconBlank' + } + return c + }) export { icons } const referenceContext = require.context('~/markdown/reference', true, /meta.json/) diff --git a/docs/markdown/intro/README.md b/docs/markdown/intro/README.md index 27c79fa6f01..e25b2a76ee6 100644 --- a/docs/markdown/intro/README.md +++ b/docs/markdown/intro/README.md @@ -36,8 +36,8 @@ some good starting points would be: - [Vue Guide](https://vuejs.org/v2/guide/) - [Vue API](https://vuejs.org/v2/api/) - [Bootstrap v{{bootstrapVersionMinor}} documentation](https://getbootstrap.com/) -- [Vue loader scoped CSS](https://vue-loader.vuejs.org/guide/scoped-css.html), if using scoped styles - in SFC (Single File Component) `.vue` files +- [Vue loader scoped CSS](https://vue-loader.vuejs.org/guide/scoped-css.html), if using scoped + styles in SFC (Single File Component) `.vue` files ## Documentation information diff --git a/docs/markdown/reference/starter-templates/README.md b/docs/markdown/reference/starter-templates/README.md index 25afc1ba153..51b8cfbcb5a 100644 --- a/docs/markdown/reference/starter-templates/README.md +++ b/docs/markdown/reference/starter-templates/README.md @@ -111,7 +111,7 @@ created when you run `yarn build`. ### Importing individual components and directives -As an example, you can import `` (plus some of it's sub components) and `` as +As an example, you can import `` (plus some of its sub components) and `` as follows: ```js diff --git a/docs/markdown/reference/validation/README.md b/docs/markdown/reference/validation/README.md index b46252cd720..b4591eff850 100644 --- a/docs/markdown/reference/validation/README.md +++ b/docs/markdown/reference/validation/README.md @@ -6,8 +6,8 @@ ## Vuelidate [Vuelidate](https://github.com/vuelidate/vuelidate/) provides "Simple, lightweight model-based -validation for Vue.js". Installation instructions and other documentation can be found at -https://vuelidate.netlify.com/. +validation for Vue.js". Installation instructions and other documentation can be found at their +[website](https://vuelidate.js.org/). ### Vuelidate example diff --git a/docs/nuxt.config.js b/docs/nuxt.config.js index 2e98febdeb2..471f99dc4d7 100644 --- a/docs/nuxt.config.js +++ b/docs/nuxt.config.js @@ -112,6 +112,10 @@ module.exports = { modern: 'client', + env: { + NETLIFY: process.env.NETLIFY + }, + build: { extractCSS: true, cssSourceMap: true, diff --git a/docs/pages/docs/icons/index.js b/docs/pages/docs/icons/index.js index 3f001e38091..a79706ab4ad 100644 --- a/docs/pages/docs/icons/index.js +++ b/docs/pages/docs/icons/index.js @@ -61,12 +61,10 @@ export default { computed: { componentMeta() { // `docs/content/index.js` massages the list of icon components - // to include only `BIcon` and an example component - const components = this.meta.components - // Add in a special property or grabbing the component props - // as `BIcon{IconName}` doesn't exist - components[1].srcComponent = 'BIconBlank' - return components + // to include only `BIcon`, `BIconstack` and an example component + // The example icon has a special `srcComponent` property that lists + // `BIconBlank` as the component to grab the `$options.props` from + return this.meta.components }, importMeta() { return { ...this.meta, slug: 'icons', components: this.componentMeta } diff --git a/docs/pages/play.vue b/docs/pages/play.vue index cde2f93273a..a1fd369b7c5 100644 --- a/docs/pages/play.vue +++ b/docs/pages/play.vue @@ -340,7 +340,7 @@ const STORAGE_MAX_RETENTION = 7 * 24 * 60 * 60 * 1000 // 7 days // --- Helper functions --- -// Remove a node from it's parent's children +// Remove a node from its parent's children const removeNode = node => node && node.parentNode && node.parentNode.removeChild(node) // Indent a value by the given count diff --git a/package.json b/package.json index 28e205aaefd..716e00fd9ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bootstrap-vue", - "version": "2.2.2", + "version": "2.3.0", "description": "BootstrapVue, with over 40 plugins and more than 80 custom components, custom directives, and over 300 icons, provides one of the most comprehensive implementations of Bootstrap v4 components and grid system for Vue.js. With extensive and automated WAI-ARIA accessibility markup.", "main": "dist/bootstrap-vue.common.js", "web": "dist/bootstrap-vue.js", @@ -91,7 +91,7 @@ "dependencies": { "@nuxt/opencollective": "^0.3.0", "bootstrap": ">=4.4.1 <5.0.0", - "popper.js": "^1.16.0", + "popper.js": "^1.16.1", "portal-vue": "^2.1.7", "vue-functional-data-merge": "^3.1.0" }, @@ -108,12 +108,12 @@ "autoprefixer": "^9.7.4", "babel-core": "^7.0.0-bridge.0", "babel-eslint": "^10.0.3", - "babel-jest": "^24.9.0", + "babel-jest": "^25.1.0", "babel-plugin-istanbul": "^6.0.0", "bootstrap-icons": "^1.0.0-alpha2", "clean-css-cli": "^4.3.0", - "codecov": "^3.6.1", - "codemirror": "^5.50.2", + "codecov": "^3.6.2", + "codemirror": "^5.51.0", "codesandbox": "^2.1.11", "core-js": ">=2.6.5 <3.0.0", "cross-env": "^6.0.3", @@ -131,26 +131,26 @@ "eslint-plugin-vue": "^6.1.2", "esm": "^3.2.25", "gh-pages": "^2.2.0", - "highlight.js": "^9.17.1", + "highlight.js": "^9.18.0", "html-loader": "^0.5.5", - "husky": "^4.0.10", - "jest": "^24.9.0", + "husky": "^4.2.1", + "jest": "^25.1.0", "jest-environment-jsdom-fourteen": "^1.0.1", - "lint-staged": "^9.5.0", + "lint-staged": "^10.0.2", "loader-utils": "^1.2.3", "lodash": "^4.17.15", "marked": "^0.8.0", - "node-sass": "^4.13.0", + "node-sass": "^4.13.1", "nuxt": "^2.11.0", "postcss-cli": "^7.1.0", "prettier": "1.14.3", "require-context": "^1.1.0", - "rollup": "^1.29.0", + "rollup": "^1.29.1", "rollup-plugin-babel": "^4.3.3", "rollup-plugin-commonjs": "^10.1.0", "rollup-plugin-node-resolve": "^5.2.0", "sass-loader": "^8.0.2", - "standard-version": "^7.0.1", + "standard-version": "^7.1.0", "terser": "^4.6.3", "vue": "^2.6.11", "vue-jest": "^3.0.5", diff --git a/scripts/create-icons.js b/scripts/create-icons.js index f2c05d929d2..17ac690dc9d 100644 --- a/scripts/create-icons.js +++ b/scripts/create-icons.js @@ -45,8 +45,8 @@ const iconsTemplateFn = _template(`// --- BEGIN AUTO-GENERATED FILE --- // @IconsVersion: <%= version %> // @Generated: <%= created %> // -// This file is generated on each build. Do not edit this file. -// +// This file is generated on each build. Do not edit this file! + /*! * BootstrapVue Icons, generated from Bootstrap Icons <%= version %> * @@ -77,14 +77,16 @@ const pluginTemplateFn = _template(`// --- BEGIN AUTO-GENERATED FILE --- // @IconsVersion: <%= version %> // @Generated: <%= created %> // -// This file is generated on each build. Do not edit this file. -// +// This file is generated on each build. Do not edit this file! import { pluginFactoryNoConfig } from '../utils/plugins' // Icon helper component import { BIcon } from './icon' +// Icon stacking component +import { BIconstack } from './iconstack' + import { // BootstrapVue custom icons BIconBlank, @@ -105,6 +107,8 @@ export const IconsPlugin = /*#__PURE__*/ pluginFactoryNoConfig({ components: { // Icon helper component BIcon, + // Icon stacking component + BIconstack, // BootstrapVue custom icon components BIconBlank, // Bootstrap icon components @@ -128,8 +132,7 @@ const typesTemplateFn = _template(`// --- BEGIN AUTO-GENERATED FILE --- // @IconsVersion: <%= version %> // @Generated: <%= created %> // -// This file is generated on each build. Do not edit this file. -// +// This file is generated on each build. Do not edit this file! import Vue from 'vue' import { BvComponent } from '../' diff --git a/src/components/button/button-close.js b/src/components/button/button-close.js index 8d7d37c6caf..5b749ef4008 100644 --- a/src/components/button/button-close.js +++ b/src/components/button/button-close.js @@ -7,6 +7,10 @@ import { hasNormalizedSlot, normalizeSlot } from '../../utils/normalize-slot' const NAME = 'BButtonClose' const props = { + content: { + type: String, + default: () => getComponentConfig(NAME, 'content') + }, disabled: { type: Boolean, default: false @@ -53,7 +57,7 @@ export const BButtonClose = /*#__PURE__*/ Vue.extend({ } // Careful not to override the default slot with innerHTML if (!hasNormalizedSlot('default', $scopedSlots, $slots)) { - componentData.domProps = { innerHTML: '×' } + componentData.domProps = { innerHTML: props.content } } return h( 'button', diff --git a/src/components/button/button-close.spec.js b/src/components/button/button-close.spec.js index cd7b92247cc..aa8bf31e07b 100644 --- a/src/components/button/button-close.spec.js +++ b/src/components/button/button-close.spec.js @@ -7,23 +7,23 @@ describe('button-close', () => { expect(wrapper.is('button')).toBe(true) }) - it('has class close', async () => { + it('has class "close"', async () => { const wrapper = mount(BButtonClose) expect(wrapper.classes()).toContain('close') expect(wrapper.classes().length).toBe(1) }) - it('has attribute type=button', async () => { + it('has attribute type="button"', async () => { const wrapper = mount(BButtonClose) expect(wrapper.attributes('type')).toBe('button') }) - it('does not have attribute disabled by default', async () => { + it('does not have attribute "disabled" by default', async () => { const wrapper = mount(BButtonClose) expect(wrapper.attributes('disabled')).not.toBeDefined() }) - it('has attribute disabled when prop disabled is set', async () => { + it('has attribute "disabled" when prop "disabled" is set', async () => { const wrapper = mount(BButtonClose, { context: { props: { disabled: true } @@ -32,12 +32,12 @@ describe('button-close', () => { expect(wrapper.attributes('disabled')).toBeDefined() }) - it('has attribute aria-label=Close by default', async () => { + it('has attribute aria-label="Close" by default', async () => { const wrapper = mount(BButtonClose) expect(wrapper.attributes('aria-label')).toBe('Close') }) - it('has custom attribute aria-label=Close when prop aria-label set', async () => { + it('has custom attribute "aria-label" when prop "aria-label" set', async () => { const wrapper = mount(BButtonClose, { context: { props: { ariaLabel: 'foobar' } @@ -46,7 +46,7 @@ describe('button-close', () => { expect(wrapper.attributes('aria-label')).toBe('foobar') }) - it('has variant class when variant prop set', async () => { + it('has text variant class when "variant" prop set', async () => { const wrapper = mount(BButtonClose, { context: { props: { textVariant: 'primary' } @@ -63,6 +63,15 @@ describe('button-close', () => { expect(wrapper.text()).toContain('×') }) + it('should have custom content from "content" prop', async () => { + const wrapper = mount(BButtonClose, { + context: { + props: { content: 'Close' } + } + }) + expect(wrapper.text()).toContain('Close') + }) + it('should have custom content from default slot', async () => { const wrapper = mount(BButtonClose, { slots: { diff --git a/src/components/button/package.json b/src/components/button/package.json index ec15122b210..7b3b74012ca 100644 --- a/src/components/button/package.json +++ b/src/components/button/package.json @@ -13,7 +13,7 @@ "props": [ { "prop": "block", - "description": "Renders a 100% width button (expands to the width of it's parent container)" + "description": "Renders a 100% width button (expands to the width of its parent container)" }, { "prop": "type", @@ -51,6 +51,13 @@ "aliases": [ "BBtnClose" ], + "props": [ + { + "prop": "content", + "version": "2.3.0", + "description": "The content of the close button" + } + ], "events": [ { "event": "click", diff --git a/src/components/card/README.md b/src/components/card/README.md index 25c8e3e0f45..8cc61ea3b47 100644 --- a/src/components/card/README.md +++ b/src/components/card/README.md @@ -91,7 +91,7 @@ The title is rendered using the sub-component `` while the Sub Tit the sub-component ``. With sub-component ``, paragraph text can be added to the card. The last -`` in the card body will have it's bottom margin automatically removed (via CSS). Text +`` in the card body will have its bottom margin automatically removed (via CSS). Text within `` can also be styled with the standard HTML tags. Links can be added and placed next to each other by adding the `.card-link` class to a `` tag (or @@ -119,7 +119,7 @@ Links can be added and placed next to each other by adding the `.card-link` clas The `` prop `img-src` places an image on the top of the card, and use the `img-alt` prop to specify a string to be placed in the image's `alt` attribute. The image specified by the `img-src` -prop will be responsive and will adjust it's width when the width of the card is changed. +prop will be responsive and will adjust its width when the width of the card is changed. Alternatively you can manually place images inside `` using the sub-component ``. See the kitchen sink example below for usage. diff --git a/src/components/dropdown/README.md b/src/components/dropdown/README.md index e7a2441a8a2..b62a3c86e72 100644 --- a/src/components/dropdown/README.md +++ b/src/components/dropdown/README.md @@ -486,7 +486,7 @@ constrain/set the menu width. ``` `` has the BootstrapVue custom class `.b-dropdown-text` applied to it which sets -some basic styles which are suitable in most situations. By default it's width will be the same as +some basic styles which are suitable in most situations. By default its width will be the same as the widest `` content. You may need to place additional styles or helper classes on the component. @@ -547,7 +547,7 @@ regular form. ``` `` has the BootstrapVue custom class `.b-dropdown-form` applied to it which sets -some basic styles which are suitable in most situations. By default it's width will be the same as +some basic styles which are suitable in most situations. By default its width will be the same as the widest `` content. You may need to place additional styles or helper classes on the component. diff --git a/src/components/dropdown/_dropdown-form.scss b/src/components/dropdown/_dropdown-form.scss index c1528e73447..759cb97076d 100644 --- a/src/components/dropdown/_dropdown-form.scss +++ b/src/components/dropdown/_dropdown-form.scss @@ -17,7 +17,7 @@ $bv-dropdown-form-defined: false !default; // From https://github.com/twbs/bootstrap/blob/master/scss/_reboot.scss // mimicking button:focus styling. // We add important here as anything with tabindex `-1` and focused will not - // have a focus ring due to reboot.scss and it's `!important` override. + // have a focus ring due to reboot.scss and its `!important` override. // Needed for keyboard navigation high-lighting outline: 1px dotted !important; outline: 5px auto -webkit-focus-ring-color !important; diff --git a/src/components/dropdown/dropdown.js b/src/components/dropdown/dropdown.js index 11ed0a4ed28..1c119d5c1dc 100644 --- a/src/components/dropdown/dropdown.js +++ b/src/components/dropdown/dropdown.js @@ -29,7 +29,7 @@ export const props = { default: false }, menuClass: { - type: [String, Array], + type: [String, Array, Object], default: null }, toggleTag: { @@ -37,7 +37,7 @@ export const props = { default: 'button' }, toggleClass: { - type: [String, Array], + type: [String, Array, Object], default: null }, noCaret: { @@ -61,7 +61,7 @@ export const props = { default: () => getComponentConfig(NAME, 'splitVariant') }, splitClass: { - type: [String, Array], + type: [String, Array, Object], default: null }, splitButtonType: { diff --git a/src/components/dropdown/package.json b/src/components/dropdown/package.json index 7c59bef9a18..1ab846aa022 100644 --- a/src/components/dropdown/package.json +++ b/src/components/dropdown/package.json @@ -70,7 +70,7 @@ { "prop": "block", "version": "2.1.0", - "description": "Renders a 100% width toggle button (expands to the width of it's parent container)" + "description": "Renders a 100% width toggle button (expands to the width of its parent container)" }, { "prop": "noCaret", diff --git a/src/components/form-input/README.md b/src/components/form-input/README.md index aacf4505949..be84dd45e8e 100644 --- a/src/components/form-input/README.md +++ b/src/components/form-input/README.md @@ -84,7 +84,7 @@ rendered and a console warning will be issued. separate inputs. - `date` and `time` inputs are native browser types, and are not a custom date/time picker. - For date and time style inputs, where supported, the displayed value in the GUI may be different - than what is returned by it's value (i.e. ordering of year-month-date). + than what is returned by its value (i.e. ordering of year-month-date). - Regardless of input type, the value is **always** returned as a string representation. - `v-model.lazy` is not supported by `` (nor any custom Vue component). Use the `lazy` prop instead. diff --git a/src/components/form-input/_form-input.scss b/src/components/form-input/_form-input.scss index 1c2915b2ee0..b5008125086 100644 --- a/src/components/form-input/_form-input.scss +++ b/src/components/form-input/_form-input.scss @@ -97,7 +97,7 @@ input[type="color"].form-control:disabled { @include transition($input-transition); // Bootstrap v4.3.2 has deprecated this mixin // @include form-control-focus(); - // So we manually add it's content here + // So we manually add its content here &:focus { color: $input-focus-color; // only needed for fallback to text input background-color: $input-focus-bg; diff --git a/src/components/form-select/README.md b/src/components/form-select/README.md index 68e1e5d1071..def09ffd261 100644 --- a/src/components/form-select/README.md +++ b/src/components/form-select/README.md @@ -403,7 +403,7 @@ Note that not all mobile browsers will show the select as a list-box. Enable multiple select mode by setting the prop `multiple`, and control how many rows are displayed in the multiple select list-box by setting `select-size` to the number of rows to display. The -default is to let the browser use it's default (typically 4). +default is to let the browser use its default (typically 4). ### Value in multiple mode diff --git a/src/components/form-tags/README.md b/src/components/form-tags/README.md index 3f6e753552d..432f735509a 100644 --- a/src/components/form-tags/README.md +++ b/src/components/form-tags/README.md @@ -239,9 +239,9 @@ not validated. ### Detecting new, invalid, and duplicate tags -The event `new-tags` will be emitted whenever new tags are entered into the new tag input element, +The event `tag-state` will be emitted whenever new tags are entered into the new tag input element, tags that do not pass validation, or duplicate tags are detected. The event handler will receive -three arrays as it's arguments: +three arrays as its arguments: - `validTags` (tags that pass validation) - `invalidTags` (tags that do not pass validation) @@ -252,10 +252,10 @@ considered part of a tag), or when the user attempts to add a tag (i.e. via ` component, you can disable the built in duplicate and invalid -messages by setting the props `duplicate-tag-text` and `invalid-tag-text` (respectively) to either -an empty string (`''`) or `null`. +If you are providing your own feedback for duplicate and invalid tags (via the use of the +`tag-state` event) outside of the `` component, you can disable the built in duplicate +and invalid messages by setting the props `duplicate-tag-text` and `invalid-tag-text` (respectively) +to either an empty string (`''`) or `null`. ```html