|  | 
| 1 |  | -# React Shadcn Starter | 
|  | 1 | +# ⚛️ react-declarative-shadcn | 
| 2 | 2 | 
 | 
| 3 |  | -React + Vite + TypeScript template for building apps with shadcn/ui. | 
|  | 3 | +> The [shadcn ui kit](https://ui.shadcn.com/) bindings for [react-declarative](https://github.com/react-declarative/react-declarative/) | 
| 4 | 4 |  | 
| 5 |  | -## Getting Started | 
|  | 5 | + | 
| 6 | 6 | 
 | 
| 7 |  | -``` | 
| 8 |  | -git clone https://github.com/hayyi2/react-shadcn-starter.git new-project | 
| 9 |  | -cd new-project | 
| 10 |  | -npm install | 
| 11 |  | -npm run dev | 
| 12 |  | -``` | 
| 13 |  | - | 
| 14 |  | -## Getting Done | 
| 15 |  | - | 
| 16 |  | -- [x] Single page app with navigation and responsif layout | 
| 17 |  | - | 
| 18 |  | -- [x] Customable configuration `/config` | 
| 19 |  | - | 
| 20 |  | -- [x] Simple starting page/feature `/pages` | 
| 21 |  | - | 
| 22 |  | -- [x] Github action deploy github pages | 
|  | 7 | +## Getting started | 
| 23 | 8 | 
 | 
| 24 |  | -## Deploy `gh-pages` | 
| 25 |  | -- change `basenameProd` in `/vite.config.ts` | 
| 26 |  | -- create deploy key `GITHUB_TOKEN` in github `/settings/keys` | 
| 27 |  | -- commit and push changes code | 
| 28 |  | -- setup gihub pages to branch `gh-pages` | 
| 29 |  | -- run action `Build & Deploy` | 
| 30 |  | - | 
| 31 |  | -### Auto Deploy | 
| 32 |  | -- change file `.github/workflows/build-and-deploy.yml` | 
| 33 |  | -- Comment on `workflow_dispatch` | 
| 34 |  | -- Uncomment on `push` | 
| 35 |  | -```yaml | 
| 36 |  | -# on: | 
| 37 |  | -# workflow_dispatch: | 
| 38 |  | -on: | 
| 39 |  | - push: | 
| 40 |  | - branches: ["main"] | 
|  | 9 | +```bash | 
|  | 10 | +npm install | 
|  | 11 | +npm start | 
| 41 | 12 | ``` | 
| 42 | 13 | 
 | 
| 43 |  | -## Features | 
| 44 |  | - | 
| 45 |  | -- React + Vite + TypeScript | 
| 46 |  | -- Tailwind CSS | 
| 47 |  | -- [react-router-dom](https://www.npmjs.com/package/react-router-dom) | 
| 48 |  | -- [shadcn-ui](https://github.com/shadcn-ui/ui/) | 
| 49 |  | -- [radix-ui/icons](https://www.radix-ui.com/icons) | 
| 50 |  | - | 
| 51 |  | -## Project Structure | 
|  | 14 | +## Code sample | 
|  | 15 | + | 
|  | 16 | +```tsx | 
|  | 17 | +import { FieldType, One, TypedField } from "react-declarative"; | 
|  | 18 | +import { FormGroup } from "@/components/ui/form"; | 
|  | 19 | +import { Button } from "@/components/ui/button"; | 
|  | 20 | + | 
|  | 21 | +const frameworks = [ | 
|  | 22 | + { | 
|  | 23 | + value: "next.js", | 
|  | 24 | + label: "Next.js", | 
|  | 25 | + }, | 
|  | 26 | + { | 
|  | 27 | + value: "sveltekit", | 
|  | 28 | + label: "SvelteKit", | 
|  | 29 | + }, | 
|  | 30 | + { | 
|  | 31 | + value: "nuxt.js", | 
|  | 32 | + label: "Nuxt.js", | 
|  | 33 | + }, | 
|  | 34 | + { | 
|  | 35 | + value: "remix", | 
|  | 36 | + label: "Remix", | 
|  | 37 | + }, | 
|  | 38 | + { | 
|  | 39 | + value: "astro", | 
|  | 40 | + label: "Astro", | 
|  | 41 | + }, | 
|  | 42 | +]; | 
|  | 43 | + | 
|  | 44 | +const fields: TypedField[] = [ | 
|  | 45 | + { | 
|  | 46 | + type: FieldType.Typography, | 
|  | 47 | + typoVariant: "h4", | 
|  | 48 | + placeholder: "Base information", | 
|  | 49 | + }, | 
|  | 50 | + { | 
|  | 51 | + type: FieldType.Outline, | 
|  | 52 | + fieldBottomMargin: "1", | 
|  | 53 | + fields: [ | 
|  | 54 | + { | 
|  | 55 | + type: FieldType.Typography, | 
|  | 56 | + typoVariant: "h6", | 
|  | 57 | + placeholder: "Profile Information", | 
|  | 58 | + }, | 
|  | 59 | + { | 
|  | 60 | + type: FieldType.Text, | 
|  | 61 | + validation: { required: true }, | 
|  | 62 | + name: "email", | 
|  | 63 | + title: "Email", | 
|  | 64 | + placeholder: "tripolskypetr@gmail.com", | 
|  | 65 | + description: "This will not be shared", | 
|  | 66 | + desktopColumns: "6", | 
|  | 67 | + phoneColumns: "12", | 
|  | 68 | + }, | 
|  | 69 | + { | 
|  | 70 | + type: FieldType.Text, | 
|  | 71 | + validation: { required: true }, | 
|  | 72 | + name: "password", | 
|  | 73 | + title: "Password", | 
|  | 74 | + placeholder: "Password", | 
|  | 75 | + description: "Use a secure password", | 
|  | 76 | + desktopColumns: "6", | 
|  | 77 | + phoneColumns: "12", | 
|  | 78 | + }, | 
|  | 79 | + { | 
|  | 80 | + type: FieldType.Text, | 
|  | 81 | + inputRows: 3, | 
|  | 82 | + validation: { required: true }, | 
|  | 83 | + name: "bio", | 
|  | 84 | + title: "Tell me about yourself", | 
|  | 85 | + placeholder: "I am ...", | 
|  | 86 | + description: "This will be used by AI", | 
|  | 87 | + desktopColumns: "12", | 
|  | 88 | + }, | 
|  | 89 | + ], | 
|  | 90 | + }, | 
|  | 91 | + { | 
|  | 92 | + type: FieldType.Typography, | 
|  | 93 | + typoVariant: "h4", | 
|  | 94 | + placeholder: "Other preferences", | 
|  | 95 | + }, | 
|  | 96 | + { | 
|  | 97 | + type: FieldType.Outline, | 
|  | 98 | + fieldBottomMargin: "1", | 
|  | 99 | + fields: [ | 
|  | 100 | + { | 
|  | 101 | + type: FieldType.Typography, | 
|  | 102 | + typoVariant: "h6", | 
|  | 103 | + placeholder: "Account Settings", | 
|  | 104 | + }, | 
|  | 105 | + { | 
|  | 106 | + type: FieldType.Component, | 
|  | 107 | + style: { width: "100%", marginBottom: "1rem" }, | 
|  | 108 | + element: () => ( | 
|  | 109 | + <FormGroup | 
|  | 110 | + label="Account Type" | 
|  | 111 | + description="Select your account type." | 
|  | 112 | + /> | 
|  | 113 | + ), | 
|  | 114 | + }, | 
|  | 115 | + { | 
|  | 116 | + type: FieldType.Box, | 
|  | 117 | + style: { width: "100%" }, | 
|  | 118 | + fields: [ | 
|  | 119 | + { | 
|  | 120 | + type: FieldType.Radio, | 
|  | 121 | + radioValue: "staff", | 
|  | 122 | + title: "Staff", | 
|  | 123 | + name: "account", | 
|  | 124 | + }, | 
|  | 125 | + { | 
|  | 126 | + type: FieldType.Radio, | 
|  | 127 | + radioValue: "admin", | 
|  | 128 | + title: "Admin", | 
|  | 129 | + name: "account", | 
|  | 130 | + }, | 
|  | 131 | + { | 
|  | 132 | + type: FieldType.Radio, | 
|  | 133 | + radioValue: "owner", | 
|  | 134 | + title: "Owner", | 
|  | 135 | + name: "account", | 
|  | 136 | + }, | 
|  | 137 | + ], | 
|  | 138 | + }, | 
|  | 139 | + { | 
|  | 140 | + type: FieldType.Combo, | 
|  | 141 | + name: "framework", | 
|  | 142 | + title: "Favorite Framework", | 
|  | 143 | + placeholder: "Select framework", | 
|  | 144 | + description: "More important than your skills", | 
|  | 145 | + itemList: frameworks.map(({ value }) => value), | 
|  | 146 | + tr: (value) => | 
|  | 147 | + frameworks.find((f) => f.value === value)?.label || value, | 
|  | 148 | + desktopColumns: "12", | 
|  | 149 | + }, | 
|  | 150 | + ], | 
|  | 151 | + }, | 
|  | 152 | + { | 
|  | 153 | + type: FieldType.Typography, | 
|  | 154 | + typoVariant: "h4", | 
|  | 155 | + placeholder: "Notifications", | 
|  | 156 | + }, | 
|  | 157 | + { | 
|  | 158 | + type: FieldType.Outline, | 
|  | 159 | + fieldBottomMargin: "1", | 
|  | 160 | + fields: [ | 
|  | 161 | + { | 
|  | 162 | + type: FieldType.Typography, | 
|  | 163 | + typoVariant: "h6", | 
|  | 164 | + placeholder: "Preferences", | 
|  | 165 | + }, | 
|  | 166 | + { | 
|  | 167 | + type: FieldType.Switch, | 
|  | 168 | + title: "Enable notifications", | 
|  | 169 | + name: "notify", | 
|  | 170 | + }, | 
|  | 171 | + ], | 
|  | 172 | + }, | 
|  | 173 | + { | 
|  | 174 | + type: FieldType.Typography, | 
|  | 175 | + typoVariant: "h4", | 
|  | 176 | + placeholder: "Finish", | 
|  | 177 | + }, | 
|  | 178 | + { | 
|  | 179 | + type: FieldType.Outline, | 
|  | 180 | + fieldBottomMargin: "1", | 
|  | 181 | + fields: [ | 
|  | 182 | + { | 
|  | 183 | + type: FieldType.Checkbox, | 
|  | 184 | + title: "Accept terms & conditions", | 
|  | 185 | + name: "agree", | 
|  | 186 | + }, | 
|  | 187 | + { | 
|  | 188 | + type: FieldType.Button, | 
|  | 189 | + fieldRightMargin: "0", | 
|  | 190 | + title: "Submit", | 
|  | 191 | + }, | 
|  | 192 | + { | 
|  | 193 | + type: FieldType.Component, | 
|  | 194 | + element: () => ( | 
|  | 195 | + <Button variant="destructive">Clear</Button> | 
|  | 196 | + ) | 
|  | 197 | + } | 
|  | 198 | + ], | 
|  | 199 | + }, | 
|  | 200 | +]; | 
|  | 201 | + | 
|  | 202 | +export default function MainPage() { | 
|  | 203 | + return <One fields={fields} sx={{ p: 1 }} />; | 
|  | 204 | +} | 
| 52 | 205 | 
 | 
| 53 | 206 | ``` | 
| 54 |  | -react-shadcn-starter/ | 
| 55 |  | -├── public/ # Public assets | 
| 56 |  | -├── src/ # Application source code | 
| 57 |  | -│ ├── components/ # React components | 
| 58 |  | -│ │ └── ui/ # shadc/ui components | 
| 59 |  | -│ │ └── layouts/ # layouts components | 
| 60 |  | -│ ├── context/ # contexts components | 
| 61 |  | -│ ├── config/ # Config data | 
| 62 |  | -│ ├── hook/ # Custom hooks | 
| 63 |  | -│ ├── lib/ # Utility functions | 
| 64 |  | -│ ├── pages/ # pages/features components | 
| 65 |  | -│ ├── App.tsx # Application entry point | 
| 66 |  | -│ ├── index.tsx # Main rendering file | 
| 67 |  | -│ └── Router.tsx # Routes component | 
| 68 |  | -├── index.html # HTML entry point | 
| 69 |  | -├── postcss.config.js # PostCSS configuration | 
| 70 |  | -├── tailwind.config.js # Tailwind CSS configuration | 
| 71 |  | -├── tsconfig.json # TypeScript configuration | 
| 72 |  | -└── vite.config.ts # Vite configuration | 
| 73 |  | -``` | 
| 74 |  | - | 
| 75 |  | -## License | 
| 76 |  | - | 
| 77 |  | -This project is licensed under the MIT License. See the [LICENSE](https://github.com/hayyi2/react-shadcn-starter/blob/main/LICENSE) file for details.  | 
|  | 
0 commit comments