├── .gitignore ├── README.md └── examples ├── basic-tags ├── .gitignore ├── .marko-run │ └── routes.d.ts ├── README.md ├── package.json ├── src │ ├── routes │ │ ├── +layout.marko │ │ ├── +meta.json │ │ ├── +page.marko │ │ ├── favicon.png │ │ └── logo.svg │ └── tags │ │ └── mouse-mask.marko └── tsconfig.json ├── basic-ts ├── .gitignore ├── .marko-run │ └── routes.d.ts ├── README.md ├── package.json ├── src │ ├── components │ │ └── mouse-mask.marko │ └── routes │ │ ├── +layout.marko │ │ ├── +meta.json │ │ ├── +page.marko │ │ ├── favicon.png │ │ └── logo.svg └── tsconfig.json ├── basic ├── .gitignore ├── README.md ├── package.json └── src │ ├── components │ └── mouse-mask.marko │ └── routes │ ├── +layout.marko │ ├── +meta.json │ ├── +page.marko │ ├── favicon.png │ └── logo.svg ├── color-picker ├── .gitignore ├── README.md ├── package.json └── src │ ├── components │ ├── color-picker-footer │ │ ├── component.js │ │ ├── demo.marko │ │ ├── index.marko │ │ └── style.css │ ├── color-picker-header │ │ ├── demo.marko │ │ ├── index.marko │ │ └── test.js │ ├── color-picker-selection │ │ ├── demo.marko │ │ ├── index.marko │ │ └── test.js │ ├── color-picker │ │ ├── demo.marko │ │ └── index.marko │ └── sample-header │ │ ├── index.marko │ │ └── logo.png │ ├── pages │ └── index.marko │ └── util │ └── getDefaultColors.js ├── language-guide ├── .gitignore ├── package.json └── src │ ├── components │ ├── async │ │ └── await.marko │ ├── attributes │ │ ├── boolean.marko │ │ ├── class.marko │ │ ├── conditional.marko │ │ ├── shorthand.marko │ │ ├── spread-attributes.marko │ │ └── style.marko │ ├── conditionals │ │ ├── conditional-parent-tag.marko │ │ └── if-else.marko │ ├── custom-tags │ │ ├── components │ │ │ └── hello │ │ │ │ └── index.marko │ │ └── hello.marko │ ├── dynamic-tagname │ │ ├── components │ │ │ ├── fancy-heading.marko │ │ │ ├── goodbye.marko │ │ │ └── hello.marko │ │ ├── dynamic-component.marko │ │ ├── dynamic-native-tag.marko │ │ └── provide-body-content.marko │ ├── dynamic-text │ │ ├── html.marko │ │ └── text.marko │ ├── embedded-js │ │ ├── blocks.marko │ │ ├── helper-functions.marko │ │ ├── import.marko │ │ └── variables.marko │ ├── import │ │ ├── helper.js │ │ └── import.marko │ ├── layouts │ │ ├── components │ │ │ └── layout.marko │ │ └── index.marko │ ├── looping │ │ ├── array.marko │ │ ├── properties.marko │ │ ├── range-loop.marko │ │ ├── separator.marko │ │ ├── while.marko │ │ └── with-index.marko │ ├── macros │ │ ├── index.marko │ │ └── macro-body.marko │ ├── parent-child-communication │ │ ├── components │ │ │ └── language-selector.marko │ │ └── parent.marko │ ├── sample-header │ │ ├── component.js │ │ ├── index.marko │ │ └── logo.png │ └── whitespace │ │ └── index.marko │ └── pages │ └── index.marko ├── lasso-express ├── .gitignore ├── README.md ├── babel.config.js ├── package.json └── src │ ├── components │ ├── app-header │ │ ├── index.marko │ │ └── logo.png │ └── app-layout │ │ └── index.marko │ ├── pages │ └── home │ │ ├── components │ │ └── app-hello │ │ │ └── index.marko │ │ ├── index.js │ │ └── template.marko │ └── server.js ├── lasso-fastify ├── README.md ├── babel.config.js ├── package.json └── src │ ├── components │ ├── app-header │ │ ├── index.marko │ │ └── logo.png │ └── app-layout │ │ └── index.marko │ ├── pages │ └── home │ │ ├── components │ │ └── app-hello │ │ │ └── index.marko │ │ ├── index.js │ │ └── template.marko │ └── server.js ├── lasso-koa ├── README.md ├── babel.config.js ├── package.json └── src │ ├── components │ ├── app-header │ │ ├── index.marko │ │ └── logo.png │ └── app-layout │ │ └── index.marko │ ├── pages │ └── home │ │ ├── components │ │ └── app-hello │ │ │ └── index.marko │ │ ├── index.js │ │ └── template.marko │ └── server.js ├── library-ts ├── .gitignore ├── .husky │ ├── .gitignore │ └── pre-commit ├── .lintstagedrc.json ├── .postcssrc.json ├── .prettierignore ├── .prettierrc.json ├── .storybook │ └── main.ts ├── .stylelintignore ├── .stylelintrc.json ├── .vscode │ └── extensions.json ├── README.md ├── eslint.config.js ├── marko.json ├── package.json ├── src │ ├── components │ │ └── counter │ │ │ ├── __snapshots__ │ │ │ └── server.test.ts.snap │ │ │ ├── browser.test.ts │ │ │ ├── index.marko │ │ │ ├── server.test.ts │ │ │ ├── stories.ts │ │ │ └── styles.module.css │ └── types.d.ts ├── tsconfig.json ├── vitest.config.ts └── vitest.workspace.ts ├── rollup-express ├── .browserslistrc ├── .gitignore ├── README.md ├── babel.config.js ├── package.json ├── postcss.config.js ├── rollup.config.mjs └── src │ ├── components │ ├── app-button │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-checkbox │ │ ├── images │ │ │ ├── checked.svg │ │ │ └── unchecked.svg │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-fetch-data │ │ ├── index.marko │ │ ├── loading.svg │ │ └── style.css │ ├── app-layout │ │ ├── favicon.png │ │ ├── index.marko │ │ └── style.css │ ├── app-main │ │ ├── component.js │ │ ├── index.marko │ │ └── style.css │ ├── app-notification │ │ ├── index.marko │ │ └── style.css │ ├── app-notifications │ │ ├── component.js │ │ └── index.marko │ ├── app-number-spinner │ │ ├── index.marko │ │ └── style.css │ ├── app-overlay │ │ ├── component.js │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-progress-bar │ │ ├── component.js │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-sections │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-state-select │ │ ├── assets │ │ │ ├── CA.png │ │ │ └── CO.png │ │ └── index.marko │ ├── app-tabs │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ └── sample-header │ │ ├── index.marko │ │ └── marko.png │ ├── index.js │ ├── pages │ └── index │ │ ├── index.js │ │ └── template.marko │ └── services │ └── users │ ├── index.js │ ├── load-browser.js │ ├── load.js │ ├── mock-users-data.json │ └── package.json ├── tic-tac-toe ├── .gitignore ├── package.json └── src │ ├── components │ ├── sample-header │ │ ├── component.js │ │ ├── index.marko │ │ └── logo.png │ └── tic-tac-toe │ │ ├── TicTacToe.js │ │ ├── index.marko │ │ └── style.css │ └── pages │ └── index.marko ├── todomvc ├── .gitignore ├── package.json └── src │ ├── components │ ├── sample-header │ │ ├── component.js │ │ ├── index.marko │ │ └── logo.png │ ├── todomvc-app │ │ ├── demo.marko │ │ └── index.marko │ ├── todomvc-footer │ │ ├── demo.marko │ │ └── index.marko │ ├── todomvc-header │ │ ├── demo.marko │ │ └── index.marko │ ├── todomvc-main │ │ ├── demo.marko │ │ └── index.marko │ └── todomvc-todo-item │ │ ├── animations.js │ │ ├── component.js │ │ ├── demo.marko │ │ ├── index.marko │ │ └── style.css │ └── pages │ ├── app.js │ └── index.marko ├── ui-components-playground ├── .gitignore ├── README.md ├── package.json └── src │ ├── components │ ├── app-button │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-checkbox │ │ ├── images │ │ │ ├── checked.svg │ │ │ └── unchecked.svg │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-layout │ │ ├── index.marko │ │ └── style.css │ ├── app-main │ │ ├── component.js │ │ ├── index.marko │ │ └── style.css │ ├── app-markdown │ │ ├── code-generator.js │ │ └── marko-tag.json │ ├── app-notification │ │ ├── index.marko │ │ └── style.css │ ├── app-notifications │ │ ├── component.js │ │ └── index.marko │ ├── app-number-spinner │ │ ├── index.marko │ │ └── style.css │ ├── app-overlay │ │ ├── component.js │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-progress-bar │ │ ├── component.js │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-sections │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-state-select │ │ ├── assets │ │ │ ├── CA.png │ │ │ └── CO.png │ │ └── index.marko │ ├── app-tabs │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ └── sample-header │ │ ├── index.marko │ │ └── logo.png │ └── pages │ └── index │ └── index.marko ├── vite-cloudflare-hn ├── .gitignore ├── README.md ├── package.json ├── src │ ├── api │ │ └── index.js │ ├── components │ │ ├── comment.marko │ │ ├── layout.marko │ │ ├── layout.style.css │ │ ├── story.marko │ │ └── toggle.marko │ ├── dev-env.js │ ├── dev-server.js │ ├── pages │ │ ├── index.marko │ │ ├── story.$id.marko │ │ └── user.$id.marko │ ├── router.js │ └── worker.js ├── vite.config.js └── wrangler.toml ├── vite-cloudflare ├── .gitignore ├── .postcssrc.json ├── README.md ├── package.json ├── src │ ├── components │ │ ├── app-layout │ │ │ ├── favicon.png │ │ │ └── index.marko │ │ └── mouse-mask.marko │ ├── dev-server.js │ ├── pages │ │ ├── index.marko │ │ └── logo.svg │ ├── router.js │ └── worker.js ├── vite.config.js └── wrangler.toml ├── vite-express ├── .gitignore ├── README.md ├── index.js ├── package.json ├── src │ ├── components │ │ ├── app-button │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ ├── app-checkbox │ │ │ ├── images │ │ │ │ ├── checked.svg │ │ │ │ └── unchecked.svg │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ ├── app-fetch-data │ │ │ ├── index.marko │ │ │ ├── loading.svg │ │ │ └── style.css │ │ ├── app-layout │ │ │ ├── favicon.png │ │ │ ├── index.marko │ │ │ └── style.css │ │ ├── app-main │ │ │ ├── component.js │ │ │ ├── index.marko │ │ │ └── style.css │ │ ├── app-notification │ │ │ ├── index.marko │ │ │ └── style.css │ │ ├── app-notifications │ │ │ ├── component.js │ │ │ └── index.marko │ │ ├── app-number-spinner │ │ │ ├── index.marko │ │ │ └── style.css │ │ ├── app-overlay │ │ │ ├── component.js │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ ├── app-progress-bar │ │ │ ├── component.js │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ ├── app-sections │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ ├── app-state-select │ │ │ ├── assets │ │ │ │ ├── CA.png │ │ │ │ └── CO.png │ │ │ └── index.marko │ │ ├── app-tabs │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ └── sample-header │ │ │ ├── index.marko │ │ │ └── marko.png │ ├── index.js │ ├── pages │ │ └── index │ │ │ ├── index.js │ │ │ └── template.marko │ └── services │ │ └── users │ │ ├── index.js │ │ ├── load-browser.js │ │ ├── load.js │ │ ├── mock-users-data.json │ │ └── package.json └── vite.config.js ├── vite-fastify ├── .gitignore ├── .postcssrc.json ├── README.md ├── index.js ├── package.json ├── src │ ├── components │ │ ├── app-layout │ │ │ ├── favicon.png │ │ │ └── index.marko │ │ └── mouse-mask.marko │ ├── index.js │ └── pages │ │ └── index │ │ ├── index.js │ │ ├── logo.svg │ │ └── template.marko └── vite.config.js ├── vite-http ├── .gitignore ├── .postcssrc.json ├── README.md ├── index.js ├── package.json ├── src │ ├── components │ │ ├── app-layout │ │ │ ├── favicon.png │ │ │ └── index.marko │ │ └── mouse-mask.marko │ ├── index.js │ ├── logo.svg │ ├── send.js │ └── template.marko └── vite.config.js ├── webpack-express ├── .gitignore ├── README.md ├── package.json ├── src │ ├── components │ │ ├── app-button │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ ├── app-checkbox │ │ │ ├── images │ │ │ │ ├── checked.svg │ │ │ │ └── unchecked.svg │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ ├── app-fetch-data │ │ │ ├── index.marko │ │ │ ├── loading.svg │ │ │ └── style.css │ │ ├── app-layout │ │ │ ├── favicon.png │ │ │ ├── index.marko │ │ │ └── style.css │ │ ├── app-main │ │ │ ├── component.js │ │ │ ├── index.marko │ │ │ └── style.css │ │ ├── app-markdown │ │ │ ├── code-generator.js │ │ │ └── marko-tag.json │ │ ├── app-notification │ │ │ ├── index.marko │ │ │ └── style.css │ │ ├── app-notifications │ │ │ ├── component.js │ │ │ └── index.marko │ │ ├── app-number-spinner │ │ │ ├── index.marko │ │ │ └── style.css │ │ ├── app-overlay │ │ │ ├── component.js │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ ├── app-progress-bar │ │ │ ├── component.js │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ ├── app-sections │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ ├── app-state-select │ │ │ ├── assets │ │ │ │ ├── CA.png │ │ │ │ └── CO.png │ │ │ └── index.marko │ │ ├── app-tabs │ │ │ ├── index.marko │ │ │ ├── marko-tag.json │ │ │ └── style.css │ │ └── sample-header │ │ │ ├── index.marko │ │ │ └── logo.png │ ├── index.js │ ├── pages │ │ └── index │ │ │ ├── index.js │ │ │ └── template.marko │ └── services │ │ └── users │ │ ├── index.js │ │ ├── load-browser.js │ │ ├── load.js │ │ ├── mock-users-data.json │ │ └── package.json └── webpack.config.js └── webpack-fastify ├── .gitignore ├── README.md ├── package.json ├── src ├── components │ ├── app-button │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-checkbox │ │ ├── images │ │ │ ├── checked.svg │ │ │ └── unchecked.svg │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-fetch-data │ │ ├── index.marko │ │ ├── loading.svg │ │ └── style.css │ ├── app-layout │ │ ├── favicon.png │ │ ├── index.marko │ │ └── style.css │ ├── app-main │ │ ├── component.js │ │ ├── index.marko │ │ └── style.css │ ├── app-markdown │ │ ├── code-generator.js │ │ └── marko-tag.json │ ├── app-notification │ │ ├── index.marko │ │ └── style.css │ ├── app-notifications │ │ ├── component.js │ │ └── index.marko │ ├── app-number-spinner │ │ ├── index.marko │ │ └── style.css │ ├── app-overlay │ │ ├── component.js │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-progress-bar │ │ ├── component.js │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-sections │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ ├── app-state-select │ │ ├── assets │ │ │ ├── CA.png │ │ │ └── CO.png │ │ └── index.marko │ ├── app-tabs │ │ ├── index.marko │ │ ├── marko-tag.json │ │ └── style.css │ └── sample-header │ │ ├── index.marko │ │ └── logo.png ├── index.js ├── pages │ └── index │ │ ├── index.js │ │ └── template.marko └── services │ └── users │ ├── index.js │ ├── load-browser.js │ ├── load.js │ ├── mock-users-data.json │ └── package.json └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | **/.git/ 2 | **/node_modules/** 3 | **/build/** 4 | **/static/** 5 | **/dist/ 6 | **/.cache/ 7 | **/*.log 8 | **/*.marko.js 9 | **/package-lock.json 10 | **/yarn.lock 11 | **/.DS_STORE 12 | **/.vscode/settings.json 13 | lerna-debug.log 14 | npm-debug.log -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Marko Logo 3 |

4 | 5 |

MarkoJS Examples

6 | 7 | ## Getting Started 8 | ### Step 1 9 | 10 | ```console 11 | foo@bar:$ npx @marko/create my-app 12 | ``` 13 | 14 | This command will give you a selection of examples to pick from. 15 | 16 | ### Step 2 17 | After picking a example, it will be downloaded and all dependencies will be installed. 18 | For most examples, you can quickly get up and running by using the following command: 19 | 20 | ```console 21 | foo@bar:$ cd ./my-app 22 | foo@bar:$ npm run dev 23 | ``` 24 | 25 | If this command is missing, review the `README.md` for the chosen example. 26 | 27 | ## Additional Resources 28 | 29 | - [marko-cli](https://github.com/marko-js/marko-cli) 30 | - [marko-serve](https://github.com/marko-js/cli/blob/master/packages/serve/README.md) 31 | -------------------------------------------------------------------------------- /examples/basic-tags/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | *.log 4 | .env 5 | -------------------------------------------------------------------------------- /examples/basic-tags/README.md: -------------------------------------------------------------------------------- 1 | # Thanks for checking out Marko 2 | 3 | # Installation 4 | 5 | ``` 6 | npm init marko -- --template basic-tags 7 | cd marko-app 8 | npm install 9 | npm run dev 10 | ``` 11 | 12 | ## Overview 13 | 14 | This project is powered by [@marko/run](https://github.com/marko-js/run). 15 | 16 | - Run `npm run dev` to start the development server 17 | - Run `npm run build` to build a production-ready node.js server 18 | - Run `npm run preview` to run the production server 19 | 20 | ## Adding Pages 21 | 22 | Pages map to the directory structure. You can add additional pages by creating files/directories under `src/routes` with `+page.marko` files. Learn more in the [`@marko/run` docs](https://github.com/marko-js/run/#file-based-routing). 23 | 24 | -------------------------------------------------------------------------------- /examples/basic-tags/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "basic-tags", 3 | "description": "The default Marko starter app with TypeScript", 4 | "version": "1.0.0", 5 | "type": "module", 6 | "dependencies": { 7 | "marko": "^6.0.0" 8 | }, 9 | "devDependencies": { 10 | "@marko/run": "^0.6.4" 11 | }, 12 | "private": true, 13 | "scripts": { 14 | "dev": "marko-run", 15 | "build": "marko-run build", 16 | "preview": "marko-run preview", 17 | "start": "node --enable-source-maps ./dist/index.mjs" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/basic-tags/src/routes/+layout.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ${$global.meta.pageTitle || "Marko"} 9 | 10 | 11 | <${input.content}/> 12 | 13 | 14 | 15 | 32 | -------------------------------------------------------------------------------- /examples/basic-tags/src/routes/+meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "pageTitle": "Welcome to Marko" 3 | } -------------------------------------------------------------------------------- /examples/basic-tags/src/routes/+page.marko: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |

7 | Edit 8 | ./src/routes/_index/+page.marko 9 | and save to reload. 10 |

11 | 12 | Learn Marko 13 | 14 |
15 |
16 | 17 | 18 | 34 | -------------------------------------------------------------------------------- /examples/basic-tags/src/routes/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js/examples/90689e6423c68147794cc8d278b1523f1764026b/examples/basic-tags/src/routes/favicon.png -------------------------------------------------------------------------------- /examples/basic-tags/src/tags/mouse-mask.marko: -------------------------------------------------------------------------------- 1 | export interface Input {} 2 | 3 | 4 | 5 | 17 | 18 |
19 | 20 | 46 | -------------------------------------------------------------------------------- /examples/basic-tags/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*"], 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "lib": ["dom", "ESNext"], 6 | "module": "ESNext", 7 | "moduleResolution": "bundler", 8 | "noEmit": true, 9 | "noImplicitOverride": true, 10 | "noUnusedLocals": true, 11 | "outDir": "dist", 12 | "resolveJsonModule": true, 13 | "skipLibCheck": true, 14 | "strict": true, 15 | "target": "ESNext", 16 | "verbatimModuleSyntax": true, 17 | "types": ["vite/client"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/basic-ts/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | *.log 4 | .env 5 | -------------------------------------------------------------------------------- /examples/basic-ts/README.md: -------------------------------------------------------------------------------- 1 | # Thanks for checking out Marko 2 | 3 | # Installation 4 | 5 | ``` 6 | npx @marko/create marko-app --template basic-ts 7 | cd marko-app 8 | npm install 9 | npm run dev 10 | ``` 11 | 12 | ## Overview 13 | 14 | This project is powered by [@marko/run](https://github.com/marko-js/run). 15 | 16 | - Run `npm run dev` to start the development server 17 | - Run `npm run build` to build a production-ready node.js server 18 | - Run `npm run preview` to run the production server 19 | 20 | ## Adding Pages 21 | 22 | Pages map to the directory structure. You can add additional pages by creating files/directories under `src/routes` with `+page.marko` files. Learn more in the [`@marko/run` docs](https://github.com/marko-js/run/#file-based-routing). 23 | 24 | -------------------------------------------------------------------------------- /examples/basic-ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "basic-ts", 3 | "description": "The default Marko starter app with TypeScript", 4 | "version": "1.0.0", 5 | "type": "module", 6 | "dependencies": { 7 | "marko": "^5.37.20" 8 | }, 9 | "devDependencies": { 10 | "@marko/run": "^0.6.1" 11 | }, 12 | "private": true, 13 | "scripts": { 14 | "dev": "marko-run", 15 | "build": "marko-run build", 16 | "preview": "marko-run preview", 17 | "start": "node --enable-source-maps ./dist/index.mjs" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/basic-ts/src/routes/+layout.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ${$global.meta.pageTitle || 'Marko'} 9 | 10 | 11 | <${input.renderBody}/> 12 | 13 | 14 | 15 | style { 16 | html, body { 17 | font-family: system-ui; 18 | padding: 0; 19 | margin: 0; 20 | height: 100%; 21 | color: #fff; 22 | background: #15151e; 23 | } 24 | code { 25 | color: #fc0; 26 | } 27 | a { 28 | color: #09c; 29 | } 30 | } -------------------------------------------------------------------------------- /examples/basic-ts/src/routes/+meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "pageTitle": "Welcome to Marko" 3 | } -------------------------------------------------------------------------------- /examples/basic-ts/src/routes/+page.marko: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 |
6 |

Edit ./src/routes/_index/+page.marko and save to reload.

7 | 8 | Learn Marko 9 | 10 |
11 |
12 | 13 | 14 | style { 15 | .container { 16 | display:flex; 17 | flex-direction: column; 18 | justify-content: center; 19 | align-items: center; 20 | font-size: clamp(1em, 2vw, 2em); 21 | padding: 1em; 22 | box-sizing: border-box; 23 | height:100%; 24 | width:100%; 25 | } 26 | img.logo { 27 | width:12em; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/basic-ts/src/routes/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js/examples/90689e6423c68147794cc8d278b1523f1764026b/examples/basic-ts/src/routes/favicon.png -------------------------------------------------------------------------------- /examples/basic-ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*"], 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "lib": ["dom", "ESNext"], 6 | "module": "ESNext", 7 | "moduleResolution": "bundler", 8 | "noEmit": true, 9 | "noImplicitOverride": true, 10 | "noUnusedLocals": true, 11 | "outDir": "dist", 12 | "resolveJsonModule": true, 13 | "skipLibCheck": true, 14 | "strict": true, 15 | "target": "ESNext", 16 | "verbatimModuleSyntax": true, 17 | "types": ["vite/client"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/basic/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | *.log 4 | .env 5 | -------------------------------------------------------------------------------- /examples/basic/README.md: -------------------------------------------------------------------------------- 1 | # Thanks for checking out Marko 2 | 3 | # Installation 4 | 5 | ``` 6 | npx @marko/create marko-app --template basic 7 | cd marko-app 8 | npm install 9 | npm run dev 10 | ``` 11 | 12 | ## Overview 13 | 14 | This project is powered by [@marko/run](https://github.com/marko-js/run). 15 | 16 | - Run `npm run dev` to start the development server 17 | - Run `npm run build` to build a production-ready node.js server 18 | - Run `npm run preview` to run the production server 19 | 20 | ## Adding Pages 21 | 22 | Pages map to the directory structure. You can add additional pages by creating files/directories under `src/routes` with `+page.marko` files. Learn more in the [`@marko/run` docs](https://github.com/marko-js/run/#file-based-routing). 23 | 24 | -------------------------------------------------------------------------------- /examples/basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "basic", 3 | "description": "The default Marko starter app", 4 | "version": "1.0.0", 5 | "type": "module", 6 | "dependencies": { 7 | "marko": "^5.37.20" 8 | }, 9 | "devDependencies": { 10 | "@marko/run": "^0.6.1" 11 | }, 12 | "private": true, 13 | "scripts": { 14 | "dev": "marko-run", 15 | "build": "marko-run build", 16 | "preview": "marko-run preview", 17 | "start": "node --enable-source-maps ./dist/index.mjs" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/basic/src/routes/+layout.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ${$global.meta.pageTitle || 'Marko'} 9 | 10 | 11 | <${input.renderBody}/> 12 | 13 | 14 | 15 | style { 16 | html, body { 17 | font-family: system-ui; 18 | padding: 0; 19 | margin: 0; 20 | height: 100%; 21 | color: #fff; 22 | background: #15151e; 23 | } 24 | code { 25 | color: #fc0; 26 | } 27 | a { 28 | color: #09c; 29 | } 30 | } -------------------------------------------------------------------------------- /examples/basic/src/routes/+meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "pageTitle": "Welcome to Marko" 3 | } -------------------------------------------------------------------------------- /examples/basic/src/routes/+page.marko: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 |
6 |

Edit ./src/routes/_index/+page.marko and save to reload.

7 | 8 | Learn Marko 9 | 10 |
11 | 12 | 13 | 14 | style { 15 | .container { 16 | display:flex; 17 | flex-direction: column; 18 | justify-content: center; 19 | align-items: center; 20 | font-size: clamp(1em, 2vw, 2em); 21 | padding: 1em; 22 | box-sizing: border-box; 23 | height:100%; 24 | width:100%; 25 | } 26 | img.logo { 27 | width:12em; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/basic/src/routes/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js/examples/90689e6423c68147794cc8d278b1523f1764026b/examples/basic/src/routes/favicon.png -------------------------------------------------------------------------------- /examples/color-picker/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | *.log 4 | .env 5 | -------------------------------------------------------------------------------- /examples/color-picker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "color-picker", 3 | "description": "Color Picker", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "marko": "^5" 7 | }, 8 | "devDependencies": { 9 | "@marko/build": "^4", 10 | "@marko/serve": "^4" 11 | }, 12 | "private": true, 13 | "scripts": { 14 | "build": "marko-build ./src/pages", 15 | "dev": "marko-serve ./src/pages", 16 | "start": "NODE_ENV=production node ./build/index.js" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker-footer/component.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = class { 4 | handleColorSelected (color) { 5 | this.emit('color-selected', color); 6 | } 7 | handleHexInput () { 8 | let hexInput = this.getEl('hexInput').value; 9 | 10 | if (!hexInput.startsWith('#')) { 11 | hexInput = '#' + hexInput; 12 | } 13 | 14 | if (!isValidHexValue(hexInput)) { 15 | hexInput = this.input.colors[0]; 16 | } 17 | 18 | this.emit('color-selected', hexInput); 19 | } 20 | }; 21 | 22 | function isValidHexValue (hexValue) { 23 | return /^#[0-9A-F]{6}$/i.test(hexValue); 24 | } -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker-footer/demo.marko: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker-footer/index.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 11 | 14 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker-footer/style.css: -------------------------------------------------------------------------------- 1 | .color-picker-footer { 2 | width: 200px; 3 | height: 100px; 4 | border-radius: 0px 0px 20px 20px; 5 | font: 30px Arial; 6 | display: flex; 7 | flex-direction: column; 8 | text-align: center; 9 | color: white; 10 | box-shadow: 0px 3px 5px #888888; 11 | } 12 | .color-picker-selection-container { 13 | width: 75%; 14 | margin: 5px 0px 0px 20px; 15 | } 16 | .color-picker-selection-container input { 17 | margin-top: 8px; 18 | border-radius: 0px 0px 0px 0px; 19 | border-width: 0px 0px 1px 0px; 20 | outline: none; 21 | color: #A9A9A9; 22 | } 23 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker-header/demo.marko: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker-header/index.marko: -------------------------------------------------------------------------------- 1 | 2 | style { 3 | .color-picker-header { 4 | width: 200px; 5 | height: 100px; 6 | border-radius: 20px 20px 0 0; 7 | font: 30px Arial; 8 | display: flex; 9 | flex-direction: column; 10 | text-align: center; 11 | color: white; 12 | } 13 | .color-picker-header > p { 14 | padding-top: 1.15em; 15 | margin: 0; 16 | } 17 | } 18 | 19 | 23 | 24 | $ const { color } = input; 25 | 26 | 27 |

${color}

28 | 29 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker-header/test.js: -------------------------------------------------------------------------------- 1 | /* global test */ 2 | const expect = require('chai').expect; 3 | 4 | test('color-picker-header color', function (context) { 5 | const output = context.render({ 6 | color: '#000000' 7 | }); 8 | 9 | expect(output.$('div').attr('style')).to.contain('background-color:#000000'); 10 | }); 11 | 12 | test('color-picker-header class included', function (context) { 13 | const output = context.render({ 14 | color: '#000000' 15 | }); 16 | 17 | expect(output.$('div').attr('class')).to.equal('color-picker-header'); 18 | }); 19 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker-selection/demo.marko: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker-selection/index.marko: -------------------------------------------------------------------------------- 1 | class { 2 | handleColorSelected() { 3 | this.emit("color-selected"); 4 | } 5 | } 6 | 7 | style { 8 | .color-picker-selection { 9 | width: 25px; 10 | height: 25px; 11 | border-radius: 5px 5px 5px 5px; 12 | display: flex; 13 | flex-direction: column; 14 | margin: 5px 0px 0px 5px; 15 | float: left; 16 | } 17 | } 18 | 19 | 25 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker-selection/test.js: -------------------------------------------------------------------------------- 1 | /* global test */ 2 | const expect = require('chai').expect; 3 | 4 | test('color-picker-selection color', function (context) { 5 | const output = context.render({ 6 | color: '#ff8080' 7 | }); 8 | 9 | expect(output.$('div').attr('style')).to.contain('background-color:#ff8080'); 10 | }); 11 | 12 | test('color-picker-selection when clicked should emit color-selected event', function (context) { 13 | const output = context.render({ 14 | color: '#ff8080' 15 | }); 16 | 17 | var component = output.component; 18 | var isCalled = false; 19 | component.on('color-selected', function () { 20 | isCalled = true; 21 | }); 22 | 23 | var componentEl = component.el; 24 | componentEl.click(); 25 | 26 | expect(isCalled).to.equal(true); 27 | }); 28 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker/demo.marko: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/color-picker/index.marko: -------------------------------------------------------------------------------- 1 | import getDefaultColors from '../../util/getDefaultColors.js' 2 | 3 | class { 4 | onInput(input) { 5 | var colors = input.colors || getDefaultColors(); 6 | 7 | this.state = { 8 | selectedColor: colors[0], 9 | colors 10 | }; 11 | } 12 | 13 | handleColorSelected(color) { 14 | this.state.selectedColor = color; 15 | } 16 | } 17 | 18 |
19 | 20 | 21 |
22 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/sample-header/index.marko: -------------------------------------------------------------------------------- 1 | style { 2 | header { 3 | font-size: 2.5em; 4 | font-weight: 300; 5 | background-color: #f1f1f1; 6 | padding: 1em; 7 | } 8 | body { 9 | font-family: "Helvetica Neue", Roboto, "Arial Nova", "Segoe UI", Arial, 10 | sans-serif; 11 | margin: 0 auto; 12 | text-align: center; 13 | } 14 | .color-picker-container { 15 | padding-top: 2em; 16 | position: absolute; 17 | left: 50%; 18 | margin-left: -96px; 19 | } 20 | .logo { 21 | height: 2.2em; 22 | } 23 | } 24 | 25 |
26 | 27 |
${input.title}
28 |
29 | -------------------------------------------------------------------------------- /examples/color-picker/src/components/sample-header/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js/examples/90689e6423c68147794cc8d278b1523f1764026b/examples/color-picker/src/components/sample-header/logo.png -------------------------------------------------------------------------------- /examples/color-picker/src/pages/index.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | Marko | Color Picker 4 | 5 | 6 | 7 |
8 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/color-picker/src/util/getDefaultColors.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function getDefaultColors () { 4 | return [ 5 | '#1ABC9C', 6 | '#2ECC71', 7 | '#3498DB', 8 | '#9B59B6', 9 | '#34495E', 10 | '#16A085', 11 | '#27AE60', 12 | '#2980B9', 13 | '#8E44AD', 14 | '#2C3E50' 15 | ]; 16 | }; -------------------------------------------------------------------------------- /examples/language-guide/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | *.log 4 | .env 5 | -------------------------------------------------------------------------------- /examples/language-guide/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "language-guide", 3 | "description": "Marko language guide and examples", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "marko": "^5" 7 | }, 8 | "devDependencies": { 9 | "@marko/build": "^4", 10 | "@marko/serve": "^4" 11 | }, 12 | "private": true, 13 | "scripts": { 14 | "build": "marko-build ./src/pages", 15 | "dev": "marko-serve ./src/pages", 16 | "start": "node ./build/index.js" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/async/await.marko: -------------------------------------------------------------------------------- 1 | $ var personPromise = new Promise((resolve, reject) => { 2 | setTimeout(function() { 3 | resolve({ 4 | name: "Frank" 5 | }); 6 | }, 1000); 7 | }); 8 | 9 | <@placeholder>Loading... 10 | <@then|person|> 11 |
Hello ${person.name}!
12 | 13 | <@catch|err|>Error: ${err.message} 14 | 15 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/attributes/boolean.marko: -------------------------------------------------------------------------------- 1 | $ const isChecked = false; 2 | $ const isDisabled = true; 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/attributes/class.marko: -------------------------------------------------------------------------------- 1 | $ const isVisible = false; 2 | 3 |
4 |
8 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/attributes/conditional.marko: -------------------------------------------------------------------------------- 1 | $ const existingTitile = "abc"; 2 | $ const missingTitle = undefined; 3 | Hello 4 | Hello 5 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/attributes/shorthand.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/attributes/spread-attributes.marko: -------------------------------------------------------------------------------- 1 | $ const divAttrs = { 2 | class: "my-class another-class", 3 | style: "border: 1px solid #000; padding: 5px; margin 5px;" 4 | }; 5 |
Hello World
6 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/attributes/style.marko: -------------------------------------------------------------------------------- 1 | $ const isComplete = false; 2 | $ const value = -100; 3 | $ const style = { 4 | textDecoration: isComplete ? "line-through" : "none", 5 | color: value < 0 ? "red" : "black" 6 | }; 7 |
${value}
8 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/conditionals/conditional-parent-tag.marko: -------------------------------------------------------------------------------- 1 | $ const url = "markojs.com"; 2 | <${url && "a"} href=url>Some body content 3 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/conditionals/if-else.marko: -------------------------------------------------------------------------------- 1 | $ const age = 20; 2 | 3 |
You are less than 50 years old
4 | 5 | 6 |
You are 50 years old
7 | 8 | 9 |
You are over 50
10 |
11 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/custom-tags/components/hello/index.marko: -------------------------------------------------------------------------------- 1 | Hello ${input.name}!
2 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/custom-tags/hello.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/dynamic-tagname/components/fancy-heading.marko: -------------------------------------------------------------------------------- 1 | 2 | Hello ${input.name}! 3 | <${input.renderBody}/> 4 | 5 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/dynamic-tagname/components/goodbye.marko: -------------------------------------------------------------------------------- 1 |
Goodbye ${input.name}!
2 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/dynamic-tagname/components/hello.marko: -------------------------------------------------------------------------------- 1 |
Hello ${input.name}!
2 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/dynamic-tagname/dynamic-component.marko: -------------------------------------------------------------------------------- 1 | import Hello from "./components/hello.marko" 2 | import Goodbye from "./components/goodbye.marko" 3 | 4 | $ const isLeaving = false; 5 | <${isLeaving ? Goodbye : Hello} name="Frank"/> 6 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/dynamic-tagname/dynamic-native-tag.marko: -------------------------------------------------------------------------------- 1 | $ const href = "http://ebay.com"; 2 | <${href ? "a" : "button"} href=href>Lets go! 3 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/dynamic-tagname/provide-body-content.marko: -------------------------------------------------------------------------------- 1 | 2 | This is the body content 3 | 4 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/dynamic-text/html.marko: -------------------------------------------------------------------------------- 1 | $ const message = "Welcome to Marko!"; 2 |
HTML $!{message}
3 |
Escaped HTML: ${message}
4 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/dynamic-text/text.marko: -------------------------------------------------------------------------------- 1 | $ const name = "Frank"; 2 | $ const messageCount = 30; 3 |

4 | Hello ${name.toUpperCase()}! 5 | You have ${messageCount} new messages. 6 |

7 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/embedded-js/blocks.marko: -------------------------------------------------------------------------------- 1 | 2 | static { 3 | var uniqueId = 0; 4 | 5 | function getNextId() { 6 | return uniqueId++; 7 | } 8 | 9 | console.log("Template loaded!"); 10 | } 11 | 12 | 13 | $ { 14 | let name = input.name || "Frank"; 15 | name = name.toUpperCase(); 16 | console.log("Name:", name); 17 | } 18 |
19 | Hello ${name}! 20 | ${getNextId()} 21 |
22 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/embedded-js/helper-functions.marko: -------------------------------------------------------------------------------- 1 | static function isNegative(value) { 2 | // Static helper functions do not have 3 | // access to non-static variables such as "value" and "person" 4 | return value < 0 ? "Yes" : "No"; 5 | } 6 | 7 | $ const value = 123; 8 | $ const person = { 9 | firstName: "John", 10 | lastName: "Doe" 11 | }; 12 | $ function getNameFormatted() { 13 | // Non-static functions have access to non-static and static variables 14 | return person.firstName + " " + person.lastName.charAt(0) + "."; 15 | } 16 |
17 | Hello ${getNameFormatted()}Is negative? ${isNegative(value)} 18 |
19 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/embedded-js/import.marko: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | 3 |
${path.join("/Users/marko", "development")}
4 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/embedded-js/variables.marko: -------------------------------------------------------------------------------- 1 | 2 | static const dateLoaded = new Date(); 3 | 4 | 5 | $ let name = "Frank"; 6 | $ name = name.toUpperCase(); 7 | $ console.log(name); 8 |
Hello ${name}!
9 |

This template was loaded at ${dateLoaded.toString()}

10 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/import/helper.js: -------------------------------------------------------------------------------- 1 | exports.add = function(a, b) { 2 | return a + b; 3 | }; 4 | 5 | exports.subtract = function(a, b) { 6 | return a - b; 7 | }; 8 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/import/import.marko: -------------------------------------------------------------------------------- 1 | import { add, subtract } from "./helper.js" 2 | 3 |

1 + 2 = ${add(1, 2)}

4 |

2 - 1 = ${subtract(2, 1)}

5 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/layouts/components/layout.marko: -------------------------------------------------------------------------------- 1 |
2 |
3 | <${input.title}/> 4 |
5 | 6 | <${input.body}/> 7 |
8 |
9 | <${input.footer}/> 10 |
11 | 12 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/layouts/index.marko: -------------------------------------------------------------------------------- 1 | 2 | <@title>This is the title 3 | <@body>This is the body content 4 | <@footer>This is the footer content 5 | 6 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/looping/array.marko: -------------------------------------------------------------------------------- 1 | $ const colors = ["red", "green", "blue"]; 2 |
    3 | 4 |
  • ${color}
  • 7 | 8 |
9 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/looping/properties.marko: -------------------------------------------------------------------------------- 1 | $ const person = { 2 | firstName: "John", 3 | lastName: "Doe", 4 | age: 20 5 | }; 6 |
    7 | 8 |
  • 9 | ${name}: ${value} 10 |
  • 11 | 12 |
13 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/looping/range-loop.marko: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 |
  • ${i}
  • 5 | 6 |
7 | 8 |
    9 | 10 |
  • ${i}
  • 11 | 12 |
13 | 14 | $ const myArray = [1, 2, 3, 4, 5]; 15 |
    16 | 17 |
  • ${myArray[i]}
  • 18 | 19 |
20 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/looping/separator.marko: -------------------------------------------------------------------------------- 1 | $ const colors = ["red", "green", "blue"]; 2 |
3 | 4 | ${color} 7 | , 8 | 9 |
10 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/looping/while.marko: -------------------------------------------------------------------------------- 1 |
    2 | $ let n = 0; 3 | 4 |
  • ${n++}
  • 5 | 6 |
7 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/looping/with-index.marko: -------------------------------------------------------------------------------- 1 | $ const colors = ["red", "green", "blue"]; 2 |
    3 | 4 |
  • 5 | ${i + 1}) ${color}- FIRST 6 | - LAST 7 |
  • 8 | 9 |
10 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/macros/index.marko: -------------------------------------------------------------------------------- 1 | 2 |
7 | Hello ${name}! 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/macros/macro-body.marko: -------------------------------------------------------------------------------- 1 | 2 |
3 |

4 | ${title} 5 |

6 |

7 | <${renderBody}/> 8 |

9 |
10 | 11 |
14 | American astronaut and the first person to walk on the Moon 15 |
16 |
17 | American author and journalist. 18 |
19 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/parent-child-communication/components/language-selector.marko: -------------------------------------------------------------------------------- 1 | class { 2 | onLanguageSelect() { 3 | const el = this.getEl("languageSelect"); 4 | const selected = el.options[el.selectedIndex].value; 5 | this.emit("select-language", selected); 6 | } 7 | } 8 | 9 |
10 | 15 |
16 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/parent-child-communication/parent.marko: -------------------------------------------------------------------------------- 1 | class { 2 | onCreate() { 3 | this.state = { selectedLanguage: "English" }; 4 | } 5 | 6 | onLanguageSelect(selectedLanguage) { 7 | this.state.selectedLanguage = selectedLanguage; 8 | } 9 | } 10 | 11 |
12 |

${state.selectedLanguage}

13 | 14 |
15 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/sample-header/component.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | onInput (input) { 3 | this.state = { 4 | title: input.title 5 | }; 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/sample-header/index.marko: -------------------------------------------------------------------------------- 1 | style { 2 | header { 3 | font-size: 2.5em; 4 | font-weight: 300; 5 | background-color: #f1f1f1; 6 | padding: 1em; 7 | text-align: center; 8 | } 9 | body { 10 | font-family: "Helvetica Neue", Roboto, "Arial Nova", "Segoe UI", Arial, 11 | sans-serif; 12 | margin: 0; 13 | } 14 | .color-picker-container { 15 | position: absolute; 16 | top: 30%; 17 | left: 50%; 18 | transform: translate(-50%, -50%); 19 | } 20 | .logo { 21 | height: 2.2em; 22 | } 23 | } 24 | 25 |
26 | 27 |
${input.title}
28 |
29 | -------------------------------------------------------------------------------- /examples/language-guide/src/components/sample-header/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js/examples/90689e6423c68147794cc8d278b1523f1764026b/examples/language-guide/src/components/sample-header/logo.png -------------------------------------------------------------------------------- /examples/language-guide/src/components/whitespace/index.marko: -------------------------------------------------------------------------------- 1 |
2 |   By default, pre tags have
3 |   their whitespace preserved
4 | 
5 | 9 | -------------------------------------------------------------------------------- /examples/language-guide/src/pages/index.marko: -------------------------------------------------------------------------------- 1 | $ const name = "Frank"; 2 | style { 3 | .container { 4 | margin-left: auto; 5 | margin-right: auto; 6 | width: 800px; 7 | } 8 | } 9 | 10 | 11 |
12 |

Hello ${name}!

13 | $ const colors = ["red", "green", "blue"]; 14 | 15 |
    16 | 17 |
  • ${color}
  • 20 | 21 |
22 | 23 | 24 |
No colors!
25 |
26 |
27 | -------------------------------------------------------------------------------- /examples/lasso-express/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | static 3 | .cache 4 | *.marko.js 5 | *.log 6 | .env 7 | -------------------------------------------------------------------------------- /examples/lasso-express/README.md: -------------------------------------------------------------------------------- 1 | Sample App: Marko + Express 2 | ====================================== 3 | 4 | This sample app illustrates how to integrate Marko with a very basic Express app. For this sample app, we use the streaming API to stream the output of the template rendering to the HTTP response stream. In addition, this sample application illustrates how to create custom tags that can be embedded into your templates. 5 | 6 | # Installation 7 | 8 | ``` 9 | npx @marko/create marko-app --template lasso-express 10 | cd marko-app 11 | npm install 12 | npm run dev 13 | ``` 14 | 15 | Navigate to [http://localhost:8080/](http://localhost:8080/) to see your server in action! 16 | -------------------------------------------------------------------------------- /examples/lasso-express/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [["@babel/preset-env", { targets: { node: "current" } }]] 3 | } 4 | -------------------------------------------------------------------------------- /examples/lasso-express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lasso-express-example", 3 | "description": "Sample Express-based server app that integrates with Marko.", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "@babel/core": "^7.19.3", 7 | "@babel/preset-env": "^7.19.3", 8 | "@babel/register": "^7.18.9", 9 | "@lasso/marko-taglib": "^2.0.5", 10 | "@marko/compiler": "^5.22.8", 11 | "@marko/express": "^2.0.1", 12 | "browser-refresh": "^1.7.3", 13 | "browser-refresh-taglib": "^1.2.1", 14 | "express": "^4.18.1", 15 | "lasso": "^4.0.1", 16 | "lasso-marko": "^3.2.1", 17 | "marko": "^5.21.9" 18 | }, 19 | "private": true, 20 | "scripts": { 21 | "dev": "browser-refresh --enable-source-maps -r @babel/register -r @marko/compiler/register src/server.js", 22 | "start": "NODE_ENV=production node -r @babel/register -r @marko/compiler/register src/server.js" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/lasso-express/src/components/app-header/index.marko: -------------------------------------------------------------------------------- 1 | style { 2 | header { 3 | font-size: 2.5em; 4 | font-weight: 300; 5 | background-color: #f1f1f1; 6 | padding: 1em; 7 | text-align: center; 8 | } 9 | body { 10 | font-family: "Helvetica Neue", Roboto, "Arial Nova", "Segoe UI", Arial, sans-serif; 11 | margin: 0; 12 | } 13 | } 14 | 15 |
16 |
19 | -------------------------------------------------------------------------------- /examples/lasso-express/src/components/app-header/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js/examples/90689e6423c68147794cc8d278b1523f1764026b/examples/lasso-express/src/components/app-header/logo.png -------------------------------------------------------------------------------- /examples/lasso-express/src/components/app-layout/index.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Marko | Lasso + Express 8 | 9 | 10 | 11 | 12 |
13 | <${input.renderBody}/> 14 |
15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | style { 27 | .container{ 28 | margin-left: auto; 29 | margin-right: auto; 30 | width: 800px; 31 | } 32 | } -------------------------------------------------------------------------------- /examples/lasso-express/src/pages/home/components/app-hello/index.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | class { 4 | onCreate() { 5 | this.state = { 6 | count: 0 7 | } 8 | } 9 | 10 | onMount() { 11 | console.log("Mounted in the browser!"); 12 | } 13 | 14 | increment() { 15 | this.state.count++; 16 | } 17 | } 18 | 19 | style { 20 | .count { 21 | color:#09c; 22 | font-size:3em; 23 | } 24 | .example-button { 25 | font-size:1em; 26 | padding:0.5em; 27 | } 28 | } 29 | 30 |

Hello ${input.name}

31 | 32 | 33 | ${state.count} 34 | 35 | 36 | 37 | Click me 38 | 39 | -------------------------------------------------------------------------------- /examples/lasso-express/src/pages/home/index.js: -------------------------------------------------------------------------------- 1 | import template from "./template.marko"; 2 | 3 | export default (req, res) => { 4 | res.marko(template, { 5 | name: "Frank", 6 | count: 30, 7 | colors: ["red", "green", "blue"] 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /examples/lasso-express/src/pages/home/template.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | You have ${input.count} new messages! 5 | 6 | 7 |
    8 | 9 |
  • ${color}
  • 10 | 11 |
12 | 13 | 14 |
No colors!
15 |
16 |
17 | -------------------------------------------------------------------------------- /examples/lasso-fastify/README.md: -------------------------------------------------------------------------------- 1 | Sample App: Marko + Fastify 2 | ====================================== 3 | 4 | This sample app illustrates how to integrate Marko with a very basic Fastify app. For this sample app, we use the streaming API to stream the output of the template rendering to the HTTP response stream. In addition, this sample application illustrates how to create custom tags that can be embedded into your templates. 5 | 6 | # Installation 7 | 8 | ``` 9 | npx @marko/create marko-app --template lasso-fastify 10 | cd marko-app 11 | npm install 12 | npm run dev 13 | ``` 14 | 15 | Navigate to [http://localhost:8080/](http://localhost:8080/) to see your server in action! 16 | -------------------------------------------------------------------------------- /examples/lasso-fastify/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [["@babel/preset-env", { targets: { node: "current" } }]] 3 | } 4 | -------------------------------------------------------------------------------- /examples/lasso-fastify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lasso-fastify-example", 3 | "description": "Sample Fastify-based server that integrates with Marko.", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "@babel/core": "^7.19.3", 7 | "@babel/preset-env": "^7.19.3", 8 | "@babel/register": "^7.18.9", 9 | "@fastify/static": "6.5.0", 10 | "@fastify/compress": "6.1.1", 11 | "@marko/compiler": "^5.22.8", 12 | "@marko/fastify": "^1.1.1", 13 | "@lasso/marko-taglib": "^2.0.5", 14 | "browser-refresh": "^1.7.3", 15 | "browser-refresh-taglib": "^1.2.1", 16 | "fastify": "^4.6.0", 17 | "lasso": "^4.0.1", 18 | "lasso-marko": "^3.2.1", 19 | "marko": "^5.21.9" 20 | }, 21 | "private": true, 22 | "scripts": { 23 | "dev": "browser-refresh --enable-source-maps -r @babel/register -r @marko/compiler/register src/server.js", 24 | "start": "NODE_ENV=production node -r @babel/register -r @marko/compiler/register src/server.js" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/lasso-fastify/src/components/app-header/index.marko: -------------------------------------------------------------------------------- 1 | style { 2 | header { 3 | font-size: 2.5em; 4 | font-weight: 300; 5 | background-color: #f1f1f1; 6 | padding: 1em; 7 | text-align: center; 8 | } 9 | body { 10 | font-family: "Helvetica Neue", Roboto, "Arial Nova", "Segoe UI", Arial, sans-serif; 11 | margin: 0; 12 | } 13 | } 14 | 15 |
16 |
19 | -------------------------------------------------------------------------------- /examples/lasso-fastify/src/components/app-header/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js/examples/90689e6423c68147794cc8d278b1523f1764026b/examples/lasso-fastify/src/components/app-header/logo.png -------------------------------------------------------------------------------- /examples/lasso-fastify/src/components/app-layout/index.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Marko | Lasso + Fastify 8 | 9 | 10 | 11 | 12 |
13 | <${input.renderBody}/> 14 |
15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | style { 27 | .container{ 28 | margin-left: auto; 29 | margin-right: auto; 30 | width: 800px; 31 | } 32 | } -------------------------------------------------------------------------------- /examples/lasso-fastify/src/pages/home/components/app-hello/index.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | class { 4 | onCreate() { 5 | this.state = { 6 | count: 0 7 | } 8 | } 9 | 10 | onMount() { 11 | console.log("Mounted in the browser!"); 12 | } 13 | 14 | increment() { 15 | this.state.count++; 16 | } 17 | } 18 | 19 | style { 20 | .count { 21 | color:#09c; 22 | font-size:3em; 23 | } 24 | .example-button { 25 | font-size:1em; 26 | padding:0.5em; 27 | } 28 | } 29 | 30 |

Hello ${input.name}

31 | 32 | 33 | ${state.count} 34 | 35 | 36 | 37 | Click me 38 | 39 | -------------------------------------------------------------------------------- /examples/lasso-fastify/src/pages/home/index.js: -------------------------------------------------------------------------------- 1 | import Template from "./template.marko"; 2 | 3 | export default (req, reply) => { 4 | reply.marko(Template, { 5 | name: "Frank", 6 | count: 30, 7 | colors: ["red", "green", "blue"] 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /examples/lasso-fastify/src/pages/home/template.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | You have ${input.count} new messages! 5 | 6 | 7 |
    8 | 9 |
  • ${color}
  • 10 | 11 |
12 | 13 | 14 |
No colors!
15 |
16 |
17 | -------------------------------------------------------------------------------- /examples/lasso-koa/README.md: -------------------------------------------------------------------------------- 1 | Sample App: Marko + Koa 2 | ====================================== 3 | 4 | This sample app illustrates how to integrate Marko with a very basic Koa app. For this sample app, we use the streaming API to stream the output of the template rendering to the HTTP response stream. In addition, this sample application illustrates how to create custom tags that can be embedded into your templates. 5 | 6 | # Installation 7 | 8 | ``` 9 | npx @marko/create marko-app --template lasso-koa 10 | cd marko-app 11 | npm install 12 | npm run dev 13 | ``` 14 | 15 | Navigate to [http://localhost:8080/](http://localhost:8080/) to see your server in action! 16 | -------------------------------------------------------------------------------- /examples/lasso-koa/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [["@babel/preset-env", { targets: { node: "current" } }]] 3 | } 4 | -------------------------------------------------------------------------------- /examples/lasso-koa/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lasso-koa-example", 3 | "description": "Sample Koa-based server app that integrates with Marko.", 4 | "version": "1.0.0", 5 | "dependencies": { 6 | "@babel/core": "^7.13.1", 7 | "@babel/preset-env": "^7.13.5", 8 | "@babel/register": "^7.13.0", 9 | "@lasso/marko-taglib": "^2.0.3", 10 | "browser-refresh": "^1.7.3", 11 | "browser-refresh-taglib": "^1.1.0", 12 | "koa": "^2.13.1", 13 | "koa-mount": "^4.0.0", 14 | "koa-router": "^10.0.0", 15 | "koa-static": "^5.0.0", 16 | "lasso": "^3.4.1", 17 | "lasso-marko": "^3.0.1", 18 | "marko": "^5.1.20" 19 | }, 20 | "private": true, 21 | "scripts": { 22 | "dev": "browser-refresh --enable-source-maps -r @babel/register -r marko/node-require src/server.js", 23 | "start": "NODE_ENV=production node -r @babel/register -r marko/node-require src/server.js" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/lasso-koa/src/components/app-header/index.marko: -------------------------------------------------------------------------------- 1 | style { 2 | header { 3 | font-size: 2.5em; 4 | font-weight: 300; 5 | background-color: #f1f1f1; 6 | padding: 1em; 7 | text-align: center; 8 | } 9 | body { 10 | font-family: "Helvetica Neue", Roboto, "Arial Nova", "Segoe UI", Arial, sans-serif; 11 | margin: 0; 12 | } 13 | .logo { 14 | height: 2.2em; 15 | } 16 | } 17 | 18 |
19 | 20 |
${input.title}
21 |
22 | -------------------------------------------------------------------------------- /examples/lasso-koa/src/components/app-header/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js/examples/90689e6423c68147794cc8d278b1523f1764026b/examples/lasso-koa/src/components/app-header/logo.png -------------------------------------------------------------------------------- /examples/lasso-koa/src/components/app-layout/index.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Marko | Lasso + Koa 8 | 9 | 10 | 11 | 12 |
13 | <${input.renderBody}/> 14 |
15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | style { 29 | .container{ 30 | margin-left: auto; 31 | margin-right: auto; 32 | width: 800px; 33 | } 34 | } -------------------------------------------------------------------------------- /examples/lasso-koa/src/pages/home/components/app-hello/index.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | class { 4 | onCreate() { 5 | this.state = { 6 | count: 0 7 | } 8 | } 9 | 10 | onMount() { 11 | console.log("Mounted in the browser!"); 12 | } 13 | 14 | increment() { 15 | this.state.count++; 16 | } 17 | } 18 | 19 | style { 20 | .count { 21 | color:#09c; 22 | font-size:3em; 23 | } 24 | .example-button { 25 | font-size:1em; 26 | padding:0.5em; 27 | } 28 | } 29 | 30 |

Hello ${input.name}

31 | 32 | 33 | ${state.count} 34 | 35 | 36 | 37 | Click me 38 | 39 | -------------------------------------------------------------------------------- /examples/lasso-koa/src/pages/home/index.js: -------------------------------------------------------------------------------- 1 | import template from "./template.marko"; 2 | 3 | export default ctx => { 4 | ctx.type = "html"; 5 | ctx.body = template.stream({ 6 | name: "Frank", 7 | count: 30, 8 | colors: ["red", "green", "blue"] 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /examples/lasso-koa/src/pages/home/template.marko: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | You have ${input.count} new messages! 5 | 6 | 7 |
    8 | 9 |
  • ${color}
  • 10 | 11 |
12 | 13 | 14 |
No colors!
15 |
16 |
17 | -------------------------------------------------------------------------------- /examples/library-ts/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/settings.json 2 | *.DS_Store 3 | *.log 4 | *.tgz 5 | coverage 6 | dist 7 | node_modules 8 | .env 9 | -------------------------------------------------------------------------------- /examples/library-ts/.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | .env 3 | -------------------------------------------------------------------------------- /examples/library-ts/.husky/pre-commit: -------------------------------------------------------------------------------- 1 | lint-staged && npm run build 2 | -------------------------------------------------------------------------------- /examples/library-ts/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/lintstagedrc.schema.json", 3 | "*.{ts,js}": ["eslint --fix", "prettier --write"], 4 | "*.css": ["stylelint --fix", "prettier --write"], 5 | "*.{marko,html,json,md}": ["prettier --write"] 6 | } 7 | -------------------------------------------------------------------------------- /examples/library-ts/.postcssrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/postcssrc.json", 3 | "plugins": { 4 | "postcss-auto-modules": {} 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/library-ts/.prettierignore: -------------------------------------------------------------------------------- 1 | __snapshots__ 2 | .vscode 3 | CHANGELOG.md 4 | coverage 5 | dist 6 | node_modules 7 | package-lock.json 8 | -------------------------------------------------------------------------------- /examples/library-ts/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "plugins": ["prettier-plugin-packagejson", "prettier-plugin-marko"] 4 | } 5 | -------------------------------------------------------------------------------- /examples/library-ts/.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from "@storybook/marko-vite"; 2 | 3 | export default { 4 | framework: "@storybook/marko-vite", 5 | stories: ["../src/**/{,*.}stories.ts"], 6 | addons: ["@storybook/addon-essentials"], 7 | core: { 8 | disableTelemetry: true, 9 | disableWhatsNewNotifications: true, 10 | }, 11 | } satisfies StorybookConfig; 12 | -------------------------------------------------------------------------------- /examples/library-ts/.stylelintignore: -------------------------------------------------------------------------------- 1 | __snapshots__ 2 | coverage 3 | dist 4 | node_modules 5 | -------------------------------------------------------------------------------- /examples/library-ts/.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/stylelintrc.json", 3 | "extends": "stylelint-config-standard", 4 | "allowEmptyInput": true, 5 | "cache": true, 6 | "rules": { 7 | "import-notation": "string" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/library-ts/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "esbenp.prettier-vscode", 5 | "Marko-JS.marko-vscode", 6 | "stylelint.vscode-stylelint" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/library-ts/README.md: -------------------------------------------------------------------------------- 1 | # Starter Marko Library with TypeScript 2 | 3 | A template for component libraries and other reusable Marko packages. 4 | 5 | ## Installation 6 | 7 | ```sh 8 | npm init marko -- --template library-ts 9 | ``` 10 | 11 | ## Overview 12 | 13 | This project is powered by [Marko](https://markojs.com), [Storybook](https://storybook.js.org), and [Vite](https://vitejs.dev). 14 | 15 | - Run `npm run storybook` to view the component storybook 16 | - Run `npm run test` to run tests with vitest 17 | - Run `npm run build` to build a production-ready library 18 | -------------------------------------------------------------------------------- /examples/library-ts/eslint.config.js: -------------------------------------------------------------------------------- 1 | import eslint from "@eslint/js"; 2 | import sortImportPlugin from "eslint-plugin-simple-import-sort"; 3 | import globals from "globals"; 4 | import tslint from "typescript-eslint"; 5 | 6 | export default tslint.config( 7 | { 8 | ignores: ["__snapshots__", "coverage", "dist", "node_modules"], 9 | }, 10 | eslint.configs.recommended, 11 | ...tslint.configs.recommended, 12 | { 13 | languageOptions: { 14 | globals: { 15 | ...globals.browser, 16 | ...globals.node, 17 | }, 18 | }, 19 | plugins: { 20 | "simple-import-sort": sortImportPlugin, 21 | }, 22 | rules: { 23 | "simple-import-sort/imports": "error", 24 | "simple-import-sort/exports": "error", 25 | "@typescript-eslint/no-import-type-side-effects": "error", 26 | "@typescript-eslint/no-non-null-assertion": "off", 27 | "@typescript-eslint/no-empty-function": "off", 28 | "@typescript-eslint/no-explicit-any": "off", 29 | }, 30 | }, 31 | ); 32 | -------------------------------------------------------------------------------- /examples/library-ts/marko.json: -------------------------------------------------------------------------------- 1 | { 2 | "exports": "./dist/components" 3 | } 4 | -------------------------------------------------------------------------------- /examples/library-ts/src/components/counter/__snapshots__/server.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`Default 1`] = ` 4 | 9 | `; 10 | 11 | exports[`Double 1`] = ` 12 | 17 | `; 18 | -------------------------------------------------------------------------------- /examples/library-ts/src/components/counter/browser.test.ts: -------------------------------------------------------------------------------- 1 | import { fireEvent, render, screen } from "@marko/testing-library"; 2 | import { composeStories } from "@storybook/marko"; 3 | 4 | import * as stories from "./stories"; 5 | 6 | const { Default, Double } = composeStories(stories); 7 | 8 | test("Default", async () => { 9 | const { emitted } = await render(Default); 10 | const $btn = screen.getByRole("button"); 11 | 12 | expect($btn).toHaveTextContent("0"); 13 | 14 | await fireEvent.click($btn); 15 | 16 | expect($btn).toHaveTextContent("1"); 17 | expect(emitted("increment")).toHaveLength(1); 18 | }); 19 | 20 | test("Double", async () => { 21 | const { emitted } = await render(Double); 22 | const $btn = screen.getByRole("button"); 23 | 24 | expect($btn).toHaveTextContent("0"); 25 | 26 | await fireEvent.click($btn); 27 | 28 | expect($btn).toHaveTextContent("2"); 29 | expect(emitted("increment")).toHaveLength(1); 30 | }); 31 | -------------------------------------------------------------------------------- /examples/library-ts/src/components/counter/index.marko: -------------------------------------------------------------------------------- 1 | import style from "./styles.module.css"; 2 | export interface Input { 3 | multiplier?: number; 4 | } 5 | class { 6 | declare state: { 7 | count: number; 8 | }; 9 | 10 | onCreate() { 11 | this.state = { 12 | count: 0, 13 | }; 14 | } 15 | 16 | increment() { 17 | this.state.count++; 18 | this.emit("increment"); 19 | } 20 | } 21 | 22 | 25 | -------------------------------------------------------------------------------- /examples/library-ts/src/components/counter/server.test.ts: -------------------------------------------------------------------------------- 1 | import { render, screen } from "@marko/testing-library"; 2 | import { composeStories } from "@storybook/marko"; 3 | 4 | import * as stories from "./stories"; 5 | 6 | for (const [name, story] of Object.entries(composeStories(stories))) { 7 | test(name, async () => { 8 | await render(story); 9 | expect(screen.getByRole("button")).toMatchSnapshot(); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /examples/library-ts/src/components/counter/stories.ts: -------------------------------------------------------------------------------- 1 | import type { Meta, Story } from "@storybook/marko"; 2 | 3 | import Template, { type Input } from "./index.marko"; 4 | 5 | export default { 6 | title: "Counter", 7 | component: Template, 8 | argTypes: { 9 | multiplier: { 10 | control: { 11 | type: "number", 12 | }, 13 | }, 14 | }, 15 | } as Meta; 16 | 17 | export const Default: Story = { 18 | args: {}, 19 | }; 20 | 21 | export const Double: Story = { 22 | args: { 23 | multiplier: 2, 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /examples/library-ts/src/components/counter/styles.module.css: -------------------------------------------------------------------------------- 1 | .test { 2 | color: blue; 3 | } 4 | -------------------------------------------------------------------------------- /examples/library-ts/src/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.css" { 2 | const content: { [className: string]: string }; 3 | export default content; 4 | } 5 | -------------------------------------------------------------------------------- /examples/library-ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*"], 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "incremental": true, 6 | "lib": ["dom", "ESNext"], 7 | "module": "ESNext", 8 | "moduleResolution": "bundler", 9 | "noImplicitOverride": true, 10 | "noUnusedLocals": true, 11 | "outDir": "dist", 12 | "resolveJsonModule": true, 13 | "rootDir": "src", 14 | "skipLibCheck": true, 15 | "strict": true, 16 | "target": "ESNext", 17 | "tsBuildInfoFile": "dist/tsconfig.tsbuildinfo", 18 | "types": ["vite/client", "vitest/globals", "@vitest/browser/matchers"], 19 | "verbatimModuleSyntax": true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/library-ts/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import marko from "@marko/vite"; 2 | import { defineConfig } from "vitest/config"; 3 | const isCI = !!process.env.CI; 4 | 5 | export default defineConfig({ 6 | plugins: [marko()], 7 | test: { 8 | globals: true, 9 | coverage: { 10 | enabled: isCI, 11 | provider: "istanbul", 12 | include: ["src/**/*"], 13 | }, 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /examples/library-ts/vitest.workspace.ts: -------------------------------------------------------------------------------- 1 | import { defineWorkspace } from "vitest/config"; 2 | const isCI = !!process.env.CI; 3 | 4 | export default defineWorkspace([ 5 | { 6 | extends: "vitest.config.ts", 7 | test: { 8 | name: "server", 9 | environment: "node", 10 | include: ["src/**/{,*.}server.test.ts"], 11 | }, 12 | }, 13 | { 14 | extends: "vitest.config.ts", 15 | test: { 16 | name: "browser", 17 | browser: { 18 | enabled: true, 19 | name: "chromium", 20 | provider: isCI ? "playwright" : "preview", 21 | }, 22 | include: ["src/**/{,*.}browser.test.ts"], 23 | }, 24 | }, 25 | ]); 26 | -------------------------------------------------------------------------------- /examples/rollup-express/.browserslistrc: -------------------------------------------------------------------------------- 1 | Safari >= 10.1 2 | Chrome >= 61 3 | Firefox >= 60 4 | Edge >= 16 5 | -------------------------------------------------------------------------------- /examples/rollup-express/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | *.log 4 | .env 5 | -------------------------------------------------------------------------------- /examples/rollup-express/README.md: -------------------------------------------------------------------------------- 1 | Marko Widgets: UI Components Playground w/ rollup.js 2 | ================================== 3 | 4 | ## Getting Started 5 | 6 | ```bash 7 | npm install 8 | npm run dev 9 | ``` 10 | 11 | ## Production Build 12 | ```bash 13 | npm run build 14 | npm start 15 | ``` 16 | -------------------------------------------------------------------------------- /examples/rollup-express/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = api => { 2 | const config = { 3 | presets: ["@babel/env"] 4 | }; 5 | 6 | if (api.caller(it => it.target) === "server") { 7 | config.targets = { node: "current" }; 8 | } 9 | 10 | return config; 11 | }; 12 | -------------------------------------------------------------------------------- /examples/rollup-express/postcss.config.js: -------------------------------------------------------------------------------- 1 | const presetEnv = require("postcss-preset-env"); 2 | 3 | module.exports = () => { 4 | return { 5 | plugins: [ 6 | presetEnv() 7 | ] 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /examples/rollup-express/src/components/app-button/index.marko: -------------------------------------------------------------------------------- 1 | class { 2 | handleClick(event) { 3 | // Every Widget instance is also an EventEmitter instance. 4 | // We will emit a custom "click" event when a DOM click event 5 | // is triggered 6 | this.emit("click", { 7 | event: event // Pass along the DOM event in case it is helpful to others 8 | }); 9 | } 10 | } 11 | 12 | $ const { 13 | label, 14 | class: className, 15 | size = "normal", 16 | variant = "primary", 17 | ...attrs 18 | } = input; 19 | 20 | 38 | -------------------------------------------------------------------------------- /examples/rollup-express/src/components/app-button/marko-tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "@label": "string", 3 | "@variant": { 4 | "type": "string", 5 | "enum": ["primary", "secondary"] 6 | }, 7 | "@size": { 8 | "type": "string", 9 | "enum": ["small", "normal", "large"] 10 | }, 11 | "@class": { 12 | "type": "string", 13 | "description": "Additional CSS class names" 14 | }, 15 | "@*": "string" 16 | } 17 | -------------------------------------------------------------------------------- /examples/rollup-express/src/components/app-button/style.css: -------------------------------------------------------------------------------- 1 | .app-button { 2 | display: inline-block; 3 | border-radius: 8px; 4 | padding: 12px; 5 | background-color: var(--button-bg); 6 | color: var(--button-fg); 7 | transition-property: background-color; 8 | transition-duration: 0.3s; 9 | transition-timing-function: ease-out; 10 | } 11 | 12 | /* Variants */ 13 | .app-button-secondary { 14 | background-color: var(--button-secondary-bg); 15 | color: var(--button-secondary-fg); 16 | } 17 | 18 | .app-button:hover, .app-button-secondary:hover { 19 | filter: brightness(110%); 20 | } 21 | 22 | 23 | 24 | /* Sizes */ 25 | .app-button-small { 26 | font-size: 0.9em; 27 | padding-top: 6px; 28 | padding-bottom: 6px; 29 | } 30 | 31 | .app-button-large { 32 | font-size: 1.2em; 33 | font-weight: 100; 34 | } 35 | -------------------------------------------------------------------------------- /examples/rollup-express/src/components/app-checkbox/images/checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/rollup-express/src/components/app-checkbox/images/unchecked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/rollup-express/src/components/app-checkbox/marko-tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "@label": "string", 3 | "@data": "expression", 4 | "@checked": "boolean", 5 | "@class": "string", 6 | "@*": "string" 7 | } -------------------------------------------------------------------------------- /examples/rollup-express/src/components/app-checkbox/style.css: -------------------------------------------------------------------------------- 1 | .app-button.app-checkbox { 2 | background-color: var(--button-secondary-bg); 3 | color: var(--button-secondary-fg); 4 | } 5 | 6 | .app-button.app-checkbox.checked { 7 | background-color: var(--button-bg); 8 | color: var(--button-fg); 9 | } 10 | 11 | .app-checkbox-icon { 12 | background-image: url(./images/unchecked.svg); 13 | background-size: contain; 14 | width: 18px; 15 | height: 18px; 16 | display: inline-block; 17 | background-repeat: no-repeat; 18 | opacity: 0.2; 19 | margin-right: 4px; 20 | } 21 | 22 | .app-checkbox.checked .app-checkbox-icon { 23 | background-image: url(./images/checked.svg); 24 | opacity: 1; 25 | } 26 | -------------------------------------------------------------------------------- /examples/rollup-express/src/components/app-fetch-data/style.css: -------------------------------------------------------------------------------- 1 | .app-fetch-data .loading { 2 | background-image: url("./loading.svg"); 3 | width: 64px; 4 | height: 64px; 5 | display: inline-block; 6 | vertical-align: middle; 7 | } 8 | 9 | .app-fetch-data .table-container { 10 | max-height: 400px; 11 | overflow: auto; 12 | } 13 | -------------------------------------------------------------------------------- /examples/rollup-express/src/components/app-layout/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marko-js/examples/90689e6423c68147794cc8d278b1523f1764026b/examples/rollup-express/src/components/app-layout/favicon.png -------------------------------------------------------------------------------- /examples/rollup-express/src/components/app-layout/index.marko: -------------------------------------------------------------------------------- 1 | import favicon from "./favicon.png"; 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | $ const jsChunk = output.find(chunk => chunk.name === entry); 12 | 13 | 14 | 15 |