diff --git a/content/getting-started/10.accessibility.md b/content/getting-started/10.accessibility.md
index 2116a9d6..134163bf 100644
--- a/content/getting-started/10.accessibility.md
+++ b/content/getting-started/10.accessibility.md
@@ -26,8 +26,6 @@ Read more: https://www.tiny.cloud/docs/tinymce/6/tinymce-and-screenreaders/
### Things to keep in mind
-- Visual Editor is only accessible on the Directus side — not your website. So we always need to click an edit button first, then the
- overlays are accessible.
- Manual Sorting is currently not supported/accessible.
- Once focused, the code interface (Codemirror) cannot be exited using the tab key.
- The Markdown interface also doesn’t allow you to exit the field. This is because it supports tabs inside the editor’s
diff --git a/content/guides/02.content/8.visual-editor/3.customization.md b/content/guides/02.content/8.visual-editor/3.customization.md
index c9d9883a..183c6512 100644
--- a/content/guides/02.content/8.visual-editor/3.customization.md
+++ b/content/guides/02.content/8.visual-editor/3.customization.md
@@ -39,6 +39,9 @@ The library ships with a number of built in CSS Selectors already applied to its
.directus-visual-editing-edit-button {
/* the edit button */
}
+.directus-visual-editing-actions-flipped {
+ /* a modifier on the rect that flips the action buttons below it, applied automatically when the rect is near the top of the viewport */
+}
```
## CSS Variables
@@ -48,21 +51,33 @@ The library also ships with a number of predefined CSS variables. These can be o
```css
:root {
--directus-visual-editing--overlay--z-index: 999999999;
- --directus-visual-editing--rect--border-spacing: 9px;
+ --directus-visual-editing--rect--border-spacing: 8px;
--directus-visual-editing--rect--border-width: 2px;
--directus-visual-editing--rect--border-color: #6644ff;
--directus-visual-editing--rect--border-radius: 6px;
--directus-visual-editing--rect-hover--opacity: 0.333;
--directus-visual-editing--rect-highlight--opacity: 0.333;
- --directus-visual-editing--edit-btn--width: 28px;
- --directus-visual-editing--edit-btn--height: 28px;
- --directus-visual-editing--edit-btn--radius: 50%;
+ --directus-visual-editing--actions--offset: 4px;
+ --directus-visual-editing--actions--focus-ring-color: #6644ff;
+ --directus-visual-editing--actions--focus-ring-width: 2px;
+ --directus-visual-editing--actions--focus-ring-offset: 2px;
+ --directus-visual-editing--edit-btn--width: 24px;
+ --directus-visual-editing--edit-btn--height: 24px;
+ --directus-visual-editing--edit-btn--radius: 6px;
--directus-visual-editing--edit-btn--bg-color: #6644ff;
+ --directus-visual-editing--edit-btn-hover--bg-color: color-mix(in srgb, #6644ff, #2e3C43 25%);
--directus-visual-editing--edit-btn--icon-bg-image: url('data:image/svg+xml,');
--directus-visual-editing--edit-btn--icon-bg-size: 66.6%;
+ --directus-visual-editing--ai-btn--bg-color: #6644ff;
+ --directus-visual-editing--ai-btn-hover--bg-color: color-mix(in srgb, #6644ff, #2e3C43 25%);
}
```
+::callout{icon="material-symbols:info-outline"}
+**Defaults inside the Directus Studio**
+When the visual editor runs inside the Directus Studio iframe, defaults for several variables are sourced from the active Studio theme (primary color, border radius, button size, focus-ring width/offset) rather than the compiled-in fallbacks shown above. Your own `:root` or `customClass` overrides still take precedence.
+::
+
## Custom Classes
Finally, custom classes can be added to all or a subset of elements defined by the library’s [apply method](/guides/content/visual-editor/frontend-library#api) using the `customClass` property. This class will be applied to the `div.directus-visual-editing-overlay` element within the `div#directus-visual-editing` container.
diff --git a/content/guides/09.extensions/3.app-extensions/5.modules.md b/content/guides/09.extensions/3.app-extensions/5.modules.md
index 8675d273..d1400593 100644
--- a/content/guides/09.extensions/3.app-extensions/5.modules.md
+++ b/content/guides/09.extensions/3.app-extensions/5.modules.md
@@ -23,19 +23,19 @@ The `index.js` or `index.ts` file exports an object that is read by Directus. It
## Entrypoint Example
```js
-import { defineInterface } from '@directus/extensions-sdk'
-import ModuleComponent from './module.vue';
+import { defineInterface } from "@directus/extensions-sdk";
+import ModuleComponent from "./module.vue";
export default defineInterface({
- id: 'custom',
- name: 'Custom',
- icon: 'box',
- routes: [
- {
- path: '',
- component: ModuleComponent,
- },
- ],
+ id: "custom",
+ name: "Custom",
+ icon: "box",
+ routes: [
+ {
+ path: "",
+ component: ModuleComponent,
+ },
+ ],
});
```
@@ -62,7 +62,6 @@ The route object uses the same syntax as Vue Router, defining each route as an o
| `path` | The route path without the leading slash. |
| `component` | A Vue component to be rendered for this route. |
-
The `routes` array should contain a root route with an empty path, which will load at the module's base route (the value of the module's `id`). Dynamic portions of the path can be defined using the `:param` syntax.
### Route Component
@@ -71,7 +70,7 @@ The module route component will be rendered in the Data Studio when the route is
```vue
-
Lorem ipsum dolor sit amet
'; + page_body.value = "Lorem ipsum dolor sit amet
"; break; - case 'hello-world': - page_title.value = 'Hello World'; - page_banner.value = '/assets/853B243D-A1BF-6051-B1BF-23EDA8E32A09?width=2000&height=563&fit=cover'; + case "hello-world": + page_title.value = "Hello World"; + page_banner.value = + "/assets/853B243D-A1BF-6051-B1BF-23EDA8E32A09?width=2000&height=563&fit=cover"; page_cards.value = all_pages.value; - page_body.value = 'Lorem ipsum dolor sit amet
'; + page_body.value = "Lorem ipsum dolor sit amet
"; break; - case 'contact': - page_title.value = 'Contact Us'; - page_banner.value = '/assets/91CE173D-A1AD-4104-A1EC-74FCB8F41B58?width=2000&height=563&fit=cover'; + case "contact": + page_title.value = "Contact Us"; + page_banner.value = + "/assets/91CE173D-A1AD-4104-A1EC-74FCB8F41B58?width=2000&height=563&fit=cover"; page_cards.value = []; - page_body.value = 'Lorem ipsum dolor sit amet
'; + page_body.value = "Lorem ipsum dolor sit amet
"; break; default: - page_title.value = '404: Not Found'; + page_title.value = "404: Not Found"; } ``` @@ -485,19 +478,22 @@ Or from the internal API providing you have a table with the fields `title`, `ba (WYSIWYG field): ```js -api.get(`/items/pages?fields=title,banner,content&filter[uri][_eq]=${page}`).then((rsp) => { - if(rsp.data.data){ - rsp.data.data.forEach(item => { - page_title.value = item.title; - page_banner.value = `/assets/${item.banner}?width=2000&height=563&fit=cover`; - page_body.value = item.content; - }); - } else { - page_title.value = "404: Not Found"; - } -}).catch((error) => { - console.log(error); -}); +api + .get(`/items/pages?fields=title,banner,content&filter[uri][_eq]=${page}`) + .then((rsp) => { + if (rsp.data.data) { + rsp.data.data.forEach((item) => { + page_title.value = item.title; + page_banner.value = `/assets/${item.banner}?width=2000&height=563&fit=cover`; + page_body.value = item.content; + }); + } else { + page_title.value = "404: Not Found"; + } + }) + .catch((error) => { + console.log(error); + }); ``` ### Work With Images @@ -528,13 +524,15 @@ export default function useDirectusToken(directusApi) { queryParams.push(`${key}=${value}`); } - return path.includes('?') ? `${path}&${queryParams.join('&')}` : `${path}?${queryParams.join('&')}`; + return path.includes("?") + ? `${path}&${queryParams.join("&")}` + : `${path}?${queryParams.join("&")}`; } function getToken() { return ( - directusApi.defaults?.headers?.['Authorization']?.split(' ')[1] || - directusApi.defaults?.headers?.common?.['Authorization']?.split(' ')[1] || + directusApi.defaults?.headers?.["Authorization"]?.split(" ")[1] || + directusApi.defaults?.headers?.common?.["Authorization"]?.split(" ")[1] || null ); } @@ -546,7 +544,7 @@ export default function useDirectusToken(directusApi) { access_token: accessToken, }); } -}; +} ``` This will use the access token of the current user to render the images. Alternatively, you can enable Read permissions @@ -555,7 +553,7 @@ on the Public role for the image ID or images with a specific folder ID to remov Import the function into the `module.vue` file to make it available in your script: ```js -import useDirectusToken from './use-directus-token'; +import useDirectusToken from "./use-directus-token"; ``` Include the function `AddTokenToURL` as a variable from the new script. @@ -573,7 +571,9 @@ setup(props) { Then wrap any internal images with this function: ```js -page_banner.value = addTokenToURL(`/assets/${item.banner}?width=2000&height=563&fit=cover`); +page_banner.value = addTokenToURL( + `/assets/${item.banner}?width=2000&height=563&fit=cover`, +); ``` ::callout{icon="material-symbols:info-outline} @@ -597,7 +597,7 @@ the following SCSS: width: 100%; max-width: 1024px; - &> div { + & > div { margin-bottom: var(--content-padding); } } @@ -694,22 +694,22 @@ images from within Directus to surface on the page. From here you can create con of the Directus platform. ```js [index.js] -import ModuleComponent from './module.vue'; +import ModuleComponent from "./module.vue"; export default { - id: 'landing-page', - name: 'Landing Page', - icon: 'rocket_launch', + id: "landing-page", + name: "Landing Page", + icon: "rocket_launch", routes: [ { - name: 'home', - path: '', + name: "home", + path: "", props: true, component: ModuleComponent, }, { - name: 'page', - path: ':page', + name: "page", + path: ":page", props: true, component: ModuleComponent, }, @@ -720,21 +720,23 @@ export default { ```vue [module.vue]