TimeInput: add confirmation text

This commit is contained in:
Elijah Duffy
2025-05-20 10:49:44 -07:00
parent 9a820794a2
commit 72bc7e23b4
5 changed files with 25 additions and 48 deletions

View File

@@ -34,15 +34,15 @@
}
},
"peerDependencies": {
"svelte": "^5.25.3",
"@sveltejs/kit": "^2.16.0"
"@sveltejs/kit": "^2.16.0",
"svelte": "^5.25.3"
},
"devDependencies": {
"@eslint/compat": "^1.2.5",
"@eslint/js": "^9.18.0",
"@jsrob/svelte-portal": "^0.2.1",
"@repo/tailwindcss-config": "workspace:*",
"@repo/validate": "workspace:*",
"@jsrob/svelte-portal": "^0.2.1",
"@sveltejs/adapter-auto": "^4.0.0",
"@sveltejs/package": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
@@ -56,6 +56,7 @@
"libphonenumber-js": "^1.12.6",
"match-sorter": "^8.0.0",
"melt": "^0.12.0",
"moment": "^2.30.1",
"phosphor-svelte": "^3.0.1",
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",

View File

@@ -1,10 +0,0 @@
import type { Snippet } from 'svelte';
type $$ComponentProps = {
for: string;
error?: boolean;
bigError?: boolean;
children: Snippet;
};
declare const Label: import("svelte").Component<$$ComponentProps, {}, "">;
type Label = ReturnType<typeof Label>;
export default Label;

View File

@@ -1,12 +0,0 @@
import type { HTMLInputAttributes } from 'svelte/elements';
import { type InputValidatorEvent, type ValidatorOptions } from '@repo/validate';
type $Props = Omit<HTMLInputAttributes, 'name' | 'value'> & {
name: string;
value?: string;
validate?: ValidatorOptions;
ref?: HTMLInputElement | null;
onvalidate?: (e: InputValidatorEvent) => void;
};
declare const StyledRawInput: import("svelte").Component<$Props, {}, "value" | "ref">;
type StyledRawInput = ReturnType<typeof StyledRawInput>;
export default StyledRawInput;

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { inputValidator, keydownValidator, liveValidator, validate } from '@repo/validate';
import { liveValidator, validate } from '@repo/validate';
import Label from './Label.svelte';
import StyledRawInput from './StyledRawInput.svelte';
import { onMount } from 'svelte';
@@ -12,7 +12,7 @@
formattedValue = $bindable(''),
required,
invalidMessage = 'Please select a time',
showText = false
showConfirm = false
}: {
name: string;
label?: string;
@@ -20,7 +20,7 @@
formattedValue?: string;
required?: boolean;
invalidMessage?: string;
showText?: boolean;
showConfirm?: boolean;
} = $props();
let ampm: 'AM' | 'PM' = $state('AM');
@@ -145,6 +145,7 @@
if (isNaN(hourValue)) {
value = '';
formattedValue = '';
updateHiddenInput();
return;
}
@@ -162,6 +163,8 @@
updateHiddenInput();
// update formatted value
const date = moment(value, 'HH:mm');
formattedValue = date.format('h:mm A');
};
/**
@@ -214,6 +217,11 @@
onkeydown={(e) => {
if (!hourInput) return;
if (e.key === ':' && hourInput.value.length !== 0) {
minuteInput?.focus();
e.preventDefault();
}
if (e.key === 'ArrowRight' && hourInput.selectionEnd === hourInput.value.length) {
minuteInput?.focus();
}
@@ -230,7 +238,6 @@
}
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
e.preventDefault();
return;
}
}}
oninput={() => {
@@ -305,7 +312,7 @@
<div class="flex flex-col">
<!-- AM Button -->
<button
class={['ampm rounded-t-sm border', ampm === 'AM' && 'selected ring-1 ring-blue-300']}
class={['ampm rounded-t-sm border', ampm === 'AM' && 'selected']}
onclick={() => {
ampm = 'AM';
updateValue();
@@ -321,10 +328,7 @@
<!-- PM Button -->
<button
class={[
'ampm rounded-b-sm border-r border-b border-l',
ampm === 'PM' && 'selected ring-1 ring-blue-300'
]}
class={['ampm rounded-b-sm border-r border-b border-l', ampm === 'PM' && 'selected']}
onclick={() => {
ampm = 'PM';
updateValue();
@@ -339,9 +343,13 @@
</div>
</div>
<div class={['opacity-0 transition-opacity', !valid && 'opacity-100']}>
<Label for={name} error>
{invalidMessage}
<div class={['opacity-0 transition-opacity', (!valid || showConfirm) && 'opacity-100']}>
<Label for={name} error={!valid}>
{#if !valid}
{invalidMessage}
{:else if showConfirm}
{formattedValue !== '' ? `See you at ${formattedValue}!` : ''}
{/if}
</Label>
</div>
</div>
@@ -367,7 +375,7 @@
@apply border-accent dark:border-accent/50 cursor-pointer px-3 py-1 font-medium;
&.selected {
@apply bg-accent text-background dark:bg-accent/30 dark:text-background/90 ring-1 ring-blue-600 dark:ring-blue-300;
@apply bg-accent text-background dark:bg-accent/30 dark:text-background/90 ring-1 ring-black dark:ring-blue-300;
}
}
</style>

View File

@@ -1,10 +0,0 @@
type $$ComponentProps = {
name: string;
label?: string;
value?: string;
required?: boolean;
invalidMessage?: string;
};
declare const TimeInput: import("svelte").Component<$$ComponentProps, {}, "value">;
type TimeInput = ReturnType<typeof TimeInput>;
export default TimeInput;