diff --git a/src/lib/components/customId.svelte b/src/lib/components/customId.svelte
index dafdb0661..913a1be8e 100644
--- a/src/lib/components/customId.svelte
+++ b/src/lib/components/customId.svelte
@@ -2,7 +2,7 @@
import { trackEvent } from '$lib/actions/analytics';
import { InnerModal } from '$lib/components';
import { InputId } from '$lib/elements/forms';
-
+ import {InputProjectId} from '$lib/elements/forms';
export let show = false;
export let name: string;
export let id: string;
@@ -29,7 +29,11 @@
+ {#if name === 'Project'}
+
+ {:else}
+ {/if}
diff --git a/src/lib/elements/forms/index.ts b/src/lib/elements/forms/index.ts
index 5e2bbd518..1f729ba4b 100644
--- a/src/lib/elements/forms/index.ts
+++ b/src/lib/elements/forms/index.ts
@@ -26,3 +26,4 @@ export { default as InputId } from './inputId.svelte';
export { default as InputSecret } from './inputSecret.svelte';
export { default as Helper } from './helper.svelte';
export { default as Label } from './label.svelte';
+export { default as InputProjectId } from './inputProjectId.svelte';
diff --git a/src/lib/elements/forms/inputProjectId.svelte b/src/lib/elements/forms/inputProjectId.svelte
new file mode 100644
index 000000000..0a534501a
--- /dev/null
+++ b/src/lib/elements/forms/inputProjectId.svelte
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+ Allowed characters: lowercase alphanumericc and non-leading hyphen
+
+
+
diff --git a/tests/unit/elements/inputProjectId.test.ts b/tests/unit/elements/inputProjectId.test.ts
new file mode 100644
index 000000000..3af99b51e
--- /dev/null
+++ b/tests/unit/elements/inputProjectId.test.ts
@@ -0,0 +1,40 @@
+import '@testing-library/jest-dom';
+import { render } from '@testing-library/svelte';
+import userEvent from '@testing-library/user-event';
+import { InputProjectId } from '../../../src/lib/elements/forms';
+
+const validStrings = ['validstring', 'valid-string', 'validstring123', 'valid-'];
+
+const invalidStrings = ['-invalid', 'Valid', '_invalid', 'Valid123', 'valid.string'];
+
+test('shows id input', () => {
+ const { getByPlaceholderText } = render(InputProjectId);
+ const input = getByPlaceholderText('Enter ID');
+
+ expect(input).toBeInTheDocument();
+ expect(input).toHaveAttribute('type', 'text');
+});
+
+test('state', async () => {
+ const { component, getByPlaceholderText } = render(InputProjectId, { value: '' });
+ const input = getByPlaceholderText('Enter ID');
+
+ expect(component.value).toEqual('');
+ await userEvent.type(input, 'lorem');
+ expect(component.value).toEqual('lorem');
+});
+
+validStrings.forEach((validString) => {
+ test(`validates ${validString} as valid`, () => {
+ const { getByPlaceholderText } = render(InputProjectId, { value: validString });
+ const input = getByPlaceholderText('Enter ID') as HTMLInputElement;
+ expect(input.checkValidity()).toBe(true);
+ });
+});
+invalidStrings.forEach((invalidString) => {
+ test(`validates ${invalidString} as invalid`, () => {
+ const { getByPlaceholderText } = render(InputProjectId, { value: invalidString });
+ const input = getByPlaceholderText('Enter ID') as HTMLInputElement;
+ expect(input.checkValidity()).toBe(false);
+ });
+});
\ No newline at end of file