🌐 AI搜索 & 代理 主页
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1829ea7
fix(b-form-textarea): handle initial auto height when in modal or oth…
tmorehouse Aug 23, 2019
3fd2ac5
Update form-textarea.js
tmorehouse Aug 23, 2019
eb835da
Update form-textarea.js
tmorehouse Aug 23, 2019
0f6e616
Create vb-visible.js
tmorehouse Aug 24, 2019
5790d77
Update form-textarea.js
tmorehouse Aug 24, 2019
613116b
Update vb-visible.js
tmorehouse Aug 24, 2019
24d1ce9
Update form-textarea.js
tmorehouse Aug 24, 2019
d53a8f2
Update form-textarea.js
tmorehouse Aug 24, 2019
84f2663
Update vb-visible.js
tmorehouse Aug 24, 2019
752b1ae
Update vb-visible.js
tmorehouse Aug 24, 2019
0f59cf6
Update vb-visible.js
tmorehouse Aug 24, 2019
3a7cc80
Update vb-visible.js
tmorehouse Aug 24, 2019
c8be11f
Update form-textarea.spec.js
tmorehouse Aug 24, 2019
0d27d05
Update vb-visible.js
tmorehouse Aug 24, 2019
83f5d43
Update form-textarea.js
tmorehouse Aug 24, 2019
2050197
Update form-textarea.js
tmorehouse Aug 24, 2019
d76f854
Update form-textarea.js
tmorehouse Aug 24, 2019
c4f863a
Update vb-visible.js
tmorehouse Aug 24, 2019
e11b1f2
Update README.md
tmorehouse Aug 24, 2019
f645564
Update vb-visible.js
tmorehouse Aug 24, 2019
ce77272
Update vb-visible.js
tmorehouse Aug 24, 2019
0fcf873
Update form-textarea.js
tmorehouse Aug 24, 2019
1881f17
Update README.md
tmorehouse Aug 24, 2019
87ebda0
Update README.md
tmorehouse Aug 24, 2019
0596def
Merge branch 'dev' into issue/3936
tmorehouse Aug 24, 2019
25da313
Merge branch 'dev' into issue/3936
tmorehouse Aug 24, 2019
b8861c5
Merge branch 'dev' into issue/3936
jacobmllr95 Aug 25, 2019
e32560c
Rename src/utils/vb-visible.js to src/directives/visible.js
tmorehouse Aug 25, 2019
3c45961
Update form-textarea.js
tmorehouse Aug 25, 2019
8f75a4a
Update visible.js
tmorehouse Aug 25, 2019
972bae8
Merge branch 'dev' into issue/3936
tmorehouse Aug 25, 2019
432e147
Update README.md
jacobmllr95 Aug 26, 2019
cd4ffa1
Merge branch 'dev' into issue/3936
tmorehouse Aug 26, 2019
4ef1945
Update visible.js
jacobmllr95 Aug 26, 2019
0cfe057
Update form-textarea.js
jacobmllr95 Aug 26, 2019
73f60b0
Merge branch 'issue/3936' of https://github.com/bootstrap-vue/bootstr…
jacobmllr95 Aug 26, 2019
7e44d12
Update visible.js
tmorehouse Aug 26, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/components/form-textarea/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,10 @@ disabled in auto-height mode.

Auto-height works by computing the resulting height via CSS queries, hence the input has to be in
document (DOM) and visible (not hidden via `display: none`). Initial height is computed on mount. If
the `b-form-text-area` is visually hidden on mount, the auto height cannot be computed.

In situations where the text area may initially be hidden visually (i.e. in non-lazy `b-tab`
components or non-lazy static `b-modal`), you may want to use `v-if` to delay mouting (lazy mount),
or delay setting the value of `b-form-textarea` until it's visually hidden parent is shown.
the browser client supports [`IntersectionObserver`](https://caniuse.com/#feat=intersectionobserver)
(either natively or via [a polyfill](/docs#js)), `<b-form-textarea>` will take advantage of this to
determine when the textarea becomes visible and will then compute the height. Refer to the
[Browser support](/docs#browser) section on the getting started page.

## Contextual states

Expand Down
81 changes: 39 additions & 42 deletions src/components/form-textarea/form-textarea.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import Vue from '../../utils/vue'
import { VBVisible } from '../../directives/visible'
import idMixin from '../../mixins/id'
import formMixin from '../../mixins/form'
import formSizeMixin from '../../mixins/form-size'
import formStateMixin from '../../mixins/form-state'
import formTextMixin from '../../mixins/form-text'
import formSelectionMixin from '../../mixins/form-selection'
import formValidityMixin from '../../mixins/form-validity'
import { getCS, isVisible } from '../../utils/dom'
import listenOnRootMixin from '../../mixins/listen-on-root'
import { getCS, isVisible, requestAF } from '../../utils/dom'
import { isNull } from '../../utils/inspect'

// @vue/component
export const BFormTextarea = /*#__PURE__*/ Vue.extend({
name: 'BFormTextarea',
directives: {
'b-visible': VBVisible
},
mixins: [
idMixin,
listenOnRootMixin,
formMixin,
formSizeMixin,
formStateMixin,
Expand Down Expand Up @@ -48,7 +54,6 @@ export const BFormTextarea = /*#__PURE__*/ Vue.extend({
},
data() {
return {
dontResize: true,
heightInPx: null
}
},
Expand All @@ -60,64 +65,52 @@ export const BFormTextarea = /*#__PURE__*/ Vue.extend({
resize: !this.computedRows || this.noResize ? 'none' : null
}
if (!this.computedRows) {
// Conditionaly set the computed CSS height when auto rows/height is enabled.
// We avoid setting the style to null, which can override user manual resize handle.
// Conditionally set the computed CSS height when auto rows/height is enabled
// We avoid setting the style to `null`, which can override user manual resize handle
styles.height = this.heightInPx
// We always add a vertical scrollbar to the textarea when auto-height is
// enabled so that the computed height calcaultion returns a stable value.
// enabled so that the computed height calculation returns a stable value
styles.overflowY = 'scroll'
}
return styles
},
computedMinRows() {
// Ensure rows is at least 2 and positive (2 is the native textarea value).
// A value of 1 can cause issues in some browsers, and most browsers only support
// 2 as the smallest value.
// Ensure rows is at least 2 and positive (2 is the native textarea value)
// A value of 1 can cause issues in some browsers, and most browsers
// only support 2 as the smallest value
return Math.max(parseInt(this.rows, 10) || 2, 2)
},
computedMaxRows() {
return Math.max(this.computedMinRows, parseInt(this.maxRows, 10) || 0)
},
computedRows() {
// This is used to set the attribute 'rows' on the textarea.
// If auto-height is enabled, then we return null as we use CSS to control height.
// This is used to set the attribute 'rows' on the textarea
// If auto-height is enabled, then we return `null` as we use CSS to control height
return this.computedMinRows === this.computedMaxRows ? this.computedMinRows : null
}
},
watch: {
dontResize(newVal, oldval) {
if (!newVal) {
this.setHeight()
}
},
localValue(newVal, oldVal) {
this.setHeight()
}
},
mounted() {
// Enable opt-in resizing once mounted
this.$nextTick(() => {
this.dontResize = false
})
},
activated() {
// If we are being re-activated in <keep-alive>, enable opt-in resizing
this.$nextTick(() => {
this.dontResize = false
})
},
deactivated() {
// If we are in a deactivated <keep-alive>, disable opt-in resizing
this.dontResize = true
},
beforeDestroy() {
/* istanbul ignore next */
this.dontResize = true
this.setHeight()
},
methods: {
// Called by intersection observer directive
visibleCallback(visible) /* istanbul ignore next */ {
if (visible) {
// We use a `$nextTick()` here just to make sure any
// transitions or portalling have completed
this.$nextTick(this.setHeight)
}
},
setHeight() {
this.$nextTick(() => {
this.heightInPx = this.computeHeight()
requestAF(() => {
this.heightInPx = this.computeHeight()
})
})
},
computeHeight() /* istanbul ignore next: can't test getComputedStyle in JSDOM */ {
Expand All @@ -127,7 +120,7 @@ export const BFormTextarea = /*#__PURE__*/ Vue.extend({

const el = this.$el

// Element must be visible (not hidden) and in document.
// Element must be visible (not hidden) and in document
// Must be checked after above checks
if (!isVisible(el)) {
return null
Expand All @@ -153,18 +146,18 @@ export const BFormTextarea = /*#__PURE__*/ Vue.extend({
// Probe scrollHeight by temporarily changing the height to `auto`
el.style.height = 'auto'
const scrollHeight = el.scrollHeight
// Place the original old height back on the element, just in case this computedProp
// returns the same value as before.
// Place the original old height back on the element, just in case `computedProp`
// returns the same value as before
el.style.height = oldHeight

// Calculate content height in "rows" (scrollHeight includes padding but not border)
// Calculate content height in 'rows' (scrollHeight includes padding but not border)
const contentRows = Math.max((scrollHeight - padding) / lineHeight, 2)
// Calculate number of rows to display (limited within min/max rows)
const rows = Math.min(Math.max(contentRows, this.computedMinRows), this.computedMaxRows)
// Calculate the required height of the textarea including border and padding (in pixels)
const height = Math.max(Math.ceil(rows * lineHeight + offset), minHeight)

// Computed height remains the larger of oldHeight and new height,
// Computed height remains the larger of `oldHeight` and new `height`,
// when height is in `sticky` mode (prop `no-auto-shrink` is true)
if (this.noAutoShrink && (parseFloat(oldHeight) || 0) > height) {
return oldHeight
Expand All @@ -184,9 +177,13 @@ export const BFormTextarea = /*#__PURE__*/ Vue.extend({
directives: [
{
name: 'model',
rawName: 'v-model',
value: self.localValue,
expression: 'localValue'
value: self.localValue
},
{
name: 'b-visible',
value: this.visibleCallback,
// If textarea is within 640px of viewport, consider it visible
modifiers: { '640': true }
}
],
attrs: {
Expand Down
46 changes: 0 additions & 46 deletions src/components/form-textarea/form-textarea.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -774,52 +774,6 @@ describe('form-textarea', () => {
input.destroy()
})

it('activate and deactivate hooks work (keepalive)', async () => {
const Keepalive = {
template:
'<div><keep-alive>' +
'<b-form-textarea ref="textarea" v-if="show" v-model="value"></b-form-textarea>' +
'<p v-else></p>' +
'</keep-alive></div>',
components: { BFormTextarea },
props: { show: true },
data() {
return { value: '' }
}
}

const keepalive = mount(Keepalive, {
attachToDocument: true,
propsData: {
show: true
}
})

expect(keepalive).toBeDefined()

const textarea = keepalive.find(BFormTextarea)
expect(textarea).toBeDefined()
expect(textarea.isVueInstance()).toBe(true)

// Check that the internal dontResize flag is now false
await keepalive.vm.$nextTick()
expect(textarea.vm.dontResize).toEqual(false)

// v-if the component out of document
keepalive.setProps({ show: false })
// Check that the internal dontResize flag is now true
await keepalive.vm.$nextTick()
expect(textarea.vm.dontResize).toEqual(true)

// v-if the component out of document
keepalive.setProps({ show: true })
// Check that the internal dontResize flag is now false
await keepalive.vm.$nextTick()
expect(textarea.vm.dontResize).toEqual(false)

keepalive.destroy()
})

it('trim modifier prop works', async () => {
const input = mount(BFormTextarea, {
attachToDocument: true,
Expand Down
4 changes: 2 additions & 2 deletions src/components/tabs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ For navigation based tabs (i.e. tabs that would change the URL), use the

**Tip:** You should supply each child `<b-tab>` component a unique `key` value if dynamically adding
or removing `<b-tab>` components (i.e. `v-if` or for loops). The `key` attribute is a special Vue
attribute, see https://vuejs.org/v2/api/#key).
attribute, see https://vuejs.org/v2/api/#key.

## Cards integration

Expand Down Expand Up @@ -479,7 +479,7 @@ order to use these methods.
</b-button>
</b-tab>

<!-- New Tab Button (Using tabs slot) -->
<!-- New Tab Button (Using tabs-end slot) -->
<template slot="tabs-end">
<b-nav-item @click.prevent="newTab" href="#"><b>+</b></b-nav-item>
</template>
Expand Down
Loading