TimeInput: add confirmation text
This commit is contained in:
@@ -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",
|
||||
|
||||
10
src/lib/Label.svelte.d.ts
vendored
10
src/lib/Label.svelte.d.ts
vendored
@@ -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;
|
||||
12
src/lib/StyledRawInput.svelte.d.ts
vendored
12
src/lib/StyledRawInput.svelte.d.ts
vendored
@@ -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;
|
||||
@@ -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>
|
||||
|
||||
10
src/lib/TimeInput.svelte.d.ts
vendored
10
src/lib/TimeInput.svelte.d.ts
vendored
@@ -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;
|
||||
Reference in New Issue
Block a user