docsgit add -u!
Some checks failed
JavaScript Police / lint_and_check_types (push) Successful in 1m57s
Ruby Police / lint_and_check_types (push) Has been cancelled

This commit is contained in:
Reese Armstrong 2024-08-07 15:24:44 -04:00
commit 676698a24a
Signed by: reesericci
GPG key ID: 86A9594B08970A4B

4
.gitignore vendored
View file

@ -11,4 +11,6 @@
*.gem
/node_modules/
.gem_rbs_collection/
.ruby-lsp
.ruby-lsp
docs/.vitepress/dist
docs/.vitepress/cache

134
README.md
View file

@ -8,138 +8,10 @@
`actionview-svelte-handler` is a template handler for Action View that allows you to create [Svelte](https://svelte.dev) views in Rails applications with ease.
## Usage
> [!INFO]
>
> The documentation for this gem is available at [svelte.rb.obl.ong](https://svelte.rb.obl.ong)
Add `.html.svelte` views to your application instead of `.html.erb`.
> [!CAUTION]
> This will make ERB helpers unavailable because Svelte is registered as a template handler, replacing ERB when it is used.
To pass props, use the `Svelte.props` object in your controller (or set instance variables), and then access them as a store with `$props`.
### Example usage
#### Controller
`app/controllers/users_controller.rb`:
```ruby
def show
Svelte.props[:user] = User.find_by(username: params[:username])
end
```
#### View
`app/views/users/show.html.svelte`:
```html
<script>
let name = $props.user.name
$: mailto = "mailto://" + $props.user.email
</script>
<h1>Hello, {name}</h1>
<a href={mailto}>{$props.user.email}</a>
<style>
h1 {
color: red
}
</style>
```
### Configuration
Configuration options can be found in `config/initializers/svelte.rb`. The following is a list of options and some information:
| Option with type | Description | Default |
| ------------------- | ---------------------------------------------------------------------- | ----------------------------------- |
| `ssr <bool>` | Global server-side rendering. Does not override the svelte[ssr] local. | `true` |
| `aliases <Hash[Symbol, String]>` | Path aliases when importing from Svelte views. | See [path aliases](#path-aliases) |
| `preprocess <Hash[String \| Symbol, String]>` | Configuration for [svelte-preprocess](https://github.com/sveltejs/svelte-preprocess/blob/main/docs/usage.md) | `{}` |
#### Example usage (with `Svelte.configure` block)
`config/initializers/svelte.rb`:
```ruby
Svelte.configure do |config|
config.ssr = true
config.aliases = {
:$views => Rails.root.join("app", "views")
}
end
```
### Locals
To set per-render options, we use a set of locals underneath the `svelte` hash. Locals are always the highest precedence
| Option with type | Description | Default |
| ------------------- | -------------------------------------------------------------------------- | ------------------------------------- |
| `ssr <bool>` | Server-side prerendering | `true` |
| `island <Hash[String, String]>` | HTML attributes for [is-land](https://github.com/11ty/is-land) | `{ "on:visible": "", "on:idle": "" }` |
#### Example usage
`app/controllers/example_controller.rb`:
```ruby
render "view", locals: { svelte: { ssr: false } }
```
### Variants
To configure server-side rendering at a file level, you can use the `client` and `server` variants. Just set your file name like in the example.
#### Example usage
`app/views/example/show.html+client.svelte`
`app/views/example/show.html+server.svelte`
`app/controllers/example_controller.rb`:
```ruby
render "view", variant: "client"
```
### Path aliases
Path aliases are used as quick references from your Svelte views to key paths in your application. They are primarily utilized when importing other Svelte components (i.e. partials).
The list of path aliases set by the generator is as follows:
| Alias | Resolution |
| -------- | -------------------------------- |
| `$root` | `Rails.root` |
| `$app` | `Rails.root.join "app"` |
| `$views` | `Rails.root.join "app", "views"` |
#### Example usage
```javascript
import Card from "$views/application/card.html.svelte"
```
## Installation
1. Ensure you have [Node.js >=v12.16.0](https://nodejs.org) and [NPM](https://npmjs.com) in your `$PATH`
3. Add the `actionview-svelte-handler` gem to your Gemfile by executing:
```bash
bundle add actionview-svelte-handler
```
4. And then execute the generator:
```bash
bin/rails generate svelte:install
```
5. Enjoy!
## Copyright

49
docs/.vitepress/config.ts Normal file
View file

@ -0,0 +1,49 @@
import { defineConfig } from 'vitepress'
const sections = [
{
text: "Getting Started",
items: [
{ text: 'Installation', link: '/getting-started/install.md' },
{ text: "Creating views", link: "/getting-started/creating-views.md" }
]
},
{
text: "Reference",
items: [
{ text: "Props", link: "/reference/props.md" },
{ text: "Path aliases", link: "/reference/aliases.md" },
{ text: "Islands", link: "/reference/islands.md" }
]
},
{
text: "Configuration",
items: [
{ text: "Global", link: "/config/global.md" },
{ text: "Local", link: "/config/local.md" },
{ text: "Variants", link: "/config/variants.md" }
]
}
]
export default defineConfig({
title: "actionview-svelte-handler",
description: "Create Svelte views seamlessly in Rails applications.",
themeConfig: {
outline: "deep",
logo: "../logo.png",
nav: [
{ text: 'Home', link: '/' },
...sections
],
sidebar: sections,
socialLinks: [
{ icon: {
svg: `
<svg width="16" height="16" viewBox="0 0 4.5 4" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient xlink:href="#a" id="b" x1="42519" y1="-7079" x2="42575" y2="-6967" gradientUnits="userSpaceOnUse"/><linearGradient id="a"><stop style="stop-color:#2185d0;stop-opacity:0" offset="0"/><stop offset="0" style="stop-color:#2185d0;stop-opacity:.30000001"/><stop style="stop-color:#2185d0;stop-opacity:.30000001" offset="1"/></linearGradient></defs><path style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:url(#b);fill-opacity:1;stroke:none;stroke-width:3.67846;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:2;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill;stop-color:#000;stop-opacity:1" d="M42519-7079a1 1 0 0 0 0 1l33 126a87 87 0 0 0 40-34l-72-93a1 1 0 0 0-1 0z" transform="translate(-1030 173) scale(.02428)"/><path style="opacity:1;fill:#2185d0;fill-opacity:1;stroke-width:17.0055;paint-order:markers fill stroke;stop-color:#000" d="M11249-1884a23 23 0 0 0-19 36l19-25h1l19 25a23 23 0 0 0-20-36z" transform="translate(-1030 173) scale(.09176)"/></svg>
`,
}, link: 'https://codeberg.org/reesericci/actionview-svelte-handler', ariaLabel: "Source code" }
]
}
})

View file

@ -0,0 +1,15 @@
@import url("https://overpass-30e2.kxcdn.com/overpass.css");
@import url("https://overpass-30e2.kxcdn.com/overpass-mono.css");
:root {
--vp-font-family-base: "Overpass", system-ui;
--vp-font-family-mono: "Overpass Mono", monospace;
--vp-c-brand-1: #ff4000;
--vp-c-brand-2: #D30001;
--vp-c-brand-3: #676779;
--vp-button-brand-bg: var(--vp-c-brand-1);
}
.title > span {
padding-top: 0.2rem;
}

View file

@ -0,0 +1,4 @@
import DefaultTheme from 'vitepress/theme-without-fonts'
import './custom.css'
export default DefaultTheme

22
docs/config/global.md Normal file
View file

@ -0,0 +1,22 @@
# Global
Global configuration options can be found in `config/initializers/svelte.rb`.
## Options
| Option with type | Description | Default |
| ---------------- | ----------- | ------- |
| `ssr` : `bool` | Global server-side rendering. Does not override the `ssr` local or variants. | `true` |
| `aliases` : <br> `Hash[Symbol, String]`| Path aliases when importing from Svelte views. <br>See [Path aliases](/reference/aliases) for more information. | `{}` |
| `preprocess` : <br>`Hash[String \| Symbol, String]` | Configuration for [svelte-preprocess](https://github.com/sveltejs/svelte-preprocess/blob/main/docs/usage.md) | `{}` |
## Example with `Svelte.configure`
```ruby
Svelte.configure do |config|
config.ssr = true
config.aliases = {
:$views => Rails.root.join("app", "views")
}
end
```

20
docs/config/local.md Normal file
View file

@ -0,0 +1,20 @@
# Local
For per-render options, we use a set of render locals underneath the `svelte` hash.
Locals are always the highest precedence of config.
## Options
| Option with type | Description | Default |
| ---------------- | ------------------------ | ------------- |
| `ssr`: `bool` | Server-side prerendering | `Svelte.ssr` |
| `island`:<br>`Hash[String, String]` | HTML attributes for<br>[is-land](https://github.com/11ty/is-land) | <pre><code>{<br> "on:visible": "",<br> "on:idle": ""<br>}</code></pre> |
## Example
### Controller
```ruby
render "view", locals: { svelte: { ssr: false } }
```

27
docs/config/variants.md Normal file
View file

@ -0,0 +1,27 @@
---
outline: 'deep'
---
# Variants
File variants are a feature in Rails that we use to denote on a file basis which components should be server or client rendered. It has precedence over the `Svelte.ssr` global but not the `ssr` local.
To set the variant, append either `+client` or `+server` after `.html` in the filename, like `index.html+client.svelte`
## Examples
### Filenames
```file
app/views/example/show.html+client.svelte
```
```file
app/views/example/show.html+server.svelte
```
### Controller
```ruby
render "view", variant: "client"
```

View file

@ -0,0 +1,8 @@
# Creating views
Create `.html.svelte` views in your app instead of `.html.erb` - they work just like any other view.
`actionview-svelte-handler` will then compile and optionally prerender the component, then serve it to the client.
> [!WARNING]
> This will make ERB helpers unavailable because Svelte is registered as a template handler, replacing ERB when it is used.

View file

@ -0,0 +1,31 @@
# Installation
This page will walk you through the quick and easy installation of <br>`actionview-svelte-handler`.
To learn more about building with Svelte, visit [svelte.dev](https://svelte.dev).
## Requirements
- Node.js >= 12.16.0
- NPM
- Ruby on Rails
> [!WARNING]
>
> This gem has only been tested with Rails 7 and Ruby 3, but it may work on older versions.
## Steps
1. Add the `actionview-svelte-handler` gem to your Gemfile by executing:
```bash
bundle add actionview-svelte-handler
```
2. Then execute the generator:
```bash
bin/rails generate svelte:install
```
3. Enjoy!

BIN
docs/hero.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 KiB

29
docs/index.md Normal file
View file

@ -0,0 +1,29 @@
---
# https://vitepress.dev/reference/default-theme-home-page
layout: home
hero:
name: "<code>actionview-svelte-handler</code>"
text: "Svelte on Rails that feels native"
tagline: An Action View template handler for Svelte that fades the build step into the background.
image:
src: "./hero.png"
actions:
- theme: brand
text: Get started
link: /getting-started/install
- theme: alt
text: Reference
link: /reference/props
features:
- title: <code>.html.svelte</code>
details: Slots in to your existing ERB workflow and works just like you'd expect.
- title: Reactive views
details: Svelte provides real client-side reactivity to your views, without forcing you to split your reactivity from your markup.
- title: Props
details: Pass props and instance variables from your controllers directly to your components inside a Svelte store.
- title: Server-side rendering
details: Render content ahead of time on the server, then hydrate client-side interaction for maximum performance and usability without JavaScript.
---

BIN
docs/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

1
docs/public/CNAME Normal file
View file

@ -0,0 +1 @@
svelte.rb.obl.ong

27
docs/reference/aliases.md Normal file
View file

@ -0,0 +1,27 @@
# Path aliases
Path aliases are used as quick references from your Svelte views to key paths in your application.
They are primarily utilized when importing other Svelte components (i.e. partials).
## Preconfigured
These are the aliases set by the generator in the [global configuration file](/config/global) and can be changed.
| Alias | Resolution |
| -------- | --------------------------------- |
| `$root` | `Rails.root` |
| `$app` | `Rails.root.join("app")` |
| `$views` | `Rails.root.join("app", "views")` |
## Example
### View
```svelte
<script>
import Card from "$views/application/card.html.svelte"
</script>
<Card/>
```

12
docs/reference/islands.md Normal file
View file

@ -0,0 +1,12 @@
# Islands
>[!WARNING]
> This section gets quite technical and is not necessary for most usecases to understand fully.
`actionview-svelte-handler` uses an [Component Island architecture](https://jasonformat.com/islands-architecture/) to allow for hydrating the Svelte components independently of the rest of the page.
This allows for loading the layout and other parts of the page without needing to render the Svelte components immediately, providing for a better user experience.
Additionally, before the component is hydrated, the server-side rendered HTML which has most of the content can be displayed, just without interactivity.
To achieve this, we heavily rely on [11ty's is-land WebComponent](https://github.com/11ty/is-land), and pass through their rendering options as [locals](/config/local).

41
docs/reference/props.md Normal file
View file

@ -0,0 +1,41 @@
---
outline: 'deep'
---
# Props
To pass props, use the `Svelte.props` hash in your controller, and then access them as a store with `$props`.
Additionally, controller instance variables are automatically passed as props, but never override props set with `Svelte.props`, and are available **without an @ symbol** in the store.
> [!WARNING] <code>$</code> accessors for stores will be going away in Svelte 5.
>
> We are not sure yet how this will impact the props store, but it is likely you will use either `props` or `window.props`, and potentially may have to subscribe manually. It is likely we will switch to using the `$state` rune for Svelte 5, but no decision has been made.
## Examples
### Controller
```ruby
def show
Svelte.props[:user] = User.find_by(username: params[:username])
end
```
### View
```html
<script>
let name = $props.user.name
$: mailto = "mailto://" + $props.user.email
</script>
<h1>Hello, {name}</h1>
<a href={mailto}>{$props.user.email}</a>
<style>
h1 {
color: red
}
</style>
```

1604
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -29,11 +29,15 @@
"lint": "ts-standard lib/ts/ --fix --format github",
"build": "node build.esbuild.js",
"postbuild": "tsc",
"watch": "node watch.esbuild.js"
"watch": "node watch.esbuild.js",
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
},
"devDependencies": {
"esbuild": "0.23.0",
"ts-standard": "^12.0.2",
"typescript": "^5.5.4"
"typescript": "^5.5.4",
"vitepress": "^1.3.2"
}
}
}