From 6f39857dc7bf59d84c89b311690e858ce0a4724e Mon Sep 17 00:00:00 2001 From: Aylur Date: Tue, 3 Sep 2024 20:32:41 +0200 Subject: docs: migrate to vitepress vitepress feels a bit more polished and clean --- .gitattributes | 1 + .github/workflows/pages.yml | 39 +- docs/.gitignore | 2 +- docs/.vitepress/config.ts | 1 + docs/.vitepress/theme/index.ts | 4 + docs/README.md | 11 +- docs/ags/cli-app.md | 127 + docs/ags/faq.md | 156 + docs/ags/first-widgets.md | 400 + docs/ags/theming.md | 119 + docs/ags/utilities.md | 174 + docs/ags/variable.md | 137 + docs/ags/widget.md | 145 + docs/astro.config.mjs | 44 - docs/getting-started/installation.md | 77 + docs/getting-started/introduction.md | 23 + docs/getting-started/nix.md | 1 + docs/getting-started/supported-languages.md | 59 + docs/index.md | 72 + docs/libraries/references.md | 44 + docs/package-lock.json | 8026 +++----------------- docs/package.json | 22 +- docs/prettier.config.mjs | 6 - docs/public/vitepress-logo-large.webp | Bin 0 -> 33980 bytes docs/showcases/Showcase.vue | 40 + docs/showcases/Showcases.vue | 45 + docs/showcases/showcases.ts | 15 + docs/src/assets/front-image.png | Bin 138489 -> 0 bytes docs/src/components/Showcase.astro | 37 - docs/src/content/config.ts | 6 - docs/src/content/docs/ags/cli-app.md | 129 - docs/src/content/docs/ags/faq.md | 159 - docs/src/content/docs/ags/first-widgets.mdx | 429 -- docs/src/content/docs/ags/theming.md | 113 - docs/src/content/docs/ags/utilities.md | 179 - docs/src/content/docs/ags/variable.md | 142 - docs/src/content/docs/ags/widget.md | 150 - .../content/docs/getting-started/installation.mdx | 103 - .../content/docs/getting-started/introduction.md | 28 - docs/src/content/docs/getting-started/languages.md | 64 - docs/src/content/docs/getting-started/nix.md | 8 - docs/src/content/docs/index.mdx | 67 - docs/src/content/docs/libraries/references.md | 49 - docs/src/content/showcases.ts | 13 - docs/src/env.d.ts | 2 - docs/src/style.css | 72 - docs/tsconfig.json | 10 - docs/vitepress.config.ts | 103 + docs/vitepress.theme.css | 126 + 49 files changed, 3030 insertions(+), 8749 deletions(-) create mode 100644 docs/.vitepress/config.ts create mode 100644 docs/.vitepress/theme/index.ts create mode 100644 docs/ags/cli-app.md create mode 100644 docs/ags/faq.md create mode 100644 docs/ags/first-widgets.md create mode 100644 docs/ags/theming.md create mode 100644 docs/ags/utilities.md create mode 100644 docs/ags/variable.md create mode 100644 docs/ags/widget.md delete mode 100644 docs/astro.config.mjs create mode 100644 docs/getting-started/installation.md create mode 100644 docs/getting-started/introduction.md create mode 100644 docs/getting-started/nix.md create mode 100644 docs/getting-started/supported-languages.md create mode 100644 docs/index.md create mode 100644 docs/libraries/references.md delete mode 100644 docs/prettier.config.mjs create mode 100644 docs/public/vitepress-logo-large.webp create mode 100644 docs/showcases/Showcase.vue create mode 100644 docs/showcases/Showcases.vue create mode 100644 docs/showcases/showcases.ts delete mode 100644 docs/src/assets/front-image.png delete mode 100644 docs/src/components/Showcase.astro delete mode 100644 docs/src/content/config.ts delete mode 100644 docs/src/content/docs/ags/cli-app.md delete mode 100644 docs/src/content/docs/ags/faq.md delete mode 100644 docs/src/content/docs/ags/first-widgets.mdx delete mode 100644 docs/src/content/docs/ags/theming.md delete mode 100644 docs/src/content/docs/ags/utilities.md delete mode 100644 docs/src/content/docs/ags/variable.md delete mode 100644 docs/src/content/docs/ags/widget.md delete mode 100644 docs/src/content/docs/getting-started/installation.mdx delete mode 100644 docs/src/content/docs/getting-started/introduction.md delete mode 100644 docs/src/content/docs/getting-started/languages.md delete mode 100644 docs/src/content/docs/getting-started/nix.md delete mode 100644 docs/src/content/docs/index.mdx delete mode 100644 docs/src/content/docs/libraries/references.md delete mode 100644 docs/src/content/showcases.ts delete mode 100644 docs/src/env.d.ts delete mode 100644 docs/src/style.css delete mode 100644 docs/tsconfig.json create mode 100644 docs/vitepress.config.ts create mode 100644 docs/vitepress.theme.css diff --git a/.gitattributes b/.gitattributes index 0b166ec..df23535 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ *.mjs linguist-language=TypeScript *.js linguist-language=TypeScript +*.vue linguist-vendored *.h linguist-vendored diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index eab90c2..85dd738 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -1,8 +1,9 @@ -name: Deploy to GitHub Pages +name: Deploy VitePress site to Pages on: push: - branches: [ main ] + branches: [main] + workflow_dispatch: permissions: contents: read @@ -10,22 +11,42 @@ permissions: id-token: write jobs: - build: + vitepress: runs-on: ubuntu-latest steps: - - name: Checkout your repository using git + - name: Checkout uses: actions/checkout@v4 - - name: Install, build, and upload your site - uses: withastro/action@v2 with: - path: ./docs + fetch-depth: 0 # Not needed if lastUpdated is not enabled + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Setup Pages + uses: actions/configure-pages@v4 + + - name: Install dependencies + run: npm ci + working-directory: docs + + - name: Build with VitePress + run: npm run build + working-directory: docs + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/dist deploy: - needs: build - runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} + needs: vitepress + runs-on: ubuntu-latest + name: Deploy steps: - name: Deploy to GitHub Pages id: deployment diff --git a/docs/.gitignore b/docs/.gitignore index 14d7ea7..f5f026b 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,7 +1,7 @@ dist/ result/ +.vitepress/cache/ -.astro/ node_modules/ npm-debug.log* diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts new file mode 100644 index 0000000..c1d77ca --- /dev/null +++ b/docs/.vitepress/config.ts @@ -0,0 +1 @@ +export { default as default } from "../vitepress.config" diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..603dd29 --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,4 @@ +import DefaultTheme from 'vitepress/theme' +import '../../vitepress.theme.css' + +export default DefaultTheme diff --git a/docs/README.md b/docs/README.md index 77144d5..6592cf4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,7 @@ # Astal Docs -[![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) - -This directory contains the Astal documentation website. Hosted at [aylur.github.io/astal](https://aylur.github.io/astal/) +This directory contains the Astal documentation and Library references. +Hosted at [aylur.github.io/astal](https://aylur.github.io/astal/) and [aylur.github.io/libastal](https://aylur.github.io/libastal/) ## Commands @@ -17,9 +16,9 @@ This directory contains the Astal documentation website. Hosted at [aylur.github 1. Add your image as a webp to `public/showcase` 2. Add it to `src/content/showcases.ts` - - `src` should be `/astal/showcase/your-name-optional-title.webp` - - `url` should point to the source code of the showcased widget - - `author` your name + - `src` should be `/astal/showcase/your-name-optional-title.webp` + - `url` should point to the source code of the showcased widget + - `author` your name ``` . diff --git a/docs/ags/cli-app.md b/docs/ags/cli-app.md new file mode 100644 index 0000000..0f17d55 --- /dev/null +++ b/docs/ags/cli-app.md @@ -0,0 +1,127 @@ +# CLI and App + +`App` is a singleton **instance** of [Astal.Application](/astal/reference/class.Application.html). + +```tsx +import { App } from "astal" +``` + +## Entry point + +:::code-group + +```ts [app.ts] +App.start({ + main() { + // setup anything + // instantiate widgets + }, +}) +``` + +::: + +:::warning +You can not instantiate widgets outside of the main function. +::: + +## Instance identifier + +You can run multiple instance by defining a unique instance name. + +```tsx +App.start({ + instanceName: "my-instance", // defaults to "astal" + main() {}, +}) +``` + +## Messaging from CLI + +If you want to interact with an instance from the cli, you can do so by sending a message. + +```ts +App.start({ + main() {}, + requestHandler(request: string, res: (response: any) => void) { + if (request == "say hi") { + res("hi cli") + } + res("unknown command") + }, +}) +``` + +```bash +# ags cli +$ ags -m "say hi" +hi cli + +# astal cli +$ astal say hi +hi cli +``` + +If you want to run arbitrary JavaScript from cli, you can use `App.eval`. +It will evaluate the passed string as the body of an `async` function. + +```ts +App.start({ + main() {}, + requestHandler(js: string, res) { + App.eval(js).then(res).catch(res) + }, +}) +``` + +If the string does not contain a semicolon, a single expression is assumed and returned implicity. + +```bash +$ ags -m "'hello'" +hello +``` + +If the string contains a semicolon, you have to return explicitly + +```bash +$ ags -m "'hello';" +undefined + +$ ags -m "return 'hello';" +hello +``` + +## App without AGS + +As mentioned before AGS is only a scaffolding tool. You can setup +a dev environment and a bundler yourself. In which case you won't be using +the ags cli to run the bundled scripts. The produced script can run as the main instance +and a "client" instance. + +The first time you run your bundled script the `main` function gets executed. +While that instance is running any subsequent execution of the script will call +the `client` function. + +:::code-group + +```ts [main.ts] +App.start({ + // main instance + main(...args: Array) { + print(...args) + }, + + // every subsequent calls + client(message: (msg: string) => string, ...args: Array) { + const res = message("you can message the main instance") + console.log(res) + }, + + // this runs in the main instance + requestHandler(request: string, res: (response: any) => void) { + res("response from main") + }, +}) +``` + +::: diff --git a/docs/ags/faq.md b/docs/ags/faq.md new file mode 100644 index 0000000..0e71516 --- /dev/null +++ b/docs/ags/faq.md @@ -0,0 +1,156 @@ +# Frequently asked question, common issues, tips and tricks + +## Monitor id does not match compositor + +The monitor property that windows expect is mapped by Gdk, which is not always +the same as the compositor. Instead use the `gdkmonitor` property which expects +a `Gdk.Monitor` object which you can get from compositor libraries. + +Example with Hyprland + +```js +import Hyprland from "gi://AstalHyprland" + +function Bar(gdkmonitor) { + return +} + +function main() { + for (const m of Hyprland.get_default().get_monitors()) { + Bar(m.gdk_monitor) + } +} + +App.start({ main }) +``` + +## Environment variables + +JavaScript is **not** an bash. + +```tsx +const HOME = exec("echo $HOME") // does not work +``` + +`exec` and `execAsync` runs the passed program as is, its **not** run in a +shell environment, so the above example just passes `$HOME` as a string literal +to the `echo` program. + +:::danger Please don't do this +You could pass it to bash, but that is a horrible approach. + +```tsx +const HOME = exec("bash -c 'echo $HOME'") +``` + +::: + +You can read environment variables with [GLib.getenv](https://gjs-docs.gnome.org/glib20~2.0/glib.getenv). + +```tsx +import GLib from "gi://GLib" + +const HOME = GLib.getenv("HOME") +``` + +## Custom svg symbolic icons + +Put the svgs in a directory, named `-symbolic.svg` +and use `App.add_icons` or `icons` parameter in `App.start` + +```js +// app.ts +App.start({ + icons: `${SRC}/icons`, + main() { + Widget.Icon({ + icon: "custom-symbolic", // custom-symbolic.svg + css: "color: green;", // can be colored, like other named icons + }) + }, +}) +``` + +:::info +If there is a name clash with an icon from your current icon pack +the icon pack will take precedence +::: + +## Logging + +The `console` API in gjs uses glib logging functions. +If you just want to print some text as is to stdout +use the globally available `print` function or `printerr` for stderr. + +```js +print("print this line to stdout") +printerr("print this line to stderr") +``` + +## Binding custom structures + +The `bind` function can take two types of objects. + +```typescript +interface Subscribable { + subscribe(callback: (value: T) => void): () => void + get(): T +} + +interface Connectable { + connect(signal: string, callback: (...args: any[]) => unknown): number + disconnect(id: number): void +} +``` + +`Connectable` is for mostly gobjects, while `Subscribable` is for `Variables` +and custom objects. + +For example you can compose `Variables` in using a class. + +```typescript +type MyVariableValue = { + number: number + string: string +} + +class MyVariable { + number = Variable(0) + string = Variable("") + + get(): MyVariableValue { + return { + number: this.number.get(), + string: this.string.get(), + } + } + + subscribe(callback: (v: MyVariableValue) => void) { + const unsub1 = this.number.subscribe((value) => { + callback({ string: value, number: this.number.get() }) + }) + + const unsub2 = this.string.subscribe((value) => { + callback({ number: value, string: this.string.get() }) + }) + + return () => { + unsub1() + unsub2() + } + } +} +``` + +Then it can be used with `bind`. + +```tsx +function MyWidget() { + const myvar = new MyVariableValue() + const label = bind(myvar).as(({ string, number }) => { + return `${string} ${number}` + }) + + return