diff --git a/README.md b/README.md index 1b35f84..75da886 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,24 @@ content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euism +Leave the title field blank to only display the admonition. +````markdown +```note +title: +content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. +``` +```` + + + **Please note that when the title is included, you _must_ specificy the content as well.** +### Collapsible + +Use `collapse: open` or `collapse: closed` to create a collapsible admonition. + + + ## Admonition Types The following admonition types are currently supported: @@ -54,7 +70,11 @@ See [this](https://squidfunk.github.io/mkdocs-material/reference/admonitions/) f ## Customization -The admonitions are each styled with with the following classes, which can be override to custom their appearance: +This is all of the CSS applied to the admonitions. Override these classes to customize the look. + +### Base Classes + +Every admonition receives the following CSS classes: ```css .admonition { @@ -66,7 +86,7 @@ The admonitions are each styled with with the following classes, which can be ov background-color: var(--background-secondary); border-left: 0.2rem solid; border-radius: 0.1rem; - box-shadow: var(--background-modifier-box-shadow); + box-shadow: 0 0.2rem 0.5rem var(--background-modifier-box-shadow); } .admonition-title::before { position: absolute; @@ -92,7 +112,9 @@ The admonitions are each styled with with the following classes, which can be ov } ``` -Additionally, each admonition type will receive the ```.admonition-``` class: +### Type Specific + +Additionally, each admonition type will receive the `.admonition-` class: ```css /* Example of .admonition-note */ @@ -109,30 +131,89 @@ Additionally, each admonition type will receive the ```.admonition-``` cla } ``` -The admonition icons are svgs defined as variables on the ```:root``` with the name ```--admonition-icon--```. Override this variable to customize the icon. Example: +#### Type Icons + +The admonition icons are svgs defined as variables on the `:root` with the name `--admonition-icon--`. Override this variable to customize the icon. Example: + ```css --admonition-icon--quote: url("data:image/svg+xml;charset=utf-8,"); ``` +### Collapsible + +If an icon is collapsible, it will receive the following CSS: + +```css +details.admonition:not([open]) { + padding-bottom: 0; + box-shadow: none; +} +details.admonition > summary { + outline: none; + list-style: none; + display: block; + min-height: 1rem; + padding: 0.4rem 1.8rem 0.4rem 2rem; + border-top-left-radius: 0.1rem; + border-top-right-radius: 0.1rem; + cursor: pointer; +} +details.admonition > summary::-webkit-details-marker { + display: none; +} + +details.admonition > summary:after { + position: absolute; + top: 8px; + right: 8px; + width: 20px; + height: 20px; + background-color: currentColor; + -webkit-mask-image: var(--admonition-details-icon); + mask-image: var(--admonition-details-icon); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-size: contain; + mask-size: contain; + transform: rotate(0deg); + transition: transform 0.25s; + content: ""; +} +details.admonition[open] > summary:after { + transform: rotate(90deg); +} +``` + +### No Title + +An icon without a title will have this CSS: + +```css +.admonition-title.no-title { + display: none; +} +``` + ## Todo -- Add the ability to collapse the admonition -- Custom admonitions -- Settings tab to customize icon and color of included admonitions -- Longterm - ability to render markdown inside an admonition + +- Add the ability to collapse the admonition +- Custom admonitions +- Settings tab to customize icon and color of included admonitions +- Longterm - ability to render markdown inside an admonition ## Installation ### From GitHub -- Download the Latest Release from the Releases section of the GitHub Repository -- Copy the `main.js`, `styles.css` and `manifest.json` files from the release to your vault's plugins folder: `/.obsidian/plugins/` -Note: On some machines the `.obsidian` folder may be hidden. On MacOS you should be able to press `Command+Shift+Dot` to show the folder in Finder. -- Reload Obsidian -- If prompted about Safe Mode, you can disable safe mode and enable the plugin. -Otherwise head to Settings, third-party plugins, make sure safe mode is off and -enable the plugin from there. +- Download the Latest Release from the Releases section of the GitHub Repository +- Copy the `main.js`, `styles.css` and `manifest.json` files from the release to your vault's plugins folder: `/.obsidian/plugins/` + Note: On some machines the `.obsidian` folder may be hidden. On MacOS you should be able to press `Command+Shift+Dot` to show the folder in Finder. +- Reload Obsidian +- If prompted about Safe Mode, you can disable safe mode and enable the plugin. + Otherwise head to Settings, third-party plugins, make sure safe mode is off and + enable the plugin from there. ## Warning This plugin comes with no guarantee of stability and bugs may delete data. -Please ensure you have automated backups. \ No newline at end of file +Please ensure you have automated backups. diff --git a/manifest.json b/manifest.json index d0b5c33..7d5b38f 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-admonition", "name": "Admonition", - "version": "0.0.4", + "version": "0.0.5", "minAppVersion": "0.11.0", "description": "Admonition block-styled content for Obsidian.md", "author": "Jeremy Valentine", diff --git a/package.json b/package.json index a1694fe..2eda7ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-admonition", - "version": "0.0.4", + "version": "0.0.5", "description": "Admonition block-styled content for Obsidian.md", "main": "main.js", "scripts": { diff --git a/src/admonitions.ts b/src/admonitions.ts index d3e571c..25b37a6 100644 --- a/src/admonitions.ts +++ b/src/admonitions.ts @@ -1,5 +1,5 @@ interface Admonition { - [key: string]: string; + [admonitionType: string]: string; } const admonitions = [ "note", diff --git a/src/main.css b/src/main.css index 6c941c5..eac4886 100644 --- a/src/main.css +++ b/src/main.css @@ -11,6 +11,7 @@ --admonition-icon--bug: url("data:image/svg+xml;charset=utf-8,"); --admonition-icon--example: url("data:image/svg+xml;charset=utf-8,"); --admonition-icon--quote: url("data:image/svg+xml;charset=utf-8,"); + --admonition-details-icon: url("data:image/svg+xml;charset=utf-8,"); } /** Constants */ @@ -24,7 +25,7 @@ background-color: var(--background-secondary); border-left: 0.2rem solid; border-radius: 0.1rem; - box-shadow: var(--background-modifier-box-shadow); + box-shadow: 0 0.2rem 0.5rem var(--background-modifier-box-shadow); } .admonition-title::before { position: absolute; @@ -44,10 +45,57 @@ font-weight: 700; border-left: 0.2rem solid; } +.admonition-title.no-title { + display: none; +} + .admonition-content { margin-bottom: 0.6rem; } +.admonition > .admonition-title.no-title + .admonition-content { + margin: 1em 0; +} + +details.admonition:not([open]) { + padding-bottom: 0; + box-shadow: none; +} +details.admonition > summary { + outline: none; + list-style: none; + display: block; + min-height: 1rem; + padding: 0.4rem 1.8rem 0.4rem 2rem; + border-top-left-radius: 0.1rem; + border-top-right-radius: 0.1rem; + cursor: pointer; +} +details.admonition > summary::-webkit-details-marker { + display: none; +} + +details.admonition > summary:after { + position: absolute; + top: 8px; + right: 8px; + width: 20px; + height: 20px; + background-color: currentColor; + -webkit-mask-image: var(--admonition-details-icon); + mask-image: var(--admonition-details-icon); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-size: contain; + mask-size: contain; + transform: rotate(0deg); + transition: transform 0.25s; + content: ""; +} +details.admonition[open] > summary:after { + transform: rotate(90deg); +} + /** Type Specific */ .admonition-note { @@ -111,13 +159,13 @@ } .admonition-question { - border-color: #00b8d4; + border-color: #64dd17; } .admonition-question > .admonition-title { background-color: rgba(100, 221, 23, 0.1); } .admonition-question > .admonition-title::before { - background-color: #00b8d4; + background-color: #64dd17; -webkit-mask-image: var(--admonition-icon--question); mask-image: var(--admonition-icon--question); } diff --git a/src/main.ts b/src/main.ts index 9d80fa1..8602aba 100644 --- a/src/main.ts +++ b/src/main.ts @@ -43,13 +43,49 @@ export default class Admonition extends Plugin { let type = ADMONITION_MAP[classType.split("language-").pop().trim()]; if (!type) return; - const { + let params = Object.fromEntries( + block.innerText + .split("\n") + .map((l) => l.split(":").map((s) => s.trim())) + ); + let { title = type[0].toUpperCase() + type.slice(1).toLowerCase(), - content = block.innerText - } = Object.fromEntries( - block.innerText.split("\n").map((l) => l.split(": ")) + content = block.innerText, + collapse + } = params; + console.log( + "🚀 ~ file: main.ts ~ line 56 ~ Admonition ~ codeBlocks.forEach ~ params", + params, + block.innerText + .split("\n") + .map((l) => l.split(":").map((s) => s.trim())) + ); + + if ( + Object.prototype.hasOwnProperty.call(params, "title") && + params.title === undefined && + params.collapse + ) { + title = ""; + } + if ( + Object.prototype.hasOwnProperty.call(params, "collapse") && + (params.collapse.length == 0 || + params.collapse === undefined) + ) { + collapse = "closed"; + } + console.log( + "🚀 ~ file: main.ts ~ line 69 ~ Admonition ~ codeBlocks.forEach ~ params.collapse", + collapse + ); + this.buildAdmonition( + block.parentElement, + type, + title, + content, + collapse ); - this.buildAdmonition(block.parentElement, type, title, content); } }); } @@ -57,13 +93,30 @@ export default class Admonition extends Plugin { el: HTMLElement, type: string, title: string, - content: string + content: string, + collapse?: string ) { - let admonition = createDiv({ - cls: `admonition admonition-${type}` + let attrs, + els = [ + "div" as keyof HTMLElementTagNameMap, + "div" as keyof HTMLElementTagNameMap + ]; + if (collapse && ["open", "closed"].includes(collapse)) { + els = [ + "details" as keyof HTMLElementTagNameMap, + "summary" as keyof HTMLElementTagNameMap + ]; + attrs = { + [collapse]: true + }; + } + + let admonition = createEl(els[0], { + cls: `admonition admonition-${type}`, + attr: attrs }); - admonition.createDiv({ - cls: "admonition-title", + admonition.createEl(els[1], { + cls: `admonition-title ${!title.trim().length ? "no-title" : ""}`, text: title }); admonition.createEl("p", { diff --git a/versions.json b/versions.json index c29f198..fdb2e69 100644 --- a/versions.json +++ b/versions.json @@ -1,3 +1,3 @@ { - "0.0.4": "0.11.0" + "0.0.5": "0.11.0" }