diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index b1ea259..f93c4ed 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -49,10 +49,15 @@ export default defineConfig({ }, ], }, - /*{ + { label: 'Guides', - autogenerate: { directory: 'guides' }, - },*/ + items: [ + { + label: "Dashboard Customization", + link: "guides/dashboard-customization" + } + ], + }, { label: 'Tools', autogenerate: { directory: 'tools' }, diff --git a/docs/src/content/docs/guides/dashboard-customization.mdx b/docs/src/content/docs/guides/dashboard-customization.mdx index 4899d6f..d9b8ea1 100644 --- a/docs/src/content/docs/guides/dashboard-customization.mdx +++ b/docs/src/content/docs/guides/dashboard-customization.mdx @@ -3,4 +3,360 @@ title: Dashboard Customization description: Learn how to make your dashboard unique, with your own styles, structure, and more. --- -TODO. +import { Steps, FileTree } from '@astrojs/starlight/components'; + +Lunaria provides several ways to customize your localization dashboard to better fit your project's look and feel. Follow this guide to understand all the available customization options. + +## Title and description + +By default, Lunaria will add a default title and description for your dashboard. You can change it to make it easy to identify and find your project's dashboard through search engines. + + +1. Add the [`dashboard.title`](/reference/configuration/#dashboardtitle) option to your Lunaria config. The defined title will also be shown in the dashboard's heading: + + ```json title="lunaria.config.json" add={2-4} + { + "dashboard": { + "title": "Lunaria Localization Status" + } + } + ``` + +2. Add the [`dashboard.description`](/reference/configuration/#dashboarddescription) option to your Lunaria config: + + ```json title="lunaria.config.json" add={4} + { + "dashboard": { + "title": "Lunaria Localization Status", + "description": "Localization status dashboard for the Lunaria project." + } + } + ``` + + +## Canonical URL + +If you desire to publicize different versions of your dashboard (e.g. localized versions of the dashboard itself), it might be helpful to set a [canonical URL](https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls#rel-canonical-link-method) to optimize your dashboard's ranking on search engines. + +To add a canonical URL, you can set [`dashboard.site`](/reference/configuration/#dashboardsite) in your Lunaria configuration file: + +```json title="lunaria.config.json" add={3} +{ + "dashboard": { + "site": "https://localization.lunaria.dev/" + } +} +``` + +## Favicons + +Setting a favicon can help match your project's feel and make it easier to identify your dashboard in the user's web browser. Lunaria allows you to define both multiple external and one inline favicon. + +To add a favicon, you have to set [`dashboard.favicon`](/reference/configuration/#dashboardfavicon) in your Lunaria configuration, with one of, or both the `external` or `inline` properties. + +:::note[Why should I have multiple favicons?] +Currently, [not all browsers support SVG favicons](https://caniuse.com/link-icon-svg), therefore having a fallback favicon (generally a `.ico` icon) is a good way to ensure most users will be able to see an icon when they open the website. +::: + +### External favicons + +External favicons are favicons you load through another URL as a resource. You can add them in the `external` property of [`dashboard.favicon`](/reference/configuration/#dashboardfavicon). The example below adds both `.svg` and `.ico` favicons. + +```json title="lunaria.config.json" add={4-13} +{ + "dashboard": { + "favicon": { + "external": [ + { + "link": "https://lunaria.dev/favicon.svg", + "type": "image/svg+xml" + }, + { + "link": "https://lunaria.dev/favicon.ico", + "type": "image/x-icon" + }, + ] + } + } +} +``` + +### Inline favicon + +An inline favicon is a local [`.svg` favicon appended to your dashboard through a Data URI](https://css-tricks.com/lodge/svg/09-svg-data-uris/). You can add one through the `inline` property of [`dashboard.favicon`](/reference/configuration/#dashboardfavicon). + + +1. Add your favicon SVG file to a directory in your project (e.g. `src/assets/`): + + + - src/ + - assets/ + - **favicon.svg** + - lunaria.config.json + + +2. Add the path to your favicon as the `inline` property of [`dashboard.favicon`](/reference/configuration/#dashboardfavicon) in your Lunaria config: + + ```json title="lunaria.config.json" add={4} + { + "dashboard": { + "favicon": { + "inline": "./src/assets/favicon.svg" + } + } + } + ``` + + +## Hidden path bases + +The dashboard contains several paths as links to your source and localized content. These can be quite lengthy depending on how far they are from your project's root directory. For example, if the unique part of your content files' paths starts only after `src/content/docs/`, you might want to hide this portion of the path and only show what's relevant, e.g. `guides/my-content.mdx`. + +To do so, you can set the [`dashboard.basesToHide`](/reference/configuration/#dashboardbasestohide) option in your Lunaria config with all the desired path bases to hide. This example assumes you're tracking content files that start at `src/content/docs/` or `src/i18n/`: + +```json title="lunaria.config.json" add={3} +{ + "dashboard": { + "basesToHide": ["src/content/docs/", "src/i18n/"] + } +} +``` + +With this, references to paths like `src/content/docs/guide.mdx` and `src/i18n/dictionary.ts` will be shortened to their unique parts, namely `guide.mdx` and `dictionary.ts`. + + +## Custom CSS + +The dashboard can be further customized by adding your own custom CSS, allowing you to modify or extend the default styles provided by Lunaria out of the box. + + +1. Add a CSS file to a directory in your project (e.g. `src/styles/`). For example, you can change the default body font family used: + + ```css title="src/styles/lunaria.css" + :root { + --ln-font-body: Tahoma, sans-serif; + } + ``` + +2. Add the path to your CSS file to your Lunaria config's [`dashboard.customCss`](/reference/configuration/#dashboardcustomcss) array property: + + ```json title="lunaria.config.json" add={3} + { + "dashboard": { + "customCss": ["./src/styles/lunaria.css"] + } + } + ``` + + +:::tip +Check out the Lunaria repository to see [all the available CSS custom properties set by Lunaria and its implementation](https://github.com/yanthomasdev/lunaria/blob/main/packages/core/src/dashboard/styles.ts). +::: + +## Custom labels and language + +By default, Lunaria's dashboard comes with UI labels written in English. These UI labels can be completely changed, be it simple text labels, language values, or dynamic sentences (e.g. "X done, X outdated, X missing"). + +### Text labels + +For example, you can change the default message shown when a locale's localization is 100% complete by changing the `statusByLocale.completeLocalization` property of [`dashboard.ui`](/reference/configuration/#dashboardui): + +```json title="lunaria.config.json" add={4} +{ + "dashboard": { + "ui": { + "statusByLocale.completeLocalization": "No missing or outdated changes found, congratulations!" + } + } +} +``` + +:::tip +Check the reference section about [`dashboard.ui`](/reference/configuration/#dashboardui) for a complete list of the available properties and their default values. +::: + +### Format labels + +Some labels, suffixed with `Format` in their name, come with named `{}` blocks that are going to be dynamically replaced with values from other UI labels or from the internal context, for example: + +```json +"statusByLocale.detailsTitleFormat": "{locale_name} ({locale_tag})", +``` + +These can also be changed, though it is highly recommended to not remove any of the `{}` blocks present by default, as that would mean possibly not inserting a dynamic value that was expected. + +For example, you could modify your dashboard to show the language details' summary from the format `Deutsch (de)` to `Deutsch - de` by making a small change in the default `statusByLocale.detailsTitleFormat` value: + +```json title="lunaria.config.json" add={4} +{ + "dashboard": { + "ui": { + "statusByLocale.detailsTitleFormat": "{locale_name} - {locale_tag}", + } + } +} +``` + +### `lang` and `dir` + +Since all labels can be changed, there is no imposition from completely translating the dashboard to another language. To make this even easier, [`dashboard.ui`](/reference/configuration/#dashboardui) exposes the `lang` and `dir` properties, which directly translates to the HTML [`lang`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang) and [`dir`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir) attributes used in your dashboard. + +For example, that's how you could go about changing your dashboard's language to Brazilian Portuguese (most properties have been omitted from this example for simplicity's sake): + +```json title="lunaria.config.json" add={4-6} +{ + "dashboard": { + "ui": { + "lang": "pt-BR", + "statusByFile.heading": "Estado da localização por arquivo", + "statusByFile.tableRowFile": "Arquivo", + } + } +} +``` + +## Custom UI elements + +Lunaria's dashboard was designed to be flexible and easily customizable through [custom CSS](#custom-css) and the available [configuration options](/reference/configuration/#dashboard-options). When that's not enough, Lunaria allows you to extend and override your dashboard's UI using its [Renderer API](/reference/renderer/). + + +1. Add a new `renderer.config.ts` or `renderer.config.js` file to your project with the following content: + + ```ts title="renderer.config.ts" + import { defineRendererConfig } from '@lunariajs/core'; + + export default defineRendererConfig({ + // options will go here... + }); + ``` + +2. Add the path to your renderer file to your Lunaria config's [`renderer`](/reference/configuration/#renderer) configuration property: + + ```json title="lunaria.config.json" add={2} + { + "renderer": "./renderer.config.ts" + } + ``` + + +### Custom components + +All UI elements in Lunaria are built without the use of frameworks, using only the good ol' HTML. To improve the authoring experience, Lunaria comes with a built-in `html` tagged template to help you build your own components. + +:::tip[Syntax highlighting] +You can get syntax highlighting and language support inside `html` using the [`lit-html` VSCode extension](https://marketplace.visualstudio.com/items?itemName=bierner.lit-html) or the [`vim-jsx-pretty` plugin for Vim](https://github.com/MaxMEllon/vim-jsx-pretty). +::: + +A component in Lunaria is a function that receives a few parameters and returns a string of HTML: + +```ts title="example-component.ts" +import { html } from '@lunariajs/core'; + +const CustomParagraph = () => html`

This is my custom paragraph component!

`; +``` + +Since these components are [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals), you can interpolate values using the `${}` notation as you normally would in JavaScript: + +```ts title="interpolating-value.ts" +import { html } from '@lunariajs/core'; + +const favoriteColor = "red"; + +const ColorComponent = () => html`

My favorite color is ${favoriteColor}!

`. +``` + +
+See the resulting HTML +```html +

My favorite color is red!

+``` +
+ +You can also interpolate over lists of values (e.g. arrays) using the `.map()` method: + +```ts title="interpolating-list.ts" +import { html } from '@lunariajs/core'; + +const catColors = ["grey", "white", "black", "orange", "buff"]; + +const CatColorsList = () => html`` +``` + +
+See the resulting HTML +```html + +``` +
+ +:::caution +Lunaria's `html` tagged template does not sanitize HTML input. Be sure to only interpolate trusted values in your components or use a package like [`sanitize-html`](https://www.npmjs.com/package/sanitize-html) to do it safely. +::: + +### Slotting elements + +Elements can be slotted into the dashboard with the [renderer's `slots` property](/reference/renderer/#slots). All components will be passed a copy of your Lunaria configuration you can use to get values from: + + +1. Create a new component using the `html` tagged template. In this case, a `"robots"` [meta tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta) with the `"noindex"` content to avoid indexing the dashboard in search engines: + + ```ts title="renderer.config.ts" add={3} + import { defineRendererConfig, html } from '@lunariajs/core'; + + const NoIndex = () => html``; + + export default defineRendererConfig({}); + ``` + +2. Add the created component to one of the available slots in the [`slots` property](/reference/renderer/#slots). Here, the `head` slot will be used to insert the component into the dashboard's [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head): + + ```ts title="renderer.config.ts" add={6-8} + import { defineRendererConfig, html } from '@lunariajs/core'; + + const NoIndex = () => html``; + + export default defineRendererConfig({ + slots: { + head: NoIndex, + } + }); + ``` + + +### Overriding elements + +Elements can also be overridden in the dashboard with the [renderer's `overrides` property](/reference/renderer/#overrides). All components added to `overrides` will be passed a copy of your Lunaria configuration, as well as the generated Lunaria status (except for the `meta` property) you can use to get values from: + + +1. Create a new component using the `html` tagged template. In this case, the component will override the dashboard's body and show the `sharedPath` for each localized content: + + ```ts title="renderer.config.ts" add={3} + import { defineRendererConfig, html } from '@lunariajs/core'; + + const NewBody = (config, status) => html``; + + export default defineRendererConfig({}); + ``` + +2. Add the created component to one of the available overrides in the [`overrides` property](/reference/renderer/#overrides). Here, the `body` slot will be used to insert the component and override everything inside the dashboard's [`` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body): + + ```ts title="renderer.config.ts" add={6-8} + import { defineRendererConfig, html } from '@lunariajs/core'; + + const NewBody = (config, status) => html``; + + export default defineRendererConfig({ + overrides: { + body: NewBody, + } + }); + ``` + + + diff --git a/docs/src/content/docs/manual-installation.mdx b/docs/src/content/docs/manual-installation.mdx index f1e8860..571f889 100644 --- a/docs/src/content/docs/manual-installation.mdx +++ b/docs/src/content/docs/manual-installation.mdx @@ -43,10 +43,10 @@ Then, add the following `lunaria` commands as part of your `package.json`'s `scr ```json title="package.json" ins={5} "scripts": { - "dev": "astro dev", - "build": "astro build", - "preview": "astro preview", - "lunaria:build": "lunaria build", + "dev": "astro dev", + "build": "astro build", + "preview": "astro preview", + "lunaria:build": "lunaria build", "lunaria:preview": "lunaria preview", } ```