Text-input / v-input fixes (#386)

* textinput fixes including masking trimming icons and fonts

* removed masked attribute from v-input

* added wrapper div

* ugh

* test fix

* fixed all calls to monospace boolean except on textarea (in separate branch)

* readonly

* Remove unused wrapper div and rename readonly to disabled

* Rename readonly to disabled in story

* Prefer style over inline styles

* Fix codesmell

Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
Jacob Rienstra
2020-04-20 10:23:01 -04:00
committed by GitHub
parent 471c759df7
commit bf79610219
18 changed files with 248 additions and 102 deletions

View File

@@ -7,17 +7,42 @@ export default defineInterface(({ i18n }) => ({
icon: 'box',
component: InterfaceTextInput,
options: [
{
field: 'monospace',
name: 'Monospace',
width: 'half',
interface: 'switch',
},
{
field: 'placeholder',
name: 'Placeholder',
width: 'half',
interface: 'text-input',
},
{
field: 'iconLeft',
name: 'Icon Left',
width: 'half',
interface: 'icon',
},
{
field: 'iconRight',
name: 'Icon Right',
width: 'half',
interface: 'icon',
},
{
field: 'trim',
name: 'Trim',
width: 'half',
interface: 'switch',
},
{
field: 'font',
name: 'Font',
width: 'half',
interface: 'select-one-dropdown',
options: {
items: [
{ itemText: 'Sans', itemValue: 'sans-serif' },
{ itemText: 'Mono', itemValue: 'monospace' },
{ itemText: 'Serif', itemValue: 'serif' },
],
},
},
],
}));

View File

@@ -1 +1,13 @@
# Text Input
## Options
| Option | Description | Default |
| ------------- | ------------------------------------------------------------------- | ------------ |
| `readonly` | Readonly | `false` |
| `placeholder` | Text to show when no input is entered | `null` |
| `masked` | Mask the value (as in a password field) | `false` |
| `iconLeft` | Icon to appear on the inside left of the input box | `null` |
| `iconRight` | Icon to appear on the inside right of the input box | `null` |
| `trim` | Trim leading and trailing whitespace | `true` |
| `font` | Font to render the value in (`sans-serif`, `serif`, or `monospace`) | `sans-serif` |

View File

@@ -1,10 +1,11 @@
import { withKnobs, boolean, text } from '@storybook/addon-knobs';
import { withKnobs, boolean, text, optionsKnob } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';
import Vue from 'vue';
import InterfaceTextInput from './text-input.vue';
import markdown from './readme.md';
import withPadding from '../../../.storybook/decorators/with-padding';
import { defineComponent } from '@vue/composition-api';
import { defineComponent, ref } from '@vue/composition-api';
import RawValue from '../../../.storybook/raw-value.vue';
Vue.component('interface-text-input', InterfaceTextInput);
@@ -18,28 +19,49 @@ export default {
export const basic = () =>
defineComponent({
components: { RawValue },
props: {
monospace: {
default: boolean('Monospace', false, 'Options'),
placeholder: {
default: text('Placeholder', 'Enter a value...', 'Options'),
},
masked: {
default: boolean('Masked', false, 'Options'),
},
iconLeft: {
default: text('Icon Left', '', 'Options'),
},
iconRight: {
default: text('Icon Right', '', 'Options'),
},
trim: {
default: boolean('Trim', false, 'Options'),
},
showCharacterCount: {
default: boolean('Show Character Count', false, 'Options'),
font: {
default: optionsKnob(
'Font',
{ Sans: 'sans-serif', Serif: 'serif', Mono: 'monospace' },
'sans',
{ display: 'select' },
'Options'
),
},
placeholder: {
default: text('Placeholder', 'Enter a value...', 'Options'),
disabled: {
default: boolean('Disabled', false, 'Options'),
},
},
setup() {
const onInput = action('input');
return { onInput };
const value = ref(null);
return { onInput, value };
},
template: `
<div>
<interface-text-input
:options="{ monospace, trim, showCharacterCount, placeholder }"
v-model="value"
v-bind="{ placeholder, masked, iconLeft, iconRight, trim, font, disabled }"
@input="onInput"
/>
<raw-value>{{ value }}</raw-value>
</div>
`,
});

View File

@@ -13,12 +13,8 @@ describe('Interfaces / Text Input', () => {
const component = shallowMount(InterfaceTextInput, {
localVue,
propsData: {
options: {
monospace: false,
trim: false,
showCharacterCount: false,
placeholder: 'Enter value...',
},
trim: false,
placeholder: 'Enter value...',
},
listeners: {
input: () => {},

View File

@@ -1,16 +1,21 @@
<template>
<v-input
:monospace="monospace"
:value="value"
:placeholder="placeholder"
:disabled="disabled"
:trim="trim"
:type="masked ? 'password' : 'text'"
:class="font"
full-width
@input="$listeners.input"
/>
>
<template v-if="iconLeft" #prepend><v-icon :name="iconLeft" /></template>
<template v-if="iconRight" #append><v-icon :name="iconRight" /></template>
</v-input>
</template>
<script lang="ts">
import { defineComponent } from '@vue/composition-api';
import { defineComponent, PropType } from '@vue/composition-api';
export default defineComponent({
props: {
@@ -22,14 +27,46 @@ export default defineComponent({
type: Boolean,
default: false,
},
monospace: {
type: Boolean,
default: false,
},
placeholder: {
type: String,
default: null,
},
masked: {
type: Boolean,
default: false,
},
iconLeft: {
type: String,
default: null,
},
iconRight: {
type: String,
default: null,
},
trim: {
type: Boolean,
default: true,
},
font: {
type: String as PropType<'sans-serif' | 'serif' | 'monospace'>,
default: 'sans-serif',
},
},
});
</script>
<style lang="scss" scoped>
.v-input {
.monospace {
--v-input-font-family: var(--family-monospace);
}
.serif {
--v-input-font-family: var(--family-serif);
}
.sans-serif {
--v-input-font-family: var(--family-sans-serif);
}
}
</style>