Add date(time) interface (#499)

* Add localized-format util

* Add active prop to v-input

* Add strings for datetime interface

* Add overflow-scroll prop to v-menu

* Add close-on-content-click prop to v-select

* Add datetime interface

* Show display value synced with prop

* Sync value with prop

* Set lang after user hydration

* Add NL date-fns lang to test datetime

* Fix locale fetching in date-fns

* Dont stage value if year isnt fully filled out

* Localize date fns based on shared util

* Handle type, render type based display

* Don't use exact on v-list-item

* Pass type to interface on v-form
This commit is contained in:
Rijk van Zanten
2020-04-29 10:00:22 -04:00
committed by GitHub
parent fcbe0af502
commit b5d6fdefa2
21 changed files with 520 additions and 69 deletions

View File

@@ -84,6 +84,7 @@
: values[field.field]
"
:width="field.width"
:type="field.type"
@input="setValue(field, $event)"
/>
</div>

View File

@@ -23,6 +23,7 @@ You can add any custom (text) prefix/suffix to the value in the input using the
| `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 | `-` |
| `active` | Force the focus state | `false` |
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`.

View File

@@ -7,7 +7,7 @@
<div v-if="$slots['prepend-outer']" class="prepend-outer">
<slot name="prepend-outer" :value="value" :disabled="disabled" />
</div>
<div class="input" :class="{ disabled }">
<div class="input" :class="{ disabled, active }">
<div v-if="$slots.prepend" class="prepend">
<slot name="prepend" :value="value" :disabled="disabled" />
</div>
@@ -105,6 +105,10 @@ export default defineComponent({
type: Number,
default: 1,
},
active: {
type: Boolean,
default: false,
},
},
setup(props, { emit, listeners }) {
const input = ref<HTMLInputElement>(null);
@@ -221,7 +225,8 @@ body {
border-color: var(--border-normal-alt);
}
&:focus-within {
&:focus-within,
&.active {
--arrow-color: var(--primary);
color: var(--foreground-normal);
@@ -249,7 +254,7 @@ body {
input {
flex-grow: 1;
width: 100px; // allows flex to shrink to allow for slots
width: 20px; // allows flex to grow/shrink to allow for slots
height: 100%;
font-family: var(--v-input-font-family);
background-color: transparent;
@@ -290,12 +295,6 @@ body {
}
}
&.active .input {
color: var(--foreground-normal);
background-color: var(--background-page);
border-color: var(--primary);
}
.append-outer {
margin-left: 8px;
}

View File

@@ -3,7 +3,6 @@
:is="component"
active-class="active"
class="v-list-item"
exact
:to="to"
:class="{
active,

View File

@@ -57,8 +57,6 @@ export default {
## Props
Strap in
### Positioning
| Prop | Description | Default |
@@ -70,22 +68,22 @@ Strap in
| `bottom` | Aligns the menu to the bottom of the activator, going down (if possible) | `false` |
| `left` | Aligns the menu to the left of the activator, expanding left (if possible) | `false` |
| `right` | Aligns the menu to the right of the activator, expanding right (if possible) | `false` |
| `offsetX` | Positions the menu along the X-Axis so as not to cover any of the activator | `false` |
| `offsetY` | Positions the menu along the Y-Axis so as not to cover any of the activator | `false` |
| `positionX` | "left" css value of menu. Only works with `absolute` or `fixed` | `undefined` |
| `positionY` | "top" css value of menu. Only works with `absolute` or `fixed` | `undefined` |
| `disabled` | Prevent the menu from being opened by clicking on the activator | `false` |
| `offset-x` | Positions the menu along the X-Axis so as not to cover any of the activator | `false` |
| `offset-y` | Positions the menu along the Y-Axis so as not to cover any of the activator | `false` |
| `position-x` | "left" css value of menu. Only works with `absolute` or `fixed` | `undefined` |
| `position-y` | "top" css value of menu. Only works with `absolute` or `fixed` | `undefined` |
### Behavior
| Prop | Description | Default |
| --------------------- | --------------------------------------------------------- | ------- |
| `closeOnClick` | Closes the menu when user clicks somewhere else | `true` |
| `closeOnContentClick` | Closes the menu when user clicks on a menu item | `false` |
| `openOnClick` | Open the menu when activator is clicked | `true` |
| `openOnHover` | Open the menu when activator is hovered over | `false` |
| `openDelay` | Delay in milliseconds after hover enter for menu to open | `0` |
| `closeDelay` | Delay in milliseconds after hover leave for menu to close | `0` |
| Prop | Description | Default |
|-----------------------|-------------------------------------------------------------|---------|
| `closeOnClick` | Closes the menu when user clicks somewhere else | `true` |
| `closeOnContentClick` | Closes the menu when user clicks on a menu item | `false` |
| `openOnClick` | Open the menu when activator is clicked | `true` |
| `openOnHover` | Open the menu when activator is hovered over | `false` |
| `openDelay` | Delay in milliseconds after hover enter for menu to open | `0` |
| `closeDelay` | Delay in milliseconds after hover leave for menu to close | `0` |
| `overflow-scroll` | Overflow the content in the menu when it reaches max height | `true` |
### Control

View File

@@ -23,7 +23,11 @@
:style="arrowStyles"
data-popper-arrow
/>
<div :class="{ active: isActive }" class="v-menu-content" @click="onContentClick">
<div
:class="{ active: isActive, 'overflow-scroll': overflowScroll }"
class="v-menu-content"
@click="onContentClick"
>
<slot />
</div>
</div>
@@ -65,6 +69,10 @@ export default defineComponent({
type: Boolean,
default: false,
},
overflowScroll: {
type: Boolean,
default: true,
},
},
setup(props, { emit }) {
const activator = ref<HTMLElement>(null);
@@ -239,8 +247,6 @@ body {
.v-menu-content {
max-height: 50vh;
padding: 0 4px;
overflow-x: hidden;
overflow-y: auto;
background-color: var(--background-subdued);
border: 2px solid var(--border-normal);
border-radius: var(--border-radius);
@@ -249,7 +255,12 @@ body {
transition-timing-function: var(--transition-out);
transition-duration: var(--fast);
transition-property: opacity, transform;
contain: content;
&.overflow-scroll {
contain: content;
overflow-x: hidden;
overflow-y: auto;
}
.v-list {
--v-list-background-color: transparent;

View File

@@ -22,17 +22,18 @@ Renders a dropdown input.
## Props
| Prop | Description | Default |
|-----------------|-----------------------------------------------------|---------|
| `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 | |
| `disabled` | Disable the select | |
| `show-deselect` | Show the deselect option when a value has been set | |
| Prop | Description | Default |
|--------------------------|-----------------------------------------------------|---------|
| `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 | |
| `disabled` | Disable the select | |
| `show-deselect` | Show the deselect option when a value has been set | |
| `close-on-content-click` | Close the select when selecting a value | `true` |
## Events

View File

@@ -1,6 +1,11 @@
<template>
<v-menu :disabled="disabled" class="v-select" attached>
<template #activator="{ toggle }">
<v-menu
:disabled="disabled"
class="v-select"
attached
:close-on-content-click="closeOnContentClick"
>
<template #activator="{ toggle, active }">
<v-input
:full-width="fullWidth"
readonly
@@ -8,6 +13,7 @@
@click="toggle"
:placeholder="placeholder"
:disabled="disabled"
:active="active"
>
<template #prepend><slot name="prepend" /></template>
<template #append><v-icon name="expand_more" /></template>
@@ -48,7 +54,11 @@
</v-list-item-content>
</v-list-item>
<v-list-item v-if="allowOther && multiple === false" :active="usesOtherValue">
<v-list-item
v-if="allowOther && multiple === false"
:active="usesOtherValue"
@click.stop
>
<v-list-item-content>
<input
class="other-input"
@@ -64,6 +74,7 @@
v-for="otherValue in otherValues"
:key="otherValue.key"
:active="(value || []).includes(otherValue.value)"
@click.stop
>
<v-list-item-icon>
<v-checkbox
@@ -157,6 +168,10 @@ export default defineComponent({
type: Boolean,
default: false,
},
closeOnContentClick: {
type: Boolean,
default: true,
},
},
setup(props, { emit }) {
const { _items } = useItems();