Skip to content

Commit

Permalink
feat: add input email to tw (#4646)
Browse files Browse the repository at this point in the history
  • Loading branch information
chinook25 authored Jan 29, 2025
1 parent 01f7a24 commit f8e8176
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 1 deletion.
62 changes: 62 additions & 0 deletions apps/tailwind-components/components/input/Email.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<InputString
ref="inputString"
type="email"
:id="id"
:label="label"
:placeholder="placeholder"
:valid="valid"
:hasError="hasError"
:required="required"
:disabled="disabled"
:value="modelValue"
@update:modelValue="validateInput"
@focus="$emit('focus')"
@blur="$emit('blur')"
/>
</template>

<script setup lang="ts">
import type { InputString } from "#build/components";
const EMAIL_REGEX =
/^(([^<>()\\[\]\\.,;:\s@"]+(\.[^<>()\\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$|^$/;
const inputString = ref<InstanceType<typeof InputString>>();
withDefaults(
defineProps<{
id: string;
modelValue?: string;
label?: string;
placeholder?: string;
disabled?: boolean;
required?: boolean;
hasError?: boolean;
valid?: boolean;
}>(),
{
disabled: false,
required: false,
hasError: false,
}
);
const emit = defineEmits(["update:modelValue", "error", "focus", "blur"]);
defineExpose({ validate });
function validateInput(value: string) {
emit("update:modelValue", value);
validate(value);
}
function validate(value: string) {
const stringErrors = inputString.value?.validate(value) || [];
if (EMAIL_REGEX.test(value)) {
emit("error", stringErrors);
} else {
emit("error", [{ message: "Invalid email" }, ...stringErrors]);
}
}
</script>
40 changes: 40 additions & 0 deletions apps/tailwind-components/pages/input/Email.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<h2>Email component</h2>
<p>
The <code>Email Component</code> enables you to use the String component
with the added validation of the input being a email.
</p>

<div
class="grid grid-cols-2 gap-6 my-5 [&>div]:bg-white [&>div]:p-4 [&_h3]:font-semibold [&_h3]:my-2"
>
<div>
<h3>Input email: (model value: {{ demoValue }})</h3>
<InputLabel for="input-email">
{{ label }}
</InputLabel>
<InputEmail
id="input-email"
v-model="demoValue"
ref="input-email"
:placeholder="placeholder"
:hasError="error.length > 0"
@error="handleError"
/>
<div>Error: {{ error[0]?.message }}</div>
</div>
</div>
</template>

<script setup lang="ts">
import type { IFieldError } from "../../../metadata-utils/src/types";
const label = "Input an email address";
const placeholder = "[email protected]";
const demoValue = ref("");
const error = ref<IFieldError[]>([]);
function handleError(errors: IFieldError[]) {
error.value = errors;
}
</script>
1 change: 0 additions & 1 deletion apps/tailwind-components/pages/input/Hyperlink.story.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
</template>

<script setup lang="ts">
import type { InputHyperlink } from "#build/components";
import type { IFieldError } from "../../../metadata-utils/src/types";
const label = "Input a hyperlink";
Expand Down
27 changes: 27 additions & 0 deletions apps/tailwind-components/tests/components/form/inputEmail.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { expect, test } from "@playwright/test";
import playwrightConfig from "../../../playwright.config";
const route = playwrightConfig?.use?.baseURL?.startsWith("http://localhost")
? ""
: "/apps/tailwind-components/#/";

test.beforeEach(async ({ page }) => {
await page.goto(`${route}input/Email.story`);
await page
.getByRole("textbox", { name: "Input an email address" })
.click({ delay: 500 });
});

test("the inputEmail", async ({ page }) => {
await expect(page.getByText("Error:")).not.toContainText(
"Error: Invalid email"
);
await page.fill("#input-email", "blaat");
await expect(page.getByText("Error: Invalid email")).toContainText(
"Error: Invalid email"
);
await page.getByPlaceholder("[email protected]").clear();
await page.fill("#input-email", "[email protected]");
await expect(page.getByText("Error:")).not.toContainText(
"Error: Invalid email"
);
});

0 comments on commit f8e8176

Please sign in to comment.