Skip to content

Commit f1ed017

Browse files
authored
feat(b-form-select): add group/tree support and dedicated option and option-group components (closes bootstrap-vue#3222) (bootstrap-vue#4267)
* feat(b-form-select): add group/tree support and dedicated option and option-group components * Improve option property handling * Update package.json * Nested `<optgroup>`'s is invalid HTML... * remove duplicate import * Update index.js * Update mixin-options.js * Update form-datalist.spec.js * Create form-select-option.spec.js * Update form-options.js * Create form-select-option-group.spec.js * Update form-select.spec.js * Improve warnings * Update form-select.spec.js * Update form-select.spec.js * Update README.md * Update README.md * Update package.json * Update _slug.js * Update componentdoc.vue * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md
1 parent f3f5279 commit f1ed017

File tree

27 files changed

+875
-115
lines changed

27 files changed

+875
-115
lines changed

docs/components/componentdoc.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<anchored-heading :id="`comp-ref-${componentName}`" level="3">
66
<code class="notranslate bigger" translate="no">{{ tag }}</code>
77
</anchored-heading>
8+
<b-badge v-if="version" variant="success">v{{ version }}+</b-badge>
89
<b-badge
910
v-if="componentFunctional"
1011
variant="secondary"
@@ -340,6 +341,10 @@ export default {
340341
aliases: {
341342
type: Array,
342343
default: () => []
344+
},
345+
version: {
346+
type: String,
347+
default: null
343348
}
344349
},
345350
computed: {

docs/pages/docs/components/_slug.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ export default {
3333
h(AnchoredHeading, { props: { id: 'component-reference' } }, 'Component reference'),
3434
// Component reference information
3535
...this.meta.components.map(
36-
({ component, events, rootEventListeners, slots, aliases, props: propsMeta }) =>
36+
({ component, events, rootEventListeners, slots, aliases, props: propsMeta, version }) =>
3737
h(Componentdoc, {
38-
props: { component, events, rootEventListeners, slots, aliases, propsMeta }
38+
props: { component, events, rootEventListeners, slots, aliases, propsMeta, version }
3939
})
4040
),
4141
// Component importing information

src/components/form-checkbox/README.md

Lines changed: 118 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,124 @@ named slot `first`.
8989

9090
## Checkbox group options array
9191

92-
Please see the [`<b-form-select>` `options` prop](/docs/components/form-select#options-property)
93-
docs for details on the formats and helper props associated with `options`.
92+
`options` can be an array of strings or objects. Available fields:
93+
94+
- **`value`** The selected value which will be set on `v-model`
95+
- **`disabled`** Disables item for selection
96+
- **`text`** Display text, or **`html`** Display basic inline html
97+
98+
`value` can be a string, number, or simple object. Avoid using complex types in values.
99+
100+
If both `html` and `text` are provided, `html` will take precedence. Only basic/native HTML is
101+
supported in the `html` field (components will not work). Note that not all browsers will render
102+
inline html (i.e. `<i>`, `<strong>`, etc) inside `<option>` elements of a `<select>`.
103+
104+
<p class="alert alert-danger">
105+
<strong>Be cautious</strong> of placing user supplied content in the <code>html</code> field,
106+
as it may make you vulnerable to
107+
<a class="alert-link" href="https://en.wikipedia.org/wiki/Cross-site_scripting">
108+
<abbr title="Cross Site Scripting Attacks">XSS attacks</abbr></a>, if you do not first
109+
<a class="alert-link" href="https://en.wikipedia.org/wiki/HTML_sanitization">sanitize</a> the
110+
user supplied string.
111+
</p>
112+
113+
<!-- eslint-disable no-unused-vars -->
114+
115+
```js
116+
const options = ['A', 'B', 'C', { text: 'D', value: { d: 1 }, disabled: true }, 'E', 'F']
117+
```
118+
119+
If an array entry is a string, it will be used for both the generated `value` and `text` fields.
120+
121+
You can mix using strings and [objects](#options-as-an-array-of-objects) in the array.
122+
123+
Internally, BootstrapVue will convert the above array to the following array (the
124+
[array of objects](#options-as-an-array-of-objects)) format:
125+
126+
<!-- eslint-disable no-unused-vars -->
127+
128+
```js
129+
const options = [
130+
{ text: 'A', value: 'A', disabled: false },
131+
{ text: 'B', value: 'B', disabled: false },
132+
{ text: 'C', value: 'C', disabled: false },
133+
{ text: 'D', value: { d: 1 }, disabled: true },
134+
{ text: 'E', value: 'E', disabled: false },
135+
{ text: 'F', value: 'F', disabled: false }
136+
]
137+
```
138+
139+
### Options as an array of objects
140+
141+
<!-- eslint-disable no-unused-vars -->
142+
143+
```js
144+
const options = [
145+
{ text: 'Item 1', value: 'first' },
146+
{ text: 'Item 2', value: 'second' },
147+
{ html: '<b>Item</b> 3', value: 'third', disabled: true },
148+
{ text: 'Item 4' },
149+
{ text: 'Item 5', value: { foo: 'bar', baz: true } }
150+
]
151+
```
152+
153+
If `value` is missing, then `text` will be used as both the `value` and `text` fields. If you use
154+
the `html` property, you **must** supply a `value` property.
155+
156+
Internally, BootstrapVue will convert the above array to the following array (the
157+
[array of objects](#options-as-an-array-of-objects)) format:
158+
159+
<!-- eslint-disable no-unused-vars -->
160+
161+
```js
162+
const options = [
163+
{ text: 'Item 1', value: 'first', disabled: false },
164+
{ text: 'Item 2', value: 'second', disabled: false },
165+
{ html: '<b>Item</b> 3', value: 'third', disabled: true },
166+
{ text: 'Item 4', value: 'Item 4', disabled: false },
167+
{ text: 'Item 5', value: 'E', disabled: false }
168+
]
169+
```
170+
171+
### Changing the option field names
172+
173+
If you want to customize the field property names (for example using `name` field for display
174+
`text`) you can easily change them by setting the `text-field`, `html-field`, `value-field`, and
175+
`disabled-field` props to a string that contains the property name you would like to use:
176+
177+
```html
178+
<template>
179+
<div>
180+
<b-form-checkbox-group
181+
v-model="selected"
182+
:options="options"
183+
class="mb-3"
184+
value-field="item"
185+
text-field="name"
186+
disabled-field="notEnabled"
187+
></b-form-checkbox-group>
188+
<div class="mt-3">Selected: <strong>{{ selected }}</strong></div>
189+
</div>
190+
</template>
191+
192+
<script>
193+
export default {
194+
data() {
195+
return {
196+
selected: [],
197+
options: [
198+
{ item: 'A', name: 'Option A' },
199+
{ item: 'B', name: 'Option B' },
200+
{ item: 'D', name: 'Option C', notEnabled: true },
201+
{ item: { d: 1 }, name: 'Option D' }
202+
]
203+
}
204+
}
205+
}
206+
</script>
207+
208+
<!-- b-form-checkbox-group-options-fields.vue -->
209+
```
94210

95211
## Inline and stacked checkboxes
96212

src/components/form-file/form-file.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import normalizeSlotMixin from '../../mixins/normalize-slot'
1212

1313
const NAME = 'BFormFile'
1414

15+
const VALUE_EMPTY_DEPRECATED_MSG =
16+
'Setting "value"/"v-model" to an empty string for reset is deprecated. Set to "null" instead.'
17+
1518
// @vue/component
1619
export const BFormFile = /*#__PURE__*/ Vue.extend({
1720
name: NAME,
@@ -32,9 +35,7 @@ export const BFormFile = /*#__PURE__*/ Vue.extend({
3235
validator: val => {
3336
/* istanbul ignore next */
3437
if (val === '') {
35-
warn(
36-
`${NAME} - setting value/v-model to an empty string for reset is deprecated. Set to 'null' instead`
37-
)
38+
warn(VALUE_EMPTY_DEPRECATED_MSG, NAME)
3839
return true
3940
}
4041
return (

src/components/form-radio/README.md

Lines changed: 118 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,124 @@ To have them appear _above_ the inputs generated by `options`, place them in the
130130

131131
## Radio group options array
132132

133-
Please see the [`<b-form-select>` `options` prop](/docs/components/form-select#options-property)
134-
docs for details on the formats and helper props associated with `options`.
133+
`options` can be an array of strings or objects. Available fields:
134+
135+
- **`value`** The selected value which will be set on `v-model`
136+
- **`disabled`** Disables item for selection
137+
- **`text`** Display text, or **`html`** Display basic inline html
138+
139+
`value` can be a string, number, or simple object. Avoid using complex types in values.
140+
141+
If both `html` and `text` are provided, `html` will take precedence. Only basic/native HTML is
142+
supported in the `html` field (components will not work). Note that not all browsers will render
143+
inline html (i.e. `<i>`, `<strong>`, etc) inside `<option>` elements of a `<select>`.
144+
145+
<p class="alert alert-danger">
146+
<strong>Be cautious</strong> of placing user supplied content in the <code>html</code> field,
147+
as it may make you vulnerable to
148+
<a class="alert-link" href="https://en.wikipedia.org/wiki/Cross-site_scripting">
149+
<abbr title="Cross Site Scripting Attacks">XSS attacks</abbr></a>, if you do not first
150+
<a class="alert-link" href="https://en.wikipedia.org/wiki/HTML_sanitization">sanitize</a> the
151+
user supplied string.
152+
</p>
153+
154+
<!-- eslint-disable no-unused-vars -->
155+
156+
```js
157+
const options = ['A', 'B', 'C', { text: 'D', value: { d: 1 }, disabled: true }, 'E', 'F']
158+
```
159+
160+
If an array entry is a string, it will be used for both the generated `value` and `text` fields.
161+
162+
You can mix using strings and [objects](#options-as-an-array-of-objects) in the array.
163+
164+
Internally, BootstrapVue will convert the above array to the following array (the
165+
[array of objects](#options-as-an-array-of-objects)) format:
166+
167+
<!-- eslint-disable no-unused-vars -->
168+
169+
```js
170+
const options = [
171+
{ text: 'A', value: 'A', disabled: false },
172+
{ text: 'B', value: 'B', disabled: false },
173+
{ text: 'C', value: 'C', disabled: false },
174+
{ text: 'D', value: { d: 1 }, disabled: true },
175+
{ text: 'E', value: 'E', disabled: false },
176+
{ text: 'F', value: 'F', disabled: false }
177+
]
178+
```
179+
180+
### Options as an array of objects
181+
182+
<!-- eslint-disable no-unused-vars -->
183+
184+
```js
185+
const options = [
186+
{ text: 'Item 1', value: 'first' },
187+
{ text: 'Item 2', value: 'second' },
188+
{ html: '<b>Item</b> 3', value: 'third', disabled: true },
189+
{ text: 'Item 4' },
190+
{ text: 'Item 5', value: { foo: 'bar', baz: true } }
191+
]
192+
```
193+
194+
If `value` is missing, then `text` will be used as both the `value` and `text` fields. If you use
195+
the `html` property, you **must** supply a `value` property.
196+
197+
Internally, BootstrapVue will convert the above array to the following array (the
198+
[array of objects](#options-as-an-array-of-objects)) format:
199+
200+
<!-- eslint-disable no-unused-vars -->
201+
202+
```js
203+
const options = [
204+
{ text: 'Item 1', value: 'first', disabled: false },
205+
{ text: 'Item 2', value: 'second', disabled: false },
206+
{ html: '<b>Item</b> 3', value: 'third', disabled: true },
207+
{ text: 'Item 4', value: 'Item 4', disabled: false },
208+
{ text: 'Item 5', value: 'E', disabled: false }
209+
]
210+
```
211+
212+
### Changing the option field names
213+
214+
If you want to customize the field property names (for example using `name` field for display
215+
`text`) you can easily change them by setting the `text-field`, `html-field`, `value-field`, and
216+
`disabled-field` props to a string that contains the property name you would like to use:
217+
218+
```html
219+
<template>
220+
<div>
221+
<b-form-radio-group
222+
v-model="selected"
223+
:options="options"
224+
class="mb-3"
225+
value-field="item"
226+
text-field="name"
227+
disabled-field="notEnabled"
228+
></b-form-radio-group>
229+
<div class="mt-3">Selected: <strong>{{ selected }}</strong></div>
230+
</div>
231+
</template>
232+
233+
<script>
234+
export default {
235+
data() {
236+
return {
237+
selected: 'A',
238+
options: [
239+
{ item: 'A', name: 'Option A' },
240+
{ item: 'B', name: 'Option B' },
241+
{ item: 'D', name: 'Option C', notEnabled: true },
242+
{ item: { d: 1 }, name: 'Option D' }
243+
]
244+
}
245+
}
246+
}
247+
</script>
248+
249+
<!-- b-form-radio-group-options-fields.vue -->
250+
```
135251

136252
## Radio value and v-model
137253

0 commit comments

Comments
 (0)