Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(client): use browser native UI on date editing #275

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ const emit = defineEmits<{
'update:modelValue': [value: string]
}>()

const inputType = computed(() => {
if (props.customType === 'date')
return 'datetime-local'
return ''
})

// TODO: keyboard shortcut, esc to cancel, enter to submit
// and show tooltip on button when hovering

Expand Down Expand Up @@ -52,7 +58,7 @@ watch(value, checkWarning())

<template>
<span class="flex-inline items-center gap4px">
<VueInput v-model="value" :variant="isWarning ? 'warning' : 'normal'" class="h25px w120px px4px" :auto-focus="autoFocus" @click.stop />
<VueInput v-model="value" :type="inputType" :variant="isWarning ? 'warning' : 'normal'" class="h25px px4px" :class="customType === 'date' ? 'w240px' : 'w120px'" :auto-focus="autoFocus" @click.stop />
<template v-if="showActions">
<VueButton
v-tooltip="{
Expand Down
2 changes: 2 additions & 0 deletions packages/devtools-kit/__tests__/component/format.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ describe('format: toEdit', () => {
{ value: { foo: NEGATIVE_INFINITY }, target: '{"foo":-Infinity}' },
{ value: { foo: UNDEFINED }, target: '{"foo":undefined}' },
{ value: '123', customType: 'bigint' as customTypeEnums, target: '123' },
{ value: '2024-03-12T00:00:55.666', customType: 'date' as customTypeEnums, target: '2024-03-12T00:00:55.666' },
])('value: $value will be deserialized to target', (value) => {
const deserialized = format.toEdit(value.value, value.customType)
expect(deserialized).toBe(value.target)
Expand Down Expand Up @@ -117,6 +118,7 @@ describe('format: toSubmit', () => {
// Regex test: The token in key field kept untouched.
{ value: '{"undefined": NaN }', target: { undefined: Number.NaN } },
{ value: '123', customType: 'bigint' as customTypeEnums, target: BigInt(123) },
{ value: '2024-03-12T00:00:55.666', customType: 'date' as customTypeEnums, target: new Date('2024-03-12T00:00:55.666') },
])('value: $value will be serialized to target', (value) => {
const serialized = format.toSubmit(value.value, value.customType)
expect(serialized).toStrictEqual(value.target)
Expand Down
13 changes: 13 additions & 0 deletions packages/devtools-kit/src/core/component/state/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ export function getBigIntDetails(val: bigint | bigint) {
}
}

export function getDateDetails(val: Date) {
const date = new Date(val.getTime())
date.setMinutes(date.getMinutes() - date.getTimezoneOffset())

return {
_custom: {
type: 'date',
displayText: Date.prototype.toString.call(val),
value: date.toISOString().slice(0, -1),
},
}
}

export function getMapDetails(val: Map<string, unknown>) {
const list: Record<string, unknown> = Object.fromEntries(val)
return {
Expand Down
4 changes: 4 additions & 0 deletions packages/devtools-kit/src/core/component/state/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,17 @@ export function getRaw(value: InspectorState['value']): {
export function toEdit(value: unknown, customType?: customTypeEnums) {
if (customType === 'bigint')
return value as string
if (customType === 'date')
return value as string

return replaceTokenToString(JSON.stringify(value))
}

export function toSubmit(value: string, customType?: customTypeEnums) {
if (customType === 'bigint')
return BigInt(value)
if (customType === 'date')
return new Date(value)

return JSON.parse(replaceStringToToken(value), reviver)
}
4 changes: 2 additions & 2 deletions packages/devtools-kit/src/core/component/state/replacer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { INFINITY, MAX_ARRAY_SIZE, MAX_STRING_SIZE, NAN, NEGATIVE_INFINITY, UNDEFINED } from './constants'
import { getBigIntDetails, getComponentDefinitionDetails, getFunctionDetails, getHTMLElementDetails, getInstanceDetails, getMapDetails, getObjectDetails, getRouterDetails, getSetDetails, getStoreDetails } from './custom'
import { getBigIntDetails, getComponentDefinitionDetails, getDateDetails, getFunctionDetails, getHTMLElementDetails, getInstanceDetails, getMapDetails, getObjectDetails, getRouterDetails, getSetDetails, getStoreDetails } from './custom'
import { isVueInstance } from './is'
import { sanitize } from './util'

Expand Down Expand Up @@ -62,7 +62,7 @@ export function stringifyReplacer(key: string) {
return `[native RegExp ${RegExp.prototype.toString.call(val)}]`
}
else if (proto === '[object Date]') {
return `[native Date ${Date.prototype.toString.call(val)}]`
return getDateDetails(val as Date)
}
else if (proto === '[object Error]') {
return `[native Error ${(val as Error).message}<>${(val as Error).stack}]`
Expand Down
2 changes: 1 addition & 1 deletion packages/devtools-kit/src/core/component/types/custom.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export type customTypeEnums = 'function' | 'bigint' | 'map' | 'set' | 'store' | 'router' | 'component' | 'component-definition' | 'HTMLElement' | 'component-definition'
export type customTypeEnums = 'function' | 'bigint' | 'map' | 'set' | 'store' | 'router' | 'component' | 'component-definition' | 'HTMLElement' | 'component-definition' | 'date'
6 changes: 3 additions & 3 deletions packages/ui/src/components/Input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ const props = withDefaults(defineProps<{
placeholder?: string
variant?: 'normal' | 'accent' | 'flat' | 'warning'
disabled?: boolean
password?: boolean
leftIcon?: string
rightIcon?: string
loading?: boolean
autoFocus?: boolean
loadingDebounceTime?: number
readonly?: boolean
type?: string
}>(), {
placeholder: '',
variant: 'normal',
disabled: false,
password: false,
type: 'text',
/**
* loading will auto enable disabled
*/
Expand Down Expand Up @@ -101,7 +101,7 @@ watchEffect(() => {
</div>
<input
ref="inputRef" v-model="value"
class="$ui-base w-full bg-transparent color-inherit outline-none placeholder-color-gray-500 dark:placeholder-gray-300" :type="props.password ? 'password' : 'text'"
class="$ui-base w-full bg-transparent color-inherit outline-none placeholder-color-gray-500 dark:placeholder-gray-300" :type="type"
:placeholder="placeholder" :disabled="disabled || readonly"
@blur="focused = false"
>
Expand Down
5 changes: 4 additions & 1 deletion packages/ui/storybook/Input.story.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ watchEffect(() => {
<Input v-model="value" :loading="loading" :disabled="disable" placeholder="Flat Input" variant="flat" />
</Variant>
<Variant title="password">
<Input v-model="value" :loading="loading" :disabled="disable" placeholder="Flat Input" password />
<Input v-model="value" :loading="loading" :disabled="disable" placeholder="Flat Input" type="password" />
</Variant>
<Variant title="datetime-local">
<Input v-model="value" :loading="loading" :disabled="disable" placeholder="Flat Input" type="datetime-local" />
</Variant>
<Variant title="icon">
<Input
Expand Down
Loading