Skip to content

Commit

Permalink
feat: use view transitions api when enabled through options (#246)
Browse files Browse the repository at this point in the history
  • Loading branch information
sergejcodes committed Aug 24, 2023
1 parent 0d5b90a commit 94d5723
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 19 deletions.
8 changes: 4 additions & 4 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,14 +339,14 @@ export default defineConfig({
text: 'TypeScript',
link: '/guide/advanced/typescript'
},
{
text: 'Patterns',
link: '/guide/advanced/patterns'
},
{
text: 'Transitions',
link: '/guide/advanced/transitions'
},
{
text: 'Patterns',
link: '/guide/advanced/patterns'
},
{
text: 'Style Guide',
link: '/guide/advanced/style-guide'
Expand Down
3 changes: 2 additions & 1 deletion docs/api/minze-element.md
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,8 @@ export class MyElement extends MinzeElement {
exposeAttrs: {
exportparts: false, // Expose an 'exportparts' attribute on the element that includes all parts present in the component. E.g. <my-element exportparts="button, headline"></my-element>
rendered: false // Expose a 'rendered' attribute on the element, after it's rendered for the first time. E.g. <my-element rendered></my-element>
}
},
viewTransitions: false // Uses the View Transition API when set to true.
}
}
```
Expand Down
48 changes: 40 additions & 8 deletions docs/guide/advanced/transitions.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Transitions

You can determine how components should appear when they are rendered. This can be especially useful if you want to animate componets.
You can determine how components are animated when they are rendered for the first time or between state changes.

::: tip
CSS transitions are not 100% reliable, since a transition isn't triggered when the component is immediately rendered under certain circumstances.
:::
## Entry Transitions

## Component
Entry transitions run when an element is rendered for the very first time.

### Local

Animations can be defined inside of component.

Expand All @@ -22,11 +22,11 @@ class MyElement extends MinzeElement {
}
@keyframes rendered {
0% {
from {
opacity: 0%;
transform: translateY(100%);
}
100% {
to {
opacity: 100%;
transform: translateY(0);
}
Expand All @@ -41,7 +41,7 @@ MyElement.define()
<my-element></my-element>
```

## Global
### Global

By exposing the `rendered` attribute you can add animations to all rendered components, or define more specific rules.

Expand Down Expand Up @@ -86,3 +86,35 @@ MyElement.define()
```html
<my-element></my-element>
```

## View Transitions <Badge text="experimental" type="warning" />

You can activate View Transitions for a specific element by setting the `viewTransitions` option. Minze then leverages the [View Transitions API](https://developer.mozilla.org/docs/Web/API/View_Transitions_API) when the template changes. Currently this only works with supported browsers, see [Can I use](https://caniuse.com/?search=View%20Transition%20API) for more info.

::: tip
By default, View Transitions API animates CSS `opacity`. Read more about customizing View Transitions with CSS on [developer.chrome.com](https://developer.chrome.com/docs/web-platform/view-transitions/).
:::

```js
import { MinzeElement } from 'minze'

class MyElement extends MinzeElement {
options = { viewTransitions: true }

reactive = [['active', false]]

toggle = () => (this.active = !this.active)

html = () => `
<button on:click="toggle">
${this.active ? 'Active' : 'Inactive'}
</button>
`
}

MyElement.define()
```

```html
<my-element></my-element>
```
3 changes: 2 additions & 1 deletion packages/minze-vscode/snippets/common.code-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@
"body": [
"options = {",
"\tcssReset: ${1:true},",
"\texposeAttrs: { exportparts: ${2:false}, rendered: ${3:false} }",
"\texposeAttrs: { exportparts: ${2:false}, rendered: ${3:false} },",
"\tviewTransitions: ${4:false}",
"}"
],
"description": "options"
Expand Down
9 changes: 8 additions & 1 deletion packages/minze/src/env.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
declare const __VERSION__: string
export declare global {
const __VERSION__: string

interface Document {
// Experimental View Transitions API
startViewTransition?: (callback: () => Promise<any> | any) => void
}
}
30 changes: 26 additions & 4 deletions packages/minze/src/lib/minze-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,10 @@ export class MinzeElement extends HTMLElement {
* options = {
* cssReset: true,
* exposeAttrs: {
* exportparts: false
* exportparts: false,
* rendered: false
* }
* },
* viewTransitions: false
* }
* }
* ```
Expand All @@ -158,6 +159,7 @@ export class MinzeElement extends HTMLElement {
exportparts?: boolean
rendered?: boolean
}
viewTransitions?: boolean
}

/**
Expand Down Expand Up @@ -403,6 +405,26 @@ export class MinzeElement extends HTMLElement {
}
}

/**
* Leverages the View Transition API while rendering.
*
* @param force - Forces the re-rendering of the template regardless of caching.
*
* @url https://developer.mozilla.org/docs/Web/API/View_Transitions_API
*
* @example
* ```
* this.render()
* ```
*/
private async renderWithTransition(force?: boolean) {
if (this.options?.viewTransitions && document.startViewTransition) {
document.startViewTransition(async () => this.render(force))
} else {
this.render(force)
}
}

/**
* Re-renders the component template, invalidating all caches.
*
Expand All @@ -412,7 +434,7 @@ export class MinzeElement extends HTMLElement {
* ```
*/
rerender() {
this.render(true)
this.renderWithTransition(true)
}

/**
Expand Down Expand Up @@ -524,7 +546,7 @@ export class MinzeElement extends HTMLElement {
}
})

this.render()
this.renderWithTransition()
}

/**
Expand Down

0 comments on commit 94d5723

Please sign in to comment.