mirror of
https://github.com/directus/directus.git
synced 2026-02-08 20:44:57 -05: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:
@@ -43,7 +43,7 @@ export const collection = () =>
|
||||
hidden_browse: false,
|
||||
required: false,
|
||||
options: {
|
||||
monospace: true,
|
||||
font: 'monospace',
|
||||
},
|
||||
locked: false,
|
||||
translation: null,
|
||||
|
||||
@@ -13,30 +13,33 @@ The HTML `<input>` element supports a huge amount of attributes and events. In o
|
||||
You can add any custom (text) prefix/suffix to the value in the input using the `prefix` and `suffix` slots.
|
||||
|
||||
## Props
|
||||
| Prop | Description | Default |
|
||||
|------------------|------------------------------------------------|---------|
|
||||
| `autofocus` | Autofocusses the input on render | `false` |
|
||||
| `disabled` | Set the disabled state for the input | `false` |
|
||||
| `monospace` | Render the entered value in the monospace font | `false` |
|
||||
| `full-width` | Render the input with 100% width | `false` |
|
||||
| `prefix` | Prefix the users value with a value | -- |
|
||||
| `suffix` | Show a value at the end of the input | -- |
|
||||
| `slug` | Force the value to be URL safe | `false` |
|
||||
| `slug-separator` | What character to use as separator in slugs | `-` |
|
||||
|
||||
| Prop | Description | Default |
|
||||
| ---------------- | ------------------------------------------- | ------- |
|
||||
| `autofocus` | Autofocusses the input on render | `false` |
|
||||
| `disabled` | Set the disabled state for the input | `false` |
|
||||
| `full-width` | Render the input with 100% width | `false` |
|
||||
| `prefix` | Prefix the users value with a value | -- |
|
||||
| `suffix` | Show a value at the end of the input | -- |
|
||||
| `slug` | Force the value to be URL safe | `false` |
|
||||
| `slug-separator` | What character to use as separator in slugs | `-` |
|
||||
| `trim` | Trim leading and trailing whitespace | `true` |
|
||||
|
||||
Note: all other attached attributes are bound to the input HTMLELement in the component. This allows you to attach any of the standard HTML attributes like `min`, `length`, or `pattern`.
|
||||
|
||||
## Slots
|
||||
|
||||
| Slot | Description | Data |
|
||||
|-----------------|---------------------------------------------------|--------------------------------------------------|
|
||||
| --------------- | ------------------------------------------------- | ------------------------------------------------ |
|
||||
| `prepend-outer` | Before the input | `{ disabled: boolean, value: string | number; }` |
|
||||
| `prepend` | In the input, before the value, before the prefix | `{ disabled: boolean, value: string | number; }` |
|
||||
| `append` | In the input, after the value, after the suffix | `{ disabled: boolean, value: string | number; }` |
|
||||
| `append-outer` | After the input | `{ disabled: boolean, value: string | number; }` |
|
||||
|
||||
## Events
|
||||
|
||||
| Events | Description | Value |
|
||||
|-----------------------|----------------------------------------------|-------|
|
||||
| --------------------- | -------------------------------------------- | ----- |
|
||||
| `input` | Updates `v-model` | `any` |
|
||||
| `click:append` | User clicks on content of inner append slot | -- |
|
||||
| `click:prepend` | User clicks on content of inner prepend slot | -- |
|
||||
@@ -46,4 +49,7 @@ Note: all other attached attributes are bound to the input HTMLELement in the co
|
||||
Note: all other listeners are bound to the input HTMLElement, allowing you to handle everything from `keydown` to `emptied`.
|
||||
|
||||
## CSS Variables
|
||||
n/a
|
||||
|
||||
| Variable | Default |
|
||||
| ----------------------- | -------------------------- |
|
||||
| `--v-input-font-family` | `var(--family-sans-serif)` |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { withKnobs, text } from '@storybook/addon-knobs';
|
||||
import { withKnobs, text, boolean } from '@storybook/addon-knobs';
|
||||
import Vue from 'vue';
|
||||
import VInput from './v-input.vue';
|
||||
import markdown from './readme.md';
|
||||
@@ -22,13 +22,21 @@ export default {
|
||||
export const basic = () =>
|
||||
defineComponent({
|
||||
components: { RawValue },
|
||||
props: {
|
||||
placeholder: {
|
||||
default: text('Placeholder', 'Enter a value...', 'Options'),
|
||||
},
|
||||
trim: {
|
||||
default: boolean('Trim', false, 'Options'),
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const value = ref(null);
|
||||
return { value };
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<v-input v-model="value" placeholder="Enter content..." />
|
||||
<v-input v-model="value" v-bind="{placeholder, trim}" />
|
||||
<raw-value>{{ value }}</raw-value>
|
||||
</div>
|
||||
`,
|
||||
@@ -42,7 +50,7 @@ export const monospace = () => ({
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<v-input v-model="value" placeholder="Enter content..." monospace />
|
||||
<v-input v-model="value" placeholder="Enter content..." :style="{'--v-input-font-family': 'var(--family-monospace)'}" />
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
@@ -54,12 +54,11 @@ describe('Input', () => {
|
||||
it('Sets the correct classes based on props', async () => {
|
||||
component.setProps({
|
||||
disabled: true,
|
||||
monospace: true,
|
||||
});
|
||||
|
||||
await component.vm.$nextTick();
|
||||
|
||||
expect(component.find('.input').classes()).toEqual(['input', 'disabled', 'monospace']);
|
||||
expect(component.find('.input').classes()).toEqual(['input', 'disabled']);
|
||||
});
|
||||
|
||||
it('Emits just the value for the input event', async () => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
f
|
||||
<template>
|
||||
<div
|
||||
class="v-input"
|
||||
@@ -7,7 +8,7 @@
|
||||
<div v-if="$slots['prepend-outer']" class="prepend-outer">
|
||||
<slot name="prepend-outer" :value="value" :disabled="disabled" />
|
||||
</div>
|
||||
<div class="input" :class="{ disabled, monospace }">
|
||||
<div class="input" :class="{ disabled }">
|
||||
<div v-if="$slots.prepend" class="prepend">
|
||||
<slot name="prepend" :value="value" :disabled="disabled" />
|
||||
</div>
|
||||
@@ -53,10 +54,6 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
monospace: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
fullWidth: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -73,6 +70,10 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: '-',
|
||||
},
|
||||
trim: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
setup(props, { emit, listeners }) {
|
||||
const _listeners = computed(() => ({
|
||||
@@ -91,6 +92,8 @@ export default defineComponent({
|
||||
|
||||
if (props.slug === true) {
|
||||
value = slugify(value, { separator: props.slugSeparator });
|
||||
} else if (props.trim === true) {
|
||||
value = value.trim();
|
||||
}
|
||||
|
||||
emit('input', value);
|
||||
@@ -101,6 +104,8 @@ export default defineComponent({
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-input {
|
||||
--v-input-font-family: var(--family-sans-serif);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: max-content;
|
||||
@@ -117,6 +122,7 @@ export default defineComponent({
|
||||
height: 100%;
|
||||
padding: var(--input-padding);
|
||||
color: var(--foreground-normal);
|
||||
font-family: var(--v-input-font-family);
|
||||
background-color: var(--background-page);
|
||||
border: var(--border-width) solid var(--border-normal);
|
||||
border-radius: var(--border-radius);
|
||||
@@ -158,6 +164,7 @@ export default defineComponent({
|
||||
flex-grow: 1;
|
||||
width: 100px; // allows flex to shrink to allow for slots
|
||||
height: 100%;
|
||||
font-family: var(--v-input-font-family);
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
appearance: none;
|
||||
@@ -167,29 +174,6 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
&.has-click {
|
||||
cursor: pointer;
|
||||
input {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.active .input {
|
||||
color: var(--foreground-normal);
|
||||
background-color: var(--background-page);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.input.monospace {
|
||||
input {
|
||||
font-family: var(--family-monospace);
|
||||
}
|
||||
}
|
||||
|
||||
.append-outer {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
&.full-width {
|
||||
width: 100%;
|
||||
|
||||
@@ -197,5 +181,26 @@ export default defineComponent({
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.has-click {
|
||||
cursor: pointer;
|
||||
input {
|
||||
pointer-events: none;
|
||||
.prefix,
|
||||
.suffix {
|
||||
color: var(--foreground-subdued);
|
||||
}
|
||||
}
|
||||
|
||||
&.active .input {
|
||||
color: var(--foreground-normal);
|
||||
background-color: var(--background-page);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.append-outer {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,25 +23,29 @@ Renders a dropdown input.
|
||||
## Props
|
||||
|
||||
| Prop | Description | Default |
|
||||
|---------------|-----------------------------------------------------|---------|
|
||||
| `items`* | Items to render in the select | |
|
||||
| ------------- | --------------------------------------------------- | ------- |
|
||||
| `items`\* | Items to render in the select | |
|
||||
| `itemText` | What item value to use for the display text | `text` |
|
||||
| `itemValue` | What item value to use for the item value | `value` |
|
||||
| `value` | Currently selected item(s) | |
|
||||
| `multiple` | Allow multiple items to be selected | `false` |
|
||||
| `placeholder` | What placeholder to show when no items are selected | |
|
||||
| `full-width` | Render the select at full width | |
|
||||
| `monospace` | Render the value and options monospaced | |
|
||||
| `disabled` | Disable the select | |
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Description | Value |
|
||||
|---------|--------------------------|-----------------------------------------|
|
||||
| ------- | ------------------------ | --------------------------------------- |
|
||||
| `input` | New value for the select | `(string | number)[] | string | number` |
|
||||
|
||||
## Slots
|
||||
|
||||
n/a
|
||||
|
||||
## CSS Variables
|
||||
n/a
|
||||
|
||||
| Variable | Default |
|
||||
| ------------------------ | -------------------------- |
|
||||
| `--v-select-font-family` | `var(--family-sans-serif)` |
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
<template #activator="{ toggle }">
|
||||
<v-input
|
||||
:full-width="fullWidth"
|
||||
:monospace="monospace"
|
||||
readonly
|
||||
:value="displayValue"
|
||||
@click="toggle"
|
||||
@@ -29,7 +28,7 @@
|
||||
@click="multiple ? null : $emit('input', item.value)"
|
||||
>
|
||||
<v-list-item-content>
|
||||
<span v-if="multiple === false" :class="{ monospace }">{{ item.text }}</span>
|
||||
<span v-if="multiple === false" class="item-text">{{ item.text }}</span>
|
||||
<v-checkbox
|
||||
v-else
|
||||
:inputValue="value || []"
|
||||
@@ -86,10 +85,6 @@ export default defineComponent({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
monospace: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
allowNull: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -147,15 +142,23 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.monospace {
|
||||
font-family: var(--family-monospace);
|
||||
}
|
||||
.v-select {
|
||||
--v-select-font-family: var(--family-sans-serif);
|
||||
|
||||
.v-input {
|
||||
cursor: pointer;
|
||||
font-family: var(--v-select-font-family);
|
||||
|
||||
.item-text {
|
||||
font-family: var(--v-select-font-family);
|
||||
}
|
||||
|
||||
.v-input {
|
||||
--v-input-font-family: var(--v-select-font-family);
|
||||
|
||||
::v-deep input {
|
||||
cursor: pointer;
|
||||
|
||||
::v-deep input {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user