mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
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:
@@ -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' },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
@@ -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` |
|
||||
|
||||
@@ -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>
|
||||
`,
|
||||
});
|
||||
|
||||
@@ -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: () => {},
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user