mirror of
https://github.com/zadam/trilium.git
synced 2025-12-22 15:24:24 +01:00
docs(user): improve documentation on custom widgets & Preact
This commit is contained in:
parent
531698cafb
commit
7567903da3
2
apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json
generated
vendored
2
apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json
generated
vendored
File diff suppressed because one or more lines are too long
@ -9,8 +9,8 @@
|
||||
feel free to report them either via a ticket or via the Matrix.</p>
|
||||
<h2>Downloading the nightly release manually</h2>
|
||||
<p>Go to <a href="https://github.com/TriliumNext/Trilium/releases/tag/nightly">github.com/TriliumNext/Trilium/releases/tag/nightly</a> and
|
||||
look for the artifacts starting with <code spellcheck="false">TriliumNotes-main</code>.
|
||||
Choose the appropriate one for your platform (e.g. <code spellcheck="false">windows-x64.zip</code>).</p>
|
||||
look for the artifacts starting with <code>TriliumNotes-main</code>. Choose
|
||||
the appropriate one for your platform (e.g. <code>windows-x64.zip</code>).</p>
|
||||
<p>Depending on your use case, you can either test the portable version or
|
||||
even use the installer.</p>
|
||||
<aside class="admonition note">
|
||||
|
||||
@ -15,7 +15,8 @@ class="image">
|
||||
<img style="aspect-ratio:1150/27;" src="4_New Layout_image.png"
|
||||
width="1150" height="27">
|
||||
</figure>
|
||||
<h3>Inline title</h3>
|
||||
|
||||
<h3>Inline title</h3>
|
||||
<p>In previous versions of Trilium, the title bar was fixed at all times.
|
||||
In the new layout, there is both a fixed title bar and one that scrolls
|
||||
with the text. The newly introduced title is called the <em>Inline title</em> and
|
||||
@ -41,18 +42,18 @@ class="image">
|
||||
width="910" height="104">
|
||||
<figcaption>The fixed title bar. The title only appears after scrolling past the <em>Inline title</em>.</figcaption>
|
||||
</figure>
|
||||
<h3>New note type switcher</h3>
|
||||
|
||||
<h3>New note type switcher</h3>
|
||||
<p>When a new <a class="reference-link" href="#root/_help_iPIMuisry3hd">Text</a> or
|
||||
<a
|
||||
class="reference-link" href="#root/_help_6f9hih2hXXZk">Code</a> note is created, a note type switcher will appear below
|
||||
the <em>Inline title</em>. Apart from changing the note type, it's also
|
||||
possible to apply a <a href="#root/_help_KC1HB96bqqHX">template</a>.</p>
|
||||
<p>The switcher will disappear as soon as a text is entered.</p>
|
||||
<p>
|
||||
<img src="5_New Layout_image.png" width="735"
|
||||
height="143">
|
||||
</p>
|
||||
<h3>Note badges</h3>
|
||||
<img src="5_New Layout_image.png"
|
||||
width="735" height="143">
|
||||
|
||||
<h3>Note badges</h3>
|
||||
<p>Note badges appear near the fixed note title and indicate important information
|
||||
about the note such as whether it is read-only. Some of the badges are
|
||||
also interactive.</p>
|
||||
@ -62,21 +63,20 @@ class="image">
|
||||
</figure>
|
||||
<p>The following badges are available:</p>
|
||||
<ul>
|
||||
<li data-list-item-id="e92dd6f75d874ac793f37db886606439d"><strong>Read-only badge</strong>, which will be shown if the note is not
|
||||
<li><strong>Read-only badge</strong>, which will be shown if the note is not
|
||||
editable due to either automatic read-only or manual read-only. Clicking
|
||||
on the badge will temporarily edit the note (similar to the Edit <a href="#root/_help_XpOYSgsLkTJy">floating button</a>).</li>
|
||||
<li
|
||||
data-list-item-id="e7bbe2a9a3ddc469e9fe1c31ec7cf1a2f"><strong>Share badge</strong>, which will indicate that the current note
|
||||
<li><strong>Share badge</strong>, which will indicate that the current note
|
||||
is shared. The badge will also indicate if the share is on the local network
|
||||
(for the desktop application without <a class="reference-link" href="#root/_help_cbkrhQjrkKrh">Synchronization</a> set
|
||||
up) or publicly accessible (for the server).</li>
|
||||
<li data-list-item-id="e2f51260db16ace77feb9eddcf987cc52"><strong>Web clip badge</strong>, which will indicate if the note was clipped
|
||||
using the <a class="reference-link" href="#root/_help_MtPxeAWVAzMg">Web Clipper</a>.
|
||||
The badge acts as a link, so it can be clicked on to navigate to the page
|
||||
or right clicked for more options.</li>
|
||||
<li data-list-item-id="ef6bec8ce5a4f3fd249bf57a16e1e235e"><strong>Execute badge</strong>, for <a href="#root/_help_CdNpE2pqjmI6">scripts</a> or
|
||||
<a
|
||||
href="#root/_help_YKWqdJhzi2VY">saved SQL queries</a>which have an execute button or a description.</li>
|
||||
<li><strong>Web clip badge</strong>, which will indicate if the note was clipped
|
||||
using the <a class="reference-link" href="#root/_help_MtPxeAWVAzMg">Web Clipper</a>.
|
||||
The badge acts as a link, so it can be clicked on to navigate to the page
|
||||
or right clicked for more options.</li>
|
||||
<li><strong>Execute badge</strong>, for <a href="#root/_help_CdNpE2pqjmI6">scripts</a> or
|
||||
<a
|
||||
href="#root/_help_YKWqdJhzi2VY">saved SQL queries</a>which have an execute button or a description.</li>
|
||||
</ul>
|
||||
<p>Some of these badges replace the dedicated panels at the top of the note.</p>
|
||||
<h3>Collapsible sections</h3>
|
||||
@ -86,26 +86,25 @@ class="image">
|
||||
</figure>
|
||||
<p>The following sections have been made collapsible:</p>
|
||||
<ul>
|
||||
<li class="ck-list-marker-italic" data-list-item-id="e8add36768a67f7f5af68545beb18037f"><em>Promoted Attributes</em>
|
||||
<li><em>Promoted Attributes</em>
|
||||
<ul>
|
||||
<li data-list-item-id="e633becb9bcfb1796d6d8203ffd2ac660">For full-height notes such as <a class="reference-link" href="#root/_help_grjYqerjn243">Canvas</a>,
|
||||
<li>For full-height notes such as <a class="reference-link" href="#root/_help_grjYqerjn243">Canvas</a>,
|
||||
the promoted attributes are collapsed by default to make room.</li>
|
||||
<li
|
||||
data-list-item-id="ee7cbce0e436fd7a00a176df51f5570a4">The keyboard shortcut previously used to trigger the promoted attributes
|
||||
<li>The keyboard shortcut previously used to trigger the promoted attributes
|
||||
ribbon tab (which was no longer working) has been repurposed to toggle
|
||||
the promoted attributes instead.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="ece11f5c363adc3938abfd8d21b2f655d"><em>Edited Notes</em>, which appears for <a class="reference-link"
|
||||
<li><em>Edited Notes</em>, which appears for <a class="reference-link"
|
||||
href="#root/_help_l0tKav7yLHGF">Day Notes</a> is now shown underneath the
|
||||
title.
|
||||
<ul>
|
||||
<li data-list-item-id="ef3f8aac2e5f49b4188acd62868b32020">Whether the section is collapsed or not depends on the choice in
|
||||
<li>Whether the section is collapsed or not depends on the choice in
|
||||
<a
|
||||
class="reference-link" href="#root/_help_4TIF1oA4VQRO">Options</a> → Appearance.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e42393439936bb76c397de5ae6e5ecd80"><em>Search Properties</em>, which appears for the full <a class="reference-link"
|
||||
<li><em>Search Properties</em>, which appears for the full <a class="reference-link"
|
||||
href="#root/_help_eIg8jdvaoNNd">Search</a> and <a class="reference-link"
|
||||
href="#root/_help_m523cpzocqaD">Saved Search</a>.</li>
|
||||
</ul>
|
||||
@ -116,78 +115,75 @@ class="image">
|
||||
<p>Here's how all the different tabs that were once part of the ribbon are
|
||||
now available in the new layout:</p>
|
||||
<ul>
|
||||
<li data-list-item-id="e758293ceb33f07215fcf5fc4700a4e5f">“Formatting toolbar” was relocated to the top of the page.
|
||||
<li>“Formatting toolbar” was relocated to the top of the page.
|
||||
<ul>
|
||||
<li data-list-item-id="e8dded8673adf680dde8615934b3f857b">Instead of having one per split, now there is a single formatting toolbar
|
||||
<li>Instead of having one per split, now there is a single formatting toolbar
|
||||
per tab. This allows more space for the toolbar items.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e2c510fd7f19155ed0e05946acf7a4cd0">“Owned attributes” and “Inherited attributes” were merged and moved to
|
||||
<li>“Owned attributes” and “Inherited attributes” were merged and moved to
|
||||
the status bar region (displayed one above the other).</li>
|
||||
<li data-list-item-id="ec032e05420954455db0884651e2d1c4e">“Basic Properties” were integrated in the <a class="reference-link"
|
||||
<li>“Basic Properties” were integrated in the <a class="reference-link"
|
||||
href="#root/_help_8YBEPzcpUgxw">Note buttons</a> menu.
|
||||
<ul>
|
||||
<li data-list-item-id="ebcff28c9a8d07526187559ebd5faa211">The only exception here is the Language combo box which can now be found
|
||||
<li>The only exception here is the Language combo box which can now be found
|
||||
in the status bar (top-right of the screen).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e0b76ace8a0be9d7bb6870398b87338ab">“File” and “Image” tabs
|
||||
<li>“File” and “Image” tabs
|
||||
<ul>
|
||||
<li data-list-item-id="e55913c9bba25585fbdcb2098a2977e0e">The buttons were moved to the right of the note title, as dedicated entries
|
||||
<li>The buttons were moved to the right of the note title, as dedicated entries
|
||||
in <a class="reference-link" href="#root/_help_8YBEPzcpUgxw">Note buttons</a>.</li>
|
||||
<li
|
||||
data-list-item-id="e749af557c7ec8307b65cebfc0b375508">The info section has been merged into the <em>Note info</em> section of
|
||||
<li>The info section has been merged into the <em>Note info</em> section of
|
||||
the status bar.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="ee3556b093a5a07fd6d239c33d8cf2611">Edited notes
|
||||
<li>Edited notes
|
||||
<ul>
|
||||
<li data-list-item-id="e541470be93aa45c6495efb6cd8063e47">Moved underneath the title, displayed under a collapsible area and the
|
||||
<li>Moved underneath the title, displayed under a collapsible area and the
|
||||
notes are represented as badges/chips.</li>
|
||||
<li data-list-item-id="e16f53a81cda714958d00ca53dbb1ffa9">Whether the section is expanded or collapsed depends on the “Edited Notes
|
||||
<li>Whether the section is expanded or collapsed depends on the “Edited Notes
|
||||
ribbon tab will automatically open on day notes” setting from Options →
|
||||
Appearance.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e0fc642280dfcbc6ca7cdc995c57941f8">Search definition tab
|
||||
<li>Search definition tab
|
||||
<ul>
|
||||
<li data-list-item-id="e616bd30c16829e863accfcab35c41874">Moved underneath the title under a collapsible area.</li>
|
||||
<li data-list-item-id="e1c2b80776b0ffe26ae69410131c1e0f2">Expanded by default for new searches, collapsed for saved searches.</li>
|
||||
<li>Moved underneath the title under a collapsible area.</li>
|
||||
<li>Expanded by default for new searches, collapsed for saved searches.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="ec4b6bd664511175e82281caf113b13b8">The Note map is now available in the Note actions menu.
|
||||
<li>The Note map is now available in the Note actions menu.
|
||||
<ul>
|
||||
<li data-list-item-id="ecd6bd6144cea4bc2148e6baaa940f9b0">Instead of opening into a panel in the ribbon, the note map now opens
|
||||
<li>Instead of opening into a panel in the ribbon, the note map now opens
|
||||
in a side split (similar to the in-app help).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="ea0cd465194ced54082c799b53a1839c0">“Note info” tab was moved to a small (i) icon in the status bar.</li>
|
||||
<li
|
||||
data-list-item-id="eeb0fd706272546ff31b629917b8fcb0a">“Similar notes” tab
|
||||
<li>“Note info” tab was moved to a small (i) icon in the status bar.</li>
|
||||
<li>“Similar notes” tab
|
||||
<ul>
|
||||
<li data-list-item-id="eb01edf7d21f73998b99516cd46e0e321">Moved to the status bar, by going to the “Note info” section and pressing
|
||||
<li>Moved to the status bar, by going to the “Note info” section and pressing
|
||||
the button to show similar notes.</li>
|
||||
<li data-list-item-id="e3aa6b54672681d8d90795c57372f2595">Displayed as a fixed panel, similar to the attributes.</li>
|
||||
<li>Displayed as a fixed panel, similar to the attributes.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e791313bf732b70bbf4d6f91755db2494">The Collection properties tab were relocated under the note title and
|
||||
grouped into:
|
||||
<ul>
|
||||
<li data-list-item-id="e712f0f389eab1a329a4df3ed6d2b49aa">A combo box to quickly switch between views.</li>
|
||||
<li data-list-item-id="edaba6f82803ed727489575b9c46d667c">Individual settings for the current view in a submenu.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e26e827650e594f717a90c0cd94c1c3a1">Some smaller ribbon tabs were converted to badges that appear near the
|
||||
note title in the breadcrumb section:
|
||||
<ul>
|
||||
<li data-list-item-id="eaf6b3ff2c30e7167a29cb58c160c55f8">Original URL indicator for clipped web pages (<code spellcheck="false">#pageUrl</code>).</li>
|
||||
<li
|
||||
data-list-item-id="ee7fc72c13a93f9e5d0edc0bba6bc0b34">SQL and script execute buttons.</li>
|
||||
</li>
|
||||
<li>The Collection properties tab were relocated under the note title and
|
||||
grouped into:
|
||||
<ul>
|
||||
<li>A combo box to quickly switch between views.</li>
|
||||
<li>Individual settings for the current view in a submenu.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</li>
|
||||
<li>Some smaller ribbon tabs were converted to badges that appear near the
|
||||
note title in the breadcrumb section:
|
||||
<ul>
|
||||
<li>Original URL indicator for clipped web pages (<code>#pageUrl</code>).</li>
|
||||
<li>SQL and script execute buttons.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<aside class="admonition note">
|
||||
<p>The ribbon keyboard shortcuts (e.g. <code spellcheck="false">toggleRibbonTabClassicEditor</code>)
|
||||
<p>The ribbon keyboard shortcuts (e.g. <code>toggleRibbonTabClassicEditor</code>)
|
||||
have been repurposed to work on the new layout, where they will toggle
|
||||
the appropriate panel.</p>
|
||||
</aside>
|
||||
@ -196,13 +192,11 @@ class="image">
|
||||
the <a class="reference-link" href="#root/_help_8YBEPzcpUgxw">Note buttons</a> area,
|
||||
with the exception of:</p>
|
||||
<ul>
|
||||
<li data-list-item-id="e68c4ff8e52782bbef0104bca4b3f972a">The Edit button is displayed near the note title, as a badge.</li>
|
||||
<li
|
||||
data-list-item-id="e45b03477a6cb8c98327562abd551967c"><em>Backlinks</em> is displayed in the status bar. When clicked, the same
|
||||
<li>The Edit button is displayed near the note title, as a badge.</li>
|
||||
<li><em>Backlinks</em> is displayed in the status bar. When clicked, the same
|
||||
list of backlinks is displayed.</li>
|
||||
<li data-list-item-id="e7241aa3a6ec8dd92a3debade61439d81">Relation map zoom buttons are now part of the relation map itself.</li>
|
||||
<li
|
||||
data-list-item-id="e2d44d21ae8b0d77bef0327f2aaf4e050">Export image to PNG/SVG are now in the Note actions menu, in the <em>Export as image</em> option.</li>
|
||||
<li>Relation map zoom buttons are now part of the relation map itself.</li>
|
||||
<li>Export image to PNG/SVG are now in the Note actions menu, in the <em>Export as image</em> option.</li>
|
||||
</ul>
|
||||
<h3>Changes to the sidebar</h3>
|
||||
<p>The sidebar (also known as the right pane) also received some important
|
||||
@ -210,7 +204,7 @@ class="image">
|
||||
<p>The previous iteration of the sidebar would appear contextually, depending
|
||||
on whether there are any items to be displayed. This caused occasional
|
||||
content shifts when moving between two panes in a split view. In the new
|
||||
layout, the sidebar acts more like the <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_oPVyFC7WL2Lp">Note Tree</a> pane,
|
||||
layout, the sidebar acts more like the <a class="reference-link" href="#root/_help_oPVyFC7WL2Lp">Note Tree</a> pane,
|
||||
remaining visible even if there is nothing to display.</p>
|
||||
<p>In order to toggle the sidebar, there is a new button on the top-right
|
||||
side of the screen, near the window buttons (on Windows and Linux).</p>
|
||||
|
||||
@ -8,48 +8,48 @@
|
||||
displayed in the bottom-left of the screen.</p>
|
||||
<h2>Layout and Interaction</h2>
|
||||
<ul>
|
||||
<li data-list-item-id="e235d35dec66a5a6e191ec5cd8af5038a">If a note or workspace is hoisted, a badge will appear on the left-most
|
||||
<li>If a note or workspace is hoisted, a badge will appear on the left-most
|
||||
side.
|
||||
<ul>
|
||||
<li data-list-item-id="e456ddbf22db13b73ffd4915431ef4edb">Clicking on the badge will un-hoist the note/workspace.</li>
|
||||
<li>Clicking on the badge will un-hoist the note/workspace.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e1f0000e6ce3c61b41a8d9ee6ec991686">The left-most icon represents the root note, or the hoisted note or workspace.
|
||||
<li>The left-most icon represents the root note, or the hoisted note or workspace.
|
||||
<ul>
|
||||
<li data-list-item-id="e224bf09301a82f6a58038c55bb4769e4">Clicking the icon will jump to the root note.</li>
|
||||
<li data-list-item-id="e5e1de710e5d166aa47ba54ddd46657cb">Right clicking the icon will display a menu that allows opening the note
|
||||
<li>Clicking the icon will jump to the root note.</li>
|
||||
<li>Right clicking the icon will display a menu that allows opening the note
|
||||
in a new tab, split, etc.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e62deaf618aa52bb7062b1801cdaf5bf5">Each segment shows the title of a note in the current note hierarchy.
|
||||
<li>Each segment shows the title of a note in the current note hierarchy.
|
||||
<ul>
|
||||
<li data-list-item-id="e03cfdc5ebec9d3dce4503960e24fc693">Clicking the icon will jump to that note.</li>
|
||||
<li data-list-item-id="e2b084f07f11586bbcfb0ec85d1fe52c2">Right clicking will open a menu with multiple options such as opening
|
||||
<li>Clicking the icon will jump to that note.</li>
|
||||
<li>Right clicking will open a menu with multiple options such as opening
|
||||
the note in a different tab/split/window, hoisting, moving/cloning the
|
||||
note, duplicating as well as changing the color of the note.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="ed8b04db71853f4c0453d321de96acfdf">Clicking the arrow next to each segment will reveal the child notes of
|
||||
<li>Clicking the arrow next to each segment will reveal the child notes of
|
||||
the segment on the left.
|
||||
<ul>
|
||||
<li data-list-item-id="e0c88db9aafa125a06b81d9e4ab40bf8e">Clicking on an icon will navigate to that particular note.</li>
|
||||
<li data-list-item-id="e04d705da35d36f06aa734b35e60e454a">It's also possible to create a new child note from here.</li>
|
||||
<li data-list-item-id="e07c9f1f7bd7ea872181c7c005513ed68">The menu can optionally hide the archived notes.</li>
|
||||
<li>Clicking on an icon will navigate to that particular note.</li>
|
||||
<li>It's also possible to create a new child note from here.</li>
|
||||
<li>The menu can optionally hide the archived notes.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="ee49ef8ad47fbb227dc69ca8f976872aa">If the current note is deep within a hierarchy, the segments will collapse
|
||||
<li>If the current note is deep within a hierarchy, the segments will collapse
|
||||
into a […] button in order not to occupy too much space.
|
||||
<ul>
|
||||
<li data-list-item-id="e1869d9d1b5a2f0c5def31172891a9b14">Clicking this button will display each collapsed entry as a menu item.
|
||||
<li>Clicking this button will display each collapsed entry as a menu item.
|
||||
Clicking on it will navigate to that particular note.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e8d793fcdf6ddc0a15f422d5ec12b05c4">Right clicking on an empty space to the right of the breadcrumb (before
|
||||
<li>Right clicking on an empty space to the right of the breadcrumb (before
|
||||
the other status bar items) will reveal another menu that allows:
|
||||
<ul>
|
||||
<li data-list-item-id="e4d96585f45337c4bac4182db334343eb">Toggling whether archived notes are displayed in the breadcrumb and in
|
||||
<li>Toggling whether archived notes are displayed in the breadcrumb and in
|
||||
the note tree.</li>
|
||||
<li data-list-item-id="e37105f037c1fe10fe48e428db4c7c0e7">Copying the current note path to clipboard.</li>
|
||||
<li>Copying the current note path to clipboard.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@ -7,47 +7,45 @@
|
||||
<p>On the right side, specific sections will show depending on the type of
|
||||
the current note.</p>
|
||||
<ol>
|
||||
<li data-list-item-id="e7409c70ee461800fea112abc0cf9ae25">For code notes, the language mode of the note is indicated (e.g. JavaScript,
|
||||
<li>For code notes, the language mode of the note is indicated (e.g. JavaScript,
|
||||
plain text), as well as allowing easy switching to another mode.</li>
|
||||
<li
|
||||
data-list-item-id="e02ade3f598cdd3dfda1abbcf9d55060b">For text notes, the content language is displayed and can be changed,
|
||||
<li>For text notes, the content language is displayed and can be changed,
|
||||
thus configuring the spell-check and the right-to-left support.
|
||||
<ol>
|
||||
<li data-list-item-id="e0e530605f6c359593162f582fc9113a1">Note that this applies to the entire note and not the selection, unlike
|
||||
<li>Note that this applies to the entire note and not the selection, unlike
|
||||
some text editors.</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li data-list-item-id="eb55ddf60b5526101fb30234178ccd4b1">If a note is placed in multiple places in the tree (cloned), the number
|
||||
of the note paths will be displayed.
|
||||
<ol>
|
||||
<li data-list-item-id="e9fa65cb2d50422d4d715a29108268c57">Clicking it will reveal the full list of note paths and a button to place
|
||||
it somewhere else.</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li data-list-item-id="e353272924ea7c0a8817b75978e74e2f4">If a note has attachments, their number will be displayed.
|
||||
<ol>
|
||||
<li data-list-item-id="e36057cb3080443d03fc54f373c4811f7">Clicking on it will reveal the list of attachments in a new tab.</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li data-list-item-id="ebed069f4938bd155c5e436fe92e44cea">If a note is linked from other text notes (backlinks), the number of backlinks
|
||||
will be displayed.
|
||||
<ol>
|
||||
<li data-list-item-id="e1a3f17eeda7672abaf283f7283dd462c">Clicking on it will show the list of notes that link to this note, as
|
||||
well as an excerpt of where the note is referenced.</li>
|
||||
</ol>
|
||||
</li>
|
||||
</li>
|
||||
<li>If a note is placed in multiple places in the tree (cloned), the number
|
||||
of the note paths will be displayed.
|
||||
<ol>
|
||||
<li>Clicking it will reveal the full list of note paths and a button to place
|
||||
it somewhere else.</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>If a note has attachments, their number will be displayed.
|
||||
<ol>
|
||||
<li>Clicking on it will reveal the list of attachments in a new tab.</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>If a note is linked from other text notes (backlinks), the number of backlinks
|
||||
will be displayed.
|
||||
<ol>
|
||||
<li>Clicking on it will show the list of notes that link to this note, as
|
||||
well as an excerpt of where the note is referenced.</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
<p>Regardless of note type, the following items will always be displayed
|
||||
if there is a note:</p>
|
||||
<ol>
|
||||
<li data-list-item-id="ecbd6632bd798107863b39fc23e251ae2">Note info, which displays:
|
||||
<li>Note info, which displays:
|
||||
<ol>
|
||||
<li data-list-item-id="e56c0d5f618b79a64326bc2ab739c2df4">The creation/modification date of the note.</li>
|
||||
<li data-list-item-id="e7843741f9e99763fcf5ded821f09d789">The type and MIME of the note.</li>
|
||||
<li data-list-item-id="eaf479da2bbf044be78676f7a68ded903">The note ID.</li>
|
||||
<li data-list-item-id="ebbeb7fde731354c1b92951e4d45be579">An estimation of the note size of the note itself and its children.</li>
|
||||
<li
|
||||
data-list-item-id="e0e10095682b51783b11592065b7e28a7">A button to show Similar notes.</li>
|
||||
</ol>
|
||||
<li>The creation/modification date of the note.</li>
|
||||
<li>The type and MIME of the note.</li>
|
||||
<li>The note ID.</li>
|
||||
<li>An estimation of the note size of the note itself and its children.</li>
|
||||
<li>A button to show Similar notes.</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
45
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Render Note.html
generated
vendored
45
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Render Note.html
generated
vendored
@ -7,13 +7,16 @@
|
||||
via an attribute.</p>
|
||||
<h2>Creating a render note</h2>
|
||||
<ol>
|
||||
<li>Create a <a class="reference-link" href="#root/_help_6f9hih2hXXZk">Code</a> note
|
||||
with the HTML language, with what needs to be displayed (for example <code><p>Hello world.</p></code>).</li>
|
||||
<li>Create a <a class="reference-link" href="#root/_help_HcABDtFCkbFN">Render Note</a>.</li>
|
||||
<li>Assign the <code>renderNote</code> <a href="#root/_help_zEY4DaJG4YT5">relation</a> to
|
||||
<li data-list-item-id="e6c172eb567596820dd7f444924e568b3">Create a <a class="reference-link" href="#root/_help_6f9hih2hXXZk">Code</a> note
|
||||
with the HTML language, with what needs to be displayed (for example
|
||||
<code
|
||||
spellcheck="false"><p>Hello world.</p></code>).</li>
|
||||
<li data-list-item-id="e06560e53dd0ab195c0e89dc8db7aec1f">Create a <a class="reference-link" href="#root/_help_HcABDtFCkbFN">Render Note</a>.</li>
|
||||
<li
|
||||
data-list-item-id="e9db87d13293c732ac62d6f92d2997cb3">Assign the <code spellcheck="false">renderNote</code> <a href="#root/_help_zEY4DaJG4YT5">relation</a> to
|
||||
point at the previously created code note.</li>
|
||||
</ol>
|
||||
<h2>Dynamic content</h2>
|
||||
<h2>Legacy scripting using jQuery</h2>
|
||||
<p>A static HTML is generally not enough for <a class="reference-link"
|
||||
href="#root/_help_CdNpE2pqjmI6">Scripting</a>. The next step is to automatically
|
||||
change parts of the note using JavaScript.</p>
|
||||
@ -26,22 +29,46 @@ The current date & time is <span class="date"></span></code></pr
|
||||
language. Make sure the newly created note is a direct child of the HTML
|
||||
note created previously; with the following content:</p><pre><code class="language-text-x-trilium-auto">const $dateEl = api.$container.find(".date");
|
||||
$dateEl.text(new Date());</code></pre>
|
||||
<p>Now create a render note at any place and set its <code>~renderNote</code> relation
|
||||
<p>Now create a render note at any place and set its <code spellcheck="false">~renderNote</code> relation
|
||||
to point to the HTML note. When the render note is accessed it will display:</p>
|
||||
<blockquote>
|
||||
<p><strong>Current date & time</strong>
|
||||
<br>The current date & time is Sun Apr 06 2025 15:26:29 GMT+0300 (Eastern
|
||||
European Summer Time)</p>
|
||||
</blockquote>
|
||||
<h2>Dynamic content using Preact & JSX</h2>
|
||||
<p>As a more modern alternative to jQuery, it's possible to use Preact &
|
||||
JSX to render pages. Since JSX is a superset of JavaScript, there's no
|
||||
need to provide a HTML anymore.</p>
|
||||
<p>Here are the steps to creating a simple render note:</p>
|
||||
<ol>
|
||||
<li data-list-item-id="ee6c6868efde1b910dac6807580e2a8e2">Create a note of type <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a>.</li>
|
||||
<li
|
||||
data-list-item-id="eae9b5f496cba824738734828c11448d5">
|
||||
<p>Create a child <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_6f9hih2hXXZk">Code</a> note
|
||||
with JSX as the language.
|
||||
<br>As an example, use the following content:</p><pre><code class="language-text-jsx">export default function() {
|
||||
return (
|
||||
<>
|
||||
<p>Hello world.</p>
|
||||
</>
|
||||
);
|
||||
}</code></pre>
|
||||
</li>
|
||||
<li data-list-item-id="e28812b27d5227675943ef98ab9477e67">In the parent render note, define a <code spellcheck="false">~renderNote</code> relation
|
||||
pointing to the newly created child.</li>
|
||||
<li data-list-item-id="e24cc71d55c7c8ec61014ac0d800653da">Refresh the render note and it should display a “Hello world” message.</li>
|
||||
</ol>
|
||||
<h2>Refreshing the note</h2>
|
||||
<p>It's possible to refresh the note via:</p>
|
||||
<ul>
|
||||
<li>The corresponding button in <a class="reference-link" href="#root/_help_XpOYSgsLkTJy">Floating buttons</a>.</li>
|
||||
<li>The “Render active note” <a href="#root/_help_A9Oc6YKKc65v">keyboard shortcut</a> (not
|
||||
<li data-list-item-id="e01c4ae9c0999b2879e914c5b641215e3">The corresponding button in <a class="reference-link" href="#root/_help_XpOYSgsLkTJy">Floating buttons</a>.</li>
|
||||
<li
|
||||
data-list-item-id="e871da2cff905b2daa180fcae27aee43b">The “Render active note” <a href="#root/_help_A9Oc6YKKc65v">keyboard shortcut</a> (not
|
||||
assigned by default).</li>
|
||||
</ul>
|
||||
<h2>Examples</h2>
|
||||
<ul>
|
||||
<li><a class="reference-link" href="#root/_help_R7abl2fc6Mxi">Weight Tracker</a> which
|
||||
<li data-list-item-id="ec01930f20370b46f519bd844b67623ee"><a class="reference-link" href="#root/_help_R7abl2fc6Mxi">Weight Tracker</a> which
|
||||
is present in the <a class="reference-link" href="#root/_help_6tZeKvSHEUiB">Demo Notes</a>.</li>
|
||||
</ul>
|
||||
46
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Common concepts/Script bundles.html
generated
vendored
Normal file
46
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Common concepts/Script bundles.html
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
<p>For both <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a> and
|
||||
more complicated scripts, it's generally useful to split the code into
|
||||
multiple <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_6f9hih2hXXZk">Code</a> notes.</p>
|
||||
<p>When a script is run, the sub-children of the script being run (or the
|
||||
<a
|
||||
class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a>) are checked for children. If the children are Code notes
|
||||
of the corresponding type (front-end or backend) as the code being run,
|
||||
they will be evaluated as well.</p>
|
||||
<p>The collection of a script and its child notes is called a <em>bundle</em>.
|
||||
A child note inside a bundle is called a <em>module</em>.</p>
|
||||
<p>As a basic example of dependencies, consider the following note structure:</p>
|
||||
<ul>
|
||||
<li class="ck-list-marker-italic" data-list-item-id="e4c343ba6ed99b3a943049b6f0af99dd6">
|
||||
<p><em>Script with dependency</em>
|
||||
</p><pre><code class="language-application-javascript-env-frontend">api.log(MyMath.sum(2, 2));</code></pre>
|
||||
<ul>
|
||||
<li class="ck-list-marker-italic" data-list-item-id="ea27318ca64cb71cfa5eceb15f9acba75">
|
||||
<p><em>MyMath</em>
|
||||
</p><pre><code class="language-application-javascript-env-frontend">module.exports = {
|
||||
sum(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
};</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>When <em>Script with dependency</em> is run, it will detect <em>MyMath</em> as
|
||||
a submodule and provide the result of its <code spellcheck="false">module.exports</code> object
|
||||
into a global object with the same name as the note.</p>
|
||||
<aside class="admonition note">
|
||||
<p>If the note contains spaces or special characters, they will be stripped.
|
||||
For example <code spellcheck="false">My Nice Note!</code> becomes <code spellcheck="false">MyNiceNote</code>.</p>
|
||||
</aside>
|
||||
<h2>Alternative syntax</h2>
|
||||
<p>Instead of providing an object to <code spellcheck="false">module.exports</code>,
|
||||
it's also possible to add fields individually:</p><pre><code class="language-application-javascript-env-frontend">module.exports.sum = (a, b) => a + b;
|
||||
module.exports.subtract = (a, b) => a - b;</code></pre>
|
||||
<h2>Ignoring a code script from a bundle</h2>
|
||||
<p>To ignore a script from being included in a bundle (e.g. if it's unrelated
|
||||
to the parent script note), apply the <code spellcheck="false">#disableInclusion</code> label.</p>
|
||||
<h2>Sharing a module across multiple bundles</h2>
|
||||
<p>Modules can be reused across multiple scripts by simply cloning the shared
|
||||
module between two modules (see <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/BFs8mudNFgCS/_help_IakOLONlIfGI">Cloning Notes</a>).</p>
|
||||
<p>Optionally, a separate note can be used to contain all the different reusable
|
||||
modules for an easy way to discover them.</p>
|
||||
@ -1,13 +1,167 @@
|
||||
<p>It's possible to create custom widget in three possible locations where
|
||||
you can display your custom content.</p>
|
||||
<p>Positions are:</p>
|
||||
<p>Custom widgets are a special subset of scripts that render graphical elements
|
||||
in certain parts of the application. These can be used to add new functionality
|
||||
to the Trilium application.</p>
|
||||
<h2>Preact with JSX vs. vanilla jQuery</h2>
|
||||
<p>In older versions of Trilium, custom widgets were exclusively written
|
||||
in a combination of jQuery with Trilium's internal widget architecture
|
||||
(e.g., <code spellcheck="false">BasicWidget</code>, <code spellcheck="false">NoteContextAwareWidget</code>).</p>
|
||||
<p>Starting with v0.101.0, custom widgets can also be written in JSX using
|
||||
the <a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/yIhgI5H7A2Sm/_help_KLsqhjaqh1QW">Preact</a> framework.
|
||||
Both legacy and Preact widgets have the same capabilities, with a single
|
||||
difference:</p>
|
||||
<ul>
|
||||
<li><code>left-pane</code>
|
||||
</li>
|
||||
<li><code>center-pane</code>
|
||||
</li>
|
||||
<li><code>note-detail-pane</code> - located within <code>center-pane</code>,
|
||||
but specific to note (split)</li>
|
||||
<li><code>right-pane</code>
|
||||
</li>
|
||||
</ul>
|
||||
<li data-list-item-id="e2a6a28bcf69987db6b33b4902b913282">Preact widgets are content-sized by default whereas legacy widgets need
|
||||
<code
|
||||
spellcheck="false">this.contentSized()</code>applied in the constructor. For more information,
|
||||
see the corresponding section in <a class="reference-link" href="#root/MgibgPcfeuGz/_help_gMkgcLJ6jBkg">Troubleshooting</a>.</li>
|
||||
</ul>
|
||||
<p>Wherever possible, widget examples will be both in the legacy and Preact
|
||||
format.</p>
|
||||
<h2>Creating a custom widget</h2>
|
||||
<ol>
|
||||
<li data-list-item-id="efdec30e3ba380f9691c2955248e662aa">Create a <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_6f9hih2hXXZk">Code</a> note.</li>
|
||||
<li
|
||||
data-list-item-id="e6ac401b11f885fbf6ee2eb486e2fb4db">Set the language to:
|
||||
<ol>
|
||||
<li data-list-item-id="ea981b36d647bb2020c63b6eb8888ffcb">JavaScript (frontend) for legacy widgets using jQuery.</li>
|
||||
<li data-list-item-id="e27097e820e8b18d5539035afc4f91cf6">JSX for Preact widgets. You might need to go to Options → Code to enable
|
||||
the language first.</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li data-list-item-id="e94ba32049422e310a2322f85bb37ab85">Apply the <code spellcheck="false">#widget</code> <a href="#root/pOsGYCXsbNQG/tC7s2alapj8V/zEY4DaJG4YT5/_help_HI6GBBIduIgv">label</a>.</li>
|
||||
</ol>
|
||||
<h2>Getting started with a simple example</h2>
|
||||
<p>Let's start by creating a widget that shows a message near the content
|
||||
area. Follow the previous section to create a code note, and use the following
|
||||
content.</p>
|
||||
<figure class="table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Legacy</th>
|
||||
<th style="width:50%;">Preact (v0.101.0+)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><pre><code class="language-text-x-trilium-auto">class HelloNoteDetail extends api.BasicWidget {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.contentSized();
|
||||
}
|
||||
|
||||
get parentWidget() { return "center-pane" }
|
||||
|
||||
doRender() {
|
||||
this.$widget = $("<span>Center pane</span>");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = new HelloNoteDetail();</code></pre>
|
||||
</td>
|
||||
<td style="vertical-align:top;"><pre><code class="language-text-x-trilium-auto">import { defineWidget } from "trilium:preact";
|
||||
|
||||
export default defineWidget({
|
||||
parent: "center-pane",
|
||||
render: () => <span>Center pane from Preact.</span>
|
||||
});</code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</figure>
|
||||
<p><a href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_s8alTXmpFR61">Refresh the application</a> and
|
||||
the widget should appear underneath the content area.</p>
|
||||
<h2>Widget location (parent widget)</h2>
|
||||
<p>A widget can be placed in one of the following sections of the applications:</p>
|
||||
<figure
|
||||
class="table" style="width:100%;">
|
||||
<table class="ck-table-resized">
|
||||
<colgroup>
|
||||
<col style="width:15.59%;">
|
||||
<col style="width:30.42%;">
|
||||
<col style="width:16.68%;">
|
||||
<col style="width:37.31%;">
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Value for <code spellcheck="false">parentWidget</code>
|
||||
</th>
|
||||
<th>Description</th>
|
||||
<th>Sample widget</th>
|
||||
<th>Special requirements</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><code spellcheck="false">left-pane</code>
|
||||
</th>
|
||||
<td>Appears within the same pane that holds the <a class="reference-link"
|
||||
href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_oPVyFC7WL2Lp">Note Tree</a>.</td>
|
||||
<td>Same as above, with only a different <code spellcheck="false">parentWidget</code>.</td>
|
||||
<td>None.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code spellcheck="false">center-pane</code>
|
||||
</th>
|
||||
<td>In the content area. If a split is open, the widget will span all of the
|
||||
splits.</td>
|
||||
<td>See example above.</td>
|
||||
<td>None.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code spellcheck="false">note-detail-pane</code>
|
||||
</th>
|
||||
<td>
|
||||
<p>In the content area, inside the note detail area. If a split is open,
|
||||
the widget will be contained inside the split.</p>
|
||||
<p>This is ideal if the widget is note-specific.</p>
|
||||
</td>
|
||||
<td><a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/yIhgI5H7A2Sm/MgibgPcfeuGz/_help_GhurYZjh8e1V">Note context aware widget</a>
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li data-list-item-id="ec06332efcc3039721606c052f0d913fa">The widget must export a <code spellcheck="false">class</code> and not an
|
||||
instance of the class (e.g. <code spellcheck="false">no new</code>) because
|
||||
it needs to be multiplied for each note, so that splits work correctly.</li>
|
||||
<li
|
||||
data-list-item-id="e8da690a2a8df148f6b5fc04ba1611688">Since the <code spellcheck="false">class</code> is exported instead of an
|
||||
instance, the <code spellcheck="false">parentWidget</code> getter must be
|
||||
<code
|
||||
spellcheck="false">static</code>, otherwise the widget is ignored.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><code spellcheck="false">right-pane</code>
|
||||
</th>
|
||||
<td>In the <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_RnaPdbciOfeq">Right Sidebar</a>,
|
||||
as a dedicated section.</td>
|
||||
<td><a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/yIhgI5H7A2Sm/MgibgPcfeuGz/_help_M8IppdwVHSjG">Right pane widget</a>
|
||||
</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li data-list-item-id="efe008d361e224f422582552648e1afe7">Although not mandatory, it's best to use a <code spellcheck="false">RightPanelWidget</code> instead
|
||||
of a <code spellcheck="false">BasicWidget</code> or a <code spellcheck="false">NoteContextAwareWidget</code>.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</figure>
|
||||
<p>To position the widget somewhere else, just change the value passed to
|
||||
<code
|
||||
spellcheck="false">get parentWidget()</code>for legacy widgets or the <code spellcheck="false">parent</code> field
|
||||
for Preact. Do note that some positions such as <code spellcheck="false">note-detail-pane</code> and
|
||||
<code
|
||||
spellcheck="false">right-pane</code>have special requirements that need to be accounted for
|
||||
(see the table above).</p>
|
||||
<h2>Launch bar widgets</h2>
|
||||
<p>Launch bar widgets are similar to <em>Custom widgets</em> but are specific
|
||||
to the <a class="reference-link" href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_xYmIYSP6wE3F">Launch Bar</a>.
|
||||
See <a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/yIhgI5H7A2Sm/_help_4Gn3psZKsfSm">Launch Bar Widgets</a> for
|
||||
more information.</p>
|
||||
<h2>Custom position</h2>
|
||||
<p> </p>
|
||||
@ -1,9 +1,22 @@
|
||||
<p>In <code>doRender()</code>:</p><pre><code class="language-text-x-trilium-auto">this.cssBlock(`#my-widget {
|
||||
<h2>Classic widgets</h2>
|
||||
<p>In <code spellcheck="false">doRender()</code>:<span class="footnote-reference"
|
||||
data-footnote-reference="" data-footnote-index="1" data-footnote-id="1saoftmefpp"
|
||||
role="doc-noteref" id="fnref1saoftmefpp"><sup><a href="#fn1saoftmefpp">[1]</a></sup></span>
|
||||
</p><pre><code class="language-text-x-trilium-auto">this.cssBlock(`#my-widget {
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
left: 60px;
|
||||
z-index: 1;
|
||||
}`)</code></pre>
|
||||
<hr>
|
||||
<p>Reference: <a href="https://trilium.rocks/X7pxYpiu0lgU">https://trilium.rocks/X7pxYpiu0lgU</a>
|
||||
</p>
|
||||
}`);</code></pre>
|
||||
<h2>Preact widgets</h2>
|
||||
<p>See the dedicated page: <a class="reference-link" href="#root/KLsqhjaqh1QW/_help_Sg9GrCtyftZf">CSS</a>.</p>
|
||||
<ol
|
||||
class="footnote-section footnotes" data-footnote-section="" role="doc-endnotes">
|
||||
<li class="footnote-item" data-footnote-item="" data-footnote-index="1"
|
||||
data-footnote-id="1saoftmefpp" role="doc-endnote" id="fn1saoftmefpp"><span class="footnote-back-link" data-footnote-back-link="" data-footnote-id="1saoftmefpp"><sup><strong><a href="#fnref1saoftmefpp">^</a></strong></sup></span>
|
||||
<div
|
||||
class="footnote-content" data-footnote-content="">
|
||||
<p>Reference: <a href="https://trilium.rocks/X7pxYpiu0lgU">https://trilium.rocks/X7pxYpiu0lgU</a> </p>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
48
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Note context aware widget.html
generated
vendored
Normal file
48
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Note context aware widget.html
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
<p>Note context-aware widgets are a different type of widget which automatically
|
||||
react to changes in the current note.</p>
|
||||
<p>Important aspects:</p>
|
||||
<ul>
|
||||
<li data-list-item-id="ebe74655683475b6a16e53832e6b2c47a">The widget must export a <code spellcheck="false">class</code> and not an
|
||||
instance of the class (e.g. <code spellcheck="false">no new</code>) because
|
||||
it needs to be multiplied for each note, so that splits work correctly.</li>
|
||||
<li
|
||||
data-list-item-id="edf648bc7ea3325255223d28f0543e5b9">Since the <code spellcheck="false">class</code> is exported instead of an
|
||||
instance, the <code spellcheck="false">parentWidget</code> getter must be
|
||||
<code
|
||||
spellcheck="false">static</code>, otherwise the widget is ignored.</li>
|
||||
</ul>
|
||||
<h2>Example displaying the current note title</h2>
|
||||
<p>This is a note context-aware widget that simply displays the name the
|
||||
current note. </p>
|
||||
<h3>Classic example</h3><pre><code class="language-text-x-trilium-auto">class HelloNoteDetail extends api.NoteContextAwareWidget {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.contentSized();
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $("<div>");
|
||||
}
|
||||
|
||||
async refreshWithNote(note) {
|
||||
this.$widget.text("Current note: " + note.title);
|
||||
}
|
||||
|
||||
static get parentWidget() { return "note-detail-pane" }
|
||||
get position() { return 10 }
|
||||
|
||||
}
|
||||
|
||||
module.exports = HelloNoteDetail;</code></pre>
|
||||
<h3>Preact (v0.101.0+)</h3><pre><code class="language-text-x-trilium-auto">import { defineWidget, useNoteContext, useNoteProperty } from "trilium:preact";
|
||||
|
||||
export default defineWidget({
|
||||
parent: "note-detail-pane",
|
||||
position: 10,
|
||||
render: () => {
|
||||
const { note } = useNoteContext();
|
||||
const title = useNoteProperty(note, "title");
|
||||
return <span>Current note JSX: {title}</span>;
|
||||
}
|
||||
});</code></pre>
|
||||
@ -1,23 +1,23 @@
|
||||
<h2>Key highlights</h2>
|
||||
<ul>
|
||||
<li data-list-item-id="e08ebed8d78d0359c71a72be31cd95074"><code spellcheck="false">doRender</code> must not be overridden, instead
|
||||
<li data-list-item-id="e05167a939f3b6c8083cf62d4f8108b4b"><code spellcheck="false">doRender</code> must not be overridden, instead
|
||||
<code
|
||||
spellcheck="false">doRenderBody()</code>has to be overridden.
|
||||
<ul>
|
||||
<li data-list-item-id="e34a4e9826ab89e0ce8ded8786a803f3a"><code spellcheck="false">doRenderBody</code> can optionally be <code spellcheck="false">async</code>.</li>
|
||||
<li data-list-item-id="eee44709b64b220f4af124ff1458a61e8"><code spellcheck="false">doRenderBody</code> can optionally be <code spellcheck="false">async</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-list-item-id="e24bc184054a9c87a6c7695bb65c8d30b"><code spellcheck="false">parentWidget()</code> must be set to <code spellcheck="false">“rightPane”</code>.</li>
|
||||
<li data-list-item-id="e94b7be0f1d366c502703ff3a5fc3bfb1"><code spellcheck="false">parentWidget()</code> must be set to <code spellcheck="false">“rightPane”</code>.</li>
|
||||
<li
|
||||
data-list-item-id="e581cbed615c9be4f249274c5c51c6a18"><code spellcheck="false">widgetTitle()</code> getter can optionally be
|
||||
data-list-item-id="ea56b04dbcf63573acbde90d990137829"><code spellcheck="false">widgetTitle()</code> getter can optionally be
|
||||
overriden, otherwise the widget will be displayed as “Untitled widget”.</li>
|
||||
</ul>
|
||||
<h2>Example for new layout</h2>
|
||||
<aside class="admonition important">
|
||||
<p>This section addresses example that are tailored for the <a class="reference-link"
|
||||
href="#root/pOsGYCXsbNQG/gh7bpGYxajRS/Vc8PjrjAGuOp/_help_IjZS7iK5EXtb">New Layout</a> (available
|
||||
starting with v0.101.0) where the right pane widget/sidebar is no longer
|
||||
shown or hidden based on the widgets it has. </p>
|
||||
href="#root/_help_IjZS7iK5EXtb">New Layout</a> (available starting with
|
||||
v0.101.0) where the right pane widget/sidebar is no longer shown or hidden
|
||||
based on the widgets it has. </p>
|
||||
</aside>
|
||||
<h3>Title widget</h3>
|
||||
<p>This is an example of a context-aware widget which displays the title
|
||||
@ -41,7 +41,8 @@
|
||||
module.exports = new NoteTitleWidget();</code></pre>
|
||||
<h3>Clock</h3>
|
||||
<p>A simple widget which will show the current time, as an example on how
|
||||
to dynamically change the content of the widget periodically.</p><pre><code class="language-text-x-trilium-auto">const template = `<div></div>`;
|
||||
to dynamically change the content of the widget periodically.</p>
|
||||
<h3>Legacy widget</h3><pre><code class="language-text-x-trilium-auto">const template = `<div></div>`;
|
||||
|
||||
class ToDoListWidget extends api.RightPanelWidget {
|
||||
|
||||
@ -60,6 +61,26 @@ class ToDoListWidget extends api.RightPanelWidget {
|
||||
}
|
||||
|
||||
module.exports = new ToDoListWidget();</code></pre>
|
||||
<h3>Preact widget</h3><pre><code class="language-text-x-trilium-auto">import { defineWidget, RightPanelWidget, useEffect, useState } from "trilium:preact";
|
||||
|
||||
export default defineWidget({
|
||||
parent: "right-pane",
|
||||
position: 1,
|
||||
render() {
|
||||
const [ time, setTime ] = useState();
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setTime(new Date().toLocaleString());
|
||||
}, 1000);
|
||||
return () => clearInterval(interval);
|
||||
});
|
||||
return (
|
||||
<RightPanelWidget id="clock-jsx" title="Clock (JSX)">
|
||||
<p>The time is: {time}</p>
|
||||
</RightPanelWidget>
|
||||
);
|
||||
}
|
||||
});</code></pre>
|
||||
<h2>Example for old layout</h2>
|
||||
<p>Here's a widget that displays a basic message ("Hi"):</p><pre><code class="language-text-x-trilium-auto">const template = `<div>Hi</div>`;
|
||||
|
||||
@ -89,7 +110,7 @@ this.triggerCommand("reEvaluateRightPaneVisibility");</code></pre>
|
||||
<p>By default, the sidebar items are displayed in the order they are found
|
||||
by the application when searching for <code spellcheck="false">#widget</code> notes.</p>
|
||||
<p>It is possible to make a widget appear higher or lower up, by adjusting
|
||||
its <code spellcheck="false">position</code> property:</p><pre><code class="language-text-x-diff">class MyWidget extends api.RightPanelWidget {
|
||||
its <code spellcheck="false">position</code> property:</p><pre><code class="language-text-x-trilium-auto">class MyWidget extends api.RightPanelWidget {
|
||||
|
||||
+ get position() { return 20 };
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<h2>Why is my widget clipped by other UI elements</h2>
|
||||
<p>For performance and layout reasons, the size of widgets in Trilium is
|
||||
independent from its children. At CSS level, this means that the widget
|
||||
container has <code spellcheck="false">contain: size</code> applied to it.</p>
|
||||
container has <code>contain: size</code> applied to it.</p>
|
||||
<p>This works well if the widget has a fixed size (or based on its parent
|
||||
container), however to make a widget resize to fit its content, apply the
|
||||
following change:</p><pre><code class="language-text-x-diff">class MyWidget extends api.RightPanelWidget {
|
||||
@ -12,5 +12,4 @@
|
||||
+ }
|
||||
|
||||
}</code></pre>
|
||||
<p>Alternatively apply <code spellcheck="false">contain: none</code> to its
|
||||
CSS.</p>
|
||||
<p>Alternatively apply <code>contain: none</code> to its CSS.</p>
|
||||
@ -16,17 +16,17 @@
|
||||
module.exports = new MyWidget();</code></pre>
|
||||
<p>To implement this widget:</p>
|
||||
<ol>
|
||||
<li>Create a new <code>JS Frontend</code> note in Trilium and paste in the code
|
||||
above.</li>
|
||||
<li>Assign the <code>#widget</code> <a href="#root/_help_zEY4DaJG4YT5">attribute</a> to
|
||||
<li data-list-item-id="e9927fa1c4b393854487094afd914ece9">Create a new <code spellcheck="false">JS Frontend</code> note in Trilium
|
||||
and paste in the code above.</li>
|
||||
<li data-list-item-id="e3741fe167b7dccae0081cc0d1a326a5d">Assign the <code spellcheck="false">#widget</code> <a href="#root/_help_zEY4DaJG4YT5">attribute</a> to
|
||||
the <a href="#root/_help_BFs8mudNFgCS">note</a>.</li>
|
||||
<li>Restart Trilium or reload the window.</li>
|
||||
<li data-list-item-id="e300febf71f84c3be97fc8556182ea124">Restart Trilium or reload the window.</li>
|
||||
</ol>
|
||||
<p>To verify that the widget is working, open the developer tools (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>I</kbd>)
|
||||
and run <code>document.querySelector("#my-widget")</code>. If the element
|
||||
is found, the widget is functioning correctly. If <code>undefined</code> is
|
||||
and run <code spellcheck="false">document.querySelector("#my-widget")</code>.
|
||||
If the element is found, the widget is functioning correctly. If <code spellcheck="false">undefined</code> is
|
||||
returned, double-check that the <a href="#root/_help_BFs8mudNFgCS">note</a> has
|
||||
the <code>#widget</code> <a href="#root/_help_zEY4DaJG4YT5">attribute</a>.</p>
|
||||
the <code spellcheck="false">#widget</code> <a href="#root/_help_zEY4DaJG4YT5">attribute</a>.</p>
|
||||
<h3>Step 2: Adding an UI Element</h3>
|
||||
<p>Next, let's improve the widget by adding a button to it.</p><pre><code class="language-text-x-trilium-auto">const template = `<div id="my-widget"><button>Click Me!</button></div>`;
|
||||
|
||||
@ -46,7 +46,9 @@ module.exports = new MyWidget();</code></pre>
|
||||
<h3>Step 3: Styling the Widget</h3>
|
||||
<p>To make the button more visually appealing and position it correctly,
|
||||
we'll apply some custom styling. Trilium includes <a href="https://boxicons.com">Box Icons</a>,
|
||||
which we'll use to replace the button text with an icon. For example the <code>bx bxs-magic-wand</code> icon.</p>
|
||||
which we'll use to replace the button text with an icon. For example the
|
||||
<code
|
||||
spellcheck="false">bx bxs-magic-wand</code>icon.</p>
|
||||
<p>Here's the updated template:</p><pre><code class="language-text-x-trilium-auto">const template = `<div id="my-widget"><button class="tree-floating-button bx bxs-magic-wand tree-settings-button"></button></div>`;</code></pre>
|
||||
<p>Next, we'll adjust the button's position using CSS:</p><pre><code class="language-text-x-trilium-auto">class MyWidget extends api.BasicWidget {
|
||||
get position() { return 1; }
|
||||
@ -69,7 +71,8 @@ module.exports = new MyWidget();</code></pre>
|
||||
of the left pane, alongside other action buttons.</p>
|
||||
<h3>Step 4: Adding User Interaction</h3>
|
||||
<p>Let’s make the button interactive by showing a message when it’s clicked.
|
||||
We'll use the <code>api.showMessage</code> method from the <a href="#root/_help_GLks18SNjxmC">Script API</a>.</p><pre><code class="language-text-x-trilium-auto">class MyWidget extends api.BasicWidget {
|
||||
We'll use the <code spellcheck="false">api.showMessage</code> method from
|
||||
the <a href="#root/_help_GLks18SNjxmC">Script API</a>.</p><pre><code class="language-text-x-trilium-auto">class MyWidget extends api.BasicWidget {
|
||||
get position() { return 1; }
|
||||
get parentWidget() { return "left-pane"; }
|
||||
|
||||
@ -87,17 +90,8 @@ module.exports = new MyWidget();</code></pre>
|
||||
}
|
||||
|
||||
module.exports = new MyWidget();</code></pre>
|
||||
<p><code>parentWidget()</code> can be given the following values:</p>
|
||||
<ul>
|
||||
<li><code>left-pane</code> - This renders the widget on the left side of the
|
||||
screen where the note tree lives.</li>
|
||||
<li><code>center-pane</code> - This renders the widget in the center of the
|
||||
layout in the same location that notes and splits appear.</li>
|
||||
<li><code>note-detail-pane</code> - This renders the widget <em>with</em> the
|
||||
note in the center pane. This means it can appear multiple times with splits.</li>
|
||||
<li><code>right-pane</code> - This renders the widget to the right of any opened
|
||||
notes.</li>
|
||||
</ul>
|
||||
<p>For the list of possible values for <code spellcheck="false">parentWidget()</code>,
|
||||
see <a class="reference-link" href="#root/yIhgI5H7A2Sm/_help_MgibgPcfeuGz">Custom Widgets</a>. </p>
|
||||
<p><a href="#root/_help_s8alTXmpFR61">Reload</a> the application one last time.
|
||||
When you click the button, a "Hello World!" message should appear, confirming
|
||||
that your widget is fully functional.</p>
|
||||
@ -5,6 +5,7 @@
|
||||
<p>This is an example of a note context-aware widget, which reacts to the
|
||||
currently opened note and refreshes automatically as the user navigates
|
||||
through the notes.</p>
|
||||
<h2>Legacy widget</h2>
|
||||
<p>In this example, the title of the note is displayed. It works best on
|
||||
the <a href="#root/_help_x0JgW8UqGXvq">horizontal layout</a>.</p><pre><code class="language-application-javascript-env-backend">const TPL = `\
|
||||
<div style="
|
||||
@ -28,4 +29,19 @@ class NoteTitleWidget extends api.NoteContextAwareWidget {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new NoteTitleWidget();</code></pre>
|
||||
module.exports = new NoteTitleWidget();</code></pre>
|
||||
<h2>Preact widget (v0.101.0+)</h2><pre><code class="language-text-jsx">import { defineLauncherWidget, useActiveNoteContext } from "trilium:preact";
|
||||
|
||||
export default defineLauncherWidget({
|
||||
render: () => {
|
||||
const { note } = useActiveNoteContext();
|
||||
return <div style={{
|
||||
display: "flex",
|
||||
height: "53px",
|
||||
width: "fit-content",
|
||||
fontSize: "0.75em",
|
||||
alignItems: "center",
|
||||
flexShrink: 0
|
||||
}}>{note?.title}</div>;
|
||||
}
|
||||
});</code></pre>
|
||||
64
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact.html
generated
vendored
Normal file
64
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact.html
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
<p>Since v0.101.0, Trilium integrates Preact for front-end scripting, including
|
||||
support for JSX.</p>
|
||||
<p>Preact can be used for:</p>
|
||||
<ul>
|
||||
<li data-list-item-id="ecaa7ce1d629d04e22a9c9e5de7bbba9d"><a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a>,
|
||||
where a JSX code note is used instead of a HTML one.</li>
|
||||
<li data-list-item-id="ebec1c35ba18bb42ce91497eae106fad6"><a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/yIhgI5H7A2Sm/_help_MgibgPcfeuGz">Custom Widgets</a>,
|
||||
where JSX can be used to replace the old, jQuery-based mechanism.</li>
|
||||
</ul>
|
||||
<p>To get started, the first step is to enable JSX in the list of Code languages.
|
||||
Go to Options → Code Notes and check the “JSX” language. Afterwards, proceed
|
||||
with the documentation in either <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a> or
|
||||
<a
|
||||
class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/yIhgI5H7A2Sm/_help_MgibgPcfeuGz">Custom Widgets</a>, which will both have a section on how to use the new
|
||||
Preact integration.</p>
|
||||
<aside class="admonition important">
|
||||
<p>The documentation assumes prior knowledge with React or Preact. As a starting
|
||||
point, consider the <a href="https://www.freecodecamp.org/learn/front-end-development-libraries-v9/">FreeCodeCamp course on Front End Development Libraries</a> or
|
||||
the <a href="https://preactjs.com/tutorial/">Preact Tutorial</a>.</p>
|
||||
</aside>
|
||||
<h2>Import/exports</h2>
|
||||
<p>When using Preact with JSX, there is a special syntax which provides ES-like
|
||||
imports. This <code spellcheck="false">import</code> syntax makes way for
|
||||
a more intuitive that doesn't make use of global objects and paves the
|
||||
way for better auto-completion support that might be introduced in the
|
||||
future. </p>
|
||||
<h3>API imports</h3>
|
||||
<p>Instead of:</p><pre><code class="language-text-jsx">api.showMessage("Hello");</code></pre>
|
||||
<p>the JSX version looks like this:</p><pre><code class="language-text-jsx">import { showMessage } from "trilium:api";
|
||||
showMessage("hello");</code></pre>
|
||||
<h3>Preact API imports (hooks, components)</h3>
|
||||
<p>There's a new <a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/_help_GLks18SNjxmC">Script API</a> dedicated
|
||||
to Preact, which provides shared components that are also used by Trilium
|
||||
internally as well as hooks, for example.</p><pre><code class="language-text-jsx">import { useState } from "trilium:preact";
|
||||
const [ myState, setMyState ] = useState("Hi");</code></pre>
|
||||
<h3>Exporting</h3>
|
||||
<p>JSX notes can export a component for use in <a class="reference-link"
|
||||
href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a> or
|
||||
for <a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/yIhgI5H7A2Sm/KLsqhjaqh1QW/_help_Bqde6BvPo05g">Component libraries</a>: </p><pre><code class="language-text-jsx">export default function() {
|
||||
return (
|
||||
<>
|
||||
<p>Hello world.</p>
|
||||
</>
|
||||
);
|
||||
}</code></pre>
|
||||
<h3>Import/export are not required</h3>
|
||||
<p>These imports are syntactic sugar meant to replace the usage for the
|
||||
<code
|
||||
spellcheck="false">api</code>global object (see <a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/_help_GLks18SNjxmC">Script API</a>). </p>
|
||||
<aside
|
||||
class="admonition note">
|
||||
<p>The <code spellcheck="false">import</code> and <code spellcheck="false">export</code> syntax
|
||||
work only for JSX notes. Standard/jQuery code notes still need to use the
|
||||
<code
|
||||
spellcheck="false">api</code>global and <code spellcheck="false">module.exports</code>.</p>
|
||||
</aside>
|
||||
<h2>Under the hood</h2>
|
||||
<p>Unlike JavaScript, JSX requires pre-processing to turn it into JavaScript
|
||||
(just like TypeScript). To do so, Trilium uses <a href="https://github.com/alangpierce/sucrase">Sucrase</a>,
|
||||
a JavaScript library which processes the JSX to pure JavaScript. The processing
|
||||
is done each time a script is run (for widgets this happens at every program
|
||||
startup). If you notice any performance degradation due to long compilation,
|
||||
consider <a href="#root/pOsGYCXsbNQG/BgmBlOIl72jZ/_help_wy8So3yZZlH9">reporting the issue</a> to
|
||||
us.</p>
|
||||
44
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components.html
generated
vendored
Normal file
44
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components.html
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<figure class="image image_resized" style="width:54.58%;">
|
||||
<img style="aspect-ratio:896/712;" src="Built-in components_image.png"
|
||||
width="896" height="712">
|
||||
<figcaption>A partial screenshot from the Widget showcase example (see below).</figcaption>
|
||||
</figure>
|
||||
<p>Trilium comes with its own set of Preact components, some of which are
|
||||
also available to <a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/yIhgI5H7A2Sm/_help_MgibgPcfeuGz">Custom Widgets</a> and
|
||||
<a
|
||||
class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a>.</p>
|
||||
<p>To use these components, simply import them from <code spellcheck="false">trilium:preact</code>:</p><pre><code class="language-text-jsx">import { ActionButton, Button, LinkButton } from "trilium:preact";</code></pre>
|
||||
<p>and then use them:</p><pre><code class="language-text-jsx">export default function MyRenderNote() {
|
||||
const onClick = () => showMessage("A button was pressed");
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Buttons</h2>
|
||||
<div style={{ display: "flex", gap: "1em", alignItems: "center" }}>
|
||||
<ActionButton icon="bx bx-rocket" text="Action button" onClick={onClick} />
|
||||
<Button icon="bx bx-rocket" text="Simple button" onClick={onClick} />
|
||||
<LinkButton text="Link button" onClick={onClick} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}</code></pre>
|
||||
<h2>Widget showcase</h2>
|
||||
<aside class="admonition tip">
|
||||
<p>Starting with v0.101.0, the widget showcase is also available in the
|
||||
<a
|
||||
class="reference-link" href="#root/pOsGYCXsbNQG/tC7s2alapj8V/wX4HbRucYSDD/_help_6tZeKvSHEUiB">Demo Notes</a>.</p>
|
||||
</aside>
|
||||
<p>This is a <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a> example
|
||||
with JSX that shows most of the built-in components that are accessible
|
||||
to custom widgets and JSX render notes.</p>
|
||||
<p>To use it, simply:</p>
|
||||
<ol>
|
||||
<li data-list-item-id="ef2da471f61429e4755fdfee1301299d8">Create a render note.</li>
|
||||
<li data-list-item-id="e2e1475eb5099d3df20de96997712a9dc">Create a child code note of JSX type with the content of this file:
|
||||
<a
|
||||
class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/yIhgI5H7A2Sm/KLsqhjaqh1QW/RSssb9S3xgSr/_help_i9B4IW7b6V6z">Widget showcase</a>
|
||||
</li>
|
||||
<li data-list-item-id="ed0b442c37c1db5287d95d8d982f025d9">Set the <code spellcheck="false">~renderNote</code> relation of the parent
|
||||
note to the child note.</li>
|
||||
<li data-list-item-id="e62386a552bb441bcb830285f5487868b">Refresh the render note to see the results.</li>
|
||||
</ol>
|
||||
189
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components/Widget showcase.jsx
generated
vendored
Normal file
189
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components/Widget showcase.jsx
generated
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
import {
|
||||
ActionButton, Button, LinkButton,
|
||||
Admonition, Collapsible,
|
||||
FormCheckbox, FormDropdownList, FormFileUploadButton, FormGroup, FormRadioGroup, FormTextArea,
|
||||
FormTextBox, FormToggle, Slider, RawHtml, LoadingSpinner, Icon,
|
||||
Dropdown, FormListItem, FormDropdownDivider, FormDropdownSubmenu,
|
||||
NoteAutocomplete, NoteLink, Modal,
|
||||
CKEditor,
|
||||
useEffect, useState
|
||||
} from "trilium:preact";
|
||||
import { showMessage } from "trilium:api";
|
||||
|
||||
export default function() {
|
||||
const [ time, setTime ] = useState();
|
||||
const lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam accumsan eu odio non gravida. Pellentesque ornare, arcu condimentum molestie dignissim, nibh turpis ultrices elit, eget elementum nunc erat at erat. Maecenas vehicula consectetur elit, nec fermentum elit venenatis eu.";
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => setTime(new Date().toLocaleString()), 1000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div style={{ padding: 20, display: "flex", flexDirection: "column", gap: "1em" }}>
|
||||
<h1>Widget showcase</h1>
|
||||
|
||||
<Buttons />
|
||||
<Admonition type="note">
|
||||
<strong>Admonition</strong><br />
|
||||
{lorem}
|
||||
</Admonition>
|
||||
|
||||
<Collapsible title="Collapsible" initiallyExpanded>
|
||||
{lorem}
|
||||
</Collapsible>
|
||||
|
||||
<FormElements />
|
||||
<NoteElements />
|
||||
<ModalSample />
|
||||
<DropdownSample />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Buttons() {
|
||||
const onClick = () => showMessage("A button was pressed");
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Buttons</h2>
|
||||
<div style={{ display: "flex", gap: "1em", alignItems: "center" }}>
|
||||
<ActionButton icon="bx bx-rocket" text="Action button" onClick={onClick} />
|
||||
<Button icon="bx bx-rocket" text="Simple button" onClick={onClick} />
|
||||
<LinkButton text="Link button" onClick={onClick} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function FormElements() {
|
||||
const [ checkboxChecked, setCheckboxChecked ] = useState(false);
|
||||
const [ dropdownValue, setDropdownValue ] = useState("key-1");
|
||||
const [ radioGroupValue, setRadioGroupValue ] = useState("key-1");
|
||||
const [ sliderValue, setSliderValue ] = useState(50);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Form elements</h2>
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: "1em" }}>
|
||||
<FormGroup name="checkbox" label="Checkbox">
|
||||
<FormCheckbox label="Checkbox" currentValue={checkboxChecked} onChange={setCheckboxChecked} />
|
||||
</FormGroup>
|
||||
<FormGroup name="toggle" label="Toggle">
|
||||
<FormToggle switchOnName="Off" switchOffName="On" currentValue={checkboxChecked} onChange={setCheckboxChecked} />
|
||||
</FormGroup>
|
||||
<FormGroup name="dropdown" label="Dropdown">
|
||||
<FormDropdownList
|
||||
values={[
|
||||
{ key: "key-1", name: "First item" },
|
||||
{ key: "key-2", name: "Second item" },
|
||||
{ key: "key-3", name: "Third item" },
|
||||
]}
|
||||
currentValue={dropdownValue} onChange={setDropdownValue}
|
||||
keyProperty="key" titleProperty="name"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="radio-group" label="Radio group">
|
||||
<FormRadioGroup
|
||||
values={[
|
||||
{ value: "key-1", label: "First item" },
|
||||
{ value: "key-2", label: "Second item" },
|
||||
{ value: "key-3", label: "Third item" },
|
||||
]}
|
||||
currentValue={radioGroupValue} onChange={setRadioGroupValue}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="text-box" label="Text box">
|
||||
<FormTextBox
|
||||
placeholder="Type something..."
|
||||
currentValue="" onChange={(newValue) => {}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="text-area" label="Text area">
|
||||
<FormTextArea
|
||||
placeholder="Type something bigger..."
|
||||
currentValue="" onChange={(newValue) => {}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="slider" label="Slider">
|
||||
<Slider
|
||||
min={1} max={100}
|
||||
value={sliderValue} onChange={setSliderValue}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="file-upload" label="File upload">
|
||||
<FormFileUploadButton
|
||||
text="Upload"
|
||||
onChange={(files) => {
|
||||
const file = files?.[0];
|
||||
if (!file) return;
|
||||
showMessage(`Got file "${file.name}" of size ${file.size} B and type ${file.type}.`);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="icon" label="Icon">
|
||||
<Icon icon="bx bx-smile" />
|
||||
</FormGroup>
|
||||
<FormGroup name="loading-spinner" label="Loading spinner">
|
||||
<LoadingSpinner />
|
||||
</FormGroup>
|
||||
<FormGroup name="raw-html" label="Raw HTML">
|
||||
<RawHtml html="<strong>Hi</strong> <em>there</em>" />
|
||||
</FormGroup>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function NoteElements() {
|
||||
const [ noteId, setNoteId ] = useState("");
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Note elements</h2>
|
||||
|
||||
<FormGroup name="note-autocomplete" label="Note autocomplete">
|
||||
<NoteAutocomplete
|
||||
placeholder="Select a note"
|
||||
noteId={noteId} noteIdChanged={setNoteId}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup name="note-link" label="Note link">
|
||||
{noteId
|
||||
? <NoteLink notePath={noteId} showNoteIcon />
|
||||
: <span>Select a note first</span>}
|
||||
</FormGroup>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ModalSample() {
|
||||
const [ shown, setShown ] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Modal</h2>
|
||||
<Button text="Open modal" onClick={() => setShown(true)} />
|
||||
<Modal title="Modal title" size="md" show={shown} onHidden={() => setShown(false)}>
|
||||
Modal goes here.
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownSample() {
|
||||
return (
|
||||
<>
|
||||
<h2>Dropdown menu</h2>
|
||||
<Dropdown text="Dropdown" hideToggleArrow>
|
||||
<FormListItem icon="bx bx-cut">Cut</FormListItem>
|
||||
<FormListItem icon="bx bx-copy">Copy</FormListItem>
|
||||
<FormListItem icon="bx bx-paste">Paste</FormListItem>
|
||||
<FormDropdownDivider />
|
||||
<FormDropdownSubmenu title="Submenu">
|
||||
<FormListItem>More items</FormListItem>
|
||||
</FormDropdownSubmenu>
|
||||
</Dropdown>
|
||||
</>
|
||||
)
|
||||
}
|
||||
BIN
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components_image.png
generated
vendored
Normal file
BIN
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components_image.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
19
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/CSS.html
generated
vendored
Normal file
19
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/CSS.html
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<h2>Inline styles</h2><pre><code class="language-text-jsx"><div style={{
|
||||
|
||||
display: "flex",
|
||||
|
||||
height: "53px",
|
||||
|
||||
width: "fit-content",
|
||||
|
||||
fontSize: "0.75em",
|
||||
|
||||
alignItems: "center",
|
||||
|
||||
flexShrink: 0
|
||||
|
||||
}}>/* [...] */</div></code></pre>
|
||||
<h2>Custom CSS file</h2>
|
||||
<p>Simply create a <a class="reference-link" href="#root/pOsGYCXsbNQG/pKK96zzmvBGf/_help_AlhDUqhENtH7">Custom app-wide CSS</a>.
|
||||
Make sure the class names are unique enough to not intersect with other
|
||||
UI elements, consider adding a prefix (e.g. <code spellcheck="false">x-mywidget-</code>).</p>
|
||||
55
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Component libraries.html
generated
vendored
Normal file
55
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Component libraries.html
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
<p>Using the concept of <a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/wqXwKJl6VpNk/_help_hA834UaHhSNn">Script bundles</a>,
|
||||
it's possible to create components that are shared for multiple widgets
|
||||
or <a class="reference-link" href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a>.</p>
|
||||
<h2>Exporting a single component</h2>
|
||||
<p>This is generally useful for big components.</p>
|
||||
<p>Here's an example child hierarchy using <a class="reference-link"
|
||||
href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a>: </p>
|
||||
<ul>
|
||||
<li data-list-item-id="e3f972228e04ea1f4801d76cb1145fe54"><em>My render note</em>
|
||||
<br>Note type: Render Note
|
||||
<br>Link <code spellcheck="false">~renderNote</code> to the child note (<em>Render note with subcomponents</em>)
|
||||
<ul>
|
||||
<li data-list-item-id="eed4ff5d1824e4f8cf1a05feef1117b91">
|
||||
<p><em>Render note with subcomponents</em>
|
||||
<br>Type: JSX</p><pre><code class="language-application-javascript-env-frontend">export default function() {
|
||||
return (
|
||||
<MyComponent />
|
||||
);
|
||||
}</code></pre>
|
||||
<ul>
|
||||
<li data-list-item-id="e9fdf8ed08c3577977dc48be1bc075f0e">
|
||||
<p><em>MyComponent</em>
|
||||
<br>Type: Code / JSX</p><pre><code class="language-application-javascript-env-frontend">export default function MyComponent() {
|
||||
return <p>Hi</p>;
|
||||
}</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Multiple components per note</h2>
|
||||
<p>To export multiple components, use the <code spellcheck="false">export</code> keyword
|
||||
next to each of the function components.</p>
|
||||
<p>Here's how a sub-note called <code spellcheck="false">MyComponents</code> would
|
||||
look like:</p><pre><code class="language-application-javascript-env-frontend">export function MyFirstComponent() {
|
||||
return <p>First</p>;
|
||||
}
|
||||
|
||||
export function MySecondComponent() {
|
||||
return <p>Bar</p>;
|
||||
}</code></pre>
|
||||
<p>Then in its parent note:</p><pre><code class="language-application-javascript-env-frontend">const { MyFirstComponent, MySecondComponent } = MyComponents;
|
||||
|
||||
export default function() {
|
||||
return (
|
||||
<>
|
||||
<MyFirstComponent />
|
||||
<MySecondComponent />
|
||||
</>
|
||||
);
|
||||
}</code></pre>
|
||||
<p>Alternatively, it's also possible to use the components directly without
|
||||
assigning them to a <code spellcheck="false">const</code> first:</p><pre><code class="language-application-javascript-env-frontend"><MyComponents.MyFirstComponent />
|
||||
<MyComponents.MySecondComponent /></code></pre>
|
||||
35
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Hooks.html
generated
vendored
Normal file
35
apps/server/src/assets/doc_notes/en/User Guide/User Guide/Scripting/Frontend Basics/Preact/Hooks.html
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
<h2>Standard Preact hooks</h2>
|
||||
<p>All standard Preact hooks are available as an import in <code spellcheck="false">trilium:api</code>.</p>
|
||||
<p>For example:</p><pre><code class="language-text-x-trilium-auto">import { useState } from "trilium:preact";
|
||||
const [ myState, setMyState ] = useState("Hi");</code></pre>
|
||||
<h2>Custom hooks</h2>
|
||||
<p>Trilium comes with a large set of custom hooks for Preact, all of which
|
||||
are also available to custom widgets and <a class="reference-link"
|
||||
href="#root/pOsGYCXsbNQG/KSZ04uQ2D1St/_help_HcABDtFCkbFN">Render Note</a>.</p>
|
||||
<h3><code spellcheck="false">useNoteContext</code></h3>
|
||||
<p>As a replacement to <a class="reference-link" href="#root/pOsGYCXsbNQG/CdNpE2pqjmI6/yIhgI5H7A2Sm/MgibgPcfeuGz/_help_GhurYZjh8e1V">Note context aware widget</a>,
|
||||
Preact exposes the current note context in the <code spellcheck="false">useNoteContext</code> hook:</p><pre><code class="language-text-x-trilium-auto">import { defineWidget, useNoteContext, useNoteProperty } from "trilium:preact";
|
||||
|
||||
export default defineWidget({
|
||||
parent: "note-detail-pane",
|
||||
position: 10,
|
||||
render: () => {
|
||||
const { note } = useNoteContext();
|
||||
const title = useNoteProperty(note, "title");
|
||||
return <span>Current note JSX: {title}</span>;
|
||||
}
|
||||
});</code></pre>
|
||||
<p>Note that the custom widget must be inside the content area (so note detail
|
||||
widget) for this to work properly, especially when dealing with splits.</p>
|
||||
<h3><code spellcheck="false">useActiveNoteContext</code></h3>
|
||||
<p><code spellcheck="false">useActiveNoteContext</code> is an alternative
|
||||
to <code spellcheck="false">useNoteContext</code> which works even if the
|
||||
widget is not within the note detail section and it automatically switches
|
||||
the note context as the user is navigating around between tabs and splits.</p>
|
||||
<h3><code spellcheck="false">useNoteProperty</code></h3>
|
||||
<p>This hook allows “listening” for changes to a particular property of a
|
||||
<code
|
||||
spellcheck="false">FNote</code>, such as the <code spellcheck="false">title</code> or
|
||||
<code
|
||||
spellcheck="false">type</code>of a note. The benefit from using the hook is that it actually
|
||||
reacts to changes, for example if the note title or type is changed.</p>
|
||||
@ -1,5 +1,5 @@
|
||||
# Documentation
|
||||
There are multiple types of documentation for Trilium:<img class="image-style-align-right" src="api/images/8sStlTtSCgN7/Documentation_image.png" width="205" height="162">
|
||||
There are multiple types of documentation for Trilium:<img class="image-style-align-right" src="api/images/nvEEQ1vvJMmS/Documentation_image.png" width="205" height="162">
|
||||
|
||||
* The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing <kbd>F1</kbd>.
|
||||
* The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers.
|
||||
|
||||
700
docs/User Guide/!!!meta.json
vendored
700
docs/User Guide/!!!meta.json
vendored
@ -3600,13 +3600,6 @@
|
||||
"isInheritable": false,
|
||||
"position": 170
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bx-layout",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
@ -3614,6 +3607,13 @@
|
||||
"isInheritable": false,
|
||||
"position": 180
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bx-layout",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
@ -15631,6 +15631,83 @@
|
||||
"value": "bx bxs-widget",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "oPVyFC7WL2Lp",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "RnaPdbciOfeq",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "xYmIYSP6wE3F",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "4Gn3psZKsfSm",
|
||||
"isInheritable": false,
|
||||
"position": 70
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "KLsqhjaqh1QW",
|
||||
"isInheritable": false,
|
||||
"position": 80
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "6f9hih2hXXZk",
|
||||
"isInheritable": false,
|
||||
"position": 90
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "HI6GBBIduIgv",
|
||||
"isInheritable": false,
|
||||
"position": 100
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "s8alTXmpFR61",
|
||||
"isInheritable": false,
|
||||
"position": 110
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "GhurYZjh8e1V",
|
||||
"isInheritable": false,
|
||||
"position": 120
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "M8IppdwVHSjG",
|
||||
"isInheritable": false,
|
||||
"position": 130
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "gMkgcLJ6jBkg",
|
||||
"isInheritable": false,
|
||||
"position": 140
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
@ -15638,6 +15715,127 @@
|
||||
"attachments": [],
|
||||
"dirFileName": "Custom Widgets",
|
||||
"children": [
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "SynTBQiBsdYJ",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"MgibgPcfeuGz",
|
||||
"SynTBQiBsdYJ"
|
||||
],
|
||||
"title": "Widget Basics",
|
||||
"notePosition": 10,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/markdown",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "zEY4DaJG4YT5",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "BFs8mudNFgCS",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "GLks18SNjxmC",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "s8alTXmpFR61",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
"value": "widget-basics",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "MgibgPcfeuGz",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"dataFileName": "Widget Basics.md",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "GhurYZjh8e1V",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"MgibgPcfeuGz",
|
||||
"GhurYZjh8e1V"
|
||||
],
|
||||
"title": "Note context aware widget",
|
||||
"notePosition": 20,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [],
|
||||
"format": "markdown",
|
||||
"dataFileName": "Note context aware widget.md",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "M8IppdwVHSjG",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"MgibgPcfeuGz",
|
||||
"M8IppdwVHSjG"
|
||||
],
|
||||
"title": "Right pane widget",
|
||||
"notePosition": 30,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "IjZS7iK5EXtb",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
"value": "right-pane-widget",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"dataFileName": "Right pane widget.md",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "YNxAqkI5Kg1M",
|
||||
@ -15649,7 +15847,7 @@
|
||||
"YNxAqkI5Kg1M"
|
||||
],
|
||||
"title": "Word count widget",
|
||||
"notePosition": 10,
|
||||
"notePosition": 40,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
@ -15697,99 +15895,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "SynTBQiBsdYJ",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"MgibgPcfeuGz",
|
||||
"SynTBQiBsdYJ"
|
||||
],
|
||||
"title": "Widget Basics",
|
||||
"notePosition": 20,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/markdown",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "zEY4DaJG4YT5",
|
||||
"isInheritable": false,
|
||||
"position": 10
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "BFs8mudNFgCS",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "GLks18SNjxmC",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "s8alTXmpFR61",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
"value": "widget-basics",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"dataFileName": "Widget Basics.md",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "M8IppdwVHSjG",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"MgibgPcfeuGz",
|
||||
"M8IppdwVHSjG"
|
||||
],
|
||||
"title": "Right pane widget",
|
||||
"notePosition": 30,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
"value": "right-pane-widget",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "IjZS7iK5EXtb",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"dataFileName": "Right pane widget.md",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "VqGQnnPGnqAU",
|
||||
@ -15801,7 +15906,7 @@
|
||||
"VqGQnnPGnqAU"
|
||||
],
|
||||
"title": "CSS",
|
||||
"notePosition": 40,
|
||||
"notePosition": 70,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
@ -15813,6 +15918,13 @@
|
||||
"value": "css",
|
||||
"isInheritable": false,
|
||||
"position": 20
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "Sg9GrCtyftZf",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
@ -15830,7 +15942,7 @@
|
||||
"gMkgcLJ6jBkg"
|
||||
],
|
||||
"title": "Troubleshooting",
|
||||
"notePosition": 50,
|
||||
"notePosition": 80,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
@ -16217,6 +16329,292 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "KLsqhjaqh1QW",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"KLsqhjaqh1QW"
|
||||
],
|
||||
"title": "Preact",
|
||||
"notePosition": 40,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bxl-react",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "MgibgPcfeuGz",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "HcABDtFCkbFN",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "wy8So3yZZlH9",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "GLks18SNjxmC",
|
||||
"isInheritable": false,
|
||||
"position": 70
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "Bqde6BvPo05g",
|
||||
"isInheritable": false,
|
||||
"position": 80
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"dataFileName": "Preact.md",
|
||||
"attachments": [],
|
||||
"dirFileName": "Preact",
|
||||
"children": [
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "Bqde6BvPo05g",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"KLsqhjaqh1QW",
|
||||
"Bqde6BvPo05g"
|
||||
],
|
||||
"title": "Component libraries",
|
||||
"notePosition": 10,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "hA834UaHhSNn",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "HcABDtFCkbFN",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bxs-component",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"dataFileName": "Component libraries.md",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "ykYtbM9k3a7B",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"KLsqhjaqh1QW",
|
||||
"ykYtbM9k3a7B"
|
||||
],
|
||||
"title": "Hooks",
|
||||
"notePosition": 20,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "HcABDtFCkbFN",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "GhurYZjh8e1V",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bx-question-mark",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"dataFileName": "Hooks.md",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "Sg9GrCtyftZf",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"KLsqhjaqh1QW",
|
||||
"Sg9GrCtyftZf"
|
||||
],
|
||||
"title": "CSS",
|
||||
"notePosition": 30,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "AlhDUqhENtH7",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bxs-file-css",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"dataFileName": "CSS.md",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "RSssb9S3xgSr",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"KLsqhjaqh1QW",
|
||||
"RSssb9S3xgSr"
|
||||
],
|
||||
"title": "Built-in components",
|
||||
"notePosition": 40,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bxs-component",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "MgibgPcfeuGz",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "HcABDtFCkbFN",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "i9B4IW7b6V6z",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "6tZeKvSHEUiB",
|
||||
"isInheritable": false,
|
||||
"position": 70
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"dataFileName": "Built-in components.md",
|
||||
"attachments": [
|
||||
{
|
||||
"attachmentId": "KtDChJYITDxC",
|
||||
"title": "image.png",
|
||||
"role": "image",
|
||||
"mime": "image/png",
|
||||
"position": 10,
|
||||
"dataFileName": "Built-in components_image.png"
|
||||
}
|
||||
],
|
||||
"dirFileName": "Built-in components",
|
||||
"children": [
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "i9B4IW7b6V6z",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"yIhgI5H7A2Sm",
|
||||
"KLsqhjaqh1QW",
|
||||
"RSssb9S3xgSr",
|
||||
"i9B4IW7b6V6z"
|
||||
],
|
||||
"title": "Widget showcase",
|
||||
"notePosition": 10,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "code",
|
||||
"mime": "text/jsx",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
"value": "widget-showcase",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
}
|
||||
],
|
||||
"dataFileName": "Widget showcase.jsx",
|
||||
"attachments": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -16340,6 +16738,98 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "wqXwKJl6VpNk",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"wqXwKJl6VpNk"
|
||||
],
|
||||
"title": "Common concepts",
|
||||
"notePosition": 40,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bxl-nodejs",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
"value": "common-concepts",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"attachments": [],
|
||||
"dirFileName": "Common concepts",
|
||||
"children": [
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "hA834UaHhSNn",
|
||||
"notePath": [
|
||||
"pOsGYCXsbNQG",
|
||||
"CdNpE2pqjmI6",
|
||||
"wqXwKJl6VpNk",
|
||||
"hA834UaHhSNn"
|
||||
],
|
||||
"title": "Script bundles",
|
||||
"notePosition": 10,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
"mime": "text/html",
|
||||
"attributes": [
|
||||
{
|
||||
"type": "label",
|
||||
"name": "iconClass",
|
||||
"value": "bx bx-package",
|
||||
"isInheritable": false,
|
||||
"position": 30
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "HcABDtFCkbFN",
|
||||
"isInheritable": false,
|
||||
"position": 40
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "6f9hih2hXXZk",
|
||||
"isInheritable": false,
|
||||
"position": 50
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "shareAlias",
|
||||
"value": "bundles",
|
||||
"isInheritable": false,
|
||||
"position": 60
|
||||
},
|
||||
{
|
||||
"type": "relation",
|
||||
"name": "internalLink",
|
||||
"value": "IakOLONlIfGI",
|
||||
"isInheritable": false,
|
||||
"position": 70
|
||||
}
|
||||
],
|
||||
"format": "markdown",
|
||||
"dataFileName": "Script bundles.md",
|
||||
"attachments": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"isClone": false,
|
||||
"noteId": "GLks18SNjxmC",
|
||||
@ -16349,7 +16839,7 @@
|
||||
"GLks18SNjxmC"
|
||||
],
|
||||
"title": "Script API",
|
||||
"notePosition": 100,
|
||||
"notePosition": 110,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
@ -16547,7 +17037,7 @@
|
||||
"vElnKeDNPSVl"
|
||||
],
|
||||
"title": "Logging",
|
||||
"notePosition": 110,
|
||||
"notePosition": 120,
|
||||
"prefix": null,
|
||||
"isExpanded": false,
|
||||
"type": "text",
|
||||
|
||||
@ -9,7 +9,7 @@ Render Note is used in <a class="reference-link" href="../Scripting.md">Scripti
|
||||
2. Create a <a class="reference-link" href="Render%20Note.md">Render Note</a>.
|
||||
3. Assign the `renderNote` [relation](../Advanced%20Usage/Attributes.md) to point at the previously created code note.
|
||||
|
||||
## Dynamic content
|
||||
## Legacy scripting using jQuery
|
||||
|
||||
A static HTML is generally not enough for <a class="reference-link" href="../Scripting.md">Scripting</a>. The next step is to automatically change parts of the note using JavaScript.
|
||||
|
||||
@ -34,6 +34,28 @@ Now create a render note at any place and set its `~renderNote` relation to poin
|
||||
> **Current date & time**
|
||||
> The current date & time is Sun Apr 06 2025 15:26:29 GMT+0300 (Eastern European Summer Time)
|
||||
|
||||
## Dynamic content using Preact & JSX
|
||||
|
||||
As a more modern alternative to jQuery, it's possible to use Preact & JSX to render pages. Since JSX is a superset of JavaScript, there's no need to provide a HTML anymore.
|
||||
|
||||
Here are the steps to creating a simple render note:
|
||||
|
||||
1. Create a note of type <a class="reference-link" href="Render%20Note.md">Render Note</a>.
|
||||
2. Create a child <a class="reference-link" href="Code.md">Code</a> note with JSX as the language.
|
||||
As an example, use the following content:
|
||||
|
||||
```jsx
|
||||
export default function() {
|
||||
return (
|
||||
<>
|
||||
<p>Hello world.</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
3. In the parent render note, define a `~renderNote` relation pointing to the newly created child.
|
||||
4. Refresh the render note and it should display a “Hello world” message.
|
||||
|
||||
## Refreshing the note
|
||||
|
||||
It's possible to refresh the note via:
|
||||
|
||||
48
docs/User Guide/User Guide/Scripting/Common concepts/Script bundles.md
vendored
Normal file
48
docs/User Guide/User Guide/Scripting/Common concepts/Script bundles.md
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
# Script bundles
|
||||
For both <a class="reference-link" href="../../Note%20Types/Render%20Note.md">Render Note</a> and more complicated scripts, it's generally useful to split the code into multiple <a class="reference-link" href="../../Note%20Types/Code.md">Code</a> notes.
|
||||
|
||||
When a script is run, the sub-children of the script being run (or the <a class="reference-link" href="../../Note%20Types/Render%20Note.md">Render Note</a>) are checked for children. If the children are Code notes of the corresponding type (front-end or backend) as the code being run, they will be evaluated as well.
|
||||
|
||||
The collection of a script and its child notes is called a _bundle_. A child note inside a bundle is called a _module_.
|
||||
|
||||
As a basic example of dependencies, consider the following note structure:
|
||||
|
||||
* _Script with dependency_
|
||||
|
||||
```javascript
|
||||
api.log(MyMath.sum(2, 2));
|
||||
```
|
||||
|
||||
* _MyMath_
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
sum(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
When _Script with dependency_ is run, it will detect _MyMath_ as a submodule and provide the result of its `module.exports` object into a global object with the same name as the note.
|
||||
|
||||
> [!NOTE]
|
||||
> If the note contains spaces or special characters, they will be stripped. For example `My Nice Note!` becomes `MyNiceNote`.
|
||||
|
||||
## Alternative syntax
|
||||
|
||||
Instead of providing an object to `module.exports`, it's also possible to add fields individually:
|
||||
|
||||
```javascript
|
||||
module.exports.sum = (a, b) => a + b;
|
||||
module.exports.subtract = (a, b) => a - b;
|
||||
```
|
||||
|
||||
## Ignoring a code script from a bundle
|
||||
|
||||
To ignore a script from being included in a bundle (e.g. if it's unrelated to the parent script note), apply the `#disableInclusion` label.
|
||||
|
||||
## Sharing a module across multiple bundles
|
||||
|
||||
Modules can be reused across multiple scripts by simply cloning the shared module between two modules (see <a class="reference-link" href="../../Basic%20Concepts%20and%20Features/Notes/Cloning%20Notes.md">Cloning Notes</a>).
|
||||
|
||||
Optionally, a separate note can be used to contain all the different reusable modules for an easy way to discover them.
|
||||
@ -1,9 +1,62 @@
|
||||
# Custom Widgets
|
||||
It's possible to create custom widget in three possible locations where you can display your custom content.
|
||||
Custom widgets are a special subset of scripts that render graphical elements in certain parts of the application. These can be used to add new functionality to the Trilium application.
|
||||
|
||||
Positions are:
|
||||
## Preact with JSX vs. vanilla jQuery
|
||||
|
||||
* `left-pane`
|
||||
* `center-pane`
|
||||
* `note-detail-pane` - located within `center-pane`, but specific to note (split)
|
||||
* `right-pane`
|
||||
In older versions of Trilium, custom widgets were exclusively written in a combination of jQuery with Trilium's internal widget architecture (e.g., `BasicWidget`, `NoteContextAwareWidget`).
|
||||
|
||||
Starting with v0.101.0, custom widgets can also be written in JSX using the <a class="reference-link" href="Preact.md">Preact</a> framework. Both legacy and Preact widgets have the same capabilities, with a single difference:
|
||||
|
||||
* Preact widgets are content-sized by default whereas legacy widgets need `this.contentSized()` applied in the constructor. For more information, see the corresponding section in <a class="reference-link" href="Custom%20Widgets/Troubleshooting.md">Troubleshooting</a>.
|
||||
|
||||
Wherever possible, widget examples will be both in the legacy and Preact format.
|
||||
|
||||
## Creating a custom widget
|
||||
|
||||
1. Create a <a class="reference-link" href="../../Note%20Types/Code.md">Code</a> note.
|
||||
2. Set the language to:
|
||||
1. JavaScript (frontend) for legacy widgets using jQuery.
|
||||
2. JSX for Preact widgets. You might need to go to Options → Code to enable the language first.
|
||||
3. Apply the `#widget` [label](../../Advanced%20Usage/Attributes/Labels.md).
|
||||
|
||||
## Getting started with a simple example
|
||||
|
||||
Let's start by creating a widget that shows a message near the content area. Follow the previous section to create a code note, and use the following content.
|
||||
|
||||
<table><thead><tr><th>Legacy</th><th style="width:50%;">Preact (v0.101.0+)</th></tr></thead><tbody><tr><td><pre><code class="language-text-x-trilium-auto">class HelloNoteDetail extends api.BasicWidget {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.contentSized();
|
||||
}
|
||||
|
||||
get parentWidget() { return "center-pane" }
|
||||
|
||||
doRender() {
|
||||
this.$widget = $("<span>Center pane</span>");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = new HelloNoteDetail();</code></pre></td><td style="vertical-align:top;"><pre><code class="language-text-x-trilium-auto">import { defineWidget } from "trilium:preact";
|
||||
|
||||
export default defineWidget({
|
||||
parent: "center-pane",
|
||||
render: () => <span>Center pane from Preact.</span>
|
||||
});</code></pre></td></tr></tbody></table>
|
||||
|
||||
[Refresh the application](../../Troubleshooting/Refreshing%20the%20application.md) and the widget should appear underneath the content area.
|
||||
|
||||
## Widget location (parent widget)
|
||||
|
||||
A widget can be placed in one of the following sections of the applications:
|
||||
|
||||
<table class="ck-table-resized"><colgroup><col style="width:15.59%;"><col style="width:30.42%;"><col style="width:16.68%;"><col style="width:37.31%;"></colgroup><thead><tr><th>Value for <code spellcheck="false">parentWidget</code></th><th>Description</th><th>Sample widget</th><th>Special requirements</th></tr></thead><tbody><tr><th><code spellcheck="false">left-pane</code></th><td>Appears within the same pane that holds the <a class="reference-link" href="../../Basic%20Concepts%20and%20Features/UI%20Elements/Note%20Tree.md">Note Tree</a>.</td><td>Same as above, with only a different <code spellcheck="false">parentWidget</code>.</td><td>None.</td></tr><tr><th><code spellcheck="false">center-pane</code></th><td>In the content area. If a split is open, the widget will span all of the splits.</td><td>See example above.</td><td>None.</td></tr><tr><th><code spellcheck="false">note-detail-pane</code></th><td><p>In the content area, inside the note detail area. If a split is open, the widget will be contained inside the split.</p><p>This is ideal if the widget is note-specific.</p></td><td><a class="reference-link" href="Custom%20Widgets/Note%20context%20aware%20widget.md">Note context aware widget</a></td><td><ul><li data-list-item-id="ec06332efcc3039721606c052f0d913fa">The widget must export a <code spellcheck="false">class</code> and not an instance of the class (e.g. <code spellcheck="false">no new</code>) because it needs to be multiplied for each note, so that splits work correctly.</li><li data-list-item-id="e8da690a2a8df148f6b5fc04ba1611688">Since the <code spellcheck="false">class</code> is exported instead of an instance, the <code spellcheck="false">parentWidget</code> getter must be <code spellcheck="false">static</code>, otherwise the widget is ignored.</li></ul></td></tr><tr><th><code spellcheck="false">right-pane</code></th><td>In the <a class="reference-link" href="../../Basic%20Concepts%20and%20Features/UI%20Elements/Right%20Sidebar.md">Right Sidebar</a>, as a dedicated section.</td><td><a class="reference-link" href="Custom%20Widgets/Right%20pane%20widget.md">Right pane widget</a></td><td><ul><li data-list-item-id="efe008d361e224f422582552648e1afe7">Although not mandatory, it's best to use a <code spellcheck="false">RightPanelWidget</code> instead of a <code spellcheck="false">BasicWidget</code> or a <code spellcheck="false">NoteContextAwareWidget</code>.</li></ul></td></tr></tbody></table>
|
||||
|
||||
To position the widget somewhere else, just change the value passed to `get parentWidget()` for legacy widgets or the `parent` field for Preact. Do note that some positions such as `note-detail-pane` and `right-pane` have special requirements that need to be accounted for (see the table above).
|
||||
|
||||
## Launch bar widgets
|
||||
|
||||
Launch bar widgets are similar to _Custom widgets_ but are specific to the <a class="reference-link" href="../../Basic%20Concepts%20and%20Features/UI%20Elements/Launch%20Bar.md">Launch Bar</a>. See <a class="reference-link" href="Launch%20Bar%20Widgets.md">Launch Bar Widgets</a> for more information.
|
||||
|
||||
## Custom position
|
||||
@ -1,5 +1,7 @@
|
||||
# CSS
|
||||
In `doRender()`:
|
||||
## Classic widgets
|
||||
|
||||
In `doRender()`:<sup><a href="#fn1saoftmefpp">[1]</a></sup>
|
||||
|
||||
```
|
||||
this.cssBlock(`#my-widget {
|
||||
@ -7,9 +9,13 @@ this.cssBlock(`#my-widget {
|
||||
bottom: 40px;
|
||||
left: 60px;
|
||||
z-index: 1;
|
||||
}`)
|
||||
}`);
|
||||
```
|
||||
|
||||
* * *
|
||||
## Preact widgets
|
||||
|
||||
Reference: [https://trilium.rocks/X7pxYpiu0lgU](https://trilium.rocks/X7pxYpiu0lgU)
|
||||
See the dedicated page: <a class="reference-link" href="../Preact/CSS.md">CSS</a>.
|
||||
|
||||
1. <sup><strong><a href="#fnref1saoftmefpp">^</a></strong></sup>
|
||||
|
||||
Reference: [https://trilium.rocks/X7pxYpiu0lgU](https://trilium.rocks/X7pxYpiu0lgU)
|
||||
53
docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Note context aware widget.md
vendored
Normal file
53
docs/User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Note context aware widget.md
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
# Note context aware widget
|
||||
Note context-aware widgets are a different type of widget which automatically react to changes in the current note.
|
||||
|
||||
Important aspects:
|
||||
|
||||
* The widget must export a `class` and not an instance of the class (e.g. `no new`) because it needs to be multiplied for each note, so that splits work correctly.
|
||||
* Since the `class` is exported instead of an instance, the `parentWidget` getter must be `static`, otherwise the widget is ignored.
|
||||
|
||||
## Example displaying the current note title
|
||||
|
||||
This is a note context-aware widget that simply displays the name the current note.
|
||||
|
||||
### Classic example
|
||||
|
||||
```
|
||||
class HelloNoteDetail extends api.NoteContextAwareWidget {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.contentSized();
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $("<div>");
|
||||
}
|
||||
|
||||
async refreshWithNote(note) {
|
||||
this.$widget.text("Current note: " + note.title);
|
||||
}
|
||||
|
||||
static get parentWidget() { return "note-detail-pane" }
|
||||
get position() { return 10 }
|
||||
|
||||
}
|
||||
|
||||
module.exports = HelloNoteDetail;
|
||||
```
|
||||
|
||||
### Preact (v0.101.0+)
|
||||
|
||||
```
|
||||
import { defineWidget, useNoteContext, useNoteProperty } from "trilium:preact";
|
||||
|
||||
export default defineWidget({
|
||||
parent: "note-detail-pane",
|
||||
position: 10,
|
||||
render: () => {
|
||||
const { note } = useNoteContext();
|
||||
const title = useNoteProperty(note, "title");
|
||||
return <span>Current note JSX: {title}</span>;
|
||||
}
|
||||
});
|
||||
```
|
||||
@ -40,6 +40,8 @@ module.exports = new NoteTitleWidget();
|
||||
|
||||
A simple widget which will show the current time, as an example on how to dynamically change the content of the widget periodically.
|
||||
|
||||
### Legacy widget
|
||||
|
||||
```
|
||||
const template = `<div></div>`;
|
||||
|
||||
@ -62,6 +64,31 @@ class ToDoListWidget extends api.RightPanelWidget {
|
||||
module.exports = new ToDoListWidget();
|
||||
```
|
||||
|
||||
### Preact widget
|
||||
|
||||
```
|
||||
import { defineWidget, RightPanelWidget, useEffect, useState } from "trilium:preact";
|
||||
|
||||
export default defineWidget({
|
||||
parent: "right-pane",
|
||||
position: 1,
|
||||
render() {
|
||||
const [ time, setTime ] = useState();
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setTime(new Date().toLocaleString());
|
||||
}, 1000);
|
||||
return () => clearInterval(interval);
|
||||
});
|
||||
return (
|
||||
<RightPanelWidget id="clock-jsx" title="Clock (JSX)">
|
||||
<p>The time is: {time}</p>
|
||||
</RightPanelWidget>
|
||||
);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Example for old layout
|
||||
|
||||
Here's a widget that displays a basic message ("Hi"):
|
||||
@ -105,7 +132,7 @@ By default, the sidebar items are displayed in the order they are found by the a
|
||||
|
||||
It is possible to make a widget appear higher or lower up, by adjusting its `position` property:
|
||||
|
||||
```diff
|
||||
```
|
||||
class MyWidget extends api.RightPanelWidget {
|
||||
|
||||
+ get position() { return 20 };
|
||||
|
||||
@ -108,11 +108,6 @@ class MyWidget extends api.BasicWidget {
|
||||
module.exports = new MyWidget();
|
||||
```
|
||||
|
||||
`parentWidget()` can be given the following values:
|
||||
|
||||
* `left-pane` - This renders the widget on the left side of the screen where the note tree lives.
|
||||
* `center-pane` - This renders the widget in the center of the layout in the same location that notes and splits appear.
|
||||
* `note-detail-pane` - This renders the widget _with_ the note in the center pane. This means it can appear multiple times with splits.
|
||||
* `right-pane` - This renders the widget to the right of any opened notes.
|
||||
For the list of possible values for `parentWidget()`, see <a class="reference-link" href="../Custom%20Widgets.md">Custom Widgets</a>.
|
||||
|
||||
[Reload](../../../Troubleshooting/Refreshing%20the%20application.md) the application one last time. When you click the button, a "Hello World!" message should appear, confirming that your widget is fully functional.
|
||||
@ -3,6 +3,8 @@
|
||||
|
||||
This is an example of a note context-aware widget, which reacts to the currently opened note and refreshes automatically as the user navigates through the notes.
|
||||
|
||||
## Legacy widget
|
||||
|
||||
In this example, the title of the note is displayed. It works best on the [horizontal layout](../../../Basic%20Concepts%20and%20Features/UI%20Elements/Vertical%20and%20horizontal%20layout.md).
|
||||
|
||||
```javascript
|
||||
@ -29,4 +31,24 @@ class NoteTitleWidget extends api.NoteContextAwareWidget {
|
||||
}
|
||||
|
||||
module.exports = new NoteTitleWidget();
|
||||
```
|
||||
|
||||
## Preact widget (v0.101.0+)
|
||||
|
||||
```jsx
|
||||
import { defineLauncherWidget, useActiveNoteContext } from "trilium:preact";
|
||||
|
||||
export default defineLauncherWidget({
|
||||
render: () => {
|
||||
const { note } = useActiveNoteContext();
|
||||
return <div style={{
|
||||
display: "flex",
|
||||
height: "53px",
|
||||
width: "fit-content",
|
||||
fontSize: "0.75em",
|
||||
alignItems: "center",
|
||||
flexShrink: 0
|
||||
}}>{note?.title}</div>;
|
||||
}
|
||||
});
|
||||
```
|
||||
65
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact.md
vendored
Normal file
65
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact.md
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
# Preact
|
||||
Since v0.101.0, Trilium integrates Preact for front-end scripting, including support for JSX.
|
||||
|
||||
Preact can be used for:
|
||||
|
||||
* <a class="reference-link" href="../../Note%20Types/Render%20Note.md">Render Note</a>, where a JSX code note is used instead of a HTML one.
|
||||
* <a class="reference-link" href="Custom%20Widgets.md">Custom Widgets</a>, where JSX can be used to replace the old, jQuery-based mechanism.
|
||||
|
||||
To get started, the first step is to enable JSX in the list of Code languages. Go to Options → Code Notes and check the “JSX” language. Afterwards, proceed with the documentation in either <a class="reference-link" href="../../Note%20Types/Render%20Note.md">Render Note</a> or <a class="reference-link" href="Custom%20Widgets.md">Custom Widgets</a>, which will both have a section on how to use the new Preact integration.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The documentation assumes prior knowledge with React or Preact. As a starting point, consider the [FreeCodeCamp course on Front End Development Libraries](https://www.freecodecamp.org/learn/front-end-development-libraries-v9/) or the [Preact Tutorial](https://preactjs.com/tutorial/).
|
||||
|
||||
## Import/exports
|
||||
|
||||
When using Preact with JSX, there is a special syntax which provides ES-like imports. This `import` syntax makes way for a more intuitive that doesn't make use of global objects and paves the way for better auto-completion support that might be introduced in the future.
|
||||
|
||||
### API imports
|
||||
|
||||
Instead of:
|
||||
|
||||
```jsx
|
||||
api.showMessage("Hello");
|
||||
```
|
||||
|
||||
the JSX version looks like this:
|
||||
|
||||
```jsx
|
||||
import { showMessage } from "trilium:api";
|
||||
showMessage("hello");
|
||||
```
|
||||
|
||||
### Preact API imports (hooks, components)
|
||||
|
||||
There's a new <a class="reference-link" href="../Script%20API.md">Script API</a> dedicated to Preact, which provides shared components that are also used by Trilium internally as well as hooks, for example.
|
||||
|
||||
```jsx
|
||||
import { useState } from "trilium:preact";
|
||||
const [ myState, setMyState ] = useState("Hi");
|
||||
```
|
||||
|
||||
### Exporting
|
||||
|
||||
JSX notes can export a component for use in <a class="reference-link" href="../../Note%20Types/Render%20Note.md">Render Note</a> or for <a class="reference-link" href="Preact/Component%20libraries.md">Component libraries</a>:
|
||||
|
||||
```jsx
|
||||
export default function() {
|
||||
return (
|
||||
<>
|
||||
<p>Hello world.</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Import/export are not required
|
||||
|
||||
These imports are syntactic sugar meant to replace the usage for the `api` global object (see <a class="reference-link" href="../Script%20API.md">Script API</a>).
|
||||
|
||||
> [!NOTE]
|
||||
> The `import` and `export` syntax work only for JSX notes. Standard/jQuery code notes still need to use the `api` global and `module.exports`.
|
||||
|
||||
## Under the hood
|
||||
|
||||
Unlike JavaScript, JSX requires pre-processing to turn it into JavaScript (just like TypeScript). To do so, Trilium uses [Sucrase](https://github.com/alangpierce/sucrase), a JavaScript library which processes the JSX to pure JavaScript. The processing is done each time a script is run (for widgets this happens at every program startup). If you notice any performance degradation due to long compilation, consider [reporting the issue](../../Troubleshooting/Reporting%20issues.md) to us.
|
||||
43
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components.md
vendored
Normal file
43
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components.md
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
# Built-in components
|
||||
<figure class="image image_resized" style="width:54.58%;"><img style="aspect-ratio:896/712;" src="Built-in components_image.png" width="896" height="712"><figcaption>A partial screenshot from the Widget showcase example (see below).</figcaption></figure>
|
||||
|
||||
Trilium comes with its own set of Preact components, some of which are also available to <a class="reference-link" href="../Custom%20Widgets.md">Custom Widgets</a> and <a class="reference-link" href="../../../Note%20Types/Render%20Note.md">Render Note</a>.
|
||||
|
||||
To use these components, simply import them from `trilium:preact`:
|
||||
|
||||
```jsx
|
||||
import { ActionButton, Button, LinkButton } from "trilium:preact";
|
||||
```
|
||||
|
||||
and then use them:
|
||||
|
||||
```jsx
|
||||
export default function MyRenderNote() {
|
||||
const onClick = () => showMessage("A button was pressed");
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Buttons</h2>
|
||||
<div style={{ display: "flex", gap: "1em", alignItems: "center" }}>
|
||||
<ActionButton icon="bx bx-rocket" text="Action button" onClick={onClick} />
|
||||
<Button icon="bx bx-rocket" text="Simple button" onClick={onClick} />
|
||||
<LinkButton text="Link button" onClick={onClick} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Widget showcase
|
||||
|
||||
> [!TIP]
|
||||
> Starting with v0.101.0, the widget showcase is also available in the <a class="reference-link" href="../../../Advanced%20Usage/Database/Demo%20Notes.md">Demo Notes</a>.
|
||||
|
||||
This is a <a class="reference-link" href="../../../Note%20Types/Render%20Note.md">Render Note</a> example with JSX that shows most of the built-in components that are accessible to custom widgets and JSX render notes.
|
||||
|
||||
To use it, simply:
|
||||
|
||||
1. Create a render note.
|
||||
2. Create a child code note of JSX type with the content of this file: <a class="reference-link" href="Built-in%20components/Widget%20showcase.jsx">Widget showcase</a>
|
||||
3. Set the `~renderNote` relation of the parent note to the child note.
|
||||
4. Refresh the render note to see the results.
|
||||
189
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components/Widget showcase.jsx
vendored
Normal file
189
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components/Widget showcase.jsx
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
import {
|
||||
ActionButton, Button, LinkButton,
|
||||
Admonition, Collapsible,
|
||||
FormCheckbox, FormDropdownList, FormFileUploadButton, FormGroup, FormRadioGroup, FormTextArea,
|
||||
FormTextBox, FormToggle, Slider, RawHtml, LoadingSpinner, Icon,
|
||||
Dropdown, FormListItem, FormDropdownDivider, FormDropdownSubmenu,
|
||||
NoteAutocomplete, NoteLink, Modal,
|
||||
CKEditor,
|
||||
useEffect, useState
|
||||
} from "trilium:preact";
|
||||
import { showMessage } from "trilium:api";
|
||||
|
||||
export default function() {
|
||||
const [ time, setTime ] = useState();
|
||||
const lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam accumsan eu odio non gravida. Pellentesque ornare, arcu condimentum molestie dignissim, nibh turpis ultrices elit, eget elementum nunc erat at erat. Maecenas vehicula consectetur elit, nec fermentum elit venenatis eu.";
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => setTime(new Date().toLocaleString()), 1000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div style={{ padding: 20, display: "flex", flexDirection: "column", gap: "1em" }}>
|
||||
<h1>Widget showcase</h1>
|
||||
|
||||
<Buttons />
|
||||
<Admonition type="note">
|
||||
<strong>Admonition</strong><br />
|
||||
{lorem}
|
||||
</Admonition>
|
||||
|
||||
<Collapsible title="Collapsible" initiallyExpanded>
|
||||
{lorem}
|
||||
</Collapsible>
|
||||
|
||||
<FormElements />
|
||||
<NoteElements />
|
||||
<ModalSample />
|
||||
<DropdownSample />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Buttons() {
|
||||
const onClick = () => showMessage("A button was pressed");
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Buttons</h2>
|
||||
<div style={{ display: "flex", gap: "1em", alignItems: "center" }}>
|
||||
<ActionButton icon="bx bx-rocket" text="Action button" onClick={onClick} />
|
||||
<Button icon="bx bx-rocket" text="Simple button" onClick={onClick} />
|
||||
<LinkButton text="Link button" onClick={onClick} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function FormElements() {
|
||||
const [ checkboxChecked, setCheckboxChecked ] = useState(false);
|
||||
const [ dropdownValue, setDropdownValue ] = useState("key-1");
|
||||
const [ radioGroupValue, setRadioGroupValue ] = useState("key-1");
|
||||
const [ sliderValue, setSliderValue ] = useState(50);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Form elements</h2>
|
||||
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: "1em" }}>
|
||||
<FormGroup name="checkbox" label="Checkbox">
|
||||
<FormCheckbox label="Checkbox" currentValue={checkboxChecked} onChange={setCheckboxChecked} />
|
||||
</FormGroup>
|
||||
<FormGroup name="toggle" label="Toggle">
|
||||
<FormToggle switchOnName="Off" switchOffName="On" currentValue={checkboxChecked} onChange={setCheckboxChecked} />
|
||||
</FormGroup>
|
||||
<FormGroup name="dropdown" label="Dropdown">
|
||||
<FormDropdownList
|
||||
values={[
|
||||
{ key: "key-1", name: "First item" },
|
||||
{ key: "key-2", name: "Second item" },
|
||||
{ key: "key-3", name: "Third item" },
|
||||
]}
|
||||
currentValue={dropdownValue} onChange={setDropdownValue}
|
||||
keyProperty="key" titleProperty="name"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="radio-group" label="Radio group">
|
||||
<FormRadioGroup
|
||||
values={[
|
||||
{ value: "key-1", label: "First item" },
|
||||
{ value: "key-2", label: "Second item" },
|
||||
{ value: "key-3", label: "Third item" },
|
||||
]}
|
||||
currentValue={radioGroupValue} onChange={setRadioGroupValue}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="text-box" label="Text box">
|
||||
<FormTextBox
|
||||
placeholder="Type something..."
|
||||
currentValue="" onChange={(newValue) => {}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="text-area" label="Text area">
|
||||
<FormTextArea
|
||||
placeholder="Type something bigger..."
|
||||
currentValue="" onChange={(newValue) => {}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="slider" label="Slider">
|
||||
<Slider
|
||||
min={1} max={100}
|
||||
value={sliderValue} onChange={setSliderValue}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="file-upload" label="File upload">
|
||||
<FormFileUploadButton
|
||||
text="Upload"
|
||||
onChange={(files) => {
|
||||
const file = files?.[0];
|
||||
if (!file) return;
|
||||
showMessage(`Got file "${file.name}" of size ${file.size} B and type ${file.type}.`);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup name="icon" label="Icon">
|
||||
<Icon icon="bx bx-smile" />
|
||||
</FormGroup>
|
||||
<FormGroup name="loading-spinner" label="Loading spinner">
|
||||
<LoadingSpinner />
|
||||
</FormGroup>
|
||||
<FormGroup name="raw-html" label="Raw HTML">
|
||||
<RawHtml html="<strong>Hi</strong> <em>there</em>" />
|
||||
</FormGroup>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function NoteElements() {
|
||||
const [ noteId, setNoteId ] = useState("");
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>Note elements</h2>
|
||||
|
||||
<FormGroup name="note-autocomplete" label="Note autocomplete">
|
||||
<NoteAutocomplete
|
||||
placeholder="Select a note"
|
||||
noteId={noteId} noteIdChanged={setNoteId}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup name="note-link" label="Note link">
|
||||
{noteId
|
||||
? <NoteLink notePath={noteId} showNoteIcon />
|
||||
: <span>Select a note first</span>}
|
||||
</FormGroup>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ModalSample() {
|
||||
const [ shown, setShown ] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Modal</h2>
|
||||
<Button text="Open modal" onClick={() => setShown(true)} />
|
||||
<Modal title="Modal title" size="md" show={shown} onHidden={() => setShown(false)}>
|
||||
Modal goes here.
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function DropdownSample() {
|
||||
return (
|
||||
<>
|
||||
<h2>Dropdown menu</h2>
|
||||
<Dropdown text="Dropdown" hideToggleArrow>
|
||||
<FormListItem icon="bx bx-cut">Cut</FormListItem>
|
||||
<FormListItem icon="bx bx-copy">Copy</FormListItem>
|
||||
<FormListItem icon="bx bx-paste">Paste</FormListItem>
|
||||
<FormDropdownDivider />
|
||||
<FormDropdownSubmenu title="Submenu">
|
||||
<FormListItem>More items</FormListItem>
|
||||
</FormDropdownSubmenu>
|
||||
</Dropdown>
|
||||
</>
|
||||
)
|
||||
}
|
||||
BIN
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components_image.png
vendored
Normal file
BIN
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components_image.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
17
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/CSS.md
vendored
Normal file
17
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/CSS.md
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# CSS
|
||||
## Inline styles
|
||||
|
||||
```jsx
|
||||
<div style={{
|
||||
display: "flex",
|
||||
height: "53px",
|
||||
width: "fit-content",
|
||||
fontSize: "0.75em",
|
||||
alignItems: "center",
|
||||
flexShrink: 0
|
||||
}}>/* [...] */</div>
|
||||
```
|
||||
|
||||
## Custom CSS file
|
||||
|
||||
Simply create a <a class="reference-link" href="../../../Theme%20development/Custom%20app-wide%20CSS.md">Custom app-wide CSS</a>. Make sure the class names are unique enough to not intersect with other UI elements, consider adding a prefix (e.g. `x-mywidget-`).
|
||||
69
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Component libraries.md
vendored
Normal file
69
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Component libraries.md
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
# Component libraries
|
||||
Using the concept of <a class="reference-link" href="../../Common%20concepts/Script%20bundles.md">Script bundles</a>, it's possible to create components that are shared for multiple widgets or <a class="reference-link" href="../../../Note%20Types/Render%20Note.md">Render Note</a>.
|
||||
|
||||
## Exporting a single component
|
||||
|
||||
This is generally useful for big components.
|
||||
|
||||
Here's an example child hierarchy using <a class="reference-link" href="../../../Note%20Types/Render%20Note.md">Render Note</a>:
|
||||
|
||||
* _My render note_
|
||||
Note type: Render Note
|
||||
Link `~renderNote` to the child note (_Render note with subcomponents_)
|
||||
* _Render note with subcomponents_
|
||||
Type: JSX
|
||||
|
||||
```javascript
|
||||
export default function() {
|
||||
return (
|
||||
<MyComponent />
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
* _MyComponent_
|
||||
Type: Code / JSX
|
||||
|
||||
```javascript
|
||||
export default function MyComponent() {
|
||||
return <p>Hi</p>;
|
||||
}
|
||||
```
|
||||
|
||||
## Multiple components per note
|
||||
|
||||
To export multiple components, use the `export` keyword next to each of the function components.
|
||||
|
||||
Here's how a sub-note called `MyComponents` would look like:
|
||||
|
||||
```javascript
|
||||
export function MyFirstComponent() {
|
||||
return <p>First</p>;
|
||||
}
|
||||
|
||||
export function MySecondComponent() {
|
||||
return <p>Bar</p>;
|
||||
}
|
||||
```
|
||||
|
||||
Then in its parent note:
|
||||
|
||||
```javascript
|
||||
const { MyFirstComponent, MySecondComponent } = MyComponents;
|
||||
|
||||
export default function() {
|
||||
return (
|
||||
<>
|
||||
<MyFirstComponent />
|
||||
<MySecondComponent />
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, it's also possible to use the components directly without assigning them to a `const` first:
|
||||
|
||||
```javascript
|
||||
<MyComponents.MyFirstComponent />
|
||||
<MyComponents.MySecondComponent />
|
||||
```
|
||||
43
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Hooks.md
vendored
Normal file
43
docs/User Guide/User Guide/Scripting/Frontend Basics/Preact/Hooks.md
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
# Hooks
|
||||
## Standard Preact hooks
|
||||
|
||||
All standard Preact hooks are available as an import in `trilium:api`.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
import { useState } from "trilium:preact";
|
||||
const [ myState, setMyState ] = useState("Hi");
|
||||
```
|
||||
|
||||
## Custom hooks
|
||||
|
||||
Trilium comes with a large set of custom hooks for Preact, all of which are also available to custom widgets and <a class="reference-link" href="../../../Note%20Types/Render%20Note.md">Render Note</a>.
|
||||
|
||||
### `useNoteContext`
|
||||
|
||||
As a replacement to <a class="reference-link" href="../Custom%20Widgets/Note%20context%20aware%20widget.md">Note context aware widget</a>, Preact exposes the current note context in the `useNoteContext` hook:
|
||||
|
||||
```
|
||||
import { defineWidget, useNoteContext, useNoteProperty } from "trilium:preact";
|
||||
|
||||
export default defineWidget({
|
||||
parent: "note-detail-pane",
|
||||
position: 10,
|
||||
render: () => {
|
||||
const { note } = useNoteContext();
|
||||
const title = useNoteProperty(note, "title");
|
||||
return <span>Current note JSX: {title}</span>;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Note that the custom widget must be inside the content area (so note detail widget) for this to work properly, especially when dealing with splits.
|
||||
|
||||
### `useActiveNoteContext`
|
||||
|
||||
`useActiveNoteContext` is an alternative to `useNoteContext` which works even if the widget is not within the note detail section and it automatically switches the note context as the user is navigating around between tabs and splits.
|
||||
|
||||
### `useNoteProperty`
|
||||
|
||||
This hook allows “listening” for changes to a particular property of a `FNote`, such as the `title` or `type` of a note. The benefit from using the hook is that it actually reacts to changes, for example if the note title or type is changed.
|
||||
Loading…
x
Reference in New Issue
Block a user