= ({ schema }) => {
<>
= ({ schema }) => {
@@ -79,13 +79,13 @@ export const FormWithRHF: React.FC = ({ schema }) => {
Submitted Values (RHF):
{
onClick={() => setIsOpen(true)}
style={{
padding: '12px 24px',
- backgroundColor: '#6366f1',
- color: 'white',
+ backgroundColor: 'var(--schepta-brand)',
+ color: '#fff',
border: 'none',
borderRadius: '6px',
cursor: 'pointer',
@@ -70,7 +70,7 @@ export const ModalForm = ({ schema, onSubmit }: FormModalProps) => {
e.stopPropagation()}
style={{
- backgroundColor: 'white',
+ backgroundColor: 'var(--schepta-bg)',
borderRadius: '12px',
width: '100%',
maxWidth: '500px',
@@ -84,7 +84,7 @@ export const ModalForm = ({ schema, onSubmit }: FormModalProps) => {
{
border: 'none',
fontSize: '24px',
cursor: 'pointer',
- color: '#6b7280',
+ color: 'var(--schepta-text-2)',
}}
>
×
@@ -121,7 +121,7 @@ export const ModalForm = ({ schema, onSubmit }: FormModalProps) => {
{
onClick={() => setIsOpen(false)}
style={{
padding: '10px 20px',
- backgroundColor: 'white',
- color: '#374151',
- border: '1px solid #d1d5db',
+ backgroundColor: 'var(--schepta-bg)',
+ color: 'var(--schepta-text-1)',
+ border: '1px solid var(--schepta-border)',
borderRadius: '6px',
cursor: 'pointer',
fontSize: '14px',
@@ -147,8 +147,8 @@ export const ModalForm = ({ schema, onSubmit }: FormModalProps) => {
data-test-id="external-submit-button"
style={{
padding: '10px 20px',
- backgroundColor: '#007bff',
- color: 'white',
+ backgroundColor: 'var(--schepta-brand)',
+ color: '#fff',
border: 'none',
borderRadius: '6px',
cursor: 'pointer',
@@ -168,13 +168,13 @@ export const ModalForm = ({ schema, onSubmit }: FormModalProps) => {
Submitted Values:
{
style={{
marginBottom: "24px",
padding: "20px",
- background: "#f9fafb",
- border: "1px solid #e5e7eb",
+ background: "var(--schepta-bg-soft)",
+ border: "1px solid var(--schepta-border)",
borderRadius: "8px",
}}
>
-
+
What you can see in this form:
@@ -166,7 +166,7 @@ export const NativeComplexForm = ({ schema }: FormProps) => {
{
style={{
marginTop: "24px",
padding: "16px",
- background: "#f9fafb",
- border: "1px solid #e5e7eb",
+ background: "var(--schepta-bg-soft)",
+ border: "1px solid var(--schepta-border)",
borderRadius: "8px",
}}
>
Submitted Values:
Submitted Values:
(
style={{
width: "100%",
padding: "8px",
- border: "1px solid #ccc",
+ border: "1px solid var(--schepta-border)",
borderRadius: "4px",
}}
{...rest}
diff --git a/showcases/src/frameworks/react/basic-ui/components/formik/FormikFieldRenderer.tsx b/docs/.vitepress/showcases/react/basic/components/formik/FormikFieldRenderer.tsx
similarity index 100%
rename from showcases/src/frameworks/react/basic-ui/components/formik/FormikFieldRenderer.tsx
rename to docs/.vitepress/showcases/react/basic/components/formik/FormikFieldRenderer.tsx
diff --git a/showcases/src/frameworks/react/basic-ui/components/formik/FormikFormContainer.tsx b/docs/.vitepress/showcases/react/basic/components/formik/FormikFormContainer.tsx
similarity index 95%
rename from showcases/src/frameworks/react/basic-ui/components/formik/FormikFormContainer.tsx
rename to docs/.vitepress/showcases/react/basic/components/formik/FormikFormContainer.tsx
index 25497ec..bb7e9ea 100644
--- a/showcases/src/frameworks/react/basic-ui/components/formik/FormikFormContainer.tsx
+++ b/docs/.vitepress/showcases/react/basic/components/formik/FormikFormContainer.tsx
@@ -82,8 +82,8 @@ export const FormikFormContainer: React.FC = ({
data-test-id="submit-button"
style={{
padding: "12px 24px",
- backgroundColor: isSubmitting ? "#6c757d" : "#28a745",
- color: "white",
+ backgroundColor: isSubmitting ? "var(--schepta-text-2)" : "var(--schepta-brand)",
+ color: "#fff",
border: "none",
borderRadius: "4px",
cursor: isSubmitting ? "not-allowed" : "pointer",
diff --git a/showcases/src/frameworks/react/basic-ui/components/rhf/RHFFieldRenderer.tsx b/docs/.vitepress/showcases/react/basic/components/rhf/RHFFieldRenderer.tsx
similarity index 100%
rename from showcases/src/frameworks/react/basic-ui/components/rhf/RHFFieldRenderer.tsx
rename to docs/.vitepress/showcases/react/basic/components/rhf/RHFFieldRenderer.tsx
diff --git a/showcases/src/frameworks/react/basic-ui/components/rhf/RHFFormContainer.tsx b/docs/.vitepress/showcases/react/basic/components/rhf/RHFFormContainer.tsx
similarity index 96%
rename from showcases/src/frameworks/react/basic-ui/components/rhf/RHFFormContainer.tsx
rename to docs/.vitepress/showcases/react/basic/components/rhf/RHFFormContainer.tsx
index 818f301..6f9df17 100644
--- a/showcases/src/frameworks/react/basic-ui/components/rhf/RHFFormContainer.tsx
+++ b/docs/.vitepress/showcases/react/basic/components/rhf/RHFFormContainer.tsx
@@ -79,8 +79,8 @@ export const RHFFormContainer: React.FC = ({
data-test-id="submit-button"
style={{
padding: '12px 24px',
- backgroundColor: '#007bff',
- color: 'white',
+ backgroundColor: 'var(--schepta-brand)',
+ color: '#fff',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
diff --git a/showcases/src/frameworks/react/basic-ui/pages/BasicFormPage.tsx b/docs/.vitepress/showcases/react/basic/pages/BasicFormPage.tsx
similarity index 61%
rename from showcases/src/frameworks/react/basic-ui/pages/BasicFormPage.tsx
rename to docs/.vitepress/showcases/react/basic/pages/BasicFormPage.tsx
index ccc1ca4..592f2f5 100644
--- a/showcases/src/frameworks/react/basic-ui/pages/BasicFormPage.tsx
+++ b/docs/.vitepress/showcases/react/basic/pages/BasicFormPage.tsx
@@ -1,5 +1,5 @@
-import React, { useState } from "react";
-import { Tab, Tabs, Paper } from "@mui/material";
+import React, { useMemo, useState } from "react";
+import { Tab, Tabs, Paper, ThemeProvider, createTheme } from "@mui/material";
import simpleFormSchema from "../../../../../../instances/form/simple-form.json";
import complexFormSchema from "../../../../../../instances/form/complex-form.json";
import { NativeForm } from "../components/Forms/NativeForm";
@@ -9,8 +9,13 @@ import { FormWithRHF } from "../components/Forms/FormWithRHF";
import { FormWithFormik } from "../components/Forms/FormWithFormik";
import { FormSchema } from "@schepta/core";
import { NativeComplexForm } from "../components/Forms/NativeComplexForm";
+import { getToken } from "../../../../utils/getToken";
-export function BasicFormPage() {
+interface BasicFormPageProps {
+ isDark?: boolean;
+}
+
+export function BasicFormPage({ isDark = false }: BasicFormPageProps) {
const [tabValue, setTabValue] = useState(0);
const simpleSchema = simpleFormSchema as FormSchema;
const complexSchema = complexFormSchema as FormSchema;
@@ -20,10 +25,34 @@ export function BasicFormPage() {
setTabValue(newValue);
};
+ const muiTheme = useMemo(() => {
+ return createTheme({
+ palette: {
+ mode: isDark ? "dark" : "light",
+ background: {
+ default: getToken("--schepta-bg", "#ffffff"),
+ paper: getToken("--schepta-bg", "#ffffff"),
+ },
+ text: {
+ primary: getToken("--schepta-text-1", "#333333"),
+ secondary: getToken("--schepta-text-2", "#666666"),
+ },
+ divider: getToken("--schepta-border", "#cccccc"),
+ },
+ });
+ }, [isDark]);
+
return (
- <>
-
-
+
+
+
@@ -47,6 +76,6 @@ export function BasicFormPage() {
- >
+
);
}
diff --git a/showcases/src/frameworks/react/chakra-ui/components/ComponentRegistry.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/ComponentRegistry.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/ComponentRegistry.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/ComponentRegistry.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Containers/FormContainer.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormContainer.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Containers/FormContainer.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormContainer.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Containers/FormField.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormField.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Containers/FormField.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormField.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Containers/FormSectionContainer.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormSectionContainer.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Containers/FormSectionContainer.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormSectionContainer.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Containers/FormSectionGroup.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormSectionGroup.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Containers/FormSectionGroup.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormSectionGroup.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Containers/FormSectionGroupContainer.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormSectionGroupContainer.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Containers/FormSectionGroupContainer.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormSectionGroupContainer.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Containers/FormSectionTitle.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormSectionTitle.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Containers/FormSectionTitle.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Containers/FormSectionTitle.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Form.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Form.tsx
similarity index 97%
rename from showcases/src/frameworks/react/chakra-ui/components/Form.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Form.tsx
index 7ac56df..9adac97 100644
--- a/showcases/src/frameworks/react/chakra-ui/components/Form.tsx
+++ b/docs/.vitepress/showcases/react/chakra-ui/components/Form.tsx
@@ -36,7 +36,7 @@ export const Form = ({ schema, onSubmit }: FormProps) => {
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Inputs/InputCheckbox.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputCheckbox.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Inputs/InputCheckbox.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputCheckbox.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Inputs/InputDate.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputDate.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Inputs/InputDate.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputDate.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Inputs/InputNumber.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputNumber.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Inputs/InputNumber.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputNumber.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Inputs/InputPhone.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputPhone.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Inputs/InputPhone.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputPhone.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Inputs/InputSelect.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputSelect.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Inputs/InputSelect.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputSelect.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Inputs/InputText.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputText.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Inputs/InputText.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputText.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/Inputs/InputTextarea.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputTextarea.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/Inputs/InputTextarea.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/Inputs/InputTextarea.tsx
diff --git a/showcases/src/frameworks/react/chakra-ui/components/SubmitButton.tsx b/docs/.vitepress/showcases/react/chakra-ui/components/SubmitButton.tsx
similarity index 100%
rename from showcases/src/frameworks/react/chakra-ui/components/SubmitButton.tsx
rename to docs/.vitepress/showcases/react/chakra-ui/components/SubmitButton.tsx
diff --git a/docs/.vitepress/showcases/react/chakra-ui/pages/ChakraFormPage.tsx b/docs/.vitepress/showcases/react/chakra-ui/pages/ChakraFormPage.tsx
new file mode 100644
index 0000000..2f9d3ca
--- /dev/null
+++ b/docs/.vitepress/showcases/react/chakra-ui/pages/ChakraFormPage.tsx
@@ -0,0 +1,79 @@
+import React, { useMemo } from "react";
+import {
+ ChakraProvider,
+ extendTheme,
+ Tabs,
+ TabList,
+ TabPanels,
+ Tab,
+ TabPanel,
+ Box,
+} from "@chakra-ui/react";
+import type { StorageManager } from "@chakra-ui/react";
+import { Form } from "../components/Form";
+import { FormSchema } from "@schepta/core";
+import simpleFormSchema from "../../../../../../instances/form/simple-form.json";
+import complexFormSchema from "../../../../../../instances/form/complex-form.json";
+import { getToken } from "../../../../utils/getToken";
+
+interface ChakraFormPageProps {
+ isDark?: boolean;
+}
+
+export function ChakraFormPage({ isDark = false }: ChakraFormPageProps) {
+ const simpleSchema = simpleFormSchema as FormSchema;
+ const complexSchema = complexFormSchema as FormSchema;
+
+ const theme = useMemo(
+ () => {
+ const bg = getToken("--schepta-bg", "#ffffff");
+ const bgSoft = getToken("--schepta-bg-soft", "#f6f6f7");
+ const text1 = getToken("--schepta-text-1", "#333333");
+ const text2 = getToken("--schepta-text-2", "#666666");
+ const border = getToken("--schepta-border", "#cccccc");
+
+ return extendTheme({
+ config: {
+ initialColorMode: isDark ? "dark" : "light",
+ useSystemColorMode: false,
+ },
+ semanticTokens: {
+ colors: {
+ "chakra-body-bg": { _light: bg, _dark: bg },
+ "chakra-body-text": { _light: text1, _dark: text1 },
+ "chakra-border-color": { _light: border, _dark: border },
+ "chakra-subtle-bg": { _light: bgSoft, _dark: bgSoft },
+ "chakra-subtle-text": { _light: text2, _dark: text2 },
+ },
+ },
+ });
+ },
+ [isDark]
+ );
+
+ return (
+
+
+
+
+ SIMPLE FORM
+ COMPLEX FORM
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/showcases/src/frameworks/react/material-ui/components/ComponentRegistry.tsx b/docs/.vitepress/showcases/react/material-ui/components/ComponentRegistry.tsx
similarity index 100%
rename from showcases/src/frameworks/react/material-ui/components/ComponentRegistry.tsx
rename to docs/.vitepress/showcases/react/material-ui/components/ComponentRegistry.tsx
diff --git a/showcases/src/frameworks/react/material-ui/components/Containers/FormContainer.tsx b/docs/.vitepress/showcases/react/material-ui/components/Containers/FormContainer.tsx
similarity index 100%
rename from showcases/src/frameworks/react/material-ui/components/Containers/FormContainer.tsx
rename to docs/.vitepress/showcases/react/material-ui/components/Containers/FormContainer.tsx
diff --git a/showcases/src/frameworks/react/material-ui/components/Containers/FormField.tsx b/docs/.vitepress/showcases/react/material-ui/components/Containers/FormField.tsx
similarity index 100%
rename from showcases/src/frameworks/react/material-ui/components/Containers/FormField.tsx
rename to docs/.vitepress/showcases/react/material-ui/components/Containers/FormField.tsx
diff --git a/showcases/src/frameworks/react/material-ui/components/Containers/FormSectionContainer.tsx b/docs/.vitepress/showcases/react/material-ui/components/Containers/FormSectionContainer.tsx
similarity index 100%
rename from showcases/src/frameworks/react/material-ui/components/Containers/FormSectionContainer.tsx
rename to docs/.vitepress/showcases/react/material-ui/components/Containers/FormSectionContainer.tsx
diff --git a/showcases/src/frameworks/react/material-ui/components/Containers/FormSectionGroup.tsx b/docs/.vitepress/showcases/react/material-ui/components/Containers/FormSectionGroup.tsx
similarity index 100%
rename from showcases/src/frameworks/react/material-ui/components/Containers/FormSectionGroup.tsx
rename to docs/.vitepress/showcases/react/material-ui/components/Containers/FormSectionGroup.tsx
diff --git a/showcases/src/frameworks/react/material-ui/components/Containers/FormSectionGroupContainer.tsx b/docs/.vitepress/showcases/react/material-ui/components/Containers/FormSectionGroupContainer.tsx
similarity index 100%
rename from showcases/src/frameworks/react/material-ui/components/Containers/FormSectionGroupContainer.tsx
rename to docs/.vitepress/showcases/react/material-ui/components/Containers/FormSectionGroupContainer.tsx
diff --git a/showcases/src/frameworks/react/material-ui/components/Containers/FormSectionTitle.tsx b/docs/.vitepress/showcases/react/material-ui/components/Containers/FormSectionTitle.tsx
similarity index 100%
rename from showcases/src/frameworks/react/material-ui/components/Containers/FormSectionTitle.tsx
rename to docs/.vitepress/showcases/react/material-ui/components/Containers/FormSectionTitle.tsx
diff --git a/showcases/src/frameworks/react/material-ui/components/Form.tsx b/docs/.vitepress/showcases/react/material-ui/components/Form.tsx
similarity index 86%
rename from showcases/src/frameworks/react/material-ui/components/Form.tsx
rename to docs/.vitepress/showcases/react/material-ui/components/Form.tsx
index f5d0612..3706550 100644
--- a/showcases/src/frameworks/react/material-ui/components/Form.tsx
+++ b/docs/.vitepress/showcases/react/material-ui/components/Form.tsx
@@ -21,7 +21,7 @@ export const Form = ({ schema, onSubmit }: FormProps) => {
return (
<>
{
/>
{submittedValues && (
-
+
Submitted Values:
{
+ return createTheme({
+ palette: {
+ mode: isDark ? "dark" : "light",
+ background: {
+ default: getToken("--schepta-bg", "#ffffff"),
+ paper: getToken("--schepta-bg", "#ffffff"),
+ },
+ text: {
+ primary: getToken("--schepta-text-1", "#333333"),
+ secondary: getToken("--schepta-text-2", "#666666"),
+ },
+ divider: getToken("--schepta-border", "#cccccc"),
+ },
+ });
+ }, [isDark]);
+
return (
- <>
+
- >
+
);
}
diff --git a/docs/.vitepress/showcases/vanilla/VanillaShowcase.ts b/docs/.vitepress/showcases/vanilla/VanillaShowcase.ts
new file mode 100644
index 0000000..7c57e2a
--- /dev/null
+++ b/docs/.vitepress/showcases/vanilla/VanillaShowcase.ts
@@ -0,0 +1,25 @@
+import { createAppRoot } from './app';
+
+export function mountVanillaShowcase(containerId: string = 'vanilla-showcase-root'): void {
+ const container = document.getElementById(containerId);
+
+ if (!container) {
+ console.error(`Container with id "${containerId}" not found`);
+ return;
+ }
+
+ // Clear any existing content
+ container.innerHTML = '';
+
+ // Create and mount the vanilla app
+ const appRoot = createAppRoot();
+ container.appendChild(appRoot);
+}
+
+export function unmountVanillaShowcase(containerId: string = 'vanilla-showcase-root'): void {
+ const container = document.getElementById(containerId);
+
+ if (container) {
+ container.innerHTML = '';
+ }
+}
diff --git a/docs/.vitepress/showcases/vanilla/VanillaShowcaseWrapper.vue b/docs/.vitepress/showcases/vanilla/VanillaShowcaseWrapper.vue
new file mode 100644
index 0000000..a3db218
--- /dev/null
+++ b/docs/.vitepress/showcases/vanilla/VanillaShowcaseWrapper.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
diff --git a/showcases/src/vanilla/app.ts b/docs/.vitepress/showcases/vanilla/app.ts
similarity index 64%
rename from showcases/src/vanilla/app.ts
rename to docs/.vitepress/showcases/vanilla/app.ts
index 798a9e1..c573c72 100644
--- a/showcases/src/vanilla/app.ts
+++ b/docs/.vitepress/showcases/vanilla/app.ts
@@ -5,39 +5,17 @@
import type { FormSchema } from '@schepta/core';
import { createNativeForm } from './components/NativeForm';
import { createNativeComplexForm } from './components/NativeComplexForm';
-import simpleFormSchema from '../../../instances/form/simple-form.json';
-import complexFormSchema from '../../../instances/form/complex-form.json';
+import simpleFormSchema from '../../../../instances/form/simple-form.json';
+import complexFormSchema from '../../../../instances/form/complex-form.json';
export function createAppRoot(): HTMLElement {
const container = document.createElement('div');
- container.style.cssText = `
- padding: 2rem;
- background: #fffbf0;
- border-radius: 8px;
- margin: 1rem 0;
- `;
-
- // Header
- const header = document.createElement('div');
- header.style.cssText = `
- color: #f7df1e;
- margin-bottom: 1rem;
- display: flex;
- align-items: center;
- gap: 0.5rem;
- `;
- header.innerHTML = `
-
- Vanilla JS Microfrontend - Schepta Forms
- `;
- container.appendChild(header);
+ container.style.cssText = `background: var(--schepta-bg); border-radius: 8px; margin: 1rem 0;border: 1px solid var(--schepta-border);`;
// Main content wrapper
const mainContent = document.createElement('div');
mainContent.style.cssText = `
- background: white;
+ background: var(--schepta-bg);
padding: 1.5rem;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
@@ -48,7 +26,7 @@ export function createAppRoot(): HTMLElement {
tabsContainer.className = 'vanilla-tabs';
tabsContainer.style.cssText = `
display: flex;
- border-bottom: 1px solid #ddd;
+ border-bottom: 1px solid var(--schepta-border);
margin-bottom: 1rem;
`;
@@ -62,8 +40,8 @@ export function createAppRoot(): HTMLElement {
border: none;
background: none;
cursor: pointer;
- border-bottom: 2px solid #f7df1e;
- color: #f7df1e;
+ border-bottom: 2px solid var(--schepta-brand);
+ color: var(--schepta-brand);
font-weight: 500;
`;
@@ -129,11 +107,11 @@ function attachTabBehavior(
tabs.forEach(t => {
t.classList.remove('active');
(t as HTMLElement).style.borderBottomColor = 'transparent';
- (t as HTMLElement).style.color = '#333';
+ (t as HTMLElement).style.color = 'var(--schepta-text-2)';
});
tab.classList.add('active');
- (tab as HTMLElement).style.borderBottomColor = '#f7df1e';
- (tab as HTMLElement).style.color = '#f7df1e';
+ (tab as HTMLElement).style.borderBottomColor = 'var(--schepta-brand)';
+ (tab as HTMLElement).style.color = 'var(--schepta-brand)';
// Update panels
panels.forEach(p => {
diff --git a/showcases/src/vanilla/components/NativeComplexForm.ts b/docs/.vitepress/showcases/vanilla/components/NativeComplexForm.ts
similarity index 85%
rename from showcases/src/vanilla/components/NativeComplexForm.ts
rename to docs/.vitepress/showcases/vanilla/components/NativeComplexForm.ts
index 17abb93..70c201b 100644
--- a/showcases/src/vanilla/components/NativeComplexForm.ts
+++ b/docs/.vitepress/showcases/vanilla/components/NativeComplexForm.ts
@@ -15,7 +15,7 @@ export function createNativeComplexForm(container: HTMLElement, schema: FormSche
// Form wrapper
const formWrapper = document.createElement('div');
- formWrapper.style.border = '1px solid #ddd';
+ formWrapper.style.border = '1px solid var(--schepta-border)';
formWrapper.style.padding = '24px';
formWrapper.style.borderRadius = '8px';
@@ -60,12 +60,12 @@ function createInfoBox(): HTMLElement {
const box = document.createElement('div');
box.style.marginBottom = '24px';
box.style.padding = '20px';
- box.style.background = '#f9fafb';
- box.style.border = '1px solid #e5e7eb';
+ box.style.background = 'var(--schepta-bg-soft)';
+ box.style.border = '1px solid var(--schepta-border)';
box.style.borderRadius = '8px';
box.innerHTML = `
- What you can see in this form:
+ What you can see in this form:
- Custom Components (x-custom): Social Name field with toggle behavior
- Template Expressions: Conditional visibility (spouseName appears when maritalStatus is 'married')
@@ -101,14 +101,14 @@ function displaySubmittedValues(container: HTMLElement, values: any) {
resultsDiv.className = 'submitted-values';
resultsDiv.style.marginTop = '24px';
resultsDiv.style.padding = '16px';
- resultsDiv.style.background = '#f9fafb';
- resultsDiv.style.border = '1px solid #e5e7eb';
+ resultsDiv.style.background = 'var(--schepta-bg-soft)';
+ resultsDiv.style.border = '1px solid var(--schepta-border)';
resultsDiv.style.borderRadius = '8px';
container.appendChild(resultsDiv);
}
resultsDiv.innerHTML = `
- Submitted Values:
-
${JSON.stringify(values, null, 2)}
+ Submitted Values:
+ ${JSON.stringify(values, null, 2)}
`;
}
diff --git a/showcases/src/vanilla/components/NativeForm.ts b/docs/.vitepress/showcases/vanilla/components/NativeForm.ts
similarity index 70%
rename from showcases/src/vanilla/components/NativeForm.ts
rename to docs/.vitepress/showcases/vanilla/components/NativeForm.ts
index 62afb3e..dc9213b 100644
--- a/showcases/src/vanilla/components/NativeForm.ts
+++ b/docs/.vitepress/showcases/vanilla/components/NativeForm.ts
@@ -7,7 +7,7 @@ import { createFormFactory, type FormFactoryResult } from '@schepta/factory-vani
export function createNativeForm(container: HTMLElement, schema: FormSchema): FormFactoryResult {
const wrapper = document.createElement('div');
- wrapper.style.border = '1px solid #ddd';
+ wrapper.style.border = '1px solid var(--schepta-border)';
wrapper.style.padding = '24px';
wrapper.style.borderRadius = '8px';
@@ -32,14 +32,14 @@ function displaySubmittedValues(container: HTMLElement, values: any) {
resultsDiv.className = 'submitted-values';
resultsDiv.style.marginTop = '24px';
resultsDiv.style.padding = '16px';
- resultsDiv.style.background = '#f9fafb';
- resultsDiv.style.border = '1px solid #e5e7eb';
+ resultsDiv.style.background = 'var(--schepta-bg-soft)';
+ resultsDiv.style.border = '1px solid var(--schepta-border)';
resultsDiv.style.borderRadius = '8px';
container.appendChild(resultsDiv);
}
resultsDiv.innerHTML = `
- Submitted Values:
- ${JSON.stringify(values, null, 2)}
+ Submitted Values:
+ ${JSON.stringify(values, null, 2)}
`;
}
diff --git a/showcases/src/vanilla/components/SocialNameInput.ts b/docs/.vitepress/showcases/vanilla/components/SocialNameInput.ts
similarity index 96%
rename from showcases/src/vanilla/components/SocialNameInput.ts
rename to docs/.vitepress/showcases/vanilla/components/SocialNameInput.ts
index cd412a1..7a77d80 100644
--- a/showcases/src/vanilla/components/SocialNameInput.ts
+++ b/docs/.vitepress/showcases/vanilla/components/SocialNameInput.ts
@@ -28,7 +28,7 @@ export function createSocialNameInput(props: SocialNameInputProps): HTMLElement
toggleBtn.setAttribute('data-test-id', 'social-name-toggle');
toggleBtn.style.background = 'none';
toggleBtn.style.border = 'none';
- toggleBtn.style.color = '#2563eb';
+ toggleBtn.style.color = 'var(--schepta-brand)';
toggleBtn.style.cursor = 'pointer';
toggleBtn.style.padding = '0';
toggleBtn.style.fontSize = '14px';
@@ -65,7 +65,7 @@ export function createSocialNameInput(props: SocialNameInputProps): HTMLElement
input.style.display = 'block';
input.style.width = '100%';
input.style.padding = '8px 12px';
- input.style.border = '1px solid #d1d5db';
+ input.style.border = '1px solid var(--schepta-border)';
input.style.borderRadius = '4px';
input.style.fontSize = '14px';
diff --git a/showcases/src/vanilla/components/SubmitButton.ts b/docs/.vitepress/showcases/vanilla/components/SubmitButton.ts
similarity index 82%
rename from showcases/src/vanilla/components/SubmitButton.ts
rename to docs/.vitepress/showcases/vanilla/components/SubmitButton.ts
index b3661b8..6aa2316 100644
--- a/showcases/src/vanilla/components/SubmitButton.ts
+++ b/docs/.vitepress/showcases/vanilla/components/SubmitButton.ts
@@ -8,8 +8,8 @@ export function createSubmitButton(props: SubmitButtonProps): HTMLElement {
button.textContent = 'Submit';
button.dataset.testId = 'submit-button-complex-form';
button.style.padding = '12px 24px';
- button.style.backgroundColor = '#007bff';
- button.style.color = 'white';
+ button.style.backgroundColor = 'var(--schepta-brand)';
+ button.style.color = 'var(--schepta-brand-text)';
button.style.border = 'none';
button.style.borderRadius = '4px';
button.style.cursor = 'pointer';
diff --git a/showcases/src/vanilla/styles.ts b/docs/.vitepress/showcases/vanilla/styles.ts
similarity index 100%
rename from showcases/src/vanilla/styles.ts
rename to docs/.vitepress/showcases/vanilla/styles.ts
diff --git a/showcases/src/vanilla/tabs.ts b/docs/.vitepress/showcases/vanilla/tabs.ts
similarity index 100%
rename from showcases/src/vanilla/tabs.ts
rename to docs/.vitepress/showcases/vanilla/tabs.ts
diff --git a/docs/.vitepress/showcases/vue/VueShowcase.vue b/docs/.vitepress/showcases/vue/VueShowcase.vue
new file mode 100644
index 0000000..61b380d
--- /dev/null
+++ b/docs/.vitepress/showcases/vue/VueShowcase.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/showcases/vue/VuetifyShowcaseWrapper.vue b/docs/.vitepress/showcases/vue/VuetifyShowcaseWrapper.vue
new file mode 100644
index 0000000..341111e
--- /dev/null
+++ b/docs/.vitepress/showcases/vue/VuetifyShowcaseWrapper.vue
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
diff --git a/showcases/src/frameworks/vue/components/NativeComplexForm.vue b/docs/.vitepress/showcases/vue/basic/components/NativeComplexForm.vue
similarity index 90%
rename from showcases/src/frameworks/vue/components/NativeComplexForm.vue
rename to docs/.vitepress/showcases/vue/basic/components/NativeComplexForm.vue
index 722d482..5ade763 100644
--- a/showcases/src/frameworks/vue/components/NativeComplexForm.vue
+++ b/docs/.vitepress/showcases/vue/basic/components/NativeComplexForm.vue
@@ -4,12 +4,12 @@
style="
margin-bottom: 24px;
padding: 20px;
- background: #f9fafb;
- border: 1px solid #e5e7eb;
+ background: var(--schepta-bg-soft);
+ border: 1px solid var(--schepta-border);
border-radius: 8px;
"
>
-
+
What you can see in this form:
@@ -57,7 +57,7 @@
- Submitted Values:
+ Submitted Values:
Submitted Values:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/showcases/src/frameworks/vue/plugins/vuetify.ts b/docs/.vitepress/showcases/vue/vuetify.ts
similarity index 70%
rename from showcases/src/frameworks/vue/plugins/vuetify.ts
rename to docs/.vitepress/showcases/vue/vuetify.ts
index 81993de..2d379b5 100644
--- a/showcases/src/frameworks/vue/plugins/vuetify.ts
+++ b/docs/.vitepress/showcases/vue/vuetify.ts
@@ -25,6 +25,18 @@ export const vuetify = createVuetify({
warning: '#fb8c00',
},
},
+ dark: {
+ dark: true,
+ colors: {
+ primary: '#90caf9',
+ secondary: '#b0bec5',
+ accent: '#82b1ff',
+ error: '#ff5252',
+ info: '#2196f3',
+ success: '#4caf50',
+ warning: '#fb8c00',
+ },
+ },
},
},
});
diff --git a/showcases/src/frameworks/vue/vuetify/components/ComponentRegistry.ts b/docs/.vitepress/showcases/vue/vuetify/components/ComponentRegistry.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/ComponentRegistry.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/ComponentRegistry.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Containers/FormContainer.ts b/docs/.vitepress/showcases/vue/vuetify/components/Containers/FormContainer.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Containers/FormContainer.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Containers/FormContainer.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Containers/FormField.ts b/docs/.vitepress/showcases/vue/vuetify/components/Containers/FormField.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Containers/FormField.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Containers/FormField.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Containers/FormSectionContainer.ts b/docs/.vitepress/showcases/vue/vuetify/components/Containers/FormSectionContainer.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Containers/FormSectionContainer.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Containers/FormSectionContainer.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Containers/FormSectionGroup.ts b/docs/.vitepress/showcases/vue/vuetify/components/Containers/FormSectionGroup.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Containers/FormSectionGroup.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Containers/FormSectionGroup.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Containers/FormSectionGroupContainer.ts b/docs/.vitepress/showcases/vue/vuetify/components/Containers/FormSectionGroupContainer.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Containers/FormSectionGroupContainer.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Containers/FormSectionGroupContainer.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Containers/FormSectionTitle.ts b/docs/.vitepress/showcases/vue/vuetify/components/Containers/FormSectionTitle.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Containers/FormSectionTitle.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Containers/FormSectionTitle.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Form.vue b/docs/.vitepress/showcases/vue/vuetify/components/Form.vue
similarity index 64%
rename from showcases/src/frameworks/vue/vuetify/components/Form.vue
rename to docs/.vitepress/showcases/vue/vuetify/components/Form.vue
index ad39309..35dc02a 100644
--- a/showcases/src/frameworks/vue/vuetify/components/Form.vue
+++ b/docs/.vitepress/showcases/vue/vuetify/components/Form.vue
@@ -6,9 +6,9 @@
@submit="handleSubmit"
/>
-
- Submitted Values:
- {{ JSON.stringify(submittedValues, null, 2) }}
+
+ Submitted Values:
+ {{ JSON.stringify(submittedValues, null, 2) }}
diff --git a/showcases/src/frameworks/vue/vuetify/components/Inputs/InputCheckbox.ts b/docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputCheckbox.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Inputs/InputCheckbox.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputCheckbox.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Inputs/InputDate.ts b/docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputDate.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Inputs/InputDate.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputDate.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Inputs/InputNumber.ts b/docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputNumber.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Inputs/InputNumber.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputNumber.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Inputs/InputSelect.ts b/docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputSelect.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Inputs/InputSelect.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputSelect.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Inputs/InputText.ts b/docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputText.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Inputs/InputText.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputText.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/Inputs/InputTextarea.ts b/docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputTextarea.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/Inputs/InputTextarea.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/Inputs/InputTextarea.ts
diff --git a/showcases/src/frameworks/vue/vuetify/components/SubmitButton.ts b/docs/.vitepress/showcases/vue/vuetify/components/SubmitButton.ts
similarity index 100%
rename from showcases/src/frameworks/vue/vuetify/components/SubmitButton.ts
rename to docs/.vitepress/showcases/vue/vuetify/components/SubmitButton.ts
diff --git a/showcases/src/frameworks/vue/vuetify/pages/VuetifyFormPage.vue b/docs/.vitepress/showcases/vue/vuetify/pages/VuetifyFormPage.vue
similarity index 89%
rename from showcases/src/frameworks/vue/vuetify/pages/VuetifyFormPage.vue
rename to docs/.vitepress/showcases/vue/vuetify/pages/VuetifyFormPage.vue
index 00b3cd4..9cc78f8 100644
--- a/showcases/src/frameworks/vue/vuetify/pages/VuetifyFormPage.vue
+++ b/docs/.vitepress/showcases/vue/vuetify/pages/VuetifyFormPage.vue
@@ -1,7 +1,5 @@
-
- Vue + Vuetify - Schepta Forms
-
+
SIMPLE FORM
diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css
index 829b2a6..5f1453f 100644
--- a/docs/.vitepress/theme/custom.css
+++ b/docs/.vitepress/theme/custom.css
@@ -20,4 +20,16 @@
background-size: 100% 4px;
background-repeat: no-repeat;
background-position: top center;
+}
+
+/* ─── Schepta tokens → VitePress theme mapping ─── */
+
+:root {
+ --schepta-bg: var(--vp-c-bg);
+ --schepta-bg-soft: var(--vp-c-bg-soft);
+ --schepta-text-1: var(--vp-c-text-1);
+ --schepta-text-2: var(--vp-c-text-2);
+ --schepta-border: var(--vp-c-divider);
+ --schepta-brand: var(--vp-c-brand-1);
+ --schepta-brand-text: #ffffff;
}
\ No newline at end of file
diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts
index c7ef144..ef80e34 100644
--- a/docs/.vitepress/theme/index.ts
+++ b/docs/.vitepress/theme/index.ts
@@ -13,6 +13,33 @@ export default {
app.use(MotionPlugin);
+ // Force full page reload when navigating to/from showcase pages.
+ // This avoids framework conflicts between React and Vue runtimes.
+ // VitePress onBeforeRouteChange only receives `to` (not `from`).
+ if (typeof window !== 'undefined') {
+ const showcasePattern = /\/showcases\/(react|material-ui|chakra-ui|vue|vuetify|vanilla)/;
+
+ router.onBeforeRouteChange = (to: string) => {
+ const currentPath = window.location.pathname;
+
+ // Normalize: remove trailing .html
+ const normalizedTo = to.replace(/\.html$/, '');
+ const normalizedFrom = currentPath.replace(/\.html$/, '');
+
+ const isFromShowcase = showcasePattern.test(normalizedFrom);
+ const isToShowcase = showcasePattern.test(normalizedTo);
+
+ // If navigating between showcases or to/from a showcase, do a full reload
+ if (isFromShowcase || isToShowcase) {
+ // Avoid infinite reload loop: if already on target, do nothing
+ if (normalizedFrom === normalizedTo) return;
+
+ window.location.href = normalizedTo;
+ return false; // Cancel SPA navigation
+ }
+ };
+ }
+
if (typeof window !== 'undefined') {
const handleLanguageClick = (e: MouseEvent) => {
const target = e.target as HTMLElement;
diff --git a/docs/.vitepress/utils/getToken.ts b/docs/.vitepress/utils/getToken.ts
new file mode 100644
index 0000000..3a0f42a
--- /dev/null
+++ b/docs/.vitepress/utils/getToken.ts
@@ -0,0 +1,4 @@
+export function getToken(name: string, fallback: string): string {
+ if (typeof document === 'undefined') return fallback;
+ return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
+}
\ No newline at end of file
diff --git a/docs/en-US/showcases/chakra-ui.md b/docs/en-US/showcases/chakra-ui.md
new file mode 100644
index 0000000..87f08e3
--- /dev/null
+++ b/docs/en-US/showcases/chakra-ui.md
@@ -0,0 +1,20 @@
+---
+title: React Chakra UI Showcase
+description: React forms with Chakra UI components
+aside: false
+---
+
+
+
+# React + Chakra UI
+
+Form implementation using React with Chakra UI component library.
+
+Chakra UI is a simple, modular and accessible component library. This showcase demonstrates how Schepta works with Chakra UI's theming system and components.
+
+
+
+
diff --git a/docs/en-US/showcases/material-ui.md b/docs/en-US/showcases/material-ui.md
new file mode 100644
index 0000000..f17eea3
--- /dev/null
+++ b/docs/en-US/showcases/material-ui.md
@@ -0,0 +1,20 @@
+---
+title: React Material UI Showcase
+description: React forms with Material UI components
+aside: false
+---
+
+
+
+# React + Material UI
+
+Form implementation using React with Material UI component library.
+
+Material UI provides a comprehensive set of pre-styled components following Material Design guidelines. This showcase demonstrates how Schepta integrates seamlessly with Material UI components.
+
+
+
+
diff --git a/docs/en-US/showcases/react.md b/docs/en-US/showcases/react.md
new file mode 100644
index 0000000..3ef9349
--- /dev/null
+++ b/docs/en-US/showcases/react.md
@@ -0,0 +1,24 @@
+---
+title: React Showcase
+description: Interactive React form examples with Schepta
+aside: false
+---
+
+
+
+# React Showcase
+
+Basic form implementation using native React components with various form libraries.
+
+Explore different tabs to see:
+- **Simple Form**: Basic form with native components
+- **Complex Form**: Advanced form with conditional fields
+- **Modal Form**: Form within a modal dialog
+- **React Hook Form**: Integration with React Hook Form library
+- **Formik**: Integration with Formik library
+
+
+
+
diff --git a/docs/en-US/showcases/vanilla.md b/docs/en-US/showcases/vanilla.md
new file mode 100644
index 0000000..e4bd0cd
--- /dev/null
+++ b/docs/en-US/showcases/vanilla.md
@@ -0,0 +1,21 @@
+---
+title: Vanilla JS Showcase
+description: Interactive Vanilla JavaScript form examples with Schepta
+aside: false
+---
+
+
+
+# Vanilla JS Showcase
+
+Form implementation using pure Vanilla JavaScript with no framework dependencies.
+
+Explore different tabs to see:
+- **Simple Form**: Basic form with native JavaScript
+- **Complex Form**: Advanced form with conditional fields and validation
+
+
+
+
diff --git a/docs/en-US/showcases/vue.md b/docs/en-US/showcases/vue.md
new file mode 100644
index 0000000..0299ce4
--- /dev/null
+++ b/docs/en-US/showcases/vue.md
@@ -0,0 +1,21 @@
+---
+title: Vue Showcase
+description: Interactive Vue 3 form examples with Schepta
+aside: false
+---
+
+
+
+# Vue Showcase
+
+Form implementation using Vue 3 Composition API with native components.
+
+Explore different tabs to see:
+- **Simple Form**: Basic form with native Vue components
+- **Complex Form**: Advanced form with conditional fields and validation
+
+
+
+
diff --git a/docs/en-US/showcases/vuetify.md b/docs/en-US/showcases/vuetify.md
new file mode 100644
index 0000000..f07b106
--- /dev/null
+++ b/docs/en-US/showcases/vuetify.md
@@ -0,0 +1,19 @@
+---
+title: Vue Vuetify Showcase
+description: Vue 3 forms with Vuetify components
+aside: false
+---
+
+
+
+# Vue + Vuetify
+
+Form implementation using Vue 3 with Vuetify component library.
+
+Vuetify is a Vue UI library with beautifully handcrafted Material Design components. This showcase demonstrates how Schepta integrates with Vuetify's comprehensive component ecosystem.
+
+
+
+
diff --git a/docs/es-ES/showcases/chakra-ui.md b/docs/es-ES/showcases/chakra-ui.md
new file mode 100644
index 0000000..6332210
--- /dev/null
+++ b/docs/es-ES/showcases/chakra-ui.md
@@ -0,0 +1,20 @@
+---
+title: Showcase React Chakra UI
+description: Formularios React con componentes Chakra UI
+aside: false
+---
+
+
+
+# React + Chakra UI
+
+Implementación de formularios usando React con la biblioteca de componentes Chakra UI.
+
+Chakra UI es una biblioteca de componentes simple, modular y accesible. Este showcase demuestra cómo Schepta funciona con el sistema de temas y componentes de Chakra UI.
+
+
+
+
diff --git a/docs/es-ES/showcases/material-ui.md b/docs/es-ES/showcases/material-ui.md
new file mode 100644
index 0000000..dc70601
--- /dev/null
+++ b/docs/es-ES/showcases/material-ui.md
@@ -0,0 +1,20 @@
+---
+title: Showcase React Material UI
+description: Formularios React con componentes Material UI
+aside: false
+---
+
+
+
+# React + Material UI
+
+Implementación de formularios usando React con la biblioteca de componentes Material UI.
+
+Material UI proporciona un conjunto completo de componentes pre-estilizados siguiendo las directrices de Material Design. Este showcase demuestra cómo Schepta se integra perfectamente con los componentes de Material UI.
+
+
+
+
diff --git a/docs/es-ES/showcases/react.md b/docs/es-ES/showcases/react.md
new file mode 100644
index 0000000..2d50065
--- /dev/null
+++ b/docs/es-ES/showcases/react.md
@@ -0,0 +1,25 @@
+---
+title: Showcase React
+description: Ejemplos interactivos de formularios React con Schepta
+aside: false
+---
+
+
+
+# Showcase React
+
+Implementación de formularios usando componentes nativos de React con varias bibliotecas de formularios.
+
+Explora las diferentes pestañas para ver:
+- **Formulario Simple**: Formulario básico con componentes nativos
+- **Formulario Complejo**: Formulario avanzado con campos condicionales
+- **Formulario Modal**: Formulario dentro de un diálogo modal
+- **React Hook Form**: Integración con la biblioteca React Hook Form
+- **Formik**: Integración con la biblioteca Formik
+
+
+
+
diff --git a/docs/es-ES/showcases/vanilla.md b/docs/es-ES/showcases/vanilla.md
new file mode 100644
index 0000000..c3148e3
--- /dev/null
+++ b/docs/es-ES/showcases/vanilla.md
@@ -0,0 +1,21 @@
+---
+title: Showcase Vanilla JS
+description: Ejemplos interactivos de formularios en JavaScript puro con Schepta
+aside: false
+---
+
+
+
+# Showcase Vanilla JS
+
+Implementación de formularios usando JavaScript puro sin dependencias de frameworks.
+
+Explora las diferentes pestañas para ver:
+- **Formulario Simple**: Formulario básico con JavaScript nativo
+- **Formulario Complejo**: Formulario avanzado con campos condicionales y validación
+
+
+
+
diff --git a/docs/es-ES/showcases/vue.md b/docs/es-ES/showcases/vue.md
new file mode 100644
index 0000000..3b8da06
--- /dev/null
+++ b/docs/es-ES/showcases/vue.md
@@ -0,0 +1,21 @@
+---
+title: Showcase Vue
+description: Ejemplos interactivos de formularios Vue 3 con Schepta
+aside: false
+---
+
+
+
+# Showcase Vue
+
+Implementación de formularios usando Vue 3 Composition API con componentes nativos.
+
+Explora las diferentes pestañas para ver:
+- **Formulario Simple**: Formulario básico con componentes Vue nativos
+- **Formulario Complejo**: Formulario avanzado con campos condicionales y validación
+
+
+
+
diff --git a/docs/es-ES/showcases/vuetify.md b/docs/es-ES/showcases/vuetify.md
new file mode 100644
index 0000000..88ee2a7
--- /dev/null
+++ b/docs/es-ES/showcases/vuetify.md
@@ -0,0 +1,19 @@
+---
+title: Showcase Vue Vuetify
+description: Formularios Vue 3 con componentes Vuetify
+aside: false
+---
+
+
+
+# Vue + Vuetify
+
+Implementación de formularios usando Vue 3 con la biblioteca de componentes Vuetify.
+
+Vuetify es una biblioteca de UI Vue con componentes Material Design bellamente elaborados. Este showcase demuestra cómo Schepta se integra con el completo ecosistema de componentes de Vuetify.
+
+
+
+
diff --git a/docs/package.json b/docs/package.json
index 22d7d7a..57016b1 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -9,17 +9,28 @@
"preview": "vitepress preview"
},
"dependencies": {
+ "@chakra-ui/react": "^2.8.2",
+ "@emotion/react": "^11.11.0",
+ "@emotion/styled": "^11.11.0",
+ "@hookform/resolvers": "^3.9.0",
"@mdi/font": "^7.4.47",
+ "@mui/material": "^5.15.0",
"@schepta/adapter-react": "workspace:*",
+ "@schepta/adapter-vanilla": "workspace:*",
"@schepta/adapter-vue": "workspace:*",
"@schepta/core": "workspace:*",
"@schepta/factory-react": "workspace:*",
+ "@schepta/factory-vanilla": "workspace:*",
"@schepta/factory-vue": "workspace:*",
+ "@tanstack/react-router": "^1.159.5",
"@vueuse/motion": "^3.0.3",
+ "formik": "^2.4.6",
+ "framer-motion": "^10.16.16",
"lucide-vue-next": "^0.561.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "react-hook-form": "^7.49.0",
+ "react-hook-form": "^7.52.2",
+ "react-icons": "^5.0.0",
"react-router-dom": "^6.20.0",
"vue": "^3.4.0",
"vue-router": "^4.2.5",
diff --git a/docs/pt-BR/showcases/chakra-ui.md b/docs/pt-BR/showcases/chakra-ui.md
new file mode 100644
index 0000000..f248a05
--- /dev/null
+++ b/docs/pt-BR/showcases/chakra-ui.md
@@ -0,0 +1,20 @@
+---
+title: Showcase React Chakra UI
+description: Formulários React com componentes Chakra UI
+aside: false
+---
+
+
+
+# React + Chakra UI
+
+Implementação de formulários usando React com a biblioteca de componentes Chakra UI.
+
+Chakra UI é uma biblioteca de componentes simples, modular e acessível. Este showcase demonstra como o Schepta funciona com o sistema de temas e componentes do Chakra UI.
+
+
+
+
diff --git a/docs/pt-BR/showcases/material-ui.md b/docs/pt-BR/showcases/material-ui.md
new file mode 100644
index 0000000..3b33770
--- /dev/null
+++ b/docs/pt-BR/showcases/material-ui.md
@@ -0,0 +1,20 @@
+---
+title: Showcase React Material UI
+description: Formulários React com componentes Material UI
+aside: false
+---
+
+
+
+# React + Material UI
+
+Implementação de formulários usando React com a biblioteca de componentes Material UI.
+
+Material UI fornece um conjunto abrangente de componentes pré-estilizados seguindo as diretrizes do Material Design. Este showcase demonstra como o Schepta se integra perfeitamente com os componentes Material UI.
+
+
+
+
diff --git a/docs/pt-BR/showcases/react.md b/docs/pt-BR/showcases/react.md
new file mode 100644
index 0000000..f2727b9
--- /dev/null
+++ b/docs/pt-BR/showcases/react.md
@@ -0,0 +1,25 @@
+---
+title: Showcase React
+description: Exemplos interativos de formulários React com Schepta
+aside: false
+---
+
+
+
+# Showcase React
+
+Implementação de formulários usando componentes nativos do React com várias bibliotecas de formulários.
+
+Explore as diferentes abas para ver:
+- **Formulário Simples**: Formulário básico com componentes nativos
+- **Formulário Complexo**: Formulário avançado com campos condicionais
+- **Formulário Modal**: Formulário dentro de um diálogo modal
+- **React Hook Form**: Integração com a biblioteca React Hook Form
+- **Formik**: Integração com a biblioteca Formik
+
+
+
+
diff --git a/docs/pt-BR/showcases/vanilla.md b/docs/pt-BR/showcases/vanilla.md
new file mode 100644
index 0000000..411e231
--- /dev/null
+++ b/docs/pt-BR/showcases/vanilla.md
@@ -0,0 +1,21 @@
+---
+title: Showcase Vanilla JS
+description: Exemplos interativos de formulários em JavaScript puro com Schepta
+aside: false
+---
+
+
+
+# Showcase Vanilla JS
+
+Implementação de formulários usando JavaScript puro sem dependências de frameworks.
+
+Explore as diferentes abas para ver:
+- **Formulário Simples**: Formulário básico com JavaScript nativo
+- **Formulário Complexo**: Formulário avançado com campos condicionais e validação
+
+
+
+
diff --git a/docs/pt-BR/showcases/vue.md b/docs/pt-BR/showcases/vue.md
new file mode 100644
index 0000000..b7c8c63
--- /dev/null
+++ b/docs/pt-BR/showcases/vue.md
@@ -0,0 +1,21 @@
+---
+title: Showcase Vue
+description: Exemplos interativos de formulários Vue 3 com Schepta
+aside: false
+---
+
+
+
+# Showcase Vue
+
+Implementação de formulários usando Vue 3 Composition API com componentes nativos.
+
+Explore as diferentes abas para ver:
+- **Formulário Simples**: Formulário básico com componentes Vue nativos
+- **Formulário Complexo**: Formulário avançado com campos condicionais e validação
+
+
+
+
diff --git a/docs/pt-BR/showcases/vuetify.md b/docs/pt-BR/showcases/vuetify.md
new file mode 100644
index 0000000..44e59b9
--- /dev/null
+++ b/docs/pt-BR/showcases/vuetify.md
@@ -0,0 +1,19 @@
+---
+title: Showcase Vue Vuetify
+description: Formulários Vue 3 com componentes Vuetify
+aside: false
+---
+
+
+
+# Vue + Vuetify
+
+Implementação de formulários usando Vue 3 com a biblioteca de componentes Vuetify.
+
+Vuetify é uma biblioteca de UI Vue com componentes Material Design lindamente elaborados. Este showcase demonstra como o Schepta se integra com o abrangente ecossistema de componentes do Vuetify.
+
+
+
+
diff --git a/packages/factories/react/src/components/DefaultFormSectionTitle.tsx b/packages/factories/react/src/components/DefaultFormSectionTitle.tsx
index 8386263..6a2d212 100644
--- a/packages/factories/react/src/components/DefaultFormSectionTitle.tsx
+++ b/packages/factories/react/src/components/DefaultFormSectionTitle.tsx
@@ -4,7 +4,7 @@
* Section title (x-content). Can be overridden via createComponentSpec.
*/
-import React from 'react';
+import React from "react";
/**
* Props passed to the FormSectionTitle component.
@@ -13,11 +13,11 @@ import React from 'react';
export interface FormSectionTitleProps
extends React.HTMLAttributes {
/** Title content (from schema x-content) */
- 'x-content'?: string;
+ "x-content"?: string;
/** Optional children (alternative to x-content) */
children?: React.ReactNode;
/** Test ID for the form section title */
- 'data-test-id'?: string;
+ "data-test-id"?: string;
externalContext?: Record;
"x-component-props"?: Record;
"x-ui"?: Record;
@@ -34,7 +34,7 @@ export type FormSectionTitleComponentType =
* Default form section title component.
*/
export const DefaultFormSectionTitle: React.FC = ({
- 'x-content': content,
+ "x-content": content,
children,
externalContext,
"x-component-props": xComponentProps,
@@ -42,7 +42,17 @@ export const DefaultFormSectionTitle: React.FC = ({
...props
}) => {
return (
-
+
{content ?? children}
);
diff --git a/packages/factories/react/src/components/DefaultInputAutocomplete.tsx b/packages/factories/react/src/components/DefaultInputAutocomplete.tsx
index 4b5b0ab..48068fc 100644
--- a/packages/factories/react/src/components/DefaultInputAutocomplete.tsx
+++ b/packages/factories/react/src/components/DefaultInputAutocomplete.tsx
@@ -43,7 +43,7 @@ export type InputAutocompleteComponentType = React.ComponentType;
const inputStyle: React.CSSProperties = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/react/src/components/DefaultInputNumber.tsx b/packages/factories/react/src/components/DefaultInputNumber.tsx
index 9e46c9b..eb0635a 100644
--- a/packages/factories/react/src/components/DefaultInputNumber.tsx
+++ b/packages/factories/react/src/components/DefaultInputNumber.tsx
@@ -38,7 +38,7 @@ export type InputNumberComponentType = React.ComponentType;
const inputStyle: React.CSSProperties = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/react/src/components/DefaultInputPhone.tsx b/packages/factories/react/src/components/DefaultInputPhone.tsx
index 9d8cdf3..ba4d4a6 100644
--- a/packages/factories/react/src/components/DefaultInputPhone.tsx
+++ b/packages/factories/react/src/components/DefaultInputPhone.tsx
@@ -36,7 +36,7 @@ export type InputPhoneComponentType = React.ComponentType;
const inputStyle: React.CSSProperties = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/react/src/components/DefaultInputSelect.tsx b/packages/factories/react/src/components/DefaultInputSelect.tsx
index 35f5e58..cd70286 100644
--- a/packages/factories/react/src/components/DefaultInputSelect.tsx
+++ b/packages/factories/react/src/components/DefaultInputSelect.tsx
@@ -43,7 +43,7 @@ export type InputSelectComponentType = React.ComponentType;
const inputStyle: React.CSSProperties = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/react/src/components/DefaultInputText.tsx b/packages/factories/react/src/components/DefaultInputText.tsx
index 9ace79b..94639aa 100644
--- a/packages/factories/react/src/components/DefaultInputText.tsx
+++ b/packages/factories/react/src/components/DefaultInputText.tsx
@@ -35,7 +35,7 @@ export type InputTextComponentType = React.ComponentType;
const inputStyle: React.CSSProperties = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/react/src/components/DefaultInputTextarea.tsx b/packages/factories/react/src/components/DefaultInputTextarea.tsx
index ecc685c..7b23426 100644
--- a/packages/factories/react/src/components/DefaultInputTextarea.tsx
+++ b/packages/factories/react/src/components/DefaultInputTextarea.tsx
@@ -36,7 +36,7 @@ export type InputTextareaComponentType = React.ComponentType
const inputStyle: React.CSSProperties = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
fontFamily: 'inherit',
};
diff --git a/packages/factories/react/src/components/DefaultSubmitButton.tsx b/packages/factories/react/src/components/DefaultSubmitButton.tsx
index 53a68cb..3622bb0 100644
--- a/packages/factories/react/src/components/DefaultSubmitButton.tsx
+++ b/packages/factories/react/src/components/DefaultSubmitButton.tsx
@@ -61,8 +61,8 @@ export const DefaultSubmitButton: React.FC = ({ onSubmit, "x-
data-test-id="submit-button"
style={{
padding: '12px 24px',
- backgroundColor: '#007bff',
- color: 'white',
+ backgroundColor: 'var(--schepta-brand)',
+ color: 'var(--schepta-brand-text)',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
diff --git a/packages/factories/react/src/form-factory.tsx b/packages/factories/react/src/form-factory.tsx
index 09cbd67..57344da 100644
--- a/packages/factories/react/src/form-factory.tsx
+++ b/packages/factories/react/src/form-factory.tsx
@@ -28,8 +28,9 @@ import formSchemaDefinition from "../../src/schemas/form-schema.json";
import { ScheptaFormProvider } from "./context/schepta-form-context";
import { defaultComponents } from "./defaults/register-default-components";
import { defaultRenderers } from "./defaults/register-default-renderers";
+import { injectScheptaTokens } from "./schepta-tokens";
-// Register factory default components (called once on module load)
+injectScheptaTokens();
setFactoryDefaultComponents(defaultComponents);
setFactoryDefaultRenderers(defaultRenderers);
@@ -116,13 +117,13 @@ export const FormFactory = forwardRef(
-
+
Schema Validation Error
(
whiteSpace: "pre-wrap",
fontSize: "12px",
margin: 0,
- color: "#660000",
+ color: "var(--schepta-error-text-muted)",
}}
>
{validation.formattedErrors}
diff --git a/packages/factories/react/src/schepta-tokens.ts b/packages/factories/react/src/schepta-tokens.ts
new file mode 100644
index 0000000..2dfc163
--- /dev/null
+++ b/packages/factories/react/src/schepta-tokens.ts
@@ -0,0 +1,53 @@
+/**
+ * Schepta Design Tokens
+ *
+ * Default CSS custom properties for all Schepta default components.
+ * Consumers can override these variables to theme the form components.
+ *
+ * @example
+ * ```css
+ * :root {
+ * --schepta-brand: #6366f1;
+ * --schepta-border: #d1d5db;
+ * }
+ * ```
+ */
+
+const SCHEPTA_TOKENS = `
+@layer schepta-defaults {
+ :root {
+ --schepta-bg: #ffffff;
+ --schepta-bg-soft: #f6f6f7;
+ --schepta-text-1: #333333;
+ --schepta-text-2: #666666;
+ --schepta-border: #cccccc;
+ --schepta-brand: #5c73e7;
+ --schepta-brand-text: #ffffff;
+ --schepta-error-bg: #fff0f0;
+ --schepta-error-border: #ffcccc;
+ --schepta-error-text: #cc0000;
+ --schepta-error-text-muted: #660000;
+ }
+}
+`;
+
+let injected = false;
+
+/**
+ * Injects default Schepta CSS tokens into the document head.
+ * Safe to call multiple times — only injects once.
+ * No-op in SSR/Node environments.
+ */
+export function injectScheptaTokens(): void {
+ if (injected || typeof document === 'undefined') return;
+ const existing = document.getElementById('schepta-default-tokens');
+ if (existing) {
+ injected = true;
+ return;
+ }
+ const style = document.createElement('style');
+ style.id = 'schepta-default-tokens';
+ style.textContent = SCHEPTA_TOKENS;
+ document.head.appendChild(style);
+ injected = true;
+}
diff --git a/packages/factories/vanilla/src/components/DefaultSubmitButton.ts b/packages/factories/vanilla/src/components/DefaultSubmitButton.ts
index 5d8502b..db29727 100644
--- a/packages/factories/vanilla/src/components/DefaultSubmitButton.ts
+++ b/packages/factories/vanilla/src/components/DefaultSubmitButton.ts
@@ -32,8 +32,8 @@ export function createDefaultSubmitButton(props: SubmitButtonProps): HTMLElement
button.textContent = 'Submit';
button.dataset.testId = 'submit-button';
button.style.padding = '12px 24px';
- button.style.backgroundColor = '#007bff';
- button.style.color = 'white';
+ button.style.backgroundColor = 'var(--schepta-brand)';
+ button.style.color = 'var(--schepta-brand-text)';
button.style.border = 'none';
button.style.borderRadius = '4px';
button.style.cursor = 'pointer';
diff --git a/packages/factories/vanilla/src/components/FormSectionContainer.ts b/packages/factories/vanilla/src/components/FormSectionContainer.ts
index 2c9782e..f59f9bb 100644
--- a/packages/factories/vanilla/src/components/FormSectionContainer.ts
+++ b/packages/factories/vanilla/src/components/FormSectionContainer.ts
@@ -10,9 +10,9 @@ export function createFormSectionContainer(props: FormSectionContainerProps): HT
const wrapper = document.createElement('div');
wrapper.style.marginBottom = '24px';
wrapper.style.padding = '20px';
- wrapper.style.border = '1px solid #e5e7eb';
+ wrapper.style.border = '1px solid var(--schepta-border)';
wrapper.style.borderRadius = '8px';
- wrapper.style.background = '#fff';
+ wrapper.style.background = 'var(--schepta-bg)';
// Render children
if (props.children) {
diff --git a/packages/factories/vanilla/src/components/FormSectionTitle.ts b/packages/factories/vanilla/src/components/FormSectionTitle.ts
index c24ebf1..d236848 100644
--- a/packages/factories/vanilla/src/components/FormSectionTitle.ts
+++ b/packages/factories/vanilla/src/components/FormSectionTitle.ts
@@ -14,7 +14,7 @@ export function createFormSectionTitle(props: FormSectionTitleProps): HTMLElemen
heading.style.fontWeight = '600';
heading.style.marginTop = '0';
heading.style.marginBottom = '16px';
- heading.style.color = '#111827';
+ heading.style.color = 'var(--schepta-text-1)';
return heading;
}
diff --git a/packages/factories/vanilla/src/components/InputAutocomplete.ts b/packages/factories/vanilla/src/components/InputAutocomplete.ts
index b475c02..829f47e 100644
--- a/packages/factories/vanilla/src/components/InputAutocomplete.ts
+++ b/packages/factories/vanilla/src/components/InputAutocomplete.ts
@@ -58,7 +58,7 @@ export function createInputAutocomplete(props: InputAutocompleteProps): HTMLElem
input.style.width = '100%';
input.style.padding = '8px';
- input.style.border = '1px solid #ccc';
+ input.style.border = '1px solid var(--schepta-border)';
input.style.borderRadius = '4px';
input.style.fontSize = '14px';
diff --git a/packages/factories/vanilla/src/components/InputDate.ts b/packages/factories/vanilla/src/components/InputDate.ts
index 2a0f83a..2576fa5 100644
--- a/packages/factories/vanilla/src/components/InputDate.ts
+++ b/packages/factories/vanilla/src/components/InputDate.ts
@@ -39,7 +39,7 @@ export function createInputDate(props: InputDateProps): HTMLElement {
input.style.width = '100%';
input.style.padding = '8px';
- input.style.border = '1px solid #ccc';
+ input.style.border = '1px solid var(--schepta-border)';
input.style.borderRadius = '4px';
input.style.fontSize = '14px';
diff --git a/packages/factories/vanilla/src/components/InputNumber.ts b/packages/factories/vanilla/src/components/InputNumber.ts
index 585820b..44078b5 100644
--- a/packages/factories/vanilla/src/components/InputNumber.ts
+++ b/packages/factories/vanilla/src/components/InputNumber.ts
@@ -46,7 +46,7 @@ export function createInputNumber(props: InputNumberProps): HTMLElement {
input.style.width = '100%';
input.style.padding = '8px';
- input.style.border = '1px solid #ccc';
+ input.style.border = '1px solid var(--schepta-border)';
input.style.borderRadius = '4px';
input.style.fontSize = '14px';
diff --git a/packages/factories/vanilla/src/components/InputPhone.ts b/packages/factories/vanilla/src/components/InputPhone.ts
index 9e54441..612789c 100644
--- a/packages/factories/vanilla/src/components/InputPhone.ts
+++ b/packages/factories/vanilla/src/components/InputPhone.ts
@@ -39,7 +39,7 @@ export function createInputPhone(props: InputPhoneProps): HTMLElement {
input.style.width = '100%';
input.style.padding = '8px';
- input.style.border = '1px solid #ccc';
+ input.style.border = '1px solid var(--schepta-border)';
input.style.borderRadius = '4px';
input.style.fontSize = '14px';
diff --git a/packages/factories/vanilla/src/components/InputSelect.ts b/packages/factories/vanilla/src/components/InputSelect.ts
index b6bc248..c30c956 100644
--- a/packages/factories/vanilla/src/components/InputSelect.ts
+++ b/packages/factories/vanilla/src/components/InputSelect.ts
@@ -43,7 +43,7 @@ export function createInputSelect(props: InputSelectProps): HTMLElement {
select.style.width = '100%';
select.style.padding = '8px';
- select.style.border = '1px solid #ccc';
+ select.style.border = '1px solid var(--schepta-border)';
select.style.borderRadius = '4px';
select.style.fontSize = '14px';
diff --git a/packages/factories/vanilla/src/components/InputText.ts b/packages/factories/vanilla/src/components/InputText.ts
index b343dfa..440e949 100644
--- a/packages/factories/vanilla/src/components/InputText.ts
+++ b/packages/factories/vanilla/src/components/InputText.ts
@@ -40,7 +40,7 @@ export function createInputText(props: InputTextProps): HTMLElement {
input.style.width = '100%';
input.style.padding = '8px';
- input.style.border = '1px solid #ccc';
+ input.style.border = '1px solid var(--schepta-border)';
input.style.borderRadius = '4px';
input.style.fontSize = '14px';
diff --git a/packages/factories/vanilla/src/components/InputTextarea.ts b/packages/factories/vanilla/src/components/InputTextarea.ts
index be84df0..915a19e 100644
--- a/packages/factories/vanilla/src/components/InputTextarea.ts
+++ b/packages/factories/vanilla/src/components/InputTextarea.ts
@@ -40,7 +40,7 @@ export function createInputTextarea(props: InputTextareaProps): HTMLElement {
textarea.style.width = '100%';
textarea.style.padding = '8px';
- textarea.style.border = '1px solid #ccc';
+ textarea.style.border = '1px solid var(--schepta-border)';
textarea.style.borderRadius = '4px';
textarea.style.fontSize = '14px';
textarea.style.fontFamily = 'inherit';
diff --git a/packages/factories/vanilla/src/form-factory.ts b/packages/factories/vanilla/src/form-factory.ts
index 5c871c8..4496c54 100644
--- a/packages/factories/vanilla/src/form-factory.ts
+++ b/packages/factories/vanilla/src/form-factory.ts
@@ -18,6 +18,7 @@ import formSchemaDefinition from '../../src/schemas/form-schema.json';
import { renderForm } from './form-renderer';
import { registerDefaultComponents } from './defaults/register-default-components';
import { createDefaultRenderers } from './defaults/register-default-renderers';
+import { injectScheptaTokens } from './schepta-tokens';
export interface FormFactoryOptions {
schema: FormSchema;
@@ -49,6 +50,8 @@ export interface FormFactoryResult {
}
export function createFormFactory(options: FormFactoryOptions): FormFactoryResult {
+ injectScheptaTokens();
+
// Register default components and renderers
registerDefaultComponents();
@@ -68,10 +71,10 @@ export function createFormFactory(options: FormFactoryOptions): FormFactoryResul
if (!validation.valid) {
console.error('Schema validation failed:', validation.errors);
const errorDiv = document.createElement('div');
- errorDiv.style.color = '#dc2626';
+ errorDiv.style.color = 'var(--schepta-error-text)';
errorDiv.style.padding = '16px';
- errorDiv.style.background = '#fee2e2';
- errorDiv.style.border = '1px solid #fecaca';
+ errorDiv.style.background = 'var(--schepta-error-bg)';
+ errorDiv.style.border = '1px solid var(--schepta-error-border)';
errorDiv.style.borderRadius = '4px';
errorDiv.style.marginBottom = '16px';
errorDiv.innerHTML = `
diff --git a/packages/factories/vanilla/src/schepta-tokens.ts b/packages/factories/vanilla/src/schepta-tokens.ts
new file mode 100644
index 0000000..2dfc163
--- /dev/null
+++ b/packages/factories/vanilla/src/schepta-tokens.ts
@@ -0,0 +1,53 @@
+/**
+ * Schepta Design Tokens
+ *
+ * Default CSS custom properties for all Schepta default components.
+ * Consumers can override these variables to theme the form components.
+ *
+ * @example
+ * ```css
+ * :root {
+ * --schepta-brand: #6366f1;
+ * --schepta-border: #d1d5db;
+ * }
+ * ```
+ */
+
+const SCHEPTA_TOKENS = `
+@layer schepta-defaults {
+ :root {
+ --schepta-bg: #ffffff;
+ --schepta-bg-soft: #f6f6f7;
+ --schepta-text-1: #333333;
+ --schepta-text-2: #666666;
+ --schepta-border: #cccccc;
+ --schepta-brand: #5c73e7;
+ --schepta-brand-text: #ffffff;
+ --schepta-error-bg: #fff0f0;
+ --schepta-error-border: #ffcccc;
+ --schepta-error-text: #cc0000;
+ --schepta-error-text-muted: #660000;
+ }
+}
+`;
+
+let injected = false;
+
+/**
+ * Injects default Schepta CSS tokens into the document head.
+ * Safe to call multiple times — only injects once.
+ * No-op in SSR/Node environments.
+ */
+export function injectScheptaTokens(): void {
+ if (injected || typeof document === 'undefined') return;
+ const existing = document.getElementById('schepta-default-tokens');
+ if (existing) {
+ injected = true;
+ return;
+ }
+ const style = document.createElement('style');
+ style.id = 'schepta-default-tokens';
+ style.textContent = SCHEPTA_TOKENS;
+ document.head.appendChild(style);
+ injected = true;
+}
diff --git a/packages/factories/vue/src/components/DefaultFormSectionTitle.ts b/packages/factories/vue/src/components/DefaultFormSectionTitle.ts
index 48b770b..c524d6a 100644
--- a/packages/factories/vue/src/components/DefaultFormSectionTitle.ts
+++ b/packages/factories/vue/src/components/DefaultFormSectionTitle.ts
@@ -20,7 +20,7 @@ export const DefaultFormSectionTitle = defineComponent({
marginBottom: '16px',
fontSize: '20px',
fontWeight: '600',
- color: '#333',
+ color: 'var(--schepta-text-1)',
},
},
props['x-content'] ?? slots.default?.()
diff --git a/packages/factories/vue/src/components/DefaultInputAutocomplete.ts b/packages/factories/vue/src/components/DefaultInputAutocomplete.ts
index e99582d..728a837 100644
--- a/packages/factories/vue/src/components/DefaultInputAutocomplete.ts
+++ b/packages/factories/vue/src/components/DefaultInputAutocomplete.ts
@@ -14,7 +14,7 @@ export interface InputAutocompleteOption {
const inputStyle = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/vue/src/components/DefaultInputDate.ts b/packages/factories/vue/src/components/DefaultInputDate.ts
index 70beb4c..93c43b8 100644
--- a/packages/factories/vue/src/components/DefaultInputDate.ts
+++ b/packages/factories/vue/src/components/DefaultInputDate.ts
@@ -9,7 +9,7 @@ import { defineComponent, h, type PropType } from 'vue';
const inputStyle = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/vue/src/components/DefaultInputNumber.ts b/packages/factories/vue/src/components/DefaultInputNumber.ts
index 8440340..c73eeb6 100644
--- a/packages/factories/vue/src/components/DefaultInputNumber.ts
+++ b/packages/factories/vue/src/components/DefaultInputNumber.ts
@@ -9,7 +9,7 @@ import { defineComponent, h, type PropType } from 'vue';
const inputStyle = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/vue/src/components/DefaultInputPhone.ts b/packages/factories/vue/src/components/DefaultInputPhone.ts
index c2f7751..b4fb7b0 100644
--- a/packages/factories/vue/src/components/DefaultInputPhone.ts
+++ b/packages/factories/vue/src/components/DefaultInputPhone.ts
@@ -9,7 +9,7 @@ import { defineComponent, h, type PropType } from 'vue';
const inputStyle = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/vue/src/components/DefaultInputSelect.ts b/packages/factories/vue/src/components/DefaultInputSelect.ts
index 33c3393..aacb233 100644
--- a/packages/factories/vue/src/components/DefaultInputSelect.ts
+++ b/packages/factories/vue/src/components/DefaultInputSelect.ts
@@ -14,7 +14,7 @@ export interface InputSelectOption {
const inputStyle = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/vue/src/components/DefaultInputText.ts b/packages/factories/vue/src/components/DefaultInputText.ts
index 26d9b23..2ceaffa 100644
--- a/packages/factories/vue/src/components/DefaultInputText.ts
+++ b/packages/factories/vue/src/components/DefaultInputText.ts
@@ -9,7 +9,7 @@ import { defineComponent, h, type PropType } from 'vue';
const inputStyle = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
};
diff --git a/packages/factories/vue/src/components/DefaultInputTextarea.ts b/packages/factories/vue/src/components/DefaultInputTextarea.ts
index ee6d2b8..eb8fb91 100644
--- a/packages/factories/vue/src/components/DefaultInputTextarea.ts
+++ b/packages/factories/vue/src/components/DefaultInputTextarea.ts
@@ -9,7 +9,7 @@ import { defineComponent, h, type PropType } from 'vue';
const inputStyle = {
width: '100%',
padding: '8px',
- border: '1px solid #ccc',
+ border: '1px solid var(--schepta-border)',
borderRadius: '4px',
fontFamily: 'inherit',
};
diff --git a/packages/factories/vue/src/components/DefaultSubmitButton.ts b/packages/factories/vue/src/components/DefaultSubmitButton.ts
index ec3a7bf..bc84e50 100644
--- a/packages/factories/vue/src/components/DefaultSubmitButton.ts
+++ b/packages/factories/vue/src/components/DefaultSubmitButton.ts
@@ -34,8 +34,8 @@ export const DefaultSubmitButton = defineComponent({
'data-test-id': 'submit-button',
style: {
padding: '12px 24px',
- backgroundColor: '#007bff',
- color: 'white',
+ backgroundColor: 'var(--schepta-brand)',
+ color: 'var(--schepta-brand-text)',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
diff --git a/packages/factories/vue/src/form-factory.ts b/packages/factories/vue/src/form-factory.ts
index ec6769e..8d09a9f 100644
--- a/packages/factories/vue/src/form-factory.ts
+++ b/packages/factories/vue/src/form-factory.ts
@@ -33,8 +33,9 @@ import { FormRenderer } from './form-renderer';
import { ScheptaFormProvider } from './context/schepta-form-context';
import { defaultComponents } from './defaults/register-default-components';
import { defaultRenderers as vueDefaultRenderers } from './defaults/register-default-renderers';
+import { injectScheptaTokens } from './schepta-tokens';
-// Register factory default components and renderers (called once on module load)
+injectScheptaTokens();
setFactoryDefaultComponents(defaultComponents);
setFactoryDefaultRenderers(vueDefaultRenderers);
@@ -218,19 +219,19 @@ export const FormFactory = defineComponent({
return h('div', {
style: {
padding: '16px',
- backgroundColor: '#fff0f0',
- border: '1px solid #ffcccc',
+ backgroundColor: 'var(--schepta-error-bg)',
+ border: '1px solid var(--schepta-error-border)',
borderRadius: '4px',
fontFamily: 'monospace',
},
}, [
- h('h3', { style: { color: '#cc0000', margin: '0 0 12px 0' } }, 'Schema Validation Error'),
+ h('h3', { style: { color: 'var(--schepta-error-text)', margin: '0 0 12px 0' } }, 'Schema Validation Error'),
h('pre', {
style: {
whiteSpace: 'pre-wrap',
fontSize: '12px',
margin: 0,
- color: '#660000',
+ color: 'var(--schepta-error-text-muted)',
},
}, validation.value.formattedErrors),
]);
diff --git a/packages/factories/vue/src/schepta-tokens.ts b/packages/factories/vue/src/schepta-tokens.ts
new file mode 100644
index 0000000..2dfc163
--- /dev/null
+++ b/packages/factories/vue/src/schepta-tokens.ts
@@ -0,0 +1,53 @@
+/**
+ * Schepta Design Tokens
+ *
+ * Default CSS custom properties for all Schepta default components.
+ * Consumers can override these variables to theme the form components.
+ *
+ * @example
+ * ```css
+ * :root {
+ * --schepta-brand: #6366f1;
+ * --schepta-border: #d1d5db;
+ * }
+ * ```
+ */
+
+const SCHEPTA_TOKENS = `
+@layer schepta-defaults {
+ :root {
+ --schepta-bg: #ffffff;
+ --schepta-bg-soft: #f6f6f7;
+ --schepta-text-1: #333333;
+ --schepta-text-2: #666666;
+ --schepta-border: #cccccc;
+ --schepta-brand: #5c73e7;
+ --schepta-brand-text: #ffffff;
+ --schepta-error-bg: #fff0f0;
+ --schepta-error-border: #ffcccc;
+ --schepta-error-text: #cc0000;
+ --schepta-error-text-muted: #660000;
+ }
+}
+`;
+
+let injected = false;
+
+/**
+ * Injects default Schepta CSS tokens into the document head.
+ * Safe to call multiple times — only injects once.
+ * No-op in SSR/Node environments.
+ */
+export function injectScheptaTokens(): void {
+ if (injected || typeof document === 'undefined') return;
+ const existing = document.getElementById('schepta-default-tokens');
+ if (existing) {
+ injected = true;
+ return;
+ }
+ const style = document.createElement('style');
+ style.id = 'schepta-default-tokens';
+ style.textContent = SCHEPTA_TOKENS;
+ document.head.appendChild(style);
+ injected = true;
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7277be5..1afad6b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -26,12 +26,30 @@ importers:
docs:
dependencies:
+ '@chakra-ui/react':
+ specifier: ^2.8.2
+ version: 2.10.9(@emotion/react@11.14.0)(@emotion/styled@11.14.1)(@types/react@18.3.27)(framer-motion@10.18.0)(react-dom@18.3.1)(react@18.3.1)
+ '@emotion/react':
+ specifier: ^11.11.0
+ version: 11.14.0(@types/react@18.3.27)(react@18.3.1)
+ '@emotion/styled':
+ specifier: ^11.11.0
+ version: 11.14.1(@emotion/react@11.14.0)(@types/react@18.3.27)(react@18.3.1)
+ '@hookform/resolvers':
+ specifier: ^3.9.0
+ version: 3.10.0(react-hook-form@7.68.0)
'@mdi/font':
specifier: ^7.4.47
version: 7.4.47
+ '@mui/material':
+ specifier: ^5.15.0
+ version: 5.18.0(@emotion/react@11.14.0)(@emotion/styled@11.14.1)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)
'@schepta/adapter-react':
specifier: workspace:*
version: link:../packages/adapters/react
+ '@schepta/adapter-vanilla':
+ specifier: workspace:*
+ version: link:../packages/adapters/vanilla
'@schepta/adapter-vue':
specifier: workspace:*
version: link:../packages/adapters/vue
@@ -41,12 +59,24 @@ importers:
'@schepta/factory-react':
specifier: workspace:*
version: link:../packages/factories/react
+ '@schepta/factory-vanilla':
+ specifier: workspace:*
+ version: link:../packages/factories/vanilla
'@schepta/factory-vue':
specifier: workspace:*
version: link:../packages/factories/vue
+ '@tanstack/react-router':
+ specifier: ^1.159.5
+ version: 1.159.5(react-dom@18.3.1)(react@18.3.1)
'@vueuse/motion':
specifier: ^3.0.3
version: 3.0.3(vue@3.5.25)
+ formik:
+ specifier: ^2.4.6
+ version: 2.4.9(@types/react@18.3.27)(react@18.3.1)
+ framer-motion:
+ specifier: ^10.16.16
+ version: 10.18.0(react-dom@18.3.1)(react@18.3.1)
lucide-vue-next:
specifier: ^0.561.0
version: 0.561.0(vue@3.5.25)
@@ -57,8 +87,11 @@ importers:
specifier: ^18.2.0
version: 18.3.1(react@18.3.1)
react-hook-form:
- specifier: ^7.49.0
+ specifier: ^7.52.2
version: 7.68.0(react@18.3.1)
+ react-icons:
+ specifier: ^5.0.0
+ version: 5.5.0(react@18.3.1)
react-router-dom:
specifier: ^6.20.0
version: 6.30.2(react-dom@18.3.1)(react@18.3.1)
@@ -92,7 +125,7 @@ importers:
version: 2.1.2(vite@5.4.21)(vue@3.5.25)(vuetify@3.11.2)
vitepress:
specifier: ^1.0.0
- version: 1.6.4(@algolia/client-search@5.46.0)(@types/node@20.19.25)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3)
+ version: 1.6.4(@algolia/client-search@5.46.0)(@types/node@20.19.25)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3)
packages/adapters/react:
dependencies:
@@ -899,10 +932,10 @@ packages:
resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==}
dev: true
- /@docsearch/js@3.8.2(@algolia/client-search@5.46.0)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3):
+ /@docsearch/js@3.8.2(@algolia/client-search@5.46.0)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3):
resolution: {integrity: sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==}
dependencies:
- '@docsearch/react': 3.8.2(@algolia/client-search@5.46.0)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3)
+ '@docsearch/react': 3.8.2(@algolia/client-search@5.46.0)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3)
preact: 10.28.0
transitivePeerDependencies:
- '@algolia/client-search'
@@ -912,7 +945,7 @@ packages:
- search-insights
dev: true
- /@docsearch/react@3.8.2(@algolia/client-search@5.46.0)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3):
+ /@docsearch/react@3.8.2(@algolia/client-search@5.46.0)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3):
resolution: {integrity: sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==}
peerDependencies:
'@types/react': '>= 16.8.0 < 19.0.0'
@@ -932,6 +965,7 @@ packages:
'@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3)
'@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)
'@docsearch/css': 3.8.2
+ '@types/react': 18.3.27
algoliasearch: 5.46.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
@@ -5632,7 +5666,7 @@ packages:
optionalDependencies:
fsevents: 2.3.3
- /vitepress@1.6.4(@algolia/client-search@5.46.0)(@types/node@20.19.25)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3):
+ /vitepress@1.6.4(@algolia/client-search@5.46.0)(@types/node@20.19.25)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.3):
resolution: {integrity: sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==}
hasBin: true
peerDependencies:
@@ -5645,7 +5679,7 @@ packages:
optional: true
dependencies:
'@docsearch/css': 3.8.2
- '@docsearch/js': 3.8.2(@algolia/client-search@5.46.0)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3)
+ '@docsearch/js': 3.8.2(@algolia/client-search@5.46.0)(@types/react@18.3.27)(react-dom@18.3.1)(react@18.3.1)(search-insights@2.17.3)
'@iconify-json/simple-icons': 1.2.61
'@shikijs/core': 2.5.0
'@shikijs/transformers': 2.5.0
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index e34b522..465806e 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,6 +1,5 @@
packages:
- 'packages/**'
- - 'showcases/**'
- 'tests'
- 'docs'
diff --git a/showcases/index.html b/showcases/index.html
deleted file mode 100644
index 6834e2e..0000000
--- a/showcases/index.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
- Single-SPA + Vite Experiment
-
-
-
-
-
-
-
-
diff --git a/showcases/package.json b/showcases/package.json
deleted file mode 100644
index 035fb6e..0000000
--- a/showcases/package.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "name": "showcases",
- "version": "0.1.0",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "vite build",
- "preview": "vite preview"
- },
- "dependencies": {
- "@chakra-ui/react": "^2.8.2",
- "@emotion/react": "^11.11.0",
- "@emotion/styled": "^11.11.0",
- "@hookform/resolvers": "^3.9.0",
- "@mdi/font": "^7.4.47",
- "@mui/material": "^5.15.0",
- "@schepta/adapter-react": "workspace:*",
- "@schepta/adapter-vanilla": "workspace:*",
- "@schepta/adapter-vue": "workspace:*",
- "@schepta/core": "workspace:*",
- "@schepta/factory-react": "workspace:*",
- "@schepta/factory-vanilla": "workspace:*",
- "@schepta/factory-vue": "workspace:*",
- "@tanstack/react-router": "^1.159.5",
- "formik": "^2.4.6",
- "framer-motion": "^10.16.16",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
- "react-hook-form": "^7.52.2",
- "react-icons": "^5.0.0",
- "single-spa": "^6.0.1",
- "single-spa-react": "^6.0.0",
- "single-spa-vue": "^3.0.1",
- "vue": "^3.4.0",
- "vuetify": "^3.11.2"
- },
- "devDependencies": {
- "@types/react": "^18.2.47",
- "@types/react-dom": "^18.2.18",
- "@vitejs/plugin-react": "^4.2.1",
- "@vitejs/plugin-vue": "^5.0.0",
- "typescript": "^5.3.3",
- "vite": "^5.0.8",
- "vite-plugin-single-spa": "^1.1.0"
- }
-}
\ No newline at end of file
diff --git a/showcases/src/frameworks/react/App.tsx b/showcases/src/frameworks/react/App.tsx
deleted file mode 100644
index cbafa07..0000000
--- a/showcases/src/frameworks/react/App.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import React from "react";
-import { router } from "./router";
-import { RouterProvider } from "@tanstack/react-router";
-
-function App() {
- return ;
-}
-
-export default App;
diff --git a/showcases/src/frameworks/react/RootLayout.tsx b/showcases/src/frameworks/react/RootLayout.tsx
deleted file mode 100644
index ad4b357..0000000
--- a/showcases/src/frameworks/react/RootLayout.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-// react/RootLayout.tsx
-import React from 'react';
-import { Outlet } from '@tanstack/react-router';
-import { ScheptaProvider } from '@schepta/adapter-react';
-import { components } from './basic-ui/components/ComponentRegistry';
-import { Box, Container } from '@mui/material';
-import { ReactHeader } from './components/ReactHeader';
-
-export function RootLayout() {
- const labelMiddleware = (props: any) => {
- if (props.label) {
- return { ...props, label: `[Provider] ${props.label}` };
- }
- return props;
- };
-
- return (
-
-
-
-
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/showcases/src/frameworks/react/chakra-ui/pages/ChakraFormPage.tsx b/showcases/src/frameworks/react/chakra-ui/pages/ChakraFormPage.tsx
deleted file mode 100644
index 306fcd8..0000000
--- a/showcases/src/frameworks/react/chakra-ui/pages/ChakraFormPage.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from "react";
-import {
- ChakraProvider,
- Tabs,
- TabList,
- TabPanels,
- Tab,
- TabPanel,
- Box,
-} from "@chakra-ui/react";
-import { Form } from "../components/Form";
-import { FormSchema } from "@schepta/core";
-import simpleFormSchema from "../../../../../../instances/form/simple-form.json";
-import complexFormSchema from "../../../../../../instances/form/complex-form.json";
-
-export function ChakraFormPage() {
- const simpleSchema = simpleFormSchema as FormSchema;
- const complexSchema = complexFormSchema as FormSchema;
-
- return (
-
-
-
-
- SIMPLE FORM
- COMPLEX FORM
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/showcases/src/frameworks/react/components/Header.tsx b/showcases/src/frameworks/react/components/Header.tsx
deleted file mode 100644
index 86db2dc..0000000
--- a/showcases/src/frameworks/react/components/Header.tsx
+++ /dev/null
@@ -1,108 +0,0 @@
-import {
- AppBar,
- Box,
- Container,
- Link,
- Toolbar,
- Typography,
-} from "@mui/material";
-
-export function Header() {
- return (
-
-
-
-
- Single-SPA + Vite Experiment
-
-
-
-
- Home
-
-
- React
-
-
- Vue
-
-
- Vanilla
-
-
-
-
-
- );
-}
diff --git a/showcases/src/frameworks/react/components/ReactHeader.tsx b/showcases/src/frameworks/react/components/ReactHeader.tsx
deleted file mode 100644
index 00aaa70..0000000
--- a/showcases/src/frameworks/react/components/ReactHeader.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import React from 'react';
-import { Link, useRouterState } from '@tanstack/react-router';
-import {
- AppBar,
- Toolbar,
- Typography,
- Box,
- Container,
- Tabs,
- Tab,
-} from '@mui/material';
-import { FaReact } from 'react-icons/fa';
-import { SiChakraui, SiMui } from 'react-icons/si';
-
-const base = '/react';
-const navigationItems = [
- { path: `${base}/basic`, label: 'Basic UI', icon: },
- { path: `${base}/chakra-ui`, label: 'Chakra UI', icon: },
- { path: `${base}/material-ui`, label: 'Material UI', icon: },
-];
-
-export function ReactHeader() {
- const router = useRouterState();
- const currentPath = router.location.pathname;
-
- return (
-
-
-
-
- Schepta React Showcases
-
-
-
- {navigationItems.map((item) => (
-
- {item.label}
- {item.icon}
-
- }
- value={item.path}
- component={Link}
- to={item.path}
- />
- ))}
-
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/showcases/src/frameworks/react/index.css b/showcases/src/frameworks/react/index.css
deleted file mode 100644
index 83bfa71..0000000
--- a/showcases/src/frameworks/react/index.css
+++ /dev/null
@@ -1,18 +0,0 @@
-body {
- margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
- monospace;
-}
-
-*, *::before, *::after {
- box-sizing: border-box;
-}
-
diff --git a/showcases/src/frameworks/react/index.tsx b/showcases/src/frameworks/react/index.tsx
deleted file mode 100644
index 49a246a..0000000
--- a/showcases/src/frameworks/react/index.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import React from "react";
-import ReactDOMClient from "react-dom/client";
-import App from "./App";
-import './index.css';
-import singleSpaReact from "single-spa-react";
-import { HomePage } from "./pages/HomePage";
-
-export const lifecycles = singleSpaReact({
- React,
- ReactDOMClient,
- rootComponent: App,
- errorBoundary(err, info, props) {
- return (
-
- Something went wrong
- {err?.message}
-
- );
- },
-});
-
-export const homeLifecycles = singleSpaReact({
- React,
- ReactDOMClient,
- rootComponent: HomePage,
- errorBoundary(err, info, props) {
- return (
-
- Something went wrong
- {err?.message}
-
- );
- },
-});
\ No newline at end of file
diff --git a/showcases/src/frameworks/react/pages/HomePage.tsx b/showcases/src/frameworks/react/pages/HomePage.tsx
deleted file mode 100644
index e350df5..0000000
--- a/showcases/src/frameworks/react/pages/HomePage.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import React from "react";
-
-export function HomePage() {
- return (
-
-
- Bem-vindo ao Single-SPA + Vite Experiment
-
- Escolha um framework para ver a demonstração do Schepta:
-
-
- (e.currentTarget.style.transform = "translateY(-4px)")}
- onMouseOut={(e) => (e.currentTarget.style.transform = "translateY(0)")}
- >
- React
- Demonstração com React + Material-UI
-
- (e.currentTarget.style.transform = "translateY(-4px)")}
- onMouseOut={(e) => (e.currentTarget.style.transform = "translateY(0)")}
- >
- Vue
- Demonstração com Vue 3 Composition API
-
- (e.currentTarget.style.transform = "translateY(-4px)")}
- onMouseOut={(e) => (e.currentTarget.style.transform = "translateY(0)")}
- >
-
- Vanilla JS
-
- Demonstração com JavaScript puro
-
-
-
- );
-}
diff --git a/showcases/src/frameworks/react/pages/ReactFormPage.tsx b/showcases/src/frameworks/react/pages/ReactFormPage.tsx
deleted file mode 100644
index 4427d15..0000000
--- a/showcases/src/frameworks/react/pages/ReactFormPage.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import React, { useState } from "react";
-import { Tab, Tabs, Paper } from "@mui/material";
-import { FaReact } from "react-icons/fa";
-
-interface TabPanelProps {
- children?: React.ReactNode;
- index: number;
- value: number;
-}
-
-function TabPanel({ children, value, index }: TabPanelProps) {
- return (
-
- {value === index && children}
-
- );
-}
-
-export function ReactFormPage() {
- const [tabValue, setTabValue] = useState(0);
-
- const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
- setTabValue(newValue);
- };
-
- return (
-
-
-
- React Microfrontend - Schepta Forms
-
-
-
-
-
-
-
-
-
-
- Simple React Form
- Esta é uma demonstração básica do Schepta no React (monorepo unificado)
-
- ✅ Funcionando! Este microfrontend React está rodando dentro do shell principal.
-
-
-
-
- Complex React Form
- Aqui seria um formulário mais complexo com Schepta
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/showcases/src/frameworks/react/router.tsx b/showcases/src/frameworks/react/router.tsx
deleted file mode 100644
index ff5301e..0000000
--- a/showcases/src/frameworks/react/router.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-// react/router.tsx
-import {
- createRouter,
- createRoute,
- createRootRoute,
- Outlet,
- redirect,
-} from '@tanstack/react-router';
-import { BasicFormPage } from './basic-ui/pages/BasicFormPage';
-import { ChakraFormPage } from './chakra-ui/pages/ChakraFormPage';
-import { MaterialFormPage } from './material-ui/pages/MaterialFormPage';
-import { RootLayout } from './RootLayout';
-
-const rootRoute = createRootRoute({
- component: () => ,
-});
-
-const reactRoute = createRoute({
- getParentRoute: () => rootRoute,
- path: 'react',
- component: RootLayout,
-});
-
-const reactIndexRoute = createRoute({
- getParentRoute: () => reactRoute,
- path: '/',
- beforeLoad: () => {
- throw redirect({ to: '/react/basic' });
- },
-});
-
-const basicRoute = createRoute({
- getParentRoute: () => reactRoute,
- path: 'basic',
- component: BasicFormPage,
-});
-
-const chakraRoute = createRoute({
- getParentRoute: () => reactRoute,
- path: 'chakra-ui',
- component: ChakraFormPage,
-});
-
-const materialRoute = createRoute({
- getParentRoute: () => reactRoute,
- path: 'material-ui',
- component: MaterialFormPage,
-});
-
-const routeTree = rootRoute.addChildren([
- reactRoute.addChildren([
- reactIndexRoute,
- basicRoute,
- chakraRoute,
- materialRoute,
- ]),
-]);
-
-export const router = createRouter({ routeTree });
-
-declare module '@tanstack/react-router' {
- interface Register {
- router: typeof router;
- }
-}
diff --git a/showcases/src/frameworks/vue/components/VueFormPage.vue b/showcases/src/frameworks/vue/components/VueFormPage.vue
deleted file mode 100644
index 68b900e..0000000
--- a/showcases/src/frameworks/vue/components/VueFormPage.vue
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
- Vue Microfrontend - Schepta Forms
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/showcases/src/frameworks/vue/index.ts b/showcases/src/frameworks/vue/index.ts
deleted file mode 100644
index 36f5955..0000000
--- a/showcases/src/frameworks/vue/index.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { createApp, h } from 'vue';
-import VueFormPage from './components/VueFormPage.vue';
-import singleSpaVue from 'single-spa-vue';
-import { vuetify } from './plugins/vuetify';
-
-const lifecycles = singleSpaVue({
- createApp,
- appOptions: {
- render: () => h(VueFormPage),
- },
- handleInstance: (app) => {
- app.use(vuetify);
- },
-});
-
-export const { bootstrap, mount, unmount } = lifecycles;
\ No newline at end of file
diff --git a/showcases/src/main.ts b/showcases/src/main.ts
deleted file mode 100644
index 1fd2399..0000000
--- a/showcases/src/main.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { registerApplication, start } from 'single-spa';
-import ReactDOM from "react-dom/client";
-import { lifecycles as reactApp, homeLifecycles } from './frameworks/react';
-import React from 'react';
-import { Header } from './frameworks/react/components/Header';
-
-
-registerApplication({
- name: 'header',
- app: () => Promise.resolve({
- bootstrap: () => Promise.resolve(),
- mount: () => {
- const root = ReactDOM.createRoot(
- document.getElementById("header")!,
- );
- root.render(React.createElement(Header));
- return Promise.resolve();
- },
- unmount: () => {
- const container = document.getElementById('header');
- if (container) container.innerHTML = '';
- return Promise.resolve();
- }
- }),
- activeWhen: '/'
-});
-
-registerApplication({
- name: 'home',
- app: () => Promise.resolve(homeLifecycles),
- activeWhen: (location) => location.pathname === '/'
-});
-
-registerApplication({
- name: 'react',
- app: () => Promise.resolve(reactApp),
- activeWhen: (location) => location.pathname.startsWith('/react')
-});
-
-registerApplication({
- name: 'vue',
- app: () => import('./frameworks/vue'),
- activeWhen: (location) => location.pathname === '/vue'
-});
-
-registerApplication({
- name: 'vanilla',
- app: () => import('./vanilla'),
- activeWhen: (location) => location.pathname === '/vanilla',
- customProps: {
- domElementGetter: () => document.getElementById('vanilla')!,
- },
-});
-
-start();
\ No newline at end of file
diff --git a/showcases/src/vanilla/index.ts b/showcases/src/vanilla/index.ts
deleted file mode 100644
index c2b8a52..0000000
--- a/showcases/src/vanilla/index.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { singleSpaVanilla } from './singleSpaVanilla';
-import { createAppRoot } from './app';
-import { vanillaStyles } from './styles';
-import { attachTabBehavior } from './tabs';
-
-const lifecycles = singleSpaVanilla({
- render() {
- const el = createAppRoot();
- attachTabBehavior(el);
- return el;
- },
- styles: vanillaStyles,
-});
-
-export const { bootstrap, mount, unmount } = lifecycles;
diff --git a/showcases/src/vanilla/singleSpaVanilla.ts b/showcases/src/vanilla/singleSpaVanilla.ts
deleted file mode 100644
index 40acc4d..0000000
--- a/showcases/src/vanilla/singleSpaVanilla.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Helper for single-spa vanilla JS apps (no framework).
- * Returns bootstrap, mount, unmount using render + optional styles + afterMount.
- */
-
-export interface SingleSpaVanillaProps {
- name?: string;
- singleSpa?: unknown;
- mountParcel?: unknown;
- customProps?: Record;
- domElement?: HTMLElement;
- domElementGetter?(): HTMLElement;
-}
-
-export interface SingleSpaVanillaOptions {
- /** Returns the root DOM element to mount. */
- render(props: SingleSpaVanillaProps): HTMLElement;
- /** Optional CSS string injected into document.head on mount, removed on unmount. */
- styles?: string;
- /** Optional: run after the root element is appended (e.g. attach event listeners). */
- afterMount?(element: HTMLElement, props: SingleSpaVanillaProps): void;
-}
-
-export interface SingleSpaVanillaLifecycles {
- bootstrap(props: SingleSpaVanillaProps): Promise;
- mount(props: SingleSpaVanillaProps): Promise;
- unmount(props: SingleSpaVanillaProps): Promise;
-}
-
-export function singleSpaVanilla(options: SingleSpaVanillaOptions): SingleSpaVanillaLifecycles {
- let rootElement: HTMLElement | null = null;
- let styleElement: HTMLStyleElement | null = null;
-
- return {
- bootstrap(): Promise {
- return Promise.resolve();
- },
-
- mount(props: SingleSpaVanillaProps): Promise {
- const container =
- props.domElement ??
- (typeof props.domElementGetter === 'function' ? props.domElementGetter() : null);
-
- if (!container) {
- return Promise.resolve();
- }
-
- rootElement = options.render(props);
- container.appendChild(rootElement);
-
- if (options.styles) {
- styleElement = document.createElement('style');
- styleElement.textContent = options.styles;
- document.head.appendChild(styleElement);
- }
-
- options.afterMount?.(rootElement, props);
- return Promise.resolve();
- },
-
- unmount(): Promise {
- if (rootElement?.parentNode) {
- rootElement.parentNode.removeChild(rootElement);
- }
- rootElement = null;
-
- if (styleElement?.parentNode) {
- styleElement.parentNode.removeChild(styleElement);
- }
- styleElement = null;
-
- return Promise.resolve();
- },
- };
-}
diff --git a/showcases/tsconfig.json b/showcases/tsconfig.json
deleted file mode 100644
index e6a6f82..0000000
--- a/showcases/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "extends": "../tsconfig.base.json",
- "compilerOptions": {
- "outDir": "./dist",
- "rootDir": "./src",
- "jsx": "preserve",
- "paths": {}
- },
- "include": ["src/**/*"],
- "exclude": ["node_modules", "dist"]
-}
diff --git a/showcases/vercel.json b/showcases/vercel.json
deleted file mode 100644
index 0f32683..0000000
--- a/showcases/vercel.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
-}
diff --git a/showcases/vite.config.ts b/showcases/vite.config.ts
deleted file mode 100644
index 7aa675f..0000000
--- a/showcases/vite.config.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { defineConfig } from 'vite';
-import vitePluginSingleSpa from 'vite-plugin-single-spa';
-import react from '@vitejs/plugin-react';
-import vue from '@vitejs/plugin-vue';
-
-export default defineConfig({
- plugins: [
- react(),
- vue(),
- vitePluginSingleSpa({
- type: 'root',
- imo: '3.1.1'
- })
- ],
- server: {
- port: 3000
- },
- build: {
- rollupOptions: {
- output: {
- manualChunks(id) {
- // React core
- if (id.includes('node_modules/react/') || id.includes('node_modules/react-dom/')) {
- return 'react-vendor';
- }
- // Vue
- if (id.includes('node_modules/vue/') || id.includes('node_modules/@vue/')) {
- return 'vue-vendor';
- }
- // TanStack Router
- if (id.includes('node_modules/@tanstack/router')) {
- return 'router-vendor';
- }
- // single-spa
- if (id.includes('node_modules/single-spa')) {
- return 'single-spa-vendor';
- }
- // React Hook Form + @hookform (separate chunk avoids circular init; Formik stays in app bundle so React is available)
- if (id.includes('node_modules/react-hook-form') || id.includes('node_modules/@hookform')) {
- return 'rhf-vendor';
- }
- }
- }
- },
- chunkSizeWarningLimit: 700
- }
-});
\ No newline at end of file
diff --git a/tests/e2e/react.spec.ts b/tests/e2e/react.spec.ts
index 2611e6c..94199b2 100644
--- a/tests/e2e/react.spec.ts
+++ b/tests/e2e/react.spec.ts
@@ -6,7 +6,7 @@ import { extractFieldsFromSchema, FormSchema } from '@schepta/core';
test.describe('React Form Factory', () => {
test.beforeEach(async ({ page, baseURL }) => {
- await page.goto(`${baseURL}/basic`);
+ await page.goto(`${baseURL}`);
});
test('should render simple form', async ({ page }) => {
@@ -165,7 +165,7 @@ test.describe('React Form Factory', () => {
test.describe('React Hook Form Integration', () => {
test.beforeEach(async ({ page, baseURL }) => {
- await page.goto(`${baseURL}/basic`);
+ await page.goto(`${baseURL}`);
// Navigate to RHF form tab
await page.click('[data-test-id*="rhf-form-tab"]');
await page.waitForSelector('[data-test-id^="FormContainer"]', { timeout: 10000 });
@@ -200,7 +200,7 @@ test.describe('React Hook Form Integration', () => {
test.describe('Formik Integration', () => {
test.beforeEach(async ({ page, baseURL }) => {
- await page.goto(`${baseURL}/basic`);
+ await page.goto(`${baseURL}`);
// Navigate to Formik form tab
await page.click('[data-test-id*="formik-form-tab"]');
await page.waitForSelector('[data-test-id^="FormContainer"]', { timeout: 10000 });
diff --git a/tests/playwright.config.ts b/tests/playwright.config.ts
index ad1ad77..91c13cf 100644
--- a/tests/playwright.config.ts
+++ b/tests/playwright.config.ts
@@ -18,13 +18,18 @@ export default defineConfig({
// Output folders for test artifacts
outputDir: '../test-results',
snapshotDir: '../test-screenshots',
+ webServer: {
+ command: 'cd ../docs && pnpm dev',
+ port: 5173,
+ reuseExistingServer: true,
+ },
projects: [
{
name: 'react',
testMatch: '**/*react.spec.ts',
use: {
...devices['Desktop Chrome'],
- baseURL: 'https://show.schepta.org/react',
+ baseURL: 'http://localhost:5173/en-US/showcases/react',
},
},
{
@@ -32,7 +37,7 @@ export default defineConfig({
testMatch: '**/*vue.spec.ts',
use: {
...devices['Desktop Chrome'],
- baseURL: 'https://show.schepta.org/vue',
+ baseURL: 'http://localhost:5173/en-US/showcases/vue',
},
},
{
@@ -40,7 +45,7 @@ export default defineConfig({
testMatch: '**/*vanilla.spec.ts',
use: {
...devices['Desktop Chrome'],
- baseURL: 'https://show.schepta.org/vanilla',
+ baseURL: 'http://localhost:5173/en-US/showcases/vanilla',
},
},
],