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:
parent
0abe83aea9
commit
f79ce72a1c
57 changed files with 1349 additions and 1265 deletions
2
apps/demo/.eslintignore
Normal file
2
apps/demo/.eslintignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
dist
|
||||||
|
node_modules
|
5
apps/demo/.eslintrc.cjs
Normal file
5
apps/demo/.eslintrc.cjs
Normal 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
24
apps/demo/.prettierrc.cjs
Normal 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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
|
@ -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)_
|
||||||
|
|
||||||
|
|
|
@ -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({});
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
---
|
---
|
||||||
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}>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
<title>{title} | Astro Reactive Demo</title>
|
<title>{title} | Astro Reactive Demo</title>
|
||||||
</head>
|
</head>
|
||||||
<body class={theme}>
|
<body class={theme}>
|
||||||
<Nav />
|
<Nav />
|
||||||
<h1>{title}</h1>
|
<h1>{title}</h1>
|
||||||
<slot />
|
<slot />
|
||||||
</body>
|
</body>
|
||||||
<style>
|
<style>
|
||||||
html.dark,
|
html.dark,
|
||||||
body.dark {
|
body.dark {
|
||||||
color-scheme: dark;
|
color-scheme: dark;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
---
|
---
|
||||||
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' },
|
||||||
];
|
];
|
||||||
---
|
---
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
{links.map((link) => <a href={link.url}>{link.label}</a>)}
|
{links.map((link) => <a href={link.url}>{link.label}</a>)}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
nav a::after {
|
nav a::after {
|
||||||
content: " | ";
|
content: ' | ';
|
||||||
}
|
}
|
||||||
nav a {
|
nav a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
nav a:hover {
|
nav a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -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,15 +71,15 @@ const skills = new FormGroup(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const submitControl: Submit = {
|
const submitControl: Submit = {
|
||||||
name: "submit",
|
name: 'submit',
|
||||||
type: "submit",
|
type: 'submit',
|
||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Form API examples">
|
<Layout title="Form API examples">
|
||||||
<h2>Simple Form</h2>
|
<h2>Simple Form</h2>
|
||||||
<Form formGroups={simpleForm} submitControl={submitControl} />
|
<Form formGroups={simpleForm} submitControl={submitControl} />
|
||||||
|
|
||||||
<h2>Form with nested form groups</h2>
|
<h2>Form with nested form groups</h2>
|
||||||
<Form formGroups={[nameForm, skills]} />
|
<Form formGroups={[nameForm, skills]} />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
import Layout from "../../components/Layout.astro";
|
import Layout from '../../components/Layout.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Docs Examples">
|
<Layout title="Docs Examples">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="./examples/form-component">Form Component</a></li>
|
<li><a href="./examples/form-component">Form Component</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
---
|
---
|
||||||
import Layout from "../../components/Layout.astro";
|
import Layout from '../../components/Layout.astro';
|
||||||
const Counter = {
|
const Counter = {
|
||||||
count: 0,
|
count: 0,
|
||||||
increment() {
|
increment() {
|
||||||
this.count++;
|
this.count++;
|
||||||
},
|
},
|
||||||
decrement() {
|
decrement() {
|
||||||
this.count--;
|
this.count--;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Hyperdrive Experiment">
|
<Layout title="Hyperdrive Experiment">
|
||||||
<!-- PROBLEM STATEMENT
|
<!-- PROBLEM STATEMENT
|
||||||
This is the problem that `hyperdrive` is trying to solve.
|
This is the problem that `hyperdrive` is trying to solve.
|
||||||
After this is rendered in the server, the Counter object is not serialized.
|
After this is rendered in the server, the Counter object is not serialized.
|
||||||
When the HTML reaches the browser, it has no idea what Counter is.
|
When the HTML reaches the browser, it has no idea what Counter is.
|
||||||
-->
|
-->
|
||||||
<button onclick="Counter.increment()">
|
<button onclick="Counter.increment()">
|
||||||
{Counter.count}
|
{Counter.count}
|
||||||
</button>
|
</button>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
import Layout from "../../components/Layout.astro";
|
import Layout from '../../components/Layout.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Experimental Demos">
|
<Layout title="Experimental Demos">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="./experimental/hyperdrive">Hyperdrive</a></li>
|
<li><a href="./experimental/hyperdrive">Hyperdrive</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -1,116 +1,112 @@
|
||||||
---
|
---
|
||||||
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!",
|
||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={title} theme={theme}>
|
<Layout title={title} theme={theme}>
|
||||||
<Form
|
<Form
|
||||||
validateOnLoad
|
validateOnLoad
|
||||||
showValidationHints
|
showValidationHints
|
||||||
formGroups={form}
|
formGroups={form}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
submitControl={submit}
|
submitControl={submit}
|
||||||
action="https://localhost"
|
action="https://localhost"
|
||||||
method="post"
|
method="post"
|
||||||
/>
|
/>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -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",
|
name: 'eligible',
|
||||||
"Guatamala",
|
label: 'Are you eligible to work?',
|
||||||
"Greenland",
|
type: 'radio',
|
||||||
"Haiti",
|
options: [
|
||||||
],
|
{ label: 'Yes', value: 'yes' },
|
||||||
placeholder: "Choose Your Country",
|
{ label: 'No', value: 'no' },
|
||||||
},
|
],
|
||||||
{
|
},
|
||||||
name: "eligible",
|
|
||||||
label: "Are you eligible to work?",
|
|
||||||
type: "radio",
|
|
||||||
options: [
|
|
||||||
{ label: "Yes", value: "yes" },
|
|
||||||
{ 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>
|
||||||
|
|
|
@ -1,96 +1,96 @@
|
||||||
---
|
---
|
||||||
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">
|
||||||
<Form showValidationHints formGroups={[baseForm, toppingsForm, infoForm]} />
|
<Form showValidationHints formGroups={[baseForm, toppingsForm, infoForm]} />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
2
apps/docs/.eslintignore
Normal file
2
apps/docs/.eslintignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
dist
|
||||||
|
node_modules
|
5
apps/docs/.eslintrc.cjs
Normal file
5
apps/docs/.eslintrc.cjs
Normal 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
24
apps/docs/.prettierrc.cjs
Normal 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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
|
@ -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)_
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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');
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
// fetch all commits for just this page's path
|
// fetch all commits for just this page's path
|
||||||
type Props = {
|
type Props = {
|
||||||
path: string;
|
path: string;
|
||||||
};
|
};
|
||||||
const { path } = Astro.props as Props;
|
const { path } = Astro.props as Props;
|
||||||
const resolvedPath = `apps/docs/${path}`;
|
const resolvedPath = `apps/docs/${path}`;
|
||||||
|
@ -9,58 +9,58 @@ const url = `https://api.github.com/repos/astro-reactive/astro-reactive/commits?
|
||||||
const commitsURL = `https://github.com/astro-reactive/astro-reactive/commits/main/${resolvedPath}`;
|
const commitsURL = `https://github.com/astro-reactive/astro-reactive/commits/main/${resolvedPath}`;
|
||||||
|
|
||||||
type Commit = {
|
type Commit = {
|
||||||
author: {
|
author: {
|
||||||
id: string;
|
id: string;
|
||||||
login: string;
|
login: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
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',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Request to fetch commits failed. Reason: ${res.statusText}
|
`Request to fetch commits failed. Reason: ${res.statusText}
|
||||||
Message: ${data.message}`
|
Message: ${data.message}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data as Commit[];
|
return data as Commit[];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(`[error] /src/components/AvatarList.astro
|
console.warn(`[error] /src/components/AvatarList.astro
|
||||||
${(e as any)?.message ?? e}`);
|
${(e as any)?.message ?? e}`);
|
||||||
return [] as Commit[];
|
return [] as Commit[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
// Deduplicate based on author.id
|
// Deduplicate based on author.id
|
||||||
map.set(author.id, { login: author.login, id: author.id });
|
map.set(author.id, { login: author.login, id: author.id });
|
||||||
}
|
}
|
||||||
|
|
||||||
return [...map.values()];
|
return [...map.values()];
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await getCommits(url);
|
const data = await getCommits(url);
|
||||||
|
@ -71,112 +71,101 @@ 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) => (
|
||||||
>
|
<li>
|
||||||
{
|
<a href={`https://github.com/${item.login}`}>
|
||||||
recentContributors.map((item) => (
|
<img
|
||||||
<li>
|
alt={`Contributor ${item.login}`}
|
||||||
<a href={`https://github.com/${item.login}`}>
|
title={`Contributor ${item.login}`}
|
||||||
<img
|
width="64"
|
||||||
alt={`Contributor ${item.login}`}
|
height="64"
|
||||||
title={`Contributor ${item.login}`}
|
src={`https://avatars.githubusercontent.com/u/${item.id}`}
|
||||||
width="64"
|
/>
|
||||||
height="64"
|
</a>
|
||||||
src={`https://avatars.githubusercontent.com/u/${item.id}`}
|
</li>
|
||||||
/>
|
))
|
||||||
</a>
|
}
|
||||||
</li>
|
</ul>
|
||||||
))
|
{
|
||||||
}
|
additionalContributors > 0 && (
|
||||||
</ul>
|
<span>
|
||||||
{
|
<a href={commitsURL}>{`and ${additionalContributors} additional contributor${
|
||||||
additionalContributors > 0 && (
|
additionalContributors > 1 ? 's' : ''
|
||||||
<span>
|
}.`}</a>
|
||||||
<a
|
</span>
|
||||||
href={commitsURL}
|
)
|
||||||
>{`and ${additionalContributors} additional contributor${
|
}
|
||||||
additionalContributors > 1 ? "s" : ""
|
{unique.length === 0 && <a href={commitsURL}>Contributors</a>}
|
||||||
}.`}</a>
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{unique.length === 0 && <a href={commitsURL}>Contributors</a>}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.avatar-list {
|
.avatar-list {
|
||||||
--avatar-size: 2.5rem;
|
--avatar-size: 2.5rem;
|
||||||
--avatar-count: 3;
|
--avatar-count: 3;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
/* 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),
|
/* `padding` matches added visual dimensions of
|
||||||
max(44px, calc(var(--avatar-size) / 1.15))
|
|
||||||
);
|
|
||||||
/* `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 */
|
||||||
padding: 0.08em;
|
padding: 0.08em;
|
||||||
font-size: var(--avatar-size);
|
font-size: var(--avatar-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (any-hover: hover) and (any-pointer: fine) {
|
@media (any-hover: hover) and (any-pointer: fine) {
|
||||||
.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)
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar-list li {
|
.avatar-list li {
|
||||||
width: var(--avatar-size);
|
width: var(--avatar-size);
|
||||||
height: var(--avatar-size);
|
height: var(--avatar-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-list li:hover ~ li a,
|
.avatar-list li:hover ~ li a,
|
||||||
.avatar-list li:focus-within ~ li a {
|
.avatar-list li:focus-within ~ li a {
|
||||||
transform: translateX(33%);
|
transform: translateX(33%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-list img,
|
.avatar-list img,
|
||||||
.avatar-list a {
|
.avatar-list a {
|
||||||
display: block;
|
display: block;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-list a {
|
.avatar-list a {
|
||||||
transition: transform 180ms ease-in-out;
|
transition: transform 180ms ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-list img {
|
.avatar-list img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
box-shadow: 0 0 0 0.05em #fff, 0 0 0 0.08em rgba(0, 0, 0, 0.15);
|
box-shadow: 0 0 0 0.05em #fff, 0 0 0 0.08em rgba(0, 0, 0, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-list a:focus {
|
.avatar-list a:focus {
|
||||||
outline: 2px solid transparent;
|
outline: 2px solid transparent;
|
||||||
/* Double-layer trick to work for dark and light backgrounds */
|
/* Double-layer trick to work for dark and light backgrounds */
|
||||||
box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white;
|
box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contributors {
|
.contributors {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contributors > * + * {
|
.contributors > * + * {
|
||||||
margin-left: 0.75rem;
|
margin-left: 0.75rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
---
|
---
|
||||||
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 = {
|
||||||
currentPage: string;
|
currentPage: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const { currentPage } = Astro.props as Props;
|
const { currentPage } = Astro.props as Props;
|
||||||
|
@ -17,140 +17,136 @@ const lang = getLanguageFromURL(currentPage);
|
||||||
---
|
---
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<SkipToContent />
|
<SkipToContent />
|
||||||
<nav class="nav-wrapper" title="Top Navigation">
|
<nav class="nav-wrapper" title="Top Navigation">
|
||||||
<div class="menu-toggle">
|
<div class="menu-toggle">
|
||||||
<SidebarToggle client:idle />
|
<SidebarToggle client:idle />
|
||||||
</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 && (
|
<!-- TODO: enable search -->
|
||||||
<LanguageSelect lang={lang} client:idle />
|
<!-- <div class="search-item">
|
||||||
)
|
|
||||||
}
|
|
||||||
<!-- TODO: enable search -->
|
|
||||||
<!-- <div class="search-item">
|
|
||||||
<Search client:idle />
|
<Search client:idle />
|
||||||
</div> -->
|
</div> -->
|
||||||
|
|
||||||
<ThemeToggleButton client:visible />
|
<ThemeToggleButton client:visible />
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
header {
|
header {
|
||||||
z-index: 11;
|
z-index: 11;
|
||||||
height: var(--theme-navbar-height);
|
height: var(--theme-navbar-height);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: var(--theme-navbar-bg);
|
background-color: var(--theme-navbar-bg);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
color: hsla(var(--color-base-white), 100%, 1);
|
color: hsla(var(--color-base-white), 100%, 1);
|
||||||
gap: 0.25em;
|
gap: 0.25em;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo a {
|
.logo a {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0.5em 0.25em;
|
padding: 0.5em 0.25em;
|
||||||
margin: -0.5em -0.25em;
|
margin: -0.5em -0.25em;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo a {
|
.logo a {
|
||||||
transition: color 100ms ease-out;
|
transition: color 100ms ease-out;
|
||||||
color: var(--theme-text);
|
color: var(--theme-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo a:hover,
|
.logo a:hover,
|
||||||
.logo a:focus {
|
.logo a:focus {
|
||||||
color: var(--theme-text-accent);
|
color: var(--theme-text-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo h1 {
|
.logo h1 {
|
||||||
display: none;
|
display: none;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-wrapper {
|
.nav-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 82em;
|
max-width: 82em;
|
||||||
padding: 0 2rem;
|
padding: 0 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 50em) {
|
@media (min-width: 50em) {
|
||||||
header {
|
header {
|
||||||
position: static;
|
position: static;
|
||||||
padding: 2rem 0rem;
|
padding: 2rem 0rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
width: auto;
|
width: auto;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo h1 {
|
.logo h1 {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-toggle {
|
.menu-toggle {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Style Algolia */
|
/** Style Algolia */
|
||||||
:root {
|
:root {
|
||||||
--docsearch-primary-color: var(--theme-accent);
|
--docsearch-primary-color: var(--theme-accent);
|
||||||
--docsearch-logo-color: var(--theme-text);
|
--docsearch-logo-color: var(--theme-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-item {
|
.search-item {
|
||||||
display: none;
|
display: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
padding-right: 0.7rem;
|
padding-right: 0.7rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 50em) {
|
@media (min-width: 50em) {
|
||||||
.search-item {
|
.search-item {
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style is:global>
|
<style is:global>
|
||||||
.search-item > * {
|
.search-item > * {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -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);
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,124 +1,119 @@
|
||||||
---
|
---
|
||||||
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);
|
||||||
const sidebar = SIDEBAR[langCode];
|
const sidebar = SIDEBAR[langCode];
|
||||||
---
|
---
|
||||||
|
|
||||||
<nav aria-labelledby="grid-left">
|
<nav aria-labelledby="grid-left">
|
||||||
<ul class="nav-groups">
|
<ul class="nav-groups">
|
||||||
{
|
{
|
||||||
Object.entries(sidebar).map(([header, children]) => (
|
Object.entries(sidebar).map(([header, children]) => (
|
||||||
<li>
|
<li>
|
||||||
<div class="nav-group">
|
<div class="nav-group">
|
||||||
<h2>{header}</h2>
|
<h2>{header}</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{children.map((child) => {
|
{children.map((child) => {
|
||||||
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}
|
{child.text}
|
||||||
aria-current={
|
</a>
|
||||||
currentPageMatch === child.link ? "page" : false
|
</li>
|
||||||
}
|
);
|
||||||
>
|
})}
|
||||||
{child.text}
|
</ul>
|
||||||
</a>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
);
|
))
|
||||||
})}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</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>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
nav {
|
nav {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-groups {
|
.nav-groups {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
overflow-x: visible;
|
overflow-x: visible;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-groups > li + li {
|
.nav-groups > li + li {
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-groups > :first-child {
|
.nav-groups > :first-child {
|
||||||
padding-top: var(--doc-padding);
|
padding-top: var(--doc-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-groups > :last-child {
|
.nav-groups > :last-child {
|
||||||
padding-bottom: 2rem;
|
padding-bottom: 2rem;
|
||||||
margin-bottom: var(--theme-navbar-height);
|
margin-bottom: var(--theme-navbar-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-group-title {
|
.nav-group-title {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
padding: 0.1rem 1rem;
|
padding: 0.1rem 1rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link a {
|
.nav-link a {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
margin: 1px;
|
margin: 1px;
|
||||||
padding: 0.3rem 1rem;
|
padding: 0.3rem 1rem;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link a:hover,
|
.nav-link a:hover,
|
||||||
.nav-link a:focus {
|
.nav-link a:focus {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 50em) {
|
@media (min-width: 50em) {
|
||||||
.nav-groups {
|
.nav-groups {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</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>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
---
|
---
|
||||||
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;
|
||||||
headings: MarkdownHeading[];
|
headings: MarkdownHeading[];
|
||||||
githubEditUrl: string;
|
githubEditUrl: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const { frontmatter, headings, githubEditUrl } = Astro.props as Props;
|
const { frontmatter, headings, githubEditUrl } = Astro.props as Props;
|
||||||
|
@ -15,39 +15,39 @@ const title = frontmatter.title;
|
||||||
---
|
---
|
||||||
|
|
||||||
<article id="article" class="content">
|
<article id="article" class="content">
|
||||||
<section class="main-section">
|
<section class="main-section">
|
||||||
<h1 class="content-title" id="overview">{title}</h1>
|
<h1 class="content-title" id="overview">{title}</h1>
|
||||||
<nav class="block sm:hidden">
|
<nav class="block sm:hidden">
|
||||||
<TableOfContents client:media="(max-width: 50em)" headings={headings} />
|
<TableOfContents client:media="(max-width: 50em)" headings={headings} />
|
||||||
</nav>
|
</nav>
|
||||||
<slot />
|
<slot />
|
||||||
</section>
|
</section>
|
||||||
<nav class="block sm:hidden">
|
<nav class="block sm:hidden">
|
||||||
<MoreMenu editHref={githubEditUrl} />
|
<MoreMenu editHref={githubEditUrl} />
|
||||||
</nav>
|
</nav>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.content {
|
.content {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
max-width: 75ch;
|
max-width: 75ch;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content > section {
|
.content > section {
|
||||||
margin-bottom: 4rem;
|
margin-bottom: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.block {
|
.block {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 50em) {
|
@media (min-width: 50em) {
|
||||||
.sm\:hidden {
|
.sm\:hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
---
|
---
|
||||||
import * as CONFIG from "../../config";
|
import * as CONFIG from '../../config';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
editHref: string;
|
editHref: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const { editHref } = Astro.props as Props;
|
const { editHref } = Astro.props as Props;
|
||||||
|
@ -11,65 +11,65 @@ const showMoreSection = CONFIG.COMMUNITY_INVITE_URL;
|
||||||
|
|
||||||
{showMoreSection && <h2 class="heading">More</h2>}
|
{showMoreSection && <h2 class="heading">More</h2>}
|
||||||
<ul>
|
<ul>
|
||||||
{
|
{
|
||||||
editHref && (
|
editHref && (
|
||||||
<li class={`heading-link depth-2`}>
|
<li class={`heading-link depth-2`}>
|
||||||
<a class="edit-on-github" href={editHref} target="_blank">
|
<a class="edit-on-github" href={editHref} target="_blank">
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
data-prefix="fas"
|
data-prefix="fas"
|
||||||
data-icon="pen"
|
data-icon="pen"
|
||||||
class="svg-inline--fa fa-pen fa-w-16"
|
class="svg-inline--fa fa-pen fa-w-16"
|
||||||
role="img"
|
role="img"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 512 512"
|
viewBox="0 0 512 512"
|
||||||
height="1em"
|
height="1em"
|
||||||
width="1em"
|
width="1em"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
d="M290.74 93.24l128.02 128.02-277.99 277.99-114.14 12.6C11.35 513.54-1.56 500.62.14 485.34l12.7-114.22 277.9-277.88zm207.2-19.06l-60.11-60.11c-18.75-18.75-49.16-18.75-67.91 0l-56.55 56.55 128.02 128.02 56.55-56.55c18.75-18.76 18.75-49.16 0-67.91z"
|
d="M290.74 93.24l128.02 128.02-277.99 277.99-114.14 12.6C11.35 513.54-1.56 500.62.14 485.34l12.7-114.22 277.9-277.88zm207.2-19.06l-60.11-60.11c-18.75-18.75-49.16-18.75-67.91 0l-56.55 56.55 128.02 128.02 56.55-56.55c18.75-18.76 18.75-49.16 0-67.91z"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<span>Edit this page</span>
|
<span>Edit this page</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CONFIG.COMMUNITY_INVITE_URL && (
|
CONFIG.COMMUNITY_INVITE_URL && (
|
||||||
<li class={`heading-link depth-2`}>
|
<li class={`heading-link depth-2`}>
|
||||||
<a href={CONFIG.COMMUNITY_INVITE_URL} target="_blank">
|
<a href={CONFIG.COMMUNITY_INVITE_URL} target="_blank">
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
data-prefix="fas"
|
data-prefix="fas"
|
||||||
data-icon="comment-alt"
|
data-icon="comment-alt"
|
||||||
class="svg-inline--fa fa-comment-alt fa-w-16"
|
class="svg-inline--fa fa-comment-alt fa-w-16"
|
||||||
role="img"
|
role="img"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 512 512"
|
viewBox="0 0 512 512"
|
||||||
height="1em"
|
height="1em"
|
||||||
width="1em"
|
width="1em"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
d="M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 9.8 11.2 15.5 19.1 9.7L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64z"
|
d="M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 9.8 11.2 15.5 19.1 9.7L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64z"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<span>Join our community</span>
|
<span>Join our community</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.edit-on-github {
|
.edit-on-github {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,31 +1,30 @@
|
||||||
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.
|
||||||
export type Frontmatter = {
|
export type Frontmatter = {
|
||||||
title: string;
|
title: string;
|
||||||
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,35 +34,35 @@ 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 = {
|
||||||
en: {
|
en: {
|
||||||
// TODO: create tutorial
|
// TODO: create tutorial
|
||||||
// Tutorial: [
|
// Tutorial: [
|
||||||
// { text: "Getting Started", link: "en/getting-started" },
|
// { text: "Getting Started", link: "en/getting-started" },
|
||||||
// { text: "Page 2", link: "en/page-2" },
|
// { text: "Page 2", link: "en/page-2" },
|
||||||
// { text: "Page 3", link: "en/page-3" },
|
// { text: "Page 3", link: "en/page-3" },
|
||||||
// ],
|
// ],
|
||||||
|
|
||||||
// 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' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,167 +1,153 @@
|
||||||
---
|
---
|
||||||
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;
|
||||||
headings: MarkdownHeading[];
|
headings: MarkdownHeading[];
|
||||||
};
|
};
|
||||||
|
|
||||||
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"}
|
<head>
|
||||||
lang={frontmatter.lang ?? "en-us"}
|
<HeadCommon />
|
||||||
class="initial"
|
<HeadSEO frontmatter={frontmatter} canonicalUrl={canonicalURL} />
|
||||||
>
|
<title>
|
||||||
<head>
|
{frontmatter.title ? `${frontmatter.title} | ${CONFIG.SITE.title}` : CONFIG.SITE.title}
|
||||||
<HeadCommon />
|
</title>
|
||||||
<HeadSEO frontmatter={frontmatter} canonicalUrl={canonicalURL} />
|
<style>
|
||||||
<title>
|
body {
|
||||||
{
|
width: 100%;
|
||||||
frontmatter.title
|
display: grid;
|
||||||
? `${frontmatter.title} | ${CONFIG.SITE.title}`
|
grid-template-rows: var(--theme-navbar-height) 1fr;
|
||||||
: CONFIG.SITE.title
|
--gutter: 0.5rem;
|
||||||
}
|
--doc-padding: 2rem;
|
||||||
</title>
|
}
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
width: 100%;
|
|
||||||
display: grid;
|
|
||||||
grid-template-rows: var(--theme-navbar-height) 1fr;
|
|
||||||
--gutter: 0.5rem;
|
|
||||||
--doc-padding: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout {
|
.layout {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-auto-flow: column;
|
grid-auto-flow: column;
|
||||||
grid-template-columns:
|
grid-template-columns:
|
||||||
minmax(var(--gutter), 1fr) minmax(0, var(--max-width))
|
minmax(var(--gutter), 1fr) minmax(0, var(--max-width))
|
||||||
minmax(var(--gutter), 1fr);
|
minmax(var(--gutter), 1fr);
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-sidebar {
|
.grid-sidebar {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grid-left {
|
#grid-left {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
background-color: var(--theme-bg);
|
background-color: var(--theme-bg);
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grid-main {
|
#grid-main {
|
||||||
padding: 0 var(--gutter);
|
padding: 0 var(--gutter);
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grid-right {
|
#grid-right {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 50em) {
|
@media (min-width: 50em) {
|
||||||
.layout {
|
.layout {
|
||||||
overflow: initial;
|
overflow: initial;
|
||||||
grid-template-columns: 20rem minmax(0, var(--max-width));
|
grid-template-columns: 20rem minmax(0, var(--max-width));
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grid-left {
|
#grid-left {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-left: 2rem;
|
padding-left: 2rem;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 72em) {
|
@media (min-width: 72em) {
|
||||||
.layout {
|
.layout {
|
||||||
grid-template-columns: 20rem minmax(0, var(--max-width)) 18rem;
|
grid-template-columns: 20rem minmax(0, var(--max-width)) 18rem;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grid-right {
|
#grid-right {
|
||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style is:global>
|
<style is:global>
|
||||||
.warning {
|
.warning {
|
||||||
background-color: var(--theme-bg-accent);
|
background-color: var(--theme-bg-accent);
|
||||||
color: var(--theme-text-accent);
|
color: var(--theme-text-accent);
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
padding: 1.25em 1.5rem;
|
padding: 1.25em 1.5rem;
|
||||||
border-radius: 0 0.25rem 0.25rem 0;
|
border-radius: 0 0.25rem 0.25rem 0;
|
||||||
border-left: 3px solid var(--theme-text-accent);
|
border-left: 3px solid var(--theme-text-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout > * {
|
.layout > * {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-sidebar-toggle {
|
.mobile-sidebar-toggle {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-sidebar-toggle #grid-left {
|
.mobile-sidebar-toggle #grid-left {
|
||||||
display: block;
|
display: block;
|
||||||
top: 2rem;
|
top: 2rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<Header currentPage={currentPage} />
|
<Header currentPage={currentPage} />
|
||||||
<main class="layout">
|
<main class="layout">
|
||||||
<aside id="grid-left" class="grid-sidebar" title="Site Navigation">
|
<aside id="grid-left" class="grid-sidebar" title="Site Navigation">
|
||||||
<LeftSidebar currentPage={currentPage} />
|
<LeftSidebar currentPage={currentPage} />
|
||||||
</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 frontmatter={frontmatter} headings={headings} githubEditUrl={githubEditUrl}>
|
||||||
<PageContent
|
<slot />
|
||||||
frontmatter={frontmatter}
|
</PageContent>
|
||||||
headings={headings}
|
</div>
|
||||||
githubEditUrl={githubEditUrl}
|
<aside id="grid-right" class="grid-sidebar" title="Table of Contents">
|
||||||
>
|
<RightSidebar headings={headings} githubEditUrl={githubEditUrl} />
|
||||||
<slot />
|
</aside>
|
||||||
</PageContent>
|
</main>
|
||||||
</div>
|
<Footer path={currentFile} />
|
||||||
<aside id="grid-right" class="grid-sidebar" title="Table of Contents">
|
</body>
|
||||||
<RightSidebar headings={headings} githubEditUrl={githubEditUrl} />
|
|
||||||
</aside>
|
|
||||||
</main>
|
|
||||||
<Footer path={currentFile} />
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
|
@ -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',
|
||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -160,16 +160,16 @@ 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 |
|
||||||
| [readOnly](#readonly) | `boolean` | optional |
|
| [readOnly](#readonly) | `boolean` | optional |
|
||||||
| [showValidationHints](#showvalidationhints) | `boolean` | optional |
|
| [showValidationHints](#showvalidationhints) | `boolean` | optional |
|
||||||
| [submitControl](#submitcontrol) | `Submit` | optional |
|
| [submitControl](#submitcontrol) | `Submit` | optional |
|
||||||
| [theme](#theme) | `'light' \| 'dark'` | optional |
|
| [theme](#theme) | `'light' \| 'dark'` | optional |
|
||||||
| [validateOnLoad](#validateOnLoad) | `boolean` | optional |
|
| [validateOnLoad](#validateOnLoad) | `boolean` | optional |
|
||||||
|
|
||||||
### `formGroups`
|
### `formGroups`
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
---
|
---
|
||||||
|
|
|
@ -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
|
||||||
---
|
---
|
||||||
|
@ -12,10 +12,10 @@ 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 |
|
||||||
|
|
||||||
### controls
|
### controls
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
// Redirect your homepage to the first page of documentation.
|
// Redirect your homepage to the first page of documentation.
|
||||||
// If you have a landing page, remove this script and add it here!
|
// If you have a landing page, remove this script and add it here!
|
||||||
window.location.pathname = `/en/api/form/form-component`;
|
window.location.pathname = `/en/api/form/form-component`;
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
// Redirect your homepage to the first page of documentation.
|
// Redirect your homepage to the first page of documentation.
|
||||||
// If you have a landing page, remove this script and add it here!
|
// If you have a landing page, remove this script and add it here!
|
||||||
window.location.pathname = `/en/api/form/form-component`;
|
window.location.pathname = `/en/api/form/form-component`;
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
window.location.pathname = `/en/api/validator/validators`;
|
window.location.pathname = `/en/api/validator/validators`;
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
// Redirect your homepage to the first page of documentation.
|
// Redirect your homepage to the first page of documentation.
|
||||||
// If you have a landing page, remove this script and add it here!
|
// If you have a landing page, remove this script and add it here!
|
||||||
window.location.pathname = `/en/introduction`;
|
window.location.pathname = `/en/introduction`;
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -48,11 +48,10 @@ 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) | [](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) | [](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) | [](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) | [](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 |
|
||||||
|
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -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_
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
// Redirect your homepage to the first page of documentation.
|
// Redirect your homepage to the first page of documentation.
|
||||||
// If you have a landing page, remove this script and add it here!
|
// If you have a landing page, remove this script and add it here!
|
||||||
window.location.pathname = `/en/introduction/`;
|
window.location.pathname = `/en/introduction/`;
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/base",
|
"extends": "@astro-reactive/tsconfig/astro-library.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"jsx": "preserve",
|
"jsx": "preserve"
|
||||||
"skipLibCheck": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
2
apps/landing-page/.eslintignore
Normal file
2
apps/landing-page/.eslintignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
dist
|
||||||
|
node_modules
|
5
apps/landing-page/.eslintrc.cjs
Normal file
5
apps/landing-page/.eslintrc.cjs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/** @type {import("@types/eslint").Linter.Config} */
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
extends: ['@astro-reactive/eslint-config-custom'],
|
||||||
|
};
|
24
apps/landing-page/.prettierrc.cjs
Normal file
24
apps/landing-page/.prettierrc.cjs
Normal 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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
|
@ -1 +0,0 @@
|
||||||
{}
|
|
|
@ -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'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
/* TODO: consider creating <Button> and <GradientText> components */
|
/* TODO: consider creating <Button> and <GradientText> components */
|
||||||
a,
|
a,
|
||||||
.btn {
|
.btn {
|
||||||
@apply transition-colors duration-200;
|
@apply transition-colors duration-200;
|
||||||
@apply hover:text-secondary;
|
@apply hover:text-secondary;
|
||||||
@apply focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-transparent focus:ring-secondary;
|
@apply focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-transparent focus:ring-secondary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gradient-text {
|
.gradient-text {
|
||||||
@apply text-transparent bg-clip-text;
|
@apply text-transparent bg-clip-text;
|
||||||
@apply bg-gradient-to-br from-indigo-500 via-fuchsia-500 to-pink-500;
|
@apply bg-gradient-to-br from-indigo-500 via-fuchsia-500 to-pink-500;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
@import "global.css";
|
@import 'global.css';
|
||||||
@import "theme.css";
|
@import 'theme.css';
|
||||||
|
|
|
@ -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%);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
59
package-lock.json
generated
|
@ -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",
|
||||||
|
|
Loading…
Reference in a new issue