diff --git a/console/src/formkit/formkit.config.ts b/console/src/formkit/formkit.config.ts
index 76cfd06ee..7d6d62245 100644
--- a/console/src/formkit/formkit.config.ts
+++ b/console/src/formkit/formkit.config.ts
@@ -19,6 +19,7 @@ import { tagCheckbox } from "./inputs/tag-checkbox";
import { roleSelect } from "./inputs/role-select";
import { attachmentPolicySelect } from "./inputs/attachment-policy-select";
import { attachmentGroupSelect } from "./inputs/attachment-group-select";
+import { password } from "./inputs/password";
import radioAlt from "./plugins/radio-alt";
import stopImplicitSubmission from "./plugins/stop-implicit-submission";
@@ -39,6 +40,7 @@ const config: DefaultConfigOptions = {
],
inputs: {
form,
+ password,
group,
attachment,
code,
diff --git a/console/src/formkit/inputs/password/RevealButton.vue b/console/src/formkit/inputs/password/RevealButton.vue
new file mode 100644
index 000000000..67c1cc41f
--- /dev/null
+++ b/console/src/formkit/inputs/password/RevealButton.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
diff --git a/console/src/formkit/inputs/password/index.ts b/console/src/formkit/inputs/password/index.ts
new file mode 100644
index 000000000..36d5b2a2b
--- /dev/null
+++ b/console/src/formkit/inputs/password/index.ts
@@ -0,0 +1,76 @@
+import type { FormKitTypeDefinition } from "@formkit/core";
+import {
+ outer,
+ inner,
+ wrapper,
+ label,
+ help,
+ messages,
+ message,
+ icon,
+ prefix,
+ suffix,
+ textInput,
+} from "@formkit/inputs";
+import RevealButton from "./RevealButton.vue";
+
+import { createSection } from "@formkit/inputs";
+
+export const RevealButtonSuffix = createSection("RevealButtonSuffix", () => ({
+ $cmp: "RevealButton",
+ props: {
+ context: "$node.context",
+ },
+}));
+
+/**
+ * Input definition for a text.
+ * @public
+ */
+export const password: FormKitTypeDefinition = {
+ /**
+ * The actual schema of the input, or a function that returns the schema.
+ */
+ schema: outer(
+ wrapper(
+ label("$label"),
+ inner(
+ icon("prefix", "label"),
+ prefix(),
+ textInput(),
+ suffix(),
+ RevealButtonSuffix()
+ )
+ ),
+ help("$help"),
+ messages(message("$message.value"))
+ ),
+ /**
+ * The type of node, can be a list, group, or input.
+ */
+ type: "input",
+ /**
+ * The family of inputs this one belongs too. For example "text" and "email"
+ * are both part of the "text" family. This is primary used for styling.
+ */
+ family: "text",
+ /**
+ * An array of extra props to accept for this input.
+ */
+ props: [],
+ /**
+ * Forces node.props.type to be this explicit value.
+ */
+ forceTypeProp: "password",
+ /**
+ * Additional features that should be added to your input
+ */
+ features: [],
+ /**
+ * The key used to memoize the schema.
+ */
+ schemaMemoKey: "92o49lnph2p",
+ library: {
+ RevealButton,
+ },
+};
diff --git a/console/src/styles/index.css b/console/src/styles/index.css
index 26269ce9d..ede60322d 100644
--- a/console/src/styles/index.css
+++ b/console/src/styles/index.css
@@ -16,3 +16,8 @@
.fade-leave-to {
@apply opacity-0;
}
+
+/* https://learn.microsoft.com/en-us/microsoft-edge/web-platform/password-reveal#remove-the-password-reveal-control */
+::-ms-reveal {
+ display: none;
+}