-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
13ba960
commit 835b11f
Showing
15 changed files
with
700 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
<template> | ||
<div class="pdap-input" :class="{ 'pdap-input-error': error }"> | ||
<label v-if="$slots.label" :id="`${name}-${id}-label`" :for="id"> | ||
<slot name="label" /> | ||
</label> | ||
<label v-else-if="label" :id="`${name}-${id}-label`" :for="id"> | ||
{{ label }} | ||
</label> | ||
<div v-if="$slots.error && error" class="pdap-input-error-message"> | ||
<slot name="error" /> | ||
</div> | ||
<div v-else-if="error" class="pdap-input-error-message">{{ error }}</div> | ||
|
||
<VueDatePicker | ||
v-bind="{ ...$attrs, ...$props }" | ||
v-model="date" | ||
:state="error" | ||
:dark="darkModePreference" | ||
/> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { computed, inject, onMounted, onUnmounted, ref, watch } from 'vue'; | ||
import VueDatePicker from '@vuepic/vue-datepicker'; | ||
import '@vuepic/vue-datepicker/dist/main.css'; | ||
import { provideKey } from '../FormV2/util'; | ||
import { PdapFormProvideV2 } from '../FormV2/types'; | ||
import { PdapDatePickerProps } from './types'; | ||
import _isEqual from 'lodash/isEqual'; | ||
const { setValues, values, v$ } = inject<PdapFormProvideV2>(provideKey)!; | ||
const { label, name, id } = defineProps<PdapDatePickerProps>(); | ||
const date = ref(); | ||
const error = computed(() => v$.value[name]?.$errors?.[0]?.$message); | ||
// TODO: when decision made on whether to do dark them with inputs, pass as `:dark` prop to `VueDatePicker` (also add listener for updates ) | ||
const darkModeQuery = ref(window.matchMedia('(prefers-color-scheme: dark)')); | ||
const darkModePreference = ref(darkModeQuery.value.matches); | ||
function updateColorMode(e: MediaQueryListEvent) { | ||
darkModePreference.value = e.matches; | ||
} | ||
onMounted(() => { | ||
darkModeQuery.value.addEventListener('change', updateColorMode); | ||
}); | ||
onUnmounted(() => { | ||
darkModeQuery.value.removeEventListener('change', updateColorMode); | ||
}); | ||
watch( | ||
() => date.value, | ||
(newDate) => { | ||
// Sync values with underlying input, for form | ||
if (newDate) setValues({ [name]: newDate }); | ||
} | ||
); | ||
watch( | ||
// Welcome to the land of edge-cases. | ||
() => values.value, | ||
// In the (unlikely, unrecommended, but sometimes unfortunately necessary) event of form values changing upstream from a parent component: | ||
(formValuesUpdated) => { | ||
// Case 0: Values are equivalent, or the change was made here, do nothing. | ||
/* | ||
* Case 1: Value does not exist in form values object, meaning either: | ||
** a. it has not been set by the upstream change, or | ||
** b. has been changed to an empty string by `Form` after submit event | ||
** In either case, clear state or keep it clear | ||
*/ | ||
if (!formValuesUpdated[name]) date.value = undefined; | ||
// Case 2 (rare): value has been programmatically updated upstream of `Form` | ||
else if ( | ||
!_isEqual(formValuesUpdated[name], date.value) && | ||
formValuesUpdated[name] instanceof Date | ||
) { | ||
// Set the date to the value of the form value | ||
date.value = formValuesUpdated[name]; | ||
} | ||
} | ||
); | ||
</script> | ||
|
||
<style> | ||
@tailwind base; | ||
.dp__theme_light, | ||
.dp__theme_dark { | ||
/* FULL LIST OF CUSTOMIZING OPTIONS from https://vue3datepicker.com/customization/theming/ */ | ||
/* --dp-background-color: #212121; | ||
--dp-text-color: #fff; | ||
--dp-hover-color: #484848; | ||
--dp-hover-text-color: #fff; | ||
--dp-hover-icon-color: #959595; | ||
--dp-primary-color: #005cb2; | ||
--dp-primary-disabled-color: #61a8ea; | ||
--dp-primary-text-color: #fff; | ||
--dp-secondary-color: #a9a9a9; | ||
--dp-border-color: #2d2d2d; | ||
--dp-menu-border-color: #2d2d2d; | ||
--dp-border-color-hover: #aaaeb7; | ||
--dp-border-color-focus: #aaaeb7; | ||
--dp-disabled-color: #737373; | ||
--dp-disabled-color-text: #d0d0d0; | ||
--dp-scroll-bar-background: #212121; | ||
--dp-scroll-bar-color: #484848; | ||
--dp-success-color: #00701a; | ||
--dp-success-color-disabled: #428f59; | ||
--dp-icon-color: #959595; | ||
--dp-danger-color: #e53935; | ||
--dp-marker-color: #e53935; | ||
--dp-tooltip-color: #3e3e3e; | ||
--dp-highlight-color: rgb(0 92 178 / 20%); | ||
--dp-range-between-dates-background-color: var(--dp-hover-color, #484848); | ||
--dp-range-between-dates-text-color: var(--dp-hover-text-color, #fff); | ||
--dp-range-between-border-color: var(--dp-hover-color, #fff); */ | ||
} | ||
.dp__theme_light { | ||
--dp-primary-color: rgb(var(--color-wine-neutral-700)); | ||
--dp-primary-text-color: rgb(var(--color-neutral-50)); | ||
} | ||
.dp__theme_dark { | ||
--dp-primary-color: rgb(var(--color-wine-neutral-300)); | ||
--dp-primary-text-color: rgb(var(--color-neutral-950)); | ||
} | ||
.pdap-input .dp__input { | ||
@apply text-lg pl-9; | ||
} | ||
div[role='gridcell'] { | ||
@apply outline-none border-2 border-solid border-transparent; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# InputSelect | ||
Date picker component. Uses Vue3 Date Picker library under the hood. | ||
|
||
## Props - required | ||
|
||
| name | required? | types | description | default | | ||
| ------- | ----------------------------- | -------- | ------------- | ------- | | ||
| `id` | yes | `string` | id attr | | | ||
| `label` | yes, if label slot not passed | `string` | label content | | | ||
| `name` | yes | `string` | name attr | | | ||
|
||
## Props - Vue3 Date Picker | ||
The props interface extends the underlying component interface, so [all props available on the Vue 3 Date Picker component](https://vue3datepicker.com/props/modes/) are available to be passed. | ||
|
||
## Slots | ||
|
||
| name | required? | types | description | default | | ||
| ------- | ----------------------------- | --------- | ------------------------------------ | ------- | | ||
| `error` | no<sup>*</sup> | `Element` | slot content to be rendered as error | | | ||
| `label` | yes, if label prop not passed | `Element` | slot content to be rendered as label | | | ||
|
||
<sup>*</sup> Note: The error message is determined by Vuelidate via our form validation schema. If the error UI needs to be more complicated than a string that can be passed with the schema, pass an `\#error` slot and it will override the string. | ||
|
||
## Example | ||
|
||
```vue | ||
<template> | ||
<FormV2 | ||
id="form-id" | ||
name="ice-cream-preference" | ||
:schema="SCHEMA" | ||
@submit="(values) => onSubmit({ values })" | ||
@change="(values, event) => onChange({ values, event })" | ||
> | ||
<!-- Other inputs... --> | ||
<InputDatePicker | ||
:id="INPUT_DATE_NAME" | ||
:name="INPUT_DATE_NAME" | ||
position="left" | ||
> | ||
<template #label> | ||
<h4>When will you next consume ice cream?</h4> | ||
</template> | ||
</InputDatePicker> | ||
</FormV2> | ||
</template> | ||
<script setup> | ||
import { InputDatePicker, FormV2 } from 'pdap-design-system'; | ||
</script> | ||
... | ||
``` |
Oops, something went wrong.