diff --git a/cspell.json b/cspell.json
index 63dab56b..ba78afdf 100644
--- a/cspell.json
+++ b/cspell.json
@@ -15,6 +15,7 @@
".git",
"pnpm-lock.yaml",
"node_modules",
- "pnpm-workspace.yaml"
+ "pnpm-workspace.yaml",
+ "docs/package.json"
]
-}
\ No newline at end of file
+}
diff --git a/docs/app/client/authcode/page.tsx b/docs/app/client/authcode/page.tsx
index 307f1a46..d164e7f7 100644
--- a/docs/app/client/authcode/page.tsx
+++ b/docs/app/client/authcode/page.tsx
@@ -1,18 +1,15 @@
import React from "react";
-import Image from "next/image";
+import dynamic from "next/dynamic";
+import { Loader } from "@heathmont/moon-base-tw";
import { getExamples } from "@/utils/getExamples";
-import { MDX } from "@/components/MDX";
import { ExampleSectionData } from "@/components/exampleSection/ExampleSection";
import { MainLayout } from "@/components/MainLayout";
+import { PageHeadComponent } from "@/components/PageHeadComponent";
+import { PropsTable } from "@/components/propsTable";
-import dynamic from "next/dynamic";
-import TitleTags from "@/components/TitleTags";
-
+import props from "./props";
import image from "./authcode.webp";
-import { Loader } from "@heathmont/moon-base-tw";
-import { PageHeadComponent } from "@/components/PageHeadComponent";
-const TITLE = "AuthCode";
const ordered = [
"Default",
"WithManualSubmit",
@@ -57,7 +54,7 @@ export default async function AuthCodePage(request: {
- {/* TODO: Props table/s */}
+
+ These are props specific to the{" "}
+ AuthCode component:
+
+ }
+ data={props}
+ />
);
diff --git a/docs/app/client/authcode/props.ts b/docs/app/client/authcode/props.ts
new file mode 100644
index 00000000..f703b6f9
--- /dev/null
+++ b/docs/app/client/authcode/props.ts
@@ -0,0 +1,67 @@
+import { PropsTableProp } from "@/types";
+
+const Props: PropsTableProp[] = [
+ {
+ name: "onChange",
+ type: ["(value: string) => {}"],
+ description: "Callback function triggered upon a value change.",
+ required: true,
+ },
+ {
+ name: "length",
+ type: ["number"],
+ description: "Number of digits for entering single values.",
+ defaultState: 6,
+ },
+ {
+ name: "allowedCharacters",
+ type: ["alphanumeric", "numeric", "alpha"],
+ defaultState: "alphanumeric",
+ description: "Specifies the type of input characters allowed.",
+ },
+ {
+ name: "autoFocus",
+ type: ["boolean"],
+ defaultState: "false",
+ description:
+ "When set to true, inputs automatically receive the keyboard focus.",
+ },
+ {
+ name: "isPassword",
+ type: ["boolean"],
+ defaultState: "false",
+ description:
+ "When set to true, inputs will show entered values as obfuscated symbols.",
+ },
+ {
+ name: "disabled",
+ type: ["boolean"],
+ defaultState: "false",
+ description: "When set to true, the AuthCode component is disabled.",
+ },
+ {
+ name: "placeholder",
+ type: ["string"],
+ description: "Default placeholder for input elements.",
+ },
+ {
+ name: "isValid",
+ type: ["boolean"],
+ defaultState: "true",
+ description: "When set to false, the AuthCode will show a error state.",
+ },
+ {
+ name: "className",
+ type: ["string"],
+ description:
+ "Specifies the extra styles for the container that wraps the set of input elements.",
+ },
+ {
+ name: "ariaLabel",
+ type: ["string"],
+ defaultState: '"Character `${i + 1}`"',
+ description: "Specifies the common of the aria phrase for input elements.",
+ },
+];
+
+export default Props;
diff --git a/docs/components/propsTable/PropsTableItem.tsx b/docs/components/propsTable/PropsTableItem.tsx
index 2dd45967..619a9521 100644
--- a/docs/components/propsTable/PropsTableItem.tsx
+++ b/docs/components/propsTable/PropsTableItem.tsx
@@ -1,11 +1,26 @@
-import type { Data } from "./index";
+import { PropsTableProp, PropsTablePropTypes } from "@/types";
+import { Tag } from "@heathmont/moon-base-tw";
type PropsTableItemProps = {
- prop: Data;
+ prop: PropsTableProp;
};
const PropsTableItem = ({ prop }: PropsTableItemProps) => {
- const { name, type, defaultState, description } = prop;
+ const { name, type, defaultState, required, description } = prop;
+
+ const renderType = (item: PropsTablePropTypes) => {
+ // Check using Regex if the prop is a arrow function
+ const isArrowFunction = /\(([^)]+)\) => \w/.test(item);
+
+ if (isArrowFunction) {
+ return item;
+ } else if (["number", "boolean", "string"].includes(item)) {
+ return item;
+ } else {
+ return `"${item}"`;
+ }
+ };
+
return (
@@ -13,9 +28,14 @@ const PropsTableItem = ({ prop }: PropsTableItemProps) => {
Prop
-
+
{name}
-
+
@@ -24,6 +44,12 @@ const PropsTableItem = ({ prop }: PropsTableItemProps) => {
{defaultState || "-"}
+
+
+ Required
+
+
{required ? "Yes" : "No"}
+
Description
@@ -31,7 +57,9 @@ const PropsTableItem = ({ prop }: PropsTableItemProps) => {
{description}
-
{type}
+
+ {type?.map(renderType).join(" | ")}
+
);
diff --git a/docs/components/propsTable/index.tsx b/docs/components/propsTable/index.tsx
index f1e19b9e..bdb814e6 100644
--- a/docs/components/propsTable/index.tsx
+++ b/docs/components/propsTable/index.tsx
@@ -1,15 +1,9 @@
import PropsTableItem from "./PropsTableItem";
import HeaderSection from "../HeaderSection";
-
-export type Data = {
- name: string;
- type: string;
- defaultState: string | React.ReactNode;
- description: string;
-};
+import { type PropsTableProp } from "@/types";
type TableProps = {
- data: Data[];
+ data: PropsTableProp[];
title?: string;
description?: string | JSX.Element;
};
@@ -19,9 +13,11 @@ export const PropsTable = ({ data, title, description }: TableProps) => {
- {data.map((prop: Data) => (
-
- ))}
+ {data
+ .sort((x: PropsTableProp) => (x.required ? -1 : 1))
+ .map((prop: PropsTableProp) => (
+
+ ))}
);
};
diff --git a/docs/package.json b/docs/package.json
index 28cd811f..382f7c25 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -37,4 +37,4 @@
"tailwindcss": "^3.3.0",
"typescript": "^5"
}
-}
\ No newline at end of file
+}
diff --git a/docs/scripts/cli.mjs b/docs/scripts/cli.mjs
index 322dd44f..c52ec3a4 100644
--- a/docs/scripts/cli.mjs
+++ b/docs/scripts/cli.mjs
@@ -1,16 +1,16 @@
-import { Command } from 'commander';
-import { promises as fs } from 'fs';
-import path from 'path';
+import { Command } from "commander";
+import { promises as fs } from "fs";
+import path from "path";
-// pnpm run doc moon-cli generate example
+// pnpm run doc moon-cli generate example
const program = new Command();
export function generateFilesContent(component, name, title) {
- const _documentation = `---
+ const _documentation = `---
title: ${title || name}
---
`;
- const _example = `"use client";
+ const _example = `"use client";
import React from "react";
export const ${name} = () => {
@@ -19,122 +19,136 @@ export const ${name} = () => {
export default ${name}
`;
- const _e2e = `test('${name}: should render and match screenshot', async ({ page }) => {
+ const _e2e = `test('${name}: should render and match screenshot', async ({ page }) => {
await expect(page).toHaveScreenshot(\`${component}-${name}.png\`, {
maxDiffPixelRatio: MAX_DIFF_PIXEL_RATIO
})
})
`;
- return Object.assign({}, {
- documentation: {
- content: _documentation,
- path: path.join(`docs/app/client/${component}/descriptions`, `${name}.md`)
- },
- example: {
- content: _example,
- path: path.join(`docs/app/client/${component}/examples`, `${name}.tsx`)
- },
- e2e: {
- content: _e2e,
- path: path.join(`docs/e2e/`, `${component}.spec.ts`) // CARE THIS JUST ADD THE END OF THE FILE
- }
- })
+ return Object.assign(
+ {},
+ {
+ documentation: {
+ content: _documentation,
+ path: path.join(
+ `docs/app/client/${component}/descriptions`,
+ `${name}.md`,
+ ),
+ },
+ example: {
+ content: _example,
+ path: path.join(`docs/app/client/${component}/examples`, `${name}.tsx`),
+ },
+ e2e: {
+ content: _e2e,
+ path: path.join(`docs/e2e/`, `${component}.spec.ts`), // CARE THIS JUST ADD THE END OF THE FILE
+ },
+ },
+ );
}
-export async function writeToFile({
- contentToWrite,
- path,
-}) {
- if (!contentToWrite) {
- throw new Error('Content for writeToFile function must be provided.');
- }
- if (!path) {
- throw new Error('Path for writeToFile function must be provided.');
- }
+export async function writeToFile({ contentToWrite, path }) {
+ if (!contentToWrite) {
+ throw new Error("Content for writeToFile function must be provided.");
+ }
+ if (!path) {
+ throw new Error("Path for writeToFile function must be provided.");
+ }
- try {
- await fs.writeFile(path, contentToWrite, 'utf8');
- console.log(`${path} file has been written successfully.`);
- } catch (err) {
- if (err instanceof Error) {
- console.error('Error writing to file:', err.message);
- throw err;
- }
+ try {
+ await fs.writeFile(path, contentToWrite, "utf8");
+ console.log(`${path} file has been written successfully.`);
+ } catch (err) {
+ if (err instanceof Error) {
+ console.error("Error writing to file:", err.message);
+ throw err;
}
+ }
}
program
- .name('moon-cli')
- .description('CLI to some moon.io utils')
- .version('0.0.1');
-
-program.command('generate')
- .description('Generate the entry in the file project')
- .argument('', 'Right now this can be only \'example\'')
- .option('--component ', 'The component of this example')
- .option('--name ', 'The name of the example')
- .option('--title ', 'The title of the example (optional)')
- .action(async (arg, options) => {
- console.log("Experimental Moon.io CLI");
- let valid = true;
- if (!['example'].includes(arg)) {
- valid = false;
- console.log('You should select a valid type for the generation');
- }
- if (
- !(typeof options.component === 'string') ||
- !(typeof options.name === 'string')
- ) {
- valid = false;
- program.help()
- console.log('[!] name and component is mandatory');
- }
+ .name("moon-cli")
+ .description("CLI to some moon.io utils")
+ .version("0.0.1");
- if (valid) {
- try {
- fs.stat(`docs/app/client/${options.component}`)
- } catch (err) {
- valid = false;
- console.log(`[!!] Component ${options.component} not exists`)
- }
- }
+program
+ .command("generate")
+ .description("Generate the entry in the file project")
+ .argument("", "Right now this can be only 'example'")
+ .option("--component ", "The component of this example")
+ .option("--name ", "The name of the example")
+ .option("--title ", "The title of the example (optional)")
+ .action(async (arg, options) => {
+ console.log("Experimental Moon.io CLI");
+ let valid = true;
+ if (!["example"].includes(arg)) {
+ valid = false;
+ console.log("You should select a valid type for the generation");
+ }
+ if (
+ !(typeof options.component === "string") ||
+ !(typeof options.name === "string")
+ ) {
+ valid = false;
+ program.help();
+ console.log("[!] name and component is mandatory");
+ }
- if (valid) {
- const filesContent = generateFilesContent(options.component, options.name, options.title);
- if (typeof options.title === "string" && options.title?.length > 0) {
- // Documentation
- try {
- await fs.access(filesContent.documentation.path, fs.constants.F_OK);
- console.log(`[!!] File ${filesContent.documentation.path} already exists`)
- } catch (err) {
- console.log(`[!] Creating ${filesContent.documentation.path}...`)
- await writeToFile({
- contentToWrite: filesContent.documentation.content,
- path: filesContent.documentation.path
- })
- }
- }
- // Component
- try {
- await fs.access(filesContent.example.path, fs.constants.F_OK);
- console.log(`[!!] File ${filesContent.example.path} already exists`)
- } catch (err) {
- console.log(`[!] Creating ${filesContent.example.path}...`)
- await writeToFile({
- contentToWrite: filesContent.example.content,
- path: filesContent.example.path
- })
- }
+ if (valid) {
+ try {
+ fs.stat(`docs/app/client/${options.component}`);
+ } catch (err) {
+ valid = false;
+ console.log(`[!!] Component ${options.component} not exists`);
+ }
+ }
- // e2e
- try {
- await fs.access(filesContent.e2e.path, fs.constants.F_OK);
- console.log(`[!!] Adding to ${filesContent.e2e.path} e2e test`);
- await fs.appendFile(filesContent.e2e.path, filesContent.e2e.content, "utf-8")
- } catch (err) {
- console.log(`[!!] Not exists e2e file ${filesContent.e2e.path}...`)
- }
+ if (valid) {
+ const filesContent = generateFilesContent(
+ options.component,
+ options.name,
+ options.title,
+ );
+ if (typeof options.title === "string" && options.title?.length > 0) {
+ // Documentation
+ try {
+ await fs.access(filesContent.documentation.path, fs.constants.F_OK);
+ console.log(
+ `[!!] File ${filesContent.documentation.path} already exists`,
+ );
+ } catch (err) {
+ console.log(`[!] Creating ${filesContent.documentation.path}...`);
+ await writeToFile({
+ contentToWrite: filesContent.documentation.content,
+ path: filesContent.documentation.path,
+ });
}
- });
+ }
+ // Component
+ try {
+ await fs.access(filesContent.example.path, fs.constants.F_OK);
+ console.log(`[!!] File ${filesContent.example.path} already exists`);
+ } catch (err) {
+ console.log(`[!] Creating ${filesContent.example.path}...`);
+ await writeToFile({
+ contentToWrite: filesContent.example.content,
+ path: filesContent.example.path,
+ });
+ }
+
+ // e2e
+ try {
+ await fs.access(filesContent.e2e.path, fs.constants.F_OK);
+ console.log(`[!!] Adding to ${filesContent.e2e.path} e2e test`);
+ await fs.appendFile(
+ filesContent.e2e.path,
+ filesContent.e2e.content,
+ "utf-8",
+ );
+ } catch (err) {
+ console.log(`[!!] Not exists e2e file ${filesContent.e2e.path}...`);
+ }
+ }
+ });
-program.parse();
\ No newline at end of file
+program.parse();
diff --git a/docs/types/index.ts b/docs/types/index.ts
new file mode 100644
index 00000000..b0b401ca
--- /dev/null
+++ b/docs/types/index.ts
@@ -0,0 +1,2 @@
+export { type PropsTableProp, type PropsTablePropTypes } from "./propsTable";
+export { type NonEmptyArray } from "./utils";
diff --git a/docs/types/propsTable.ts b/docs/types/propsTable.ts
new file mode 100644
index 00000000..03a488b1
--- /dev/null
+++ b/docs/types/propsTable.ts
@@ -0,0 +1,17 @@
+import { type ReactNode } from "react";
+import { type NonEmptyArray } from "./utils";
+
+export type PropsTablePropTypes = "number" | "boolean" | "string" | string;
+
+export interface PropsTableProp {
+ /* This field is mandatory, name of the prop */
+ name: string;
+ /* Type field is mandatory, array contains the types of the prop, should contains at least 1 value */
+ type: NonEmptyArray;
+ /* Description is mandatory for every props */
+ description: string;
+ /* Default is not mandatory */
+ defaultState?: ReactNode;
+ /* The field required can be used only for required prop */
+ required?: boolean;
+}
diff --git a/docs/types/utils.ts b/docs/types/utils.ts
new file mode 100644
index 00000000..1f523e86
--- /dev/null
+++ b/docs/types/utils.ts
@@ -0,0 +1,2 @@
+// Type Non-Empty-Array
+export type NonEmptyArray = [T, ...T[]];
diff --git a/words.txt b/words.txt
index 3b27d544..aad714fa 100644
--- a/words.txt
+++ b/words.txt
@@ -1,4 +1,6 @@
crey
authcode
webp
-heathmont
\ No newline at end of file
+heathmont
+frieza
+beerus