chore(apps): Setup prettier + eslint for all our apps (#254)

* chore(apps): setup prettier + eslint for all our apps

* fix(docs): Fixed the use of implicit any type

* chore(apps): Added .eslintignore files
This commit is contained in:
Lalit 2023-01-14 15:10:40 +05:30 committed by GitHub
parent 0abe83aea9
commit f79ce72a1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 1349 additions and 1265 deletions

2
apps/demo/.eslintignore Normal file
View file

@ -0,0 +1,2 @@
dist
node_modules

5
apps/demo/.eslintrc.cjs Normal file
View file

@ -0,0 +1,5 @@
/** @type {import("@types/eslint").Linter.Config} */
module.exports = {
root: true,
extends: ['@astro-reactive/eslint-config-custom'],
};

24
apps/demo/.prettierrc.cjs Normal file
View file

@ -0,0 +1,24 @@
/** @type {import("@types/prettier").Options} */
module.exports = {
printWidth: 100,
semi: true,
singleQuote: true,
tabWidth: 2,
trailingComma: 'es5',
useTabs: true,
plugins: ['../../node_modules/prettier-plugin-astro'],
overrides: [
{
files: '*.astro',
options: {
parser: 'astro',
},
},
{
files: ['.*', '*.json', '*.md', '*.toml', '*.yml'],
options: {
useTabs: false,
},
},
],
};

View file

@ -5,4 +5,3 @@
Start the dev server by running: `npm start` Start the dev server by running: `npm start`
👉 _[Join our contributors!](https://github.com/astro-reactive/astro-reactive/blob/main/CONTRIBUTING.md)_ 👉 _[Join our contributors!](https://github.com/astro-reactive/astro-reactive/blob/main/CONTRIBUTING.md)_

View file

@ -1,4 +1,4 @@
import { defineConfig } from "astro/config"; import { defineConfig } from 'astro/config';
// https://astro.build/config // https://astro.build/config
export default defineConfig({}); export default defineConfig({});

View file

@ -12,10 +12,12 @@
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro", "astro": "astro",
"format": "prettier -w .",
"lint": "eslint . --ext .ts,.js",
"lint:fix": "eslint --fix . --ext .ts,.js",
"clean": "rimraf node_modules .turbo dist" "clean": "rimraf node_modules .turbo dist"
}, },
"dependencies": { "dependencies": {
"@astro-reactive/tsconfig": "*",
"@astro-reactive/form": "*", "@astro-reactive/form": "*",
"@astro-reactive/validator": "*", "@astro-reactive/validator": "*",
"astro": "^1.6.5" "astro": "^1.6.5"
@ -31,7 +33,13 @@
}, },
"homepage": "https://github.com/astro-reactive/astro-reactive#readme", "homepage": "https://github.com/astro-reactive/astro-reactive#readme",
"devDependencies": { "devDependencies": {
"@astro-reactive/eslint-config-custom": "*",
"@astro-reactive/tsconfig": "*",
"@types/eslint": "^8.4.10",
"@types/prettier": "^2.7.2",
"eslint": "^8.31.0",
"prettier": "^2.8.3",
"prettier-plugin-astro": "^0.7.2",
"rimraf": "^3.0.2" "rimraf": "^3.0.2"
} }
} }

View file

@ -1,11 +1,11 @@
--- ---
import Nav from "./Nav.astro"; import Nav from './Nav.astro';
export interface Props { export interface Props {
title: string; title: string;
theme?: "dark" | "light"; theme?: 'dark' | 'light';
} }
const { theme = "light", title } = Astro.props; const { theme = 'light', title } = Astro.props;
--- ---
<html lang="en" class={theme}> <html lang="en" class={theme}>

View file

@ -1,10 +1,10 @@
--- ---
const links = [ const links = [
{ label: "Home", url: "/" }, { label: 'Home', url: '/' },
{ label: "Pizza Delivery", url: "/pizza-delivery" }, { label: 'Pizza Delivery', url: '/pizza-delivery' },
{ label: "Job Application", url: "/job-application" }, { label: 'Job Application', url: '/job-application' },
{ label: "Docs Examples", url: "/examples" }, { label: 'Docs Examples', url: '/examples' },
{ label: "Experimental", url: "/experimental" }, { label: 'Experimental', url: '/experimental' },
]; ];
--- ---
@ -14,7 +14,7 @@ const links = [
<style> <style>
nav a::after { nav a::after {
content: " | "; content: ' | ';
} }
nav a { nav a {
text-decoration: none; text-decoration: none;

View file

@ -1,69 +1,69 @@
--- ---
import type { Submit } from "@astro-reactive/common"; import type { Submit } from '@astro-reactive/common';
import Form, { FormGroup } from "@astro-reactive/form"; import Form, { FormGroup } from '@astro-reactive/form';
import Layout from "../../components/Layout.astro"; import Layout from '../../components/Layout.astro';
const simpleForm = new FormGroup([ const simpleForm = new FormGroup([
{ {
name: "username", name: 'username',
label: "Username", label: 'Username',
value: "awesome_dev", value: 'awesome_dev',
}, },
{ {
name: "comment", name: 'comment',
label: "Feedback", label: 'Feedback',
type: "textarea", type: 'textarea',
value: "Nice!", value: 'Nice!',
}, },
{ {
name: "size", name: 'size',
label: "Size", label: 'Size',
type: "dropdown", type: 'dropdown',
options: ["S", "M", "L", "XL", "XXL"], options: ['S', 'M', 'L', 'XL', 'XXL'],
placeholder: "-- Please choose an option --", placeholder: '-- Please choose an option --',
}, },
]); ]);
const nameForm = new FormGroup( const nameForm = new FormGroup(
[ [
{ {
name: "firstName", name: 'firstName',
label: "First Name", label: 'First Name',
value: "John", value: 'John',
}, },
{ {
name: "lastName", name: 'lastName',
label: "Last Name", label: 'Last Name',
value: "Doe", value: 'Doe',
}, },
], ],
"Name" 'Name'
); );
const skills = new FormGroup( const skills = new FormGroup(
[ [
{ {
name: "JavaScript", name: 'JavaScript',
type: "checkbox", type: 'checkbox',
label: "JavaScript", label: 'JavaScript',
}, },
{ {
name: "TypeScript", name: 'TypeScript',
type: "checkbox", type: 'checkbox',
label: "TypeScript", label: 'TypeScript',
}, },
{ {
name: "React", name: 'React',
type: "checkbox", type: 'checkbox',
label: "React", label: 'React',
}, },
{ {
name: "Vue", name: 'Vue',
type: "checkbox", type: 'checkbox',
label: "Vue", label: 'Vue',
}, },
], ],
"Skills" 'Skills'
); );
/** /**
@ -71,8 +71,8 @@ const skills = new FormGroup(
*/ */
const submitControl: Submit = { const submitControl: Submit = {
name: "submit", name: 'submit',
type: "submit", type: 'submit',
}; };
--- ---

View file

@ -1,5 +1,5 @@
--- ---
import Layout from "../../components/Layout.astro"; import Layout from '../../components/Layout.astro';
--- ---
<Layout title="Docs Examples"> <Layout title="Docs Examples">

View file

@ -1,5 +1,5 @@
--- ---
import Layout from "../../components/Layout.astro"; import Layout from '../../components/Layout.astro';
const Counter = { const Counter = {
count: 0, count: 0,
increment() { increment() {

View file

@ -1,5 +1,5 @@
--- ---
import Layout from "../../components/Layout.astro"; import Layout from '../../components/Layout.astro';
--- ---
<Layout title="Experimental Demos"> <Layout title="Experimental Demos">

View file

@ -1,104 +1,100 @@
--- ---
import Form, { import Form, { ControlConfig, FormGroup, FormControl } from '@astro-reactive/form';
ControlConfig, import type { Submit } from '@astro-reactive/common/types';
FormGroup, import { Validators } from '@astro-reactive/validator';
FormControl, import Layout from '../components/Layout.astro';
} from "@astro-reactive/form";
import type { Submit } from "@astro-reactive/common/types";
import { Validators } from "@astro-reactive/validator";
import Layout from "../components/Layout.astro";
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "username", name: 'username',
label: "Username", label: 'Username',
validators: [ validators: [
{ {
validator: Validators.required, validator: Validators.required,
category: "info", category: 'info',
}, },
], ],
}, },
{ {
name: "email", name: 'email',
label: "Email", label: 'Email',
validators: [ validators: [
{ validator: Validators.required }, { validator: Validators.required },
{ validator: Validators.email, category: "warn" }, { validator: Validators.email, category: 'warn' },
], ],
}, },
{ {
name: "password", name: 'password',
label: "Password", label: 'Password',
type: "password", type: 'password',
validators: [Validators.required, Validators.minLength(8)], validators: [Validators.required, Validators.minLength(8)],
}, },
{ {
name: "rating", name: 'rating',
label: "Rating", label: 'Rating',
type: "radio", type: 'radio',
value: "5", value: '5',
options: ["1", "2", "3", "4", "5"], options: ['1', '2', '3', '4', '5'],
}, },
{ {
name: "agreement", name: 'agreement',
label: "Agreement", label: 'Agreement',
type: "radio", type: 'radio',
value: "yes", value: 'yes',
options: [ options: [
{ label: "Agree", value: "yes" }, { label: 'Agree', value: 'yes' },
{ label: "Disagree", value: "no" }, { label: 'Disagree', value: 'no' },
], ],
}, },
{ {
name: "size", name: 'size',
label: "Size", label: 'Size',
type: "dropdown", type: 'dropdown',
options: ["S", "M", "L", "XL", "XXL"], options: ['S', 'M', 'L', 'XL', 'XXL'],
placeholder: "-- Please choose an option --", placeholder: '-- Please choose an option --',
}, },
{ {
name: "comment", name: 'comment',
label: "Feedback", label: 'Feedback',
type: "textarea", type: 'textarea',
value: "Nice!", value: 'Nice!',
}, },
{ {
name: "terms", name: 'terms',
label: "Terms and Conditions", label: 'Terms and Conditions',
type: "checkbox", type: 'checkbox',
validators: [Validators.requiredChecked], validators: [Validators.requiredChecked],
}, },
]); ]);
form.name = "Simple Form"; form.name = 'Simple Form';
const config: ControlConfig = { const config: ControlConfig = {
type: "checkbox", type: 'checkbox',
name: "is-awesome", name: 'is-awesome',
label: "is Awesome?", label: 'is Awesome?',
}; };
// insert a control // insert a control
form.controls.push(new FormControl(config)); form.controls.push(new FormControl(config));
// get the FormControl object // get the FormControl object
const userNameControl = form.get("username"); const userNameControl = form.get('username');
// set values dynamically // set values dynamically
userNameControl?.setValue("RAMOOOON"); userNameControl?.setValue('RAMOOOON');
form.get("is-awesome")?.setValue("checked"); form.get('is-awesome')?.setValue('checked');
// setting an invalid value will cause errors as server-rendered // setting an invalid value will cause errors as server-rendered
form.get("email")?.setValue("invalid-email"); form.get('email')?.setValue('invalid-email');
// switch between light and dark mode // switch between light and dark mode
const title = "Form Demo"; const title = 'Form Demo';
const theme = "dark"; const theme = 'dark';
const submit: Submit = { const submit: Submit = {
name: "submit", name: 'submit',
type: "submit", type: 'submit',
value: "Let's go!", value: "Let's go!",
}; };
--- ---

View file

@ -1,127 +1,111 @@
--- ---
import Form, { import Form, { ControlConfig, FormControl, FormGroup } from '@astro-reactive/form';
ControlConfig, import { Validators } from '@astro-reactive/validator';
FormControl, import type { Submit } from '@astro-reactive/common';
FormGroup, import Layout from '../components/Layout.astro';
} from "@astro-reactive/form";
import { Validators } from "@astro-reactive/validator";
import type { Submit } from "@astro-reactive/common";
import Layout from "../components/Layout.astro";
const infoForm = new FormGroup([ const infoForm = new FormGroup([
{ {
name: "firstName", name: 'firstName',
label: "First Name", label: 'First Name',
placeholder: "ex. John", placeholder: 'ex. John',
validators: [Validators.required], validators: [Validators.required],
}, },
{ {
name: "lastName", name: 'lastName',
label: "Last Name", label: 'Last Name',
placeholder: "ex. Doe", placeholder: 'ex. Doe',
validators: [Validators.required], validators: [Validators.required],
}, },
{ {
name: "email", name: 'email',
label: "Email", label: 'Email',
placeholder: "ex. john.doe@email.com", placeholder: 'ex. john.doe@email.com',
validators: [Validators.email, Validators.required], validators: [Validators.email, Validators.required],
}, },
{ {
name: "whyHire", name: 'whyHire',
label: "Why should we hire you?", label: 'Why should we hire you?',
}, },
{ {
name: "country", name: 'country',
label: "Country of Residence", label: 'Country of Residence',
type: "dropdown", type: 'dropdown',
options: [ options: ['U.S.A', 'Canada', 'Mexico', 'Cuba', 'Guatamala', 'Greenland', 'Haiti'],
"U.S.A", placeholder: 'Choose Your Country',
"Canada",
"Mexico",
"Cuba",
"Guatamala",
"Greenland",
"Haiti",
],
placeholder: "Choose Your Country",
}, },
{ {
name: "eligible", name: 'eligible',
label: "Are you eligible to work?", label: 'Are you eligible to work?',
type: "radio", type: 'radio',
options: [ options: [
{ label: "Yes", value: "yes" }, { label: 'Yes', value: 'yes' },
{ label: "No", value: "no" }, { label: 'No', value: 'no' },
], ],
}, },
]); ]);
const skillsForm = new FormGroup([ const skillsForm = new FormGroup([
{ {
name: "js", name: 'js',
label: "Javascript", label: 'Javascript',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "java", name: 'java',
label: "Java", label: 'Java',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "astro", name: 'astro',
label: "Astro", label: 'Astro',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "cpp", name: 'cpp',
label: "C/C++", label: 'C/C++',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "sql", name: 'sql',
label: "SQL", label: 'SQL',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "devops", name: 'devops',
label: "DevOps", label: 'DevOps',
type: "checkbox", type: 'checkbox',
}, },
]); ]);
const resume: ControlConfig = { const resume: ControlConfig = {
name: "resume", name: 'resume',
label: "Upload Resume", label: 'Upload Resume',
type: "file", type: 'file',
}; };
const submit: Submit = { const submit: Submit = {
name: "submit", name: 'submit',
type: "submit", type: 'submit',
value: "Let's go!", value: "Let's go!",
}; };
const values = { const values = {
firstName: "James", firstName: 'James',
lastName: "Bond", lastName: 'Bond',
email: "james.bond@gmail.com", email: 'james.bond@gmail.com',
country: "U.S.A", country: 'U.S.A',
eligible: "yes", eligible: 'yes',
}; };
infoForm.setValue(values); infoForm.setValue(values);
infoForm.name = "Application Form"; infoForm.name = 'Application Form';
skillsForm.name = "Skills"; skillsForm.name = 'Skills';
skillsForm.controls.push(new FormControl(resume)); skillsForm.controls.push(new FormControl(resume));
--- ---
<Layout title="Programmer Job Application"> <Layout title="Programmer Job Application">
<Form <Form showValidationHints formGroups={[infoForm, skillsForm]} submitControl={submit} />
showValidationHints
formGroups={[infoForm, skillsForm]}
submitControl={submit}
/>
</Layout> </Layout>

View file

@ -1,94 +1,94 @@
--- ---
import Form, { FormGroup } from "@astro-reactive/form"; import Form, { FormGroup } from '@astro-reactive/form';
import { Validators } from "@astro-reactive/validator"; import { Validators } from '@astro-reactive/validator';
import Layout from "../components/Layout.astro"; import Layout from '../components/Layout.astro';
const baseForm = new FormGroup([ const baseForm = new FormGroup([
{ {
name: "crust", name: 'crust',
label: "Crust", label: 'Crust',
type: "radio", type: 'radio',
options: [{ label: "Garlic", value: "garlic" }], options: [{ label: 'Garlic', value: 'garlic' }],
}, },
{ {
name: "size", name: 'size',
label: "Size", label: 'Size',
type: "radio", type: 'radio',
options: ["Small", "Medium", "Large"], options: ['Small', 'Medium', 'Large'],
}, },
{ {
name: "sauce", name: 'sauce',
label: "Sauce", label: 'Sauce',
type: "radio", type: 'radio',
options: ["Tomato", "Barbeque"], options: ['Tomato', 'Barbeque'],
}, },
]); ]);
const toppingsForm = new FormGroup([ const toppingsForm = new FormGroup([
{ {
name: "mushrooms", name: 'mushrooms',
label: "Mushrooms", label: 'Mushrooms',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "extraCheese", name: 'extraCheese',
label: "Extra Cheese", label: 'Extra Cheese',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "onions", name: 'onions',
label: "Onions", label: 'Onions',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "peppers", name: 'peppers',
label: "Peppers", label: 'Peppers',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "pepperoni", name: 'pepperoni',
label: "Pepperoni", label: 'Pepperoni',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "sausage", name: 'sausage',
label: "Sausage", label: 'Sausage',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "chicken", name: 'chicken',
label: "Chicken", label: 'Chicken',
type: "checkbox", type: 'checkbox',
}, },
{ {
name: "pineapple", name: 'pineapple',
label: "Pineapple", label: 'Pineapple',
type: "checkbox", type: 'checkbox',
}, },
]); ]);
const infoForm = new FormGroup([ const infoForm = new FormGroup([
{ {
name: "name", name: 'name',
label: "Name", label: 'Name',
validators: [Validators.required], validators: [Validators.required],
}, },
{ {
name: "address", name: 'address',
label: "Delivery Address", label: 'Delivery Address',
validators: [Validators.required], validators: [Validators.required],
}, },
{ {
name: "contact", name: 'contact',
label: "Contact Number", label: 'Contact Number',
validators: [Validators.required], validators: [Validators.required],
}, },
]); ]);
baseForm.name = "Base"; baseForm.name = 'Base';
toppingsForm.name = "Toppings"; toppingsForm.name = 'Toppings';
infoForm.name = "Customer Info"; infoForm.name = 'Customer Info';
infoForm.get("contact")?.setValidators([Validators.minLength(9)]); infoForm.get('contact')?.setValidators([Validators.minLength(9)]);
--- ---
<Layout title="Pizza Form Demo"> <Layout title="Pizza Form Demo">

2
apps/docs/.eslintignore Normal file
View file

@ -0,0 +1,2 @@
dist
node_modules

5
apps/docs/.eslintrc.cjs Normal file
View file

@ -0,0 +1,5 @@
/** @type {import("@types/eslint").Linter.Config} */
module.exports = {
root: true,
extends: ['@astro-reactive/eslint-config-custom'],
};

24
apps/docs/.prettierrc.cjs Normal file
View file

@ -0,0 +1,24 @@
/** @type {import("@types/prettier").Options} */
module.exports = {
printWidth: 100,
semi: true,
singleQuote: true,
tabWidth: 2,
trailingComma: "es5",
useTabs: true,
plugins: ["../../node_modules/prettier-plugin-astro"],
overrides: [
{
files: "*.astro",
options: {
parser: "astro",
},
},
{
files: [".*", "*.json", "*.md", "*.toml", "*.yml"],
options: {
useTabs: false,
},
},
],
};

View file

@ -5,4 +5,3 @@
Start the dev server by running: `npm run docs` Start the dev server by running: `npm run docs`
👉 _[Join our contributors!](https://github.com/astro-reactive/astro-reactive/blob/main/CONTRIBUTING.md)_ 👉 _[Join our contributors!](https://github.com/astro-reactive/astro-reactive/blob/main/CONTRIBUTING.md)_

View file

@ -11,6 +11,9 @@
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro", "astro": "astro",
"format": "prettier -w .",
"lint": "eslint . --ext .ts,.js",
"lint:fix": "eslint --fix . --ext .ts,.js",
"clean": "rimraf node_modules .turbo dist" "clean": "rimraf node_modules .turbo dist"
}, },
"dependencies": { "dependencies": {
@ -24,7 +27,6 @@
"@types/react-dom": "^18.0.0", "@types/react-dom": "^18.0.0",
"astro": "^1.4.4", "astro": "^1.4.4",
"preact": "^10.7.3", "preact": "^10.7.3",
"prettier-plugin-astro": "^0.7.0",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0" "react-dom": "^18.1.0"
}, },
@ -41,7 +43,13 @@
}, },
"homepage": "https://github.com/astro-reactive/astro-reactive#readme", "homepage": "https://github.com/astro-reactive/astro-reactive#readme",
"devDependencies": { "devDependencies": {
"@astro-reactive/eslint-config-custom": "*",
"@astro-reactive/tsconfig": "*",
"@types/eslint": "^8.4.10",
"@types/prettier": "^2.7.2",
"eslint": "^8.31.0",
"prettier": "^2.8.3",
"prettier-plugin-astro": "^0.7.2",
"rimraf": "^3.0.2" "rimraf": "^3.0.2"
} }
} }

View file

@ -1,3 +1,4 @@
// eslint-disable-next-line no-undef
Array.from(document.getElementsByTagName('pre')).forEach((element) => { Array.from(document.getElementsByTagName('pre')).forEach((element) => {
element.setAttribute('tabindex', '0'); element.setAttribute('tabindex', '0');
}); });

View file

@ -17,20 +17,20 @@ type Commit = {
async function getCommits(url: string) { async function getCommits(url: string) {
try { try {
const token = import.meta.env.SNOWPACK_PUBLIC_GITHUB_TOKEN ?? "hello"; const token = import.meta.env.SNOWPACK_PUBLIC_GITHUB_TOKEN ?? 'hello';
if (!token) { if (!token) {
throw new Error( throw new Error(
'Cannot find "SNOWPACK_PUBLIC_GITHUB_TOKEN" used for escaping rate-limiting.' 'Cannot find "SNOWPACK_PUBLIC_GITHUB_TOKEN" used for escaping rate-limiting.'
); );
} }
const auth = `Basic ${Buffer.from(token, "binary").toString("base64")}`; const auth = `Basic ${Buffer.from(token, 'binary').toString('base64')}`;
const res = await fetch(url, { const res = await fetch(url, {
method: "GET", method: 'GET',
headers: { headers: {
Authorization: auth, Authorization: auth,
"User-Agent": "astro-docs/1.0", 'User-Agent': 'astro-docs/1.0',
}, },
}); });
@ -52,7 +52,7 @@ async function getCommits(url: string) {
} }
function removeDups(arr: Commit[]) { function removeDups(arr: Commit[]) {
const map = new Map<string, Commit["author"]>(); const map = new Map<string, Commit['author']>();
for (let item of arr) { for (let item of arr) {
const author = item.author; const author = item.author;
@ -71,10 +71,7 @@ const additionalContributors = unique.length - recentContributors.length; // lis
<!-- Thanks to @5t3ph for https://smolcss.dev/#smol-avatar-list! --> <!-- Thanks to @5t3ph for https://smolcss.dev/#smol-avatar-list! -->
<div class="contributors"> <div class="contributors">
<ul <ul class="avatar-list" style={`--avatar-count: ${recentContributors.length}`}>
class="avatar-list"
style={`--avatar-count: ${recentContributors.length}`}
>
{ {
recentContributors.map((item) => ( recentContributors.map((item) => (
<li> <li>
@ -94,10 +91,8 @@ const additionalContributors = unique.length - recentContributors.length; // lis
{ {
additionalContributors > 0 && ( additionalContributors > 0 && (
<span> <span>
<a <a href={commitsURL}>{`and ${additionalContributors} additional contributor${
href={commitsURL} additionalContributors > 1 ? 's' : ''
>{`and ${additionalContributors} additional contributor${
additionalContributors > 1 ? "s" : ""
}.`}</a> }.`}</a>
</span> </span>
) )
@ -115,10 +110,7 @@ const additionalContributors = unique.length - recentContributors.length; // lis
/* Default to displaying most of the avatar to /* Default to displaying most of the avatar to
enable easier access on touch devices, ensuring enable easier access on touch devices, ensuring
the WCAG touch target size is met or exceeded */ the WCAG touch target size is met or exceeded */
grid-template-columns: repeat( grid-template-columns: repeat(var(--avatar-count), max(44px, calc(var(--avatar-size) / 1.15)));
var(--avatar-count),
max(44px, calc(var(--avatar-size) / 1.15))
);
/* `padding` matches added visual dimensions of /* `padding` matches added visual dimensions of
the `box-shadow` to help create a more accurate the `box-shadow` to help create a more accurate
computed component size */ computed component size */
@ -130,10 +122,7 @@ const additionalContributors = unique.length - recentContributors.length; // lis
.avatar-list { .avatar-list {
/* We create 1 extra cell to enable the computed /* We create 1 extra cell to enable the computed
width to match the final visual width */ width to match the final visual width */
grid-template-columns: repeat( grid-template-columns: repeat(calc(var(--avatar-count) + 1), calc(var(--avatar-size) / 1.75));
calc(var(--avatar-count) + 1),
calc(var(--avatar-size) / 1.75)
);
} }
} }

View file

@ -21,9 +21,7 @@ import '../styles/index.css';
/> />
<!-- Scrollable a11y code helper --> <!-- Scrollable a11y code helper -->
<script src="/make-scrollable-code-focusable.js" is:inline> <script src="/make-scrollable-code-focusable.js" is:inline></script>
</script>
<!-- This is intentionally inlined to avoid FOUC --> <!-- This is intentionally inlined to avoid FOUC -->
<script is:inline> <script is:inline>

View file

@ -1,11 +1,11 @@
--- ---
import { getLanguageFromURL, KNOWN_LANGUAGE_CODES } from "../../languages"; import { getLanguageFromURL, KNOWN_LANGUAGE_CODES } from '../../languages';
import ThemeToggleButton from "./ThemeToggleButton"; import ThemeToggleButton from './ThemeToggleButton';
import * as CONFIG from "../../config"; import * as CONFIG from '../../config';
// import AstroLogo from "./AstroLogo.astro"; // import AstroLogo from "./AstroLogo.astro";
import SkipToContent from "./SkipToContent.astro"; import SkipToContent from './SkipToContent.astro';
import SidebarToggle from "./SidebarToggle"; import SidebarToggle from './SidebarToggle';
import LanguageSelect from "./LanguageSelect"; import LanguageSelect from './LanguageSelect';
// import Search from "./Search"; // import Search from "./Search";
type Props = { type Props = {
@ -24,15 +24,11 @@ const lang = getLanguageFromURL(currentPage);
</div> </div>
<div class="logo flex"> <div class="logo flex">
<a href="/"> <a href="/">
<h1>{CONFIG.SITE.title ?? "Documentation"}</h1> <h1>{CONFIG.SITE.title ?? 'Documentation'}</h1>
</a> </a>
</div> </div>
<div style="flex-grow: 1;"></div> <div style="flex-grow: 1;"></div>
{ {KNOWN_LANGUAGE_CODES.length > 1 && <LanguageSelect lang={lang} client:idle />}
KNOWN_LANGUAGE_CODES.length > 1 && (
<LanguageSelect lang={lang} client:idle />
)
}
<!-- TODO: enable search --> <!-- TODO: enable search -->
<!-- <div class="search-item"> <!-- <div class="search-item">
<Search client:idle /> <Search client:idle />

View file

@ -28,7 +28,7 @@ export default function Search() {
}, [setIsOpen]); }, [setIsOpen]);
const onInput = useCallback( const onInput = useCallback(
(e) => { (e: KeyboardEvent) => {
setIsOpen(true); setIsOpen(true);
setInitialQuery(e.key); setInitialQuery(e.key);
}, },

View file

@ -1,13 +1,13 @@
--- ---
import { getLanguageFromURL } from "../../languages"; import { getLanguageFromURL } from '../../languages';
import { SIDEBAR } from "../../config"; import { SIDEBAR } from '../../config';
type Props = { type Props = {
currentPage: string; currentPage: string;
}; };
const { currentPage } = Astro.props as Props; const { currentPage } = Astro.props as Props;
const currentPageMatch = currentPage.endsWith("/") const currentPageMatch = currentPage.endsWith('/')
? currentPage.slice(1, -1) ? currentPage.slice(1, -1)
: currentPage.slice(1); : currentPage.slice(1);
const langCode = getLanguageFromURL(currentPage); const langCode = getLanguageFromURL(currentPage);
@ -26,12 +26,7 @@ const sidebar = SIDEBAR[langCode];
const url = Astro.site?.pathname + child.link; const url = Astro.site?.pathname + child.link;
return ( return (
<li class="nav-link"> <li class="nav-link">
<a <a href={url} aria-current={currentPageMatch === child.link ? 'page' : false}>
href={url}
aria-current={
currentPageMatch === child.link ? "page" : false
}
>
{child.text} {child.text}
</a> </a>
</li> </li>
@ -46,10 +41,10 @@ const sidebar = SIDEBAR[langCode];
</nav> </nav>
<script is:inline> <script is:inline>
window.addEventListener("DOMContentLoaded", () => { window.addEventListener('DOMContentLoaded', () => {
var target = document.querySelector('[aria-current="page"]'); var target = document.querySelector('[aria-current="page"]');
if (target && target.offsetTop > window.innerHeight - 100) { if (target && target.offsetTop > window.innerHeight - 100) {
document.querySelector(".nav-groups").scrollTop = target.offsetTop; document.querySelector('.nav-groups').scrollTop = target.offsetTop;
} }
}); });
</script> </script>
@ -104,7 +99,7 @@ const sidebar = SIDEBAR[langCode];
background-color: var(--theme-bg-hover); background-color: var(--theme-bg-hover);
} }
.nav-link a[aria-current="page"] { .nav-link a[aria-current='page'] {
color: var(--theme-text-accent); color: var(--theme-text-accent);
background-color: var(--theme-bg-accent); background-color: var(--theme-bg-accent);
font-weight: 600; font-weight: 600;
@ -118,7 +113,7 @@ const sidebar = SIDEBAR[langCode];
</style> </style>
<style is:global> <style is:global>
:root.theme-dark .nav-link a[aria-current="page"] { :root.theme-dark .nav-link a[aria-current='page'] {
color: hsla(var(--color-base-white), 100%, 1); color: hsla(var(--color-base-white), 100%, 1);
} }
</style> </style>

View file

@ -1,8 +1,8 @@
--- ---
import type { Frontmatter } from "../../config"; import type { Frontmatter } from '../../config';
import MoreMenu from "../RightSidebar/MoreMenu.astro"; import MoreMenu from '../RightSidebar/MoreMenu.astro';
import TableOfContents from "../RightSidebar/TableOfContents"; import TableOfContents from '../RightSidebar/TableOfContents';
import type { MarkdownHeading } from "astro"; import type { MarkdownHeading } from 'astro';
type Props = { type Props = {
frontmatter: Frontmatter; frontmatter: Frontmatter;

View file

@ -1,5 +1,5 @@
--- ---
import * as CONFIG from "../../config"; import * as CONFIG from '../../config';
type Props = { type Props = {
editHref: string; editHref: string;

View file

@ -1,16 +1,15 @@
export const SITE = { export const SITE = {
title: "Astro Reactive Docs", title: 'Astro Reactive Docs',
description: description: 'Let your data build your UI with native Astro components and architecture.',
"Let your data build your UI with native Astro components and architecture.", defaultLanguage: 'en_US',
defaultLanguage: "en_US",
}; };
export const OPEN_GRAPH = { export const OPEN_GRAPH = {
image: { image: {
src: "https://github.com/astro-reactive/astro-reactive/blob/main/.github/assets/astro-reactive-library-cover.png?raw=true", src: 'https://github.com/astro-reactive/astro-reactive/blob/main/.github/assets/astro-reactive-library-cover.png?raw=true',
alt: "astro logo and astro reactive library text on a starry expanse of space", alt: 'astro logo and astro reactive library text on a starry expanse of space',
}, },
twitter: "astroreactive", twitter: 'astroreactive',
}; };
// This is the type of the frontmatter you put in the docs markdown files. // This is the type of the frontmatter you put in the docs markdown files.
@ -19,13 +18,13 @@ export type Frontmatter = {
description: string; description: string;
layout: string; layout: string;
image?: { src: string; alt: string }; image?: { src: string; alt: string };
dir?: "ltr" | "rtl"; dir?: 'ltr' | 'rtl';
ogLocale?: string; ogLocale?: string;
lang?: string; lang?: string;
}; };
export const KNOWN_LANGUAGES = { export const KNOWN_LANGUAGES = {
English: "en", English: 'en',
} as const; } as const;
export const KNOWN_LANGUAGE_CODES = Object.values(KNOWN_LANGUAGES); export const KNOWN_LANGUAGE_CODES = Object.values(KNOWN_LANGUAGES);
@ -35,13 +34,13 @@ export const COMMUNITY_INVITE_URL = `https://discord.gg/fkpkKdPJ`;
// See "Algolia" section of the README for more information. // See "Algolia" section of the README for more information.
export const ALGOLIA = { export const ALGOLIA = {
indexName: "XXXXXXXXXX", indexName: 'XXXXXXXXXX',
appId: "XXXXXXXXXX", appId: 'XXXXXXXXXX',
apiKey: "XXXXXXXXXX", apiKey: 'XXXXXXXXXX',
}; };
export type Sidebar = Record< export type Sidebar = Record<
typeof KNOWN_LANGUAGE_CODES[number], (typeof KNOWN_LANGUAGE_CODES)[number],
Record<string, { text: string; link: string }[]> Record<string, { text: string; link: string }[]>
>; >;
export const SIDEBAR: Sidebar = { export const SIDEBAR: Sidebar = {
@ -55,15 +54,15 @@ export const SIDEBAR: Sidebar = {
// TODO: create overview // TODO: create overview
Introduction: [ Introduction: [
{ text: "Overview", link: "en/introduction" }, { text: 'Overview', link: 'en/introduction' },
// { text: "Philosophy", link: "en/philosophy" }, // { text: "Philosophy", link: "en/philosophy" },
], ],
"API Docs": [ 'API Docs': [
{ text: "Form", link: "en/api/form/form-component" }, { text: 'Form', link: 'en/api/form/form-component' },
{ text: "FormGroup", link: "en/api/form/form-group" }, { text: 'FormGroup', link: 'en/api/form/form-group' },
{ text: "FormControl", link: "en/api/form/form-control" }, { text: 'FormControl', link: 'en/api/form/form-control' },
{ text: "Validators", link: "en/api/validator/validators" }, { text: 'Validators', link: 'en/api/validator/validators' },
], ],
}, },
}; };

View file

@ -6,5 +6,5 @@ export const langPathRegex = /\/([a-z]{2}-?[A-Z]{0,2})\//;
export function getLanguageFromURL(pathname: string) { export function getLanguageFromURL(pathname: string) {
const langCodeMatch = pathname.match(langPathRegex); const langCodeMatch = pathname.match(langPathRegex);
const langCode = langCodeMatch ? langCodeMatch[1] : 'en'; const langCode = langCodeMatch ? langCodeMatch[1] : 'en';
return langCode as typeof KNOWN_LANGUAGE_CODES[number]; return langCode as (typeof KNOWN_LANGUAGE_CODES)[number];
} }

View file

@ -1,13 +1,13 @@
--- ---
import HeadCommon from "../components/HeadCommon.astro"; import HeadCommon from '../components/HeadCommon.astro';
import HeadSEO from "../components/HeadSEO.astro"; import HeadSEO from '../components/HeadSEO.astro';
import Header from "../components/Header/Header.astro"; import Header from '../components/Header/Header.astro';
import PageContent from "../components/PageContent/PageContent.astro"; import PageContent from '../components/PageContent/PageContent.astro';
import LeftSidebar from "../components/LeftSidebar/LeftSidebar.astro"; import LeftSidebar from '../components/LeftSidebar/LeftSidebar.astro';
import RightSidebar from "../components/RightSidebar/RightSidebar.astro"; import RightSidebar from '../components/RightSidebar/RightSidebar.astro';
import * as CONFIG from "../config"; import * as CONFIG from '../config';
import type { MarkdownHeading } from "astro"; import type { MarkdownHeading } from 'astro';
import Footer from "../components/Footer/Footer.astro"; import Footer from '../components/Footer/Footer.astro';
type Props = { type Props = {
frontmatter: CONFIG.Frontmatter; frontmatter: CONFIG.Frontmatter;
@ -17,24 +17,16 @@ type Props = {
const { frontmatter, headings } = Astro.props as Props; const { frontmatter, headings } = Astro.props as Props;
const canonicalURL = new URL(Astro.url.pathname, Astro.site); const canonicalURL = new URL(Astro.url.pathname, Astro.site);
const currentPage = Astro.url.pathname; const currentPage = Astro.url.pathname;
const currentFile = `src/pages${currentPage.replace(/\/$/, "")}.md`; const currentFile = `src/pages${currentPage.replace(/\/$/, '')}.md`;
const githubEditUrl = `${CONFIG.GITHUB_EDIT_URL}/${currentFile}`; const githubEditUrl = `${CONFIG.GITHUB_EDIT_URL}/${currentFile}`;
--- ---
<html <html dir={frontmatter.dir ?? 'ltr'} lang={frontmatter.lang ?? 'en-us'} class="initial">
dir={frontmatter.dir ?? "ltr"}
lang={frontmatter.lang ?? "en-us"}
class="initial"
>
<head> <head>
<HeadCommon /> <HeadCommon />
<HeadSEO frontmatter={frontmatter} canonicalUrl={canonicalURL} /> <HeadSEO frontmatter={frontmatter} canonicalUrl={canonicalURL} />
<title> <title>
{ {frontmatter.title ? `${frontmatter.title} | ${CONFIG.SITE.title}` : CONFIG.SITE.title}
frontmatter.title
? `${frontmatter.title} | ${CONFIG.SITE.title}`
: CONFIG.SITE.title
}
</title> </title>
<style> <style>
body { body {
@ -143,17 +135,12 @@ const githubEditUrl = `${CONFIG.GITHUB_EDIT_URL}/${currentFile}`;
</aside> </aside>
<div id="grid-main"> <div id="grid-main">
<div class="warning"> <div class="warning">
<strong>🛠 Under Construction:</strong> This library and the documentation <strong>🛠 Under Construction:</strong> This library and the documentation are undergoing rigorous
are undergoing rigorous development. Read and join our <a development. Read and join our <a
href="https://github.com/astro-reactive/astro-reactive/discussions" href="https://github.com/astro-reactive/astro-reactive/discussions">discussions</a
>discussions</a
> for questions, suggestions, or feedback. > for questions, suggestions, or feedback.
</div> </div>
<PageContent <PageContent frontmatter={frontmatter} headings={headings} githubEditUrl={githubEditUrl}>
frontmatter={frontmatter}
headings={headings}
githubEditUrl={githubEditUrl}
>
<slot /> <slot />
</PageContent> </PageContent>
</div> </div>
@ -164,4 +151,3 @@ const githubEditUrl = `${CONFIG.GITHUB_EDIT_URL}/${currentFile}`;
<Footer path={currentFile} /> <Footer path={currentFile} />
</body> </body>
</html> </html>

View file

@ -1,7 +1,7 @@
--- ---
title: Form title: Form
type: component type: component
package: "@astro-reactive/form" package: '@astro-reactive/form'
description: The Reactive Form component for Astro description: The Reactive Form component for Astro
layout: ../../../../layouts/MainLayout.astro layout: ../../../../layouts/MainLayout.astro
--- ---
@ -10,7 +10,7 @@ The `Form` component renders a form element and various control components (e.g.
```astro ```astro
--- ---
import Form, { FormGroup } from "@astro-reactive/form"; import Form, { FormGroup } from '@astro-reactive/form';
const form = new FormGroup(); const form = new FormGroup();
// your controls configuration data // your controls configuration data
--- ---
@ -36,26 +36,26 @@ Assigning a `FormGroup` object to the `formGroup` property will set up a form.
```astro ```astro
--- ---
import Form, { FormGroup } from "@astro-reactive/form"; import Form, { FormGroup } from '@astro-reactive/form';
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "username", name: 'username',
label: "Username", label: 'Username',
value: "awesome_dev", value: 'awesome_dev',
}, },
{ {
name: "comment", name: 'comment',
label: "Feedback", label: 'Feedback',
type: "textarea", type: 'textarea',
value: "Nice!", value: 'Nice!',
}, },
{ {
name: "size", name: 'size',
label: "Size", label: 'Size',
type: "dropdown", type: 'dropdown',
options: ["S", "M", "L", "XL", "XXL"], options: ['S', 'M', 'L', 'XL', 'XXL'],
placeholder: "-- Please choose an option --", placeholder: '-- Please choose an option --',
}, },
]); ]);
--- ---
@ -77,48 +77,48 @@ To render a form with multiple field sets, assign an array `FormGroup[]` to the
```astro ```astro
--- ---
import Form, { FormGroup } from "@astro-reactive/form"; import Form, { FormGroup } from '@astro-reactive/form';
const nameForm = new FormGroup( const nameForm = new FormGroup(
[ [
{ {
name: "firstName", name: 'firstName',
label: "First Name", label: 'First Name',
value: "John", value: 'John',
}, },
{ {
name: "lastName", name: 'lastName',
label: "Last Name", label: 'Last Name',
value: "Doe", value: 'Doe',
}, },
], ],
"Name" 'Name'
); );
const skills = new FormGroup( const skills = new FormGroup(
[ [
{ {
name: "JavaScript", name: 'JavaScript',
type: "checkbox", type: 'checkbox',
label: "JavaScript", label: 'JavaScript',
}, },
{ {
name: "TypeScript", name: 'TypeScript',
type: "checkbox", type: 'checkbox',
label: "TypeScript", label: 'TypeScript',
}, },
{ {
name: "React", name: 'React',
type: "checkbox", type: 'checkbox',
label: "React", label: 'React',
}, },
{ {
name: "Vue", name: 'Vue',
type: "checkbox", type: 'checkbox',
label: "Vue", label: 'Vue',
}, },
], ],
"Skills" 'Skills'
); );
--- ---
@ -139,13 +139,13 @@ This implementation is to distinguish the submit button from other buttons and l
```astro ```astro
--- ---
import Form, { FormGroup } from "@astro-reactive/form"; import Form, { FormGroup } from '@astro-reactive/form';
const form = new FormGroup([]); const form = new FormGroup([]);
const submitControl: Submit = { const submitControl: Submit = {
name: "submit", name: 'submit',
type: "submit", type: 'submit',
}; };
--- ---
@ -161,7 +161,7 @@ This is a very crude solution to prevent having multiple submit buttons. For sug
The following are input properties a `Form` component can take. Only the `formGroups` property is required. The following are input properties a `Form` component can take. Only the `formGroups` property is required.
| Property | Type | | | Property | Type | |
| ------------------------------------------- | -------------------------- | ----------------------------------- | | ------------------------------------------- | ----------------------------- | -------- |
| [formGroups](#formgroups) | `FormGroup \| FormGroup[]` | required | | [formGroups](#formgroups) | `FormGroup \| FormGroup[]` | required |
| [action](#action) | `string` | optional | | [action](#action) | `string` | optional |
| [method](#method) | `'get' \| 'post' \| 'dialog'` | optional | | [method](#method) | `'get' \| 'post' \| 'dialog'` | optional |
@ -190,6 +190,7 @@ Type: HTTPSubmitMethod
Sets the `method` [attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-method) for the form. Set this to the HTTP method to submit the form: 'post', 'get', or 'dialog'. Sets the `method` [attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-method) for the form. Set this to the HTTP method to submit the form: 'post', 'get', or 'dialog'.
From [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-method): From [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-method):
- `post` - The POST method; form data sent as the request body. - `post` - The POST method; form data sent as the request body.
- `get (default)` - The GET method; form data appended to the action URL with a ? separator. Use this method when the form has no side effects. - `get (default)` - The GET method; form data appended to the action URL with a ? separator. Use this method when the form has no side effects.
- `dialog` - When the form is inside a <dialog>, closes the dialog and throws a submit event on submission without submitting data or clearing the form. - `dialog` - When the form is inside a <dialog>, closes the dialog and throws a submit event on submission without submitting data or clearing the form.
@ -218,8 +219,8 @@ A special button that triggers the submit event for a form.
```ts ```ts
const submit: Submit = { const submit: Submit = {
type: 'submit', type: 'submit',
value: 'Let\'s go!' value: "Let's go!",
} };
``` ```
### `theme` ### `theme`
@ -233,4 +234,3 @@ Sets the form to use light or dark mode.
Type: `boolean` Type: `boolean`
When used with our `validator` package, the `Form` component is able to render validation errors on server-side rendering when `validateOnLoad` is set to true. Otherwise, the validation errors will only be rendered on the client-side upon user interaction. When used with our `validator` package, the `Form` component is able to render validation errors on server-side rendering when `validateOnLoad` is set to true. Otherwise, the validation errors will only be rendered on the client-side upon user interaction.

View file

@ -1,7 +1,7 @@
--- ---
title: FormControl title: FormControl
type: class type: class
package: "@astro-reactive/form" package: '@astro-reactive/form'
description: FormControl class description: FormControl class
layout: ../../../../layouts/MainLayout.astro layout: ../../../../layouts/MainLayout.astro
--- ---

View file

@ -1,7 +1,7 @@
--- ---
title: FormGroup title: FormGroup
type: class type: class
package: "@astro-reactive/form" package: '@astro-reactive/form'
description: The FormGroup class represents a group of controls that will be rendered as a fieldset element in a form. description: The FormGroup class represents a group of controls that will be rendered as a fieldset element in a form.
layout: ../../../../layouts/MainLayout.astro layout: ../../../../layouts/MainLayout.astro
--- ---
@ -13,7 +13,7 @@ The `FormGroup` class represents a group of controls that will be rendered as a
## Properties ## Properties
| Property | Type | | | Property | Type | |
|---|---|---| | --------------------- | --------------- | -------- |
| [controls](#controls) | `FormControl[]` | required | | [controls](#controls) | `FormControl[]` | required |
| [name](#name) | `string` | optional | | [name](#name) | `string` | optional |

View file

@ -1,7 +1,7 @@
--- ---
title: Validators title: Validators
type: class type: class
package: "@astro-reactive/validators" package: '@astro-reactive/validators'
description: Validator package for @astro-reactive/forms package for providing validation to forms. description: Validator package for @astro-reactive/forms package for providing validation to forms.
layout: ../../../../layouts/MainLayout.astro layout: ../../../../layouts/MainLayout.astro
--- ---
@ -10,21 +10,21 @@ The `Validators` class provides a set of built-in validators that can be used by
```astro ```astro
--- ---
import Form, {FormGroup} from "@astro-reactive/form" import Form, { FormGroup } from '@astro-reactive/form';
import {Validators} from "@astro-reactive/validator" import { Validators } from '@astro-reactive/validator';
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "username", name: 'username',
label: "Username", label: 'Username',
validators: [Validators.required], validators: [Validators.required],
}, },
{ {
name: "password", name: 'password',
label: "Password", label: 'Password',
validators: [Validators.required, Validators.minLength(8)], validators: [Validators.required, Validators.minLength(8)],
}, },
]) ]);
--- ---
<Form formGroups={form} /> <Form formGroups={form} />
@ -48,16 +48,16 @@ The `Validators.required` validator is used to ensure that a form control has a
```astro ```astro
--- ---
import Form, {FormGroup} from "@astro-reactive/form" import Form, { FormGroup } from '@astro-reactive/form';
import {Validators} from "@astro-reactive/validator" import { Validators } from '@astro-reactive/validator';
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "username", name: 'username',
label: "Username", label: 'Username',
validators: [Validators.required], validators: [Validators.required],
}, },
]) ]);
--- ---
<Form formGroups={form} /> <Form formGroups={form} />
@ -69,17 +69,17 @@ The `Validators.requiredChecked` validator is used to ensure that a checkbox is
```astro ```astro
--- ---
import Form, {FormGroup} from "@astro-reactive/form" import Form, { FormGroup } from '@astro-reactive/form';
import {Validators} from "@astro-reactive/validator" import { Validators } from '@astro-reactive/validator';
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "terms", name: 'terms',
label: "Terms and Conditions", label: 'Terms and Conditions',
type: "checkbox", type: 'checkbox',
validators: [Validators.requiredChecked], validators: [Validators.requiredChecked],
}, },
]) ]);
--- ---
<Form formGroups={form} /> <Form formGroups={form} />
@ -91,16 +91,16 @@ The `Validators.email` validator is used to ensure that a form control has a val
```astro ```astro
--- ---
import Form, {FormGroup} from "@astro-reactive/form" import Form, { FormGroup } from '@astro-reactive/form';
import {Validators} from "@astro-reactive/validator" import { Validators } from '@astro-reactive/validator';
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "email", name: 'email',
label: "Email", label: 'Email',
validators: [Validators.email], validators: [Validators.email],
}, },
]) ]);
--- ---
<Form formGroups={form} /> <Form formGroups={form} />
@ -112,17 +112,17 @@ The `Validators.min` validator is used to ensure that the numeric value of form
```astro ```astro
--- ---
import Form, {FormGroup} from "@astro-reactive/form" import Form, { FormGroup } from '@astro-reactive/form';
import {Validators} from "@astro-reactive/validator" import { Validators } from '@astro-reactive/validator';
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "price", name: 'price',
label: "Price", label: 'Price',
type: "number", type: 'number',
validators: [Validators.min(8)], validators: [Validators.min(8)],
}, },
]) ]);
--- ---
<Form formGroups={forms} /> <Form formGroups={forms} />
@ -134,17 +134,17 @@ The `Validators.max` validator is used to ensure that the numeric value of form
```astro ```astro
--- ---
import Form, {FormGroup} from "@astro-reactive/form" import Form, { FormGroup } from '@astro-reactive/form';
import {Validators} from "@astro-reactive/validator" import { Validators } from '@astro-reactive/validator';
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "price", name: 'price',
label: "Price", label: 'Price',
type: "number", type: 'number',
validators: [Validators.max(8)], validators: [Validators.max(8)],
}, },
]) ]);
--- ---
<Form formGroups={forms} /> <Form formGroups={forms} />
@ -156,16 +156,16 @@ The `Validators.minLength` validator is used to ensure that the length of the va
```astro ```astro
--- ---
import Form, {FormGroup} from "@astro-reactive/form" import Form, { FormGroup } from '@astro-reactive/form';
import {Validators} from "@astro-reactive/validator" import { Validators } from '@astro-reactive/validator';
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "password", name: 'password',
label: "Password", label: 'Password',
validators: [Validators.minLength(8)], validators: [Validators.minLength(8)],
}, },
]) ]);
--- ---
<Form formGroups={forms} /> <Form formGroups={forms} />
@ -177,16 +177,16 @@ The `Validators.maxLength` validator is used to ensure that the length of the va
```astro ```astro
--- ---
import Form, {FormGroup} from "@astro-reactive/form" import Form, { FormGroup } from '@astro-reactive/form';
import {Validators} from "@astro-reactive/validator" import { Validators } from '@astro-reactive/validator';
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "password", name: 'password',
label: "Password", label: 'Password',
validators: [Validators.maxLength(8)], validators: [Validators.maxLength(8)],
}, },
]) ]);
--- ---
<Form formGroups={forms} /> <Form formGroups={forms} />

View file

@ -49,10 +49,9 @@ We will also make this clear in our library documentation as we see them.
## Packages ## Packages
| Package | Release notes | Description | | Package | Release notes | Description |
| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| [form](/en/api/form/form-component) | [![npm](https://img.shields.io/npm/v/@astro-reactive/form)](https://github.com/astro-reactive/astro-reactive/blob/main/packages/form/RELEASE.md) | a dynamic form which can be modified programmatically | | [form](/en/api/form/form-component) | [![npm](https://img.shields.io/npm/v/@astro-reactive/form)](https://github.com/astro-reactive/astro-reactive/blob/main/packages/form/RELEASE.md) | a dynamic form which can be modified programmatically |
| [validator](https://github.com/astro-reactive/astro-reactive/blob/main/packages/validator/README.md) | [![npm](https://img.shields.io/npm/v/@astro-reactive/validator)](https://github.com/astro-reactive/astro-reactive/blob/main/packages/validator/RELEASE.md) | validators for editable fields | | [validator](https://github.com/astro-reactive/astro-reactive/blob/main/packages/validator/README.md) | [![npm](https://img.shields.io/npm/v/@astro-reactive/validator)](https://github.com/astro-reactive/astro-reactive/blob/main/packages/validator/RELEASE.md) | validators for editable fields |
| data-grid | 🛠 | a dynamic data grid of values | | data-grid | 🛠 | a dynamic data grid of values |
| themes | 🛠 | easy-to-use, accessible, consistent cross-browser styles | | themes | 🛠 | easy-to-use, accessible, consistent cross-browser styles |
| viz | 🛠 | data visualization that emits and responds to events | | viz | 🛠 | data visualization that emits and responds to events |

View file

@ -6,26 +6,24 @@ layout: ../../../layouts/MainLayout.astro
Consider the following code: Consider the following code:
```astro
``` astro
--- ---
import Form { FormGroup } from '@astro-reactive/form'; import Form, { FormGroup } from '@astro-reactive/form';
import { Validators } from '@astro-reactive/validator'; import { Validators } from '@astro-reactive/validator';
const form = new FormGroup([ const form = new FormGroup([
{ {
name: 'username', name: 'username',
label: 'Username', label: 'Username',
validators: [Validators.required] validators: [Validators.required],
}, },
{ {
name: 'password', name: 'password',
label: 'Password', label: 'Password',
validators: [Validators.required, Validators.minLength(8)] validators: [Validators.required, Validators.minLength(8)],
}, },
]); ]);
--- ---
<Form formGroups={form} /> <Form formGroups={form} />
``` ```

View file

@ -33,45 +33,44 @@ Use in an Astro page:
```astro ```astro
--- ---
import { FormControl, FormGroup } from "@astro-reactive/form/core"; import { FormControl, FormGroup } from '@astro-reactive/form/core';
import Form from "@astro-reactive/form"; import Form from '@astro-reactive/form';
// create a form group // create a form group
const form = new FormGroup([ const form = new FormGroup([
{ {
name: "username", name: 'username',
label: "Username", label: 'Username',
}, },
{ {
name: "password", name: 'password',
label: "Password", label: 'Password',
type: "password", type: 'password',
}, },
]); ]);
// set the name optionally // set the name optionally
form.name = "Simple Form"; form.name = 'Simple Form';
// you can insert a control at any point // you can insert a control at any point
form.controls.push( form.controls.push(
new FormControl({ new FormControl({
type: "checkbox", type: 'checkbox',
name: "is-awesome", name: 'is-awesome',
label: "is Awesome?", label: 'is Awesome?',
}) })
); );
// you can get a FormControl object // you can get a FormControl object
const userNameControl = form.get("username"); const userNameControl = form.get('username');
// you can set values dynamically // you can set values dynamically
userNameControl?.setValue("RAMOOOON"); userNameControl?.setValue('RAMOOOON');
form.get('is-awesome')?.setValue("checked"); form.get('is-awesome')?.setValue('checked');
--- ---
<!-- the formGroups attribute takes an array of FormGroup--> <!-- the formGroups attribute takes an array of FormGroup-->
<Form formGroups={[form]} /> <Form formGroups={[form]} />
``` ```
# Screenshots # Screenshots
@ -105,4 +104,3 @@ Currently this only supports very basic form creation, but the goal of the proje
... and so much more ... and so much more
_All contributions are welcome. Let's make the fastest web form component powered by Astro_ _All contributions are welcome. Let's make the fastest web form component powered by Astro_

View file

@ -1,7 +1,6 @@
{ {
"extends": "astro/tsconfigs/base", "extends": "@astro-reactive/tsconfig/astro-library.json",
"compilerOptions": { "compilerOptions": {
"jsx": "preserve", "jsx": "preserve"
"skipLibCheck": true
} }
} }

View file

@ -0,0 +1,2 @@
dist
node_modules

View file

@ -0,0 +1,5 @@
/** @type {import("@types/eslint").Linter.Config} */
module.exports = {
root: true,
extends: ['@astro-reactive/eslint-config-custom'],
};

View file

@ -0,0 +1,24 @@
/** @type {import("@types/prettier").Options} */
module.exports = {
printWidth: 100,
semi: true,
singleQuote: true,
tabWidth: 2,
trailingComma: 'es5',
useTabs: true,
plugins: ['../../node_modules/prettier-plugin-astro'],
overrides: [
{
files: '*.astro',
options: {
parser: 'astro',
},
},
{
files: ['.*', '*.json', '*.md', '*.toml', '*.yml'],
options: {
useTabs: false,
},
},
],
};

View file

@ -1 +0,0 @@
{}

View file

@ -1,12 +1,12 @@
import tailwind from "@astrojs/tailwind"; import tailwind from '@astrojs/tailwind';
import { defineConfig } from "astro/config"; import { defineConfig } from 'astro/config';
export default defineConfig({ export default defineConfig({
site: "https://astro-reactive.dev", site: 'https://astro-reactive.dev',
integrations: [tailwind()], integrations: [tailwind()],
vite: { vite: {
ssr: { ssr: {
external: ["svgo"], external: ['svgo'],
}, },
}, },
}); });

View file

@ -10,16 +10,22 @@
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro", "astro": "astro",
"format": "prettier --write .", "format": "prettier -w .",
"lint": "eslint . --ext .ts,.js",
"lint:fix": "eslint --fix . --ext .ts,.js",
"clean": "rimraf dist node_modules dist .turbo" "clean": "rimraf dist node_modules dist .turbo"
}, },
"devDependencies": { "devDependencies": {
"@astro-reactive/eslint-config-custom": "*",
"@astrojs/tailwind": "^2.0.2", "@astrojs/tailwind": "^2.0.2",
"@types/eslint": "^8.4.10",
"@types/micromodal": "^0.3.3", "@types/micromodal": "^0.3.3",
"@types/prettier": "^2.7.2",
"astro": "^1.4.7", "astro": "^1.4.7",
"astro-icon": "^0.8.0", "astro-icon": "^0.8.0",
"prettier": "2.7.1", "eslint": "^8.31.0",
"prettier-plugin-astro": "^0.7.0", "prettier": "^2.7.1",
"prettier-plugin-astro": "^0.7.2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"tailwindcss-fluid-type": "^2.0.3" "tailwindcss-fluid-type": "^2.0.3"
}, },
@ -41,4 +47,3 @@
}, },
"homepage": "https://github.com/astro-reactive/astro-reactive#readme" "homepage": "https://github.com/astro-reactive/astro-reactive#readme"
} }

View file

@ -1,2 +1,2 @@
@import "global.css"; @import 'global.css';
@import "theme.css"; @import 'theme.css';

View file

@ -1,19 +1,19 @@
[data-theme="light"] { [data-theme='light'] {
--color-primary: theme("colors.pink.500"); --color-primary: theme('colors.pink.500');
--color-secondary: theme("colors.indigo.500"); --color-secondary: theme('colors.indigo.500');
--color-text: theme("colors.gray.900"); --color-text: theme('colors.gray.900');
--color-text-offset: theme("colors.gray.600"); --color-text-offset: theme('colors.gray.600');
--color-background: theme("colors.gray.50"); --color-background: theme('colors.gray.50');
--color-background-offset: theme("colors.gray.100"); --color-background-offset: theme('colors.gray.100');
--color-border: theme("colors.gray.900" / 10%); --color-border: theme('colors.gray.900' / 10%);
} }
[data-theme="dark"] { [data-theme='dark'] {
--color-primary: theme("colors.pink.400"); --color-primary: theme('colors.pink.400');
--color-secondary: theme("colors.indigo.400"); --color-secondary: theme('colors.indigo.400');
--color-text: theme("colors.gray.50"); --color-text: theme('colors.gray.50');
--color-text-offset: theme("colors.gray.400"); --color-text-offset: theme('colors.gray.400');
--color-background: theme("colors.gray.900"); --color-background: theme('colors.gray.900');
--color-background-offset: theme("colors.gray.800"); --color-background-offset: theme('colors.gray.800');
--color-border: theme("colors.gray.50" / 10%); --color-border: theme('colors.gray.50' / 10%);
} }

View file

@ -1,38 +1,38 @@
const defaultTheme = require("tailwindcss/defaultTheme"); const defaultTheme = require('tailwindcss/defaultTheme');
module.exports = { module.exports = {
content: ["./src/**/*.{astro,html,js,jsx,svelte,ts,tsx,vue}"], content: ['./src/**/*.{astro,html,js,jsx,svelte,ts,tsx,vue}'],
theme: { theme: {
screens: { screens: {
"astro-sm": { max: "1000px" }, 'astro-sm': { max: '1000px' },
"astro-md": { min: "640px", max: "1000px" }, 'astro-md': { min: '640px', max: '1000px' },
"astro-img": { min: "600px", max: "1000px" }, 'astro-img': { min: '600px', max: '1000px' },
"astro-lg": { min: "1000px" }, 'astro-lg': { min: '1000px' },
...defaultTheme.screens, ...defaultTheme.screens,
}, },
extend: { extend: {
fontFamily: { fontFamily: {
sans: ["Inter", ...defaultTheme.fontFamily.sans], sans: ['Inter', ...defaultTheme.fontFamily.sans],
}, },
colors: { colors: {
primary: "var(--color-primary)", primary: 'var(--color-primary)',
secondary: "var(--color-secondary)", secondary: 'var(--color-secondary)',
}, },
textColor: { textColor: {
default: "var(--color-text)", default: 'var(--color-text)',
offset: "var(--color-text-offset)", offset: 'var(--color-text-offset)',
}, },
backgroundColor: { backgroundColor: {
default: "var(--color-background)", default: 'var(--color-background)',
offset: "var(--color-background-offset)", offset: 'var(--color-background-offset)',
}, },
borderColor: { borderColor: {
default: "var(--color-border)", default: 'var(--color-border)',
}, },
}, },
}, },
corePlugins: { corePlugins: {
fontSize: false, fontSize: false,
}, },
plugins: [require("tailwindcss-fluid-type")], plugins: [require('tailwindcss-fluid-type')],
}; };

59
package-lock.json generated
View file

@ -30,11 +30,17 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@astro-reactive/form": "*", "@astro-reactive/form": "*",
"@astro-reactive/tsconfig": "*",
"@astro-reactive/validator": "*", "@astro-reactive/validator": "*",
"astro": "^1.6.5" "astro": "^1.6.5"
}, },
"devDependencies": { "devDependencies": {
"@astro-reactive/eslint-config-custom": "*",
"@astro-reactive/tsconfig": "*",
"@types/eslint": "^8.4.10",
"@types/prettier": "^2.7.2",
"eslint": "^8.31.0",
"prettier": "^2.8.3",
"prettier-plugin-astro": "^0.7.2",
"rimraf": "^3.0.2" "rimraf": "^3.0.2"
} }
}, },
@ -53,11 +59,17 @@
"@types/react-dom": "^18.0.0", "@types/react-dom": "^18.0.0",
"astro": "^1.4.4", "astro": "^1.4.4",
"preact": "^10.7.3", "preact": "^10.7.3",
"prettier-plugin-astro": "^0.7.0",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0" "react-dom": "^18.1.0"
}, },
"devDependencies": { "devDependencies": {
"@astro-reactive/eslint-config-custom": "*",
"@astro-reactive/tsconfig": "*",
"@types/eslint": "^8.4.10",
"@types/prettier": "^2.7.2",
"eslint": "^8.31.0",
"prettier": "^2.8.3",
"prettier-plugin-astro": "^0.7.2",
"rimraf": "^3.0.2" "rimraf": "^3.0.2"
} }
}, },
@ -71,20 +83,25 @@
"tailwindcss": "^3.1.8" "tailwindcss": "^3.1.8"
}, },
"devDependencies": { "devDependencies": {
"@astro-reactive/eslint-config-custom": "*",
"@astrojs/tailwind": "^2.0.2", "@astrojs/tailwind": "^2.0.2",
"@types/eslint": "^8.4.10",
"@types/micromodal": "^0.3.3", "@types/micromodal": "^0.3.3",
"@types/prettier": "^2.7.2",
"astro": "^1.4.7", "astro": "^1.4.7",
"astro-icon": "^0.8.0", "astro-icon": "^0.8.0",
"prettier": "2.7.1", "eslint": "^8.31.0",
"prettier-plugin-astro": "^0.7.0", "prettier": "^2.7.1",
"prettier-plugin-astro": "^0.7.2",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"tailwindcss-fluid-type": "^2.0.3" "tailwindcss-fluid-type": "^2.0.3"
} }
}, },
"apps/landing-page/node_modules/prettier": { "apps/landing-page/node_modules/prettier": {
"version": "2.7.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
"dev": true, "dev": true,
"license": "MIT",
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin-prettier.js"
}, },
@ -6450,9 +6467,9 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "2.8.1", "version": "2.8.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz",
"integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==",
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin-prettier.js"
}, },
@ -8647,10 +8664,16 @@
"@astro-reactive/demo": { "@astro-reactive/demo": {
"version": "file:apps/demo", "version": "file:apps/demo",
"requires": { "requires": {
"@astro-reactive/eslint-config-custom": "*",
"@astro-reactive/form": "*", "@astro-reactive/form": "*",
"@astro-reactive/tsconfig": "*", "@astro-reactive/tsconfig": "*",
"@astro-reactive/validator": "*", "@astro-reactive/validator": "*",
"@types/eslint": "^8.4.10",
"@types/prettier": "^2.7.2",
"astro": "^1.6.5", "astro": "^1.6.5",
"eslint": "^8.31.0",
"prettier": "^2.8.3",
"prettier-plugin-astro": "^0.7.2",
"rimraf": "^3.0.2" "rimraf": "^3.0.2"
} }
}, },
@ -8658,16 +8681,22 @@
"version": "file:apps/docs", "version": "file:apps/docs",
"requires": { "requires": {
"@algolia/client-search": "^4.13.1", "@algolia/client-search": "^4.13.1",
"@astro-reactive/eslint-config-custom": "*",
"@astro-reactive/tsconfig": "*",
"@astrojs/preact": "^1.1.1", "@astrojs/preact": "^1.1.1",
"@astrojs/react": "^1.1.4", "@astrojs/react": "^1.1.4",
"@docsearch/css": "^3.1.0", "@docsearch/css": "^3.1.0",
"@docsearch/react": "^3.1.0", "@docsearch/react": "^3.1.0",
"@types/eslint": "^8.4.10",
"@types/node": "^18.0.0", "@types/node": "^18.0.0",
"@types/prettier": "^2.7.2",
"@types/react": "^18.0.24", "@types/react": "^18.0.24",
"@types/react-dom": "^18.0.0", "@types/react-dom": "^18.0.0",
"astro": "^1.4.4", "astro": "^1.4.4",
"eslint": "^8.31.0",
"preact": "^10.7.3", "preact": "^10.7.3",
"prettier-plugin-astro": "^0.7.0", "prettier": "^2.8.3",
"prettier-plugin-astro": "^0.7.2",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"rimraf": "^3.0.2" "rimraf": "^3.0.2"
@ -8709,11 +8738,15 @@
"@astro-reactive/landing-page": { "@astro-reactive/landing-page": {
"version": "file:apps/landing-page", "version": "file:apps/landing-page",
"requires": { "requires": {
"@astro-reactive/eslint-config-custom": "*",
"@astro-reactive/tsconfig": "*", "@astro-reactive/tsconfig": "*",
"@astrojs/tailwind": "^2.0.2", "@astrojs/tailwind": "^2.0.2",
"@types/eslint": "*",
"@types/micromodal": "^0.3.3", "@types/micromodal": "^0.3.3",
"@types/prettier": "*",
"astro": "^1.4.7", "astro": "^1.4.7",
"astro-icon": "^0.8.0", "astro-icon": "^0.8.0",
"eslint": "*",
"micromodal": "^0.4.10", "micromodal": "^0.4.10",
"prettier": "2.7.1", "prettier": "2.7.1",
"prettier-plugin-astro": "^0.7.0", "prettier-plugin-astro": "^0.7.0",
@ -8724,6 +8757,8 @@
"dependencies": { "dependencies": {
"prettier": { "prettier": {
"version": "2.7.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
"dev": true "dev": true
} }
} }
@ -12904,9 +12939,9 @@
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
}, },
"prettier": { "prettier": {
"version": "2.8.1", "version": "2.8.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz",
"integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==" "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw=="
}, },
"prettier-linter-helpers": { "prettier-linter-helpers": {
"version": "1.0.0", "version": "1.0.0",