ソースを参照

Refactor breadcrumb and vector map components, add clipboard functionality (#2378)

Co-authored-by: ethancrawford <[email protected]>
Paweł Kuna 4 ヶ月 前
コミット
72a1d67709

+ 5 - 0
.changeset/lovely-trees-divide.md

@@ -0,0 +1,5 @@
+---
+"@tabler/core": patch
+---
+
+Add clipboard functionality to Tabler documentation

+ 1 - 1
core/scss/ui/_markdown.scss

@@ -47,7 +47,7 @@ Markdown
     border: 1px solid var(--#{$prefix}border-color);
   }
 
-  > pre {
+  pre {
     max-height: 20rem;
   }
 }

+ 119 - 46
docs/content/ui/components/badges.md

@@ -10,50 +10,56 @@ bootstrapLink: components/badge/
 The default badges are square and come in the basic set of colors.
 
 {% capture html -%}
-<span class="badge bg-blue-lt">Blue</span>
-<span class="badge bg-azure-lt">Azure</span>
-<span class="badge bg-indigo-lt">Indigo</span>
-<span class="badge bg-purple-lt">Purple</span>
-<span class="badge bg-pink-lt">Pink</span>
-<span class="badge bg-red-lt">Red</span>
-<span class="badge bg-orange-lt">Orange</span>
-<span class="badge bg-yellow-lt">Yellow</span>
-<span class="badge bg-lime-lt">Lime</span>
-<span class="badge bg-green-lt">Green</span>
-<span class="badge bg-teal-lt">Teal</span>
-<span class="badge bg-cyan-lt">Cyan</span>
+<div class="badges-list">
+{% for color in site.colors -%}
+{% include "ui/badge.html" color=color[0] text=color[1].title %}
+{%- endfor -%}
+</div>
 {%- endcapture %}
 {% include "docs/example.html" html=html centered %}
 
 ## Headings
 
+Badges can be used in headings to draw attention to new or important information. You can use them in any heading level, from `<h1>` to `<h6>`. The example below shows how to use badges in headings.
+
 {% capture html -%}
-<h1>Example heading <span class="badge">New</span></h1>
-<h2>Example heading <span class="badge">New</span></h2>
-<h3>Example heading <span class="badge">New</span></h3>
-<h4>Example heading <span class="badge">New</span></h4>
-<h5>Example heading <span class="badge">New</span></h5>
-<h6>Example heading <span class="badge">New</span></h6>
+<h1>
+  Example heading 
+  {% include "ui/badge.html" text="New" -%}
+</h1>
+<h2>
+  Example heading 
+  {% include "ui/badge.html" text="New" -%}
+</h2>
+<h3>
+  Example heading 
+  {% include "ui/badge.html" text="New" -%}
+</h3>
+<h4>
+  Example heading 
+  {% include "ui/badge.html" text="New" -%}
+</h4>
+<h5>
+  Example heading 
+  {% include "ui/badge.html" text="New" -%}
+</h5>
+<h6>
+  Example heading 
+  {% include "ui/badge.html" text="New" -%}
+</h6>
 {%- endcapture %}
 {% include "docs/example.html" html=html %}
 
-## Outline badges
+## Light versions of badges
 
+You can use the `-lt` classes to create a light version of the badge. This is useful for creating a more subtle look.
 
+For example you can use the `bg-blue-lt` class to create a light blue badge. If you add the `text-blue-lt-fg` class, the text will be blue as well.
 
 {% capture html -%}
-<span class="badge badge-outline text-blue">blue</span>
-<span class="badge badge-outline text-azure">azure</span>
-<span class="badge badge-outline text-indigo">indigo</span>
-<span class="badge badge-outline text-purple">purple</span>
-<span class="badge badge-outline text-pink">pink</span>
-<span class="badge badge-outline text-red">red</span>
-<span class="badge badge-outline text-orange">orange</span>
-<span class="badge badge-outline text-yellow">yellow</span>
-<span class="badge badge-outline text-lime">lime</span>
-<span class="badge badge-outline text-green">green</span>
-<span class="badge badge-outline text-teal">teal</span>
-<span class="badge badge-outline text-cyan">cyan</span>
+{%- for color in site.colors -%}
+{% include "ui/badge.html" color=color[0] text=color[1].title light %}
+{%- endfor -%}
 {%- endcapture %}
 {% include "docs/example.html" html=html centered %}
 
@@ -62,18 +68,44 @@ The default badges are square and come in the basic set of colors.
 Use the `.badge-pill` class if you want to create a badge with rounded corners. Its width will adjust to the label text.
 
 {% capture html -%}
-<span class="badge badge-pill bg-blue-lt">1</span>
-<span class="badge badge-pill bg-azure-lt">2</span>
-<span class="badge badge-pill bg-indigo-lt">3</span>
-<span class="badge badge-pill bg-purple-lt">4</span>
-<span class="badge badge-pill bg-pink-lt">5</span>
-<span class="badge badge-pill bg-red-lt">6</span>
-<span class="badge badge-pill bg-orange-lt">7</span>
-<span class="badge badge-pill bg-yellow-lt">8</span>
-<span class="badge badge-pill bg-lime-lt">9</span>
-<span class="badge badge-pill bg-green-lt">10</span>
-<span class="badge badge-pill bg-teal-lt">11</span>
-<span class="badge badge-pill bg-cyan-lt">12</span>
+{%- for color in site.colors -%}
+{% include "ui/badge.html" color=color[0] text=color[1].title class="badge-pill" %}
+{%- endfor -%}
+{%- endcapture %}
+{% include "docs/example.html" html=html centered %}
+
+You can use it to create a pill with numbers, for example, to show the number of unread messages. The badge will adjust its width to the number of digits.
+
+{% capture html -%}
+{%- for color in site.colors -%}
+{% include "ui/badge.html" color=color[0] text=forloop.index class="badge-pill" %}
+{%- endfor -%}
+{%- endcapture %}
+{% include "docs/example.html" html=html centered %}
+
+## Badges with icons
+
+You can use icons in badges to make them more visually appealing. The example below demonstrates how to use icons in badges.
+
+{% capture html -%}
+{% include "ui/badge.html" text="Star" icon="star" -%}
+{% include "ui/badge.html" text="Heart" icon="heart" -%}
+{% include "ui/badge.html" text="Check" icon="check" -%}
+{% include "ui/badge.html" text="X" icon="x" -%}
+{% include "ui/badge.html" text="Plus" icon="plus" -%}
+{% include "ui/badge.html" text="Minus" icon="minus" -%}
+{%- endcapture %}
+{% include "docs/example.html" html=html centered %}
+
+You can also use an icon on the right side of the badge. The example below demonstrates how to use icons on the right side of badges.
+
+{% capture html -%}
+{% include "ui/badge.html" text="Star" icon-right="arrow-right" -%}
+{% include "ui/badge.html" text="Heart" icon-right="arrow-right" -%}
+{% include "ui/badge.html" text="Check" icon-right="arrow-right" -%}
+{% include "ui/badge.html" text="X" icon-right="arrow-right" -%}
+{% include "ui/badge.html" text="Plus" icon-right="arrow-right" -%}
+{% include "ui/badge.html" text="Minus" icon-right="arrow-right" -%}
 {%- endcapture %}
 {% include "docs/example.html" html=html centered %}
 
@@ -99,14 +131,55 @@ Place the badge within an `<a>` element if you want it to perform the function o
 
 ## Button with badge
 
-Badges can be used as part of links or buttons to provide, for example, a counter.
+Badges can be used as parts of links or buttons to provide, for example, a counter. Use the `.badge-notification` class to create a notification badge. This class will position the badge in the top right corner of the button.
+
+If you don't provide text for the badge, you end up with a small dot. This is useful for creating a simple notification button.
 
 {% capture html -%}
 <button type="button" class="btn">
-	Notifications <span class="badge bg-red-lt ms-2">4</span>
+	Notifications {% include "ui/badge.html" text="2" color="red" class="ms-2" -%}
 </button>
 <button type="button" class="btn">
-  Notifications <span class="badge bg-green-lt ms-2">4</span>
+  Inbox {% include "ui/badge.html" text="4" color="red" class="badge-notification" -%}
+</button>
+<button type="button" class="btn">
+  Profile {% include "ui/badge.html" text="" color="red" class="badge-notification" -%}
 </button>
 {%- endcapture %}
 {% include "docs/example.html" html=html centered %}
+
+## Animated badges
+
+You can use the `.badge-blink` class to create a blinking effect. This class will add a CSS animation to the badge, so it will blink to draw attention.
+
+{% capture html -%}
+<button type="button" class="btn">
+  Profile {% include "ui/badge.html" text="" color="red" class="badge-notification badge-blink" -%}
+</button>
+{% endcapture %}
+{% include "docs/example.html" html=html centered %}
+
+## Size Options
+
+Use `.badge-sm` or `.badge-lg` to change badge size according to your needs. The default size is `.badge` and it is used in the examples above.
+
+{% capture html -%}
+<div>
+  {% include "ui/badge.html" color="primary" scale="sm" text="New" class="badge-sm" -%}
+  {% include "ui/badge.html" color="primary" scale="sm" text="1" class="badge-pill" -%}
+</div>
+<div>
+  {% include "ui/badge.html" color="primary" text="New" class="badge-sm" -%}
+  {% include "ui/badge.html" color="primary" text="1" class="badge-pill" -%}
+</div>
+<div>
+  {% include "ui/badge.html" color="primary" scale="lg" text="New" class="badge-sm" -%}
+  {% include "ui/badge.html" color="primary" scale="lg" text="1" class="badge-pill" -%}
+</div>
+{%- endcapture %}
+{% include "docs/example.html" html=html centered vertical %}
+
+
+## More examples 
+
+If you want to see more examples of badges, you can check out the [Bootstrap documentation](https://getbootstrap.com/docs/5.3/components/badge/) for badges. You can also find more examples in the Tabler [Badges](https://preview.tabler.io/badges.html) preview.

+ 11 - 90
docs/content/ui/components/breadcrumb.md

@@ -12,19 +12,9 @@ Use the `breadcrumb` class to add a breadcrumb to your interface design for bett
 Look at the example below to see how breadcrumbs work in practice.
 
 {% capture html -%}
-<ol class="breadcrumb">
-  <li class="breadcrumb-item">
-    <a href="#">Home</a>
-  </li>
-  <li class="breadcrumb-item">
-    <a href="#">Library</a>
-  </li>
-  <li class="breadcrumb-item active">
-    <a href="#">Data</a>
-  </li>
-</ol>
+{% include "ui/breadcrumb.html" pages="Home,Library,Data" %}
 {%- endcapture %}
-{% include "docs/example.html" html=html vertical separated %}
+{% include "docs/example.html" html=html centered %}
 
 ## Different separators
 
@@ -33,60 +23,18 @@ You can use different breadcrumb styles to match your website or app design. Cho
 This example shows how to use different breadcrumb styles.
 
 {% capture html -%}
-<ol class="breadcrumb breadcrumb-dots">
-  <li class="breadcrumb-item">
-    <a href="#">Home</a>
-  </li>
-  <li class="breadcrumb-item">
-    <a href="#">Library</a>
-  </li>
-  <li class="breadcrumb-item active">
-    <a href="#">Data</a>
-  </li>
-</ol>
-<ol class="breadcrumb breadcrumb-arrows">
-  <li class="breadcrumb-item">
-    <a href="#">Home</a>
-  </li>
-  <li class="breadcrumb-item">
-    <a href="#">Library</a>
-  </li>
-  <li class="breadcrumb-item active">
-    <a href="#">Data</a>
-  </li>
-</ol>
-<ol class="breadcrumb breadcrumb-bullets">
-  <li class="breadcrumb-item">
-    <a href="#">Home</a>
-  </li>
-  <li class="breadcrumb-item">
-    <a href="#">Library</a>
-  </li>
-  <li class="breadcrumb-item active">
-    <a href="#">Data</a>
-  </li>
-</ol>
+{% include "ui/breadcrumb.html" pages="Home,Library,Data" separator="dots" %}
+{% include "ui/breadcrumb.html" pages="Home,Library,Data" separator="arrows" %}
+{% include "ui/breadcrumb.html" pages="Home,Library,Data" separator="bullets" %}
 {%- endcapture %}
-{% include "docs/example.html" html=html vertical separated %}
+{% include "docs/example.html" html=html vertical separated centered %}
 
 ## With icon
 
 You can use icons in breadcrumbs to make them more visually appealing. The example below demonstrates how to use icons in breadcrumbs.
 
 {% capture html -%}
-<ol class="breadcrumb">
-  <li class="breadcrumb-item">
-    <a href="#">
-	 	{% include "ui/icon.html" icon="home" %}
-    </a>
-  </li>
-  <li class="breadcrumb-item">
-    <a href="#">Library</a>
-  </li>
-  <li class="breadcrumb-item active">
-    <a href="#">Data</a>
-  </li>
-</ol>
+{% include "ui/breadcrumb.html" pages="Home,Library,Data" home-icon %}
 {%- endcapture %}
 {% include "docs/example.html" html=html vertical separated %}
 
@@ -95,19 +43,7 @@ You can use icons in breadcrumbs to make them more visually appealing. The examp
 You can use the `breadcrumb-muted` class to create a muted breadcrumb style. This style is perfect for breadcrumbs that are not the main focus of your website or app.
 
 {% capture html -%}
-<nav aria-label="breadcrumb">
-  <ol class="breadcrumb breadcrumb-muted">
-    <li class="breadcrumb-item">
-      <a href="#">Home</a>
-    </li>
-    <li class="breadcrumb-item">
-      <a href="#">Library</a>
-    </li>
-    <li class="breadcrumb-item active">
-      <a href="#">Data</a>
-    </li>
-  </ol>
-</nav>
+{% include "ui/breadcrumb.html" pages="Home,Library,Data" class="breadcrumb-muted" %}
 {%- endcapture %}
 {% include "docs/example.html" html=html %}
 
@@ -119,24 +55,9 @@ You can use breadcrumbs in headers to show the current page location and provide
 <div class="page-header">
   <div class="row align-items-center mw-100">
     <div class="col">
-      <div class="mb-1">
-        <ol class="breadcrumb">
-          <li class="breadcrumb-item">
-            <a href="#">Home</a>
-          </li>
-          <li class="breadcrumb-item">
-            <a href="#">Library</a>
-          </li>
-          <li class="breadcrumb-item active">
-            <a href="#">Articles</a>
-          </li>
-        </ol>
-      </div>
+		{% include "ui/breadcrumb.html" pages="Home,Library,Articles" -%}
       <h2 class="page-title">
-        <span class="text-truncate"
-          >Knights of Ni, we are but simple travelers who seek the enchanter who lives beyond these
-          woods.</span
-        >
+        <span class="text-truncate">How to Build a Modern Dashboard with Tabler</span>
       </h2>
     </div>
     <div class="col-auto">
@@ -151,5 +72,5 @@ You can use breadcrumbs in headers to show the current page location and provide
   </div>
 </div>
 {%- endcapture %}
-{% include "docs/example.html" html=html %}
+{% include "docs/example.html" html=html centered vertical %}
 

+ 24 - 24
docs/content/ui/components/buttons.md

@@ -16,7 +16,7 @@ As one of the most common elements of UI design, buttons have a very important f
 <input type="submit" class="btn" value="Submit" />
 <input type="reset" class="btn" value="Reset" />
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 ## Default button
 
@@ -25,7 +25,7 @@ The standard button creates a white background and subtle hover animation. It's
 {% capture html -%}
 <a href="#" class="btn" role="button">Link</a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 ## Button variations
 
@@ -41,7 +41,7 @@ Use the button classes that correspond to the function of your button. The big r
 <a href="#" class="btn btn-dark">Dark</a>
 <a href="#" class="btn btn-light">Light</a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated centered -%}
+{%- include "docs/example.html" html=html separated centered %}
 
 ## Disabled buttons
 
@@ -57,7 +57,7 @@ Make buttons look inactive to show that an action is possible once the user meet
 <a href="#" class="btn btn-dark disabled">Dark</a>
 <a href="#" class="btn btn-light disabled">Light</a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated centered -%}
+{%- include "docs/example.html" html=html separated centered %}
 
 ## Color variations
 
@@ -77,7 +77,7 @@ Choose the right color for your button to make it go well with your design and d
 <a href="#" class="btn btn-teal">Teal</a>
 <a href="#" class="btn btn-cyan">Cyan</a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated centered -%}
+{%- include "docs/example.html" html=html separated centered %}
 
 ## Ghost buttons
 
@@ -95,7 +95,7 @@ Use the `.btn-ghost-*` class to make your button look simple yet aesthetically a
   <a href="#" class="btn btn-ghost-light">Light</a>
 </div>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated vertical -%}
+{%- include "docs/example.html" html=html separated vertical %}
 
 ## Square buttons
 
@@ -104,7 +104,7 @@ Use the `.btn-square` class to remove the border radius, if you want the corners
 {% capture html -%}
 <a href="#" class="btn btn-square">Square button</a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 ## Pill buttons
 
@@ -113,7 +113,7 @@ Add the `.btn-pill` class to your button to make it rounded and give it a modern
 {% capture html -%}
 <a href="#" class="btn btn-pill">Pill button</a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 ## Outline buttons
 
@@ -129,7 +129,7 @@ Replace the default modifier class with the `.btn-outline-*` class, if you want
 <a href="#" class="btn btn-outline-dark">Dark</a>
 <a href="#" class="btn btn-outline-light">Light</a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 ## Button size
 
@@ -139,13 +139,13 @@ Add `.btn-lg` or `.btn-sm` to change the size of your button and differentiate t
 <button type="button" class="btn btn-primary btn-lg">Large button</button>
 <button type="button" class="btn btn-lg">Large button</button>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 {% capture html -%}
 <button type="button" class="btn btn-primary btn-sm">Small button</button>
 <button type="button" class="btn btn-sm">Small button</button>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 ## Buttons with icons
 
@@ -179,7 +179,7 @@ See all icons at [tabler.io/icons]({{ site.icons.link }}).
   Comment
 </button>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 ## Social buttons
 
@@ -243,7 +243,7 @@ You can use the icons of popular social networking sites, which users are famili
   Tabler
 </a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated centered hide-code -%}
+{%- include "docs/example.html" html=html separated centered hide-code %}
 
 ```html
 <a href="#" class="btn btn-facebook">
@@ -298,7 +298,7 @@ You can also add an icon without the name of a social networking site, if you wa
   {%- include "ui/icon.html" icon="brand-tabler" -%}
 </a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated vertical hide-code -%}
+{%- include "docs/example.html" html=html separated vertical hide-code %}
 
 ```html
 <a href="#" class="btn btn-facebook btn-icon" aria-label="Button">
@@ -333,7 +333,7 @@ Add the `.btn-icon` class to remove unnecessary padding from your button and use
   {%- include "ui/icon.html" icon="git-merge" -%}
 </a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated centered hide-code -%}
+{%- include "docs/example.html" html=html separated centered hide-code %}
 
 ```html
 <a href="#" class="btn btn-primary btn-icon" aria-label="Button">
@@ -373,7 +373,7 @@ Create a dropdown button that will encourage users to click for more options. Yo
   </div>
 </div>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered hide-code height="260px" -%}
+{%- include "docs/example.html" html=html centered hide-code height="260px" %}
 
 ```html
 <div class="dropdown">
@@ -399,7 +399,7 @@ Add the `.btn-loading` class to show a button's loading state, which can be usef
 	Loading button with loooong content
 </a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 {% capture html -%}
 <a href="#" class="btn btn-primary">
@@ -407,7 +407,7 @@ Add the `.btn-loading` class to show a button's loading state, which can be usef
   Button
 </a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 ## List of buttons
 
@@ -420,7 +420,7 @@ Create a list of buttons using the `.btn-list` container to display different ac
   <a href="#" class="btn btn-danger">Cancel</a>
 </div>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 If the list is long, it will be wrapped and some buttons will be moved to the next line, keeping them all evenly spaced.
 
@@ -447,7 +447,7 @@ If the list is long, it will be wrapped and some buttons will be moved to the ne
   <a href="#" class="btn">Nineteen</a>
 </div>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 Use the `.text-center` or the `.text-end` modifiers to change the buttons' alignment and place them where they suit best.
 
@@ -457,7 +457,7 @@ Use the `.text-center` or the `.text-end` modifiers to change the buttons' align
   <a href="#" class="btn btn-primary">Save changes</a>
 </div>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html -%}
+{%- include "docs/example.html" html=html %}
 
 {% capture html -%}
 <div class="btn-list justify-content-end">
@@ -465,7 +465,7 @@ Use the `.text-center` or the `.text-end` modifiers to change the buttons' align
   <a href="#" class="btn btn-primary">Save changes</a>
 </div>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html -%}
+{%- include "docs/example.html" html=html %}
 
 {% capture html -%}
 <div class="btn-list">
@@ -474,7 +474,7 @@ Use the `.text-center` or the `.text-end` modifiers to change the buttons' align
   <a href="#" class="btn btn-primary">Save changes</a>
 </div>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html -%}
+{%- include "docs/example.html" html=html %}
 
 ## Buttons with avatars
 
@@ -507,4 +507,4 @@ Use buttons with avatars to simplify the process of interaction and make your de
   Avatar
 </a>
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}

+ 19 - 134
docs/content/ui/components/vector-maps.md

@@ -14,55 +14,22 @@ To use vector maps in your project, you need to include the jsVectorMap library
 <script src="{{ cdnUrl }}/dist/libs/jsvectormap/dist/maps/js/jsvectormap-world.js"></script>
 ```
 
-## Sample demo
+## Default map
 
 Integrating the vector map into your website is straightforward. Below is a sample implementation for a world map:
 
 ```html
-<div id="map-world" class="w-100 h-100"></div>
-<script>
-  document.addEventListener("DOMContentLoaded", function () {
-    const map = new jsVectorMap({
-      selector: "#map-world",
-      map: "world",
-    });
-  });
-</script>
+{% include "ui/map-vector.html" map-id="empty" %}
+{{ script }}
 ```
 
+## Sample demo
+
 Look at the example below to see how the vector map works with a world map.
 
 {% capture html -%}
-<div class="card">
-  <div class="card-body">
-    <div class="ratio ratio-16x9">
-      <div>
-        <div id="map-world" class="w-100 h-100"></div>
-      </div>
-    </div>
-  </div>
-</div>
-<script>
-  document.addEventListener("DOMContentLoaded", function () {
-    const map = new jsVectorMap({
-      selector: "#map-world",
-      map: "world",
-      backgroundColor: "transparent",
-      regionStyle: {
-        initial: {
-          fill: "var(--tblr-body-bg)",
-          stroke: "var(--tblr-border-color)",
-          strokeWidth: 2,
-        },
-      },
-      zoomOnScroll: false,
-      zoomButtons: false,
-    });
-    window.addEventListener("resize", () => {
-      map.updateSize();
-    });
-  });
-</script>
+{% include "ui/map-vector.html" map-id="world" %}
+{{ script }}
 {%- endcapture %}
 {% include "docs/example.html" html=html %}
 
@@ -71,99 +38,17 @@ Look at the example below to see how the vector map works with a world map.
 You can add markers to the map to highlight specific locations. Below is a sample implementation for a world map with markers:
 
 {% capture html -%}
-<div class="card">
-  <div class="card-body">
-    <div class="ratio ratio-16x9">
-      <div>
-        <div id="map-world-markers" class="w-100 h-100"></div>
-      </div>
-    </div>
-  </div>
-</div>
-<script>
-  document.addEventListener("DOMContentLoaded", function () {
-    const map = new jsVectorMap({
-      selector: "#map-world-markers",
-      map: "world_merc",
-      backgroundColor: "transparent",
-      regionStyle: {
-        initial: {
-          fill: "var(--tblr-body-bg)",
-          stroke: "var(--tblr-border-color)",
-          strokeWidth: 2,
-        },
-      },
-      zoomOnScroll: false,
-      zoomButtons: false,
-      markers: [
-        {
-          coords: [61.524, 105.3188],
-          name: "Russia",
-        },
-        {
-          coords: [56.1304, -106.3468],
-          name: "Canada",
-        },
-        {
-          coords: [71.7069, -42.6043],
-          name: "Greenland",
-        },
-        {
-          coords: [26.8206, 30.8025],
-          name: "Egypt",
-        },
-        {
-          coords: [-14.235, -51.9253],
-          name: "Brazil",
-        },
-        {
-          coords: [35.8617, 104.1954],
-          name: "China",
-        },
-        {
-          coords: [37.0902, -95.7129],
-          name: "United States",
-        },
-        {
-          coords: [60.472024, 8.468946],
-          name: "Norway",
-        },
-        {
-          coords: [48.379433, 31.16558],
-          name: "Ukraine",
-        },
-      ],
-      markerStyle: {
-        initial: {
-          r: 4,
-          stroke: "#fff",
-          opacity: 1,
-          strokeWidth: 3,
-          stokeOpacity: 0.5,
-          fill: "var(--tblr-primary)",
-        },
-        hover: {
-          fill: "var(--tblr-primary)",
-          stroke: "var(--tblr-primary)",
-        },
-      },
-      markerLabelStyle: {
-        initial: {
-          fontSize: 10,
-        },
-      },
-      labels: {
-        markers: {
-          render: function (marker) {
-            return marker.name;
-          },
-        },
-      },
-    });
-    window.addEventListener("resize", () => {
-      map.updateSize();
-    });
-  });
-</script>
+{% include "ui/map-vector.html" map-id="world-markers" %}
+{{ script }}
+{%- endcapture %}
+{% include "docs/example.html" html=html %}
+
+## Lines 
+
+You can also draw lines on the map to represent routes or connections between different locations. Below is a sample implementation for a world map with lines:
+
+{% capture html -%}
+{% include "ui/map-vector.html" map-id="world-lines" %}
+{{ script }}
 {%- endcapture %}
 {% include "docs/example.html" html=html %}

+ 11 - 1
docs/eleventy.config.mjs

@@ -163,7 +163,17 @@ export default function (eleventyConfig) {
 				children: []
 			}
 		}).sort((a, b) => {
-			return (a.data.order || 999) - (b.data.order || 999);
+			const orderA = a.data.order ?? 999;
+			const orderB = b.data.order ?? 999;
+
+			if (orderA !== orderB) {
+				return orderA - orderB;
+			}
+
+			const titleA = a.data.title ?? '';
+			const titleB = b.data.title ?? '';
+
+			return titleA.localeCompare(titleB);
 		});
 
 		return buildCollectionTree(a);

+ 1 - 1
docs/js/docs.js

@@ -5,4 +5,4 @@ docsearch({
 	appId: "NE1EGTYLS9",
 	indexName: "tabler",
 	apiKey: "016353235ef1dd32a6c392be0e939058",
-});
+});

+ 1 - 0
docs/package.json

@@ -32,6 +32,7 @@
     "apexcharts": "3.54.1",
     "autosize": "^6.0.1",
     "choices.js": "^11.1.0",
+    "clipboard": "^2.0.11",
     "countup.js": "^2.8.0",
     "dropzone": "^6.0.0-beta.2",
     "flatpickr": "^4.6.13",

+ 37 - 0
pnpm-lock.yaml

@@ -128,6 +128,9 @@ importers:
       choices.js:
         specifier: ^11.1.0
         version: 11.1.0
+      clipboard:
+        specifier: ^2.0.11
+        version: 2.0.11
       countup.js:
         specifier: ^2.8.0
         version: 2.8.2
@@ -216,6 +219,9 @@ importers:
       choices.js:
         specifier: ^11.1.0
         version: 11.1.0
+      clipboard:
+        specifier: ^2.0.11
+        version: 2.0.11
       countup.js:
         specifier: ^2.8.2
         version: 2.8.2
@@ -1235,6 +1241,9 @@ packages:
     resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==}
     engines: {node: '>= 10.0'}
 
+  [email protected]:
+    resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==}
+
   [email protected]:
     resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
     engines: {node: '>=12'}
@@ -1360,6 +1369,9 @@ packages:
     resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
     engines: {node: '>=0.4.0'}
 
+  [email protected]:
+    resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==}
+
   [email protected]:
     resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
     engines: {node: '>= 0.8'}
@@ -1722,6 +1734,9 @@ packages:
     resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
     engines: {node: '>=10'}
 
+  [email protected]:
+    resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==}
+
   [email protected]:
     resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
     engines: {node: '>= 0.4'}
@@ -2624,6 +2639,9 @@ packages:
     resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
     engines: {node: '>=4'}
 
+  [email protected]:
+    resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==}
+
   [email protected]:
     resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
 
@@ -2870,6 +2888,9 @@ packages:
   [email protected]:
     resolution: {integrity: sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==}
 
+  [email protected]:
+    resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==}
+
   [email protected]:
     resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==}
     engines: {node: '>=12.0.0'}
@@ -4273,6 +4294,12 @@ snapshots:
     dependencies:
       source-map: 0.6.1
 
+  [email protected]:
+    dependencies:
+      good-listener: 1.2.2
+      select: 1.1.2
+      tiny-emitter: 2.1.0
+
   [email protected]:
     dependencies:
       string-width: 4.2.3
@@ -4385,6 +4412,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]: {}
@@ -4760,6 +4789,10 @@ snapshots:
       merge2: 1.4.1
       slash: 3.0.0
 
+  [email protected]:
+    dependencies:
+      delegate: 3.2.0
+
   [email protected]: {}
 
   [email protected]: {}
@@ -5611,6 +5644,8 @@ snapshots:
       extend-shallow: 2.0.1
       kind-of: 6.0.3
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]: {}
@@ -5874,6 +5909,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       fdir: 6.4.4([email protected])

+ 1 - 0
preview/package.json

@@ -38,6 +38,7 @@
     "apexcharts": "3.54.1",
     "autosize": "^6.0.1",
     "choices.js": "^11.1.0",
+    "clipboard": "^2.0.11",
     "countup.js": "^2.8.2",
     "dropzone": "^6.0.0-beta.2",
     "flatpickr": "^4.6.13",

+ 1 - 0
shared/data/libs.json

@@ -22,6 +22,7 @@
     "coloris.js": "@melloware/coloris/dist/umd/coloris.min.js",
     "typed.js": "typed.js/dist/typed.umd.js",
     "signature_pad": "signature_pad/dist/signature_pad.umd.min.js",
+    "clipboard": "clipboard/dist/clipboard.min.js",
     "fullcalendar": "fullcalendar/index.global.min.js"
   },
   "js-head": {

+ 5 - 0
shared/data/maps-vector.json

@@ -1,4 +1,9 @@
 {
+  "empty": {
+    "title": "Empty map",
+    "map": "world",
+    "color": "primary"
+  },
   "world": {
     "title": "World map",
     "map": "world",

+ 11 - 1
shared/e11ty/filters.mjs

@@ -34,6 +34,17 @@ export function appFilters(eleventyConfig) {
 		}
 	});
 
+	eleventyConfig.addFilter("escape_attribute", (text) => {
+		return text
+			.replace(/&/g, '&amp;')
+			.replace(/'/g, '&apos;')
+			.replace(/"/g, '&quot;')
+			.replace(/</g, '&lt;')
+			.replace(/>/g, '&gt;')
+			.replace(/\r\n/g, '&#13;')
+			.replace(/[\r\n]/g, '&#13;');
+	});
+
 	eleventyConfig.addFilter("contains", (items, item) => {
 		return items && Array.isArray(items) && items.includes(item);
 	});
@@ -149,7 +160,6 @@ export function appFilters(eleventyConfig) {
 
 	// Convert a URL path to an absolute URL
 	eleventyConfig.addFilter("absolute_url", function (url) {
-		// Base URL for the site - change this to your production domain
 		const baseUrl = "https://docs.tabler.io";
 
 		// Ensure url starts with a slash

+ 11 - 3
shared/includes/docs/example.html

@@ -1,14 +1,22 @@
 <!--EXAMPLE-->
 <div
 	class="example fs-base border rounded my-5{% unless include.raw %} d-flex flex-wrap justify-content-center{% endunless %} overflow-{{ include.overflow | default: 'auto' }} position-relative {% if include.bg %}bg-{{ include.bg }}{% endif %}{% if include.class %} {{ include.class }}{% endif %}"{% if include.height %} style="height: {{ include.height }}"{% endif %}{% unless include.bg %} style="background: url('data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'20\' height=\'20\' viewBox=\'0 0 20 20\'><rect fill=\'rgba(0, 0, 0, .01)\' x=\'0\' y=\'0\' width=\'10\' height=\'10\' /><rect fill=\'rgba(0, 0, 0, .01)\' x=\'10\' y=\'10\' width=\'10\' height=\'10\' /></svg>')"{% endunless %}}>
-	{%- unless include.raw -%}<div class="p-6 w-full{% if include.column %} d-flex gap-3 flex-column{% elsif include.centered %} justify-content-center flex-fill flex-wrap gap-2{% if include.vertical %} flex-column{% endif %}{% endif %}" {% if include.column %}style="max-width: 25rem;"{% endif %}>{%- endunless -%}
-		{{ html | remove-href }}
+	{%- unless include.raw -%}<div class="p-6 w-full{% if include.column %} d-flex gap-3 flex-column{% elsif include.centered %} d-flex flex-fill flex-wrap gap-2{% if include.vertical %} align-items-center flex-column{% else %} justify-content-center{% endif %}{% endif %}" {% if include.column %}style="max-width: 25rem;"{% endif %}>{%- endunless -%}
+		{{ include.html | remove-href }}
 	{%- unless include.raw -%}</div>{%- endunless -%}
 </div>
 
 {% unless include.hide-code %}
+<div class="position-relative">
+<a class="btn btn-icon btn-dark position-absolute m-2 top-0 end-0 z-3" data-clipboard-text="{{ include.html | escape_attribute }}">
+	{% include "ui/icon.html" icon="clipboard" %}
+	{% include "ui/icon.html" icon="check" class="d-none" %}
+</a>
+
 ```html
-{{ html }}
+{{ include.html }}
 ```
+
+</div>
 {% endunless %}
 <!--/EXAMPLE-->

+ 5 - 1
shared/includes/ui/badge.html

@@ -1,5 +1,9 @@
 {%- assign el = 'span' -%}
-<{{ el }} class="badge{% if include['size'] %} badge-{{ include['size'] }}{% endif %}{% if include.color %} bg-{{ include.color }} text-{{ include.color }}-fg{% endif %}{% if include.class %} {{ include.class }}{% endif %}">
+<{{ el }} class="badge{% if include.scale %} badge-{{ include.scale }}{% endif %}{% if include.color %} bg-{{ include.color }}{% if include.light %}-lt{% endif %} text-{{ include.color }}{% if include.light %}-lt{% endif %}-fg{% endif %}{% if include.class %} {{ include.class }}{% endif %}">
+{%- if include.icon -%}
+	 {%- assign icon = include.icon -%}
+	 {% include "ui/icon.html" icon=icon %}
+{%- endif -%}
 {%- if include.person-id -%}
     {%- assign person-id = include.person-id | minus: 1 -%}
     {%- assign person = people[person-id] -%}

+ 19 - 9
shared/includes/ui/breadcrumb.html

@@ -1,10 +1,20 @@
-{% assign breadcrumb-pages = include.pages | default: "Home,Library,Data" | split: "," %}
-<ol class="breadcrumb{% if include.class %} {{ include.class }}{% endif %}" aria-label="breadcrumbs">
-   {% for page in breadcrumb-pages %}
-   {% if forloop.last %}
-   <li class="breadcrumb-item active" aria-current="page"><a href="#">{{ page }}</a></li>
-   {% else %}
-   <li class="breadcrumb-item"><a href="#">{{ page }}</a></li>
-   {% endif %}
-   {% endfor %}
+{% assign breadcrumb-pages = include.pages | default: "Home,Library,Data" | split: "," -%}
+<ol class="breadcrumb{% if include.class %} {{ include.class }}{% endif %}{% if include.separator %} breadcrumb-{{ include.separator }}{% endif %}" aria-label="breadcrumbs">
+   {%- for page in breadcrumb-pages -%}
+   {%- if forloop.last -%}
+   <li class="breadcrumb-item active" aria-current="page">
+		<a href="#">{{ page }}</a>
+   </li>
+   {%- else -%}
+   <li class="breadcrumb-item">
+		{% if forloop.first and include.home-icon-%}
+		<a href="{{ site.baseurl }}/">
+			{% include "ui/icon.html" icon="home" %}
+		</a>
+		{%- else -%}
+		<a href="#">{{ page }}</a>
+		{%- endif -%}
+	</li>
+   {%- endif -%}
+   {%- endfor -%}
 </ol>

+ 99 - 99
shared/includes/ui/map-vector.html

@@ -1,117 +1,117 @@
+{% removeemptylines %} 
 {% assign id = include.map-id %}
 {% assign data = maps-vector[id] %}
-{% assign color = include.color | default: data.color | default: 'green' %}
+{% assign color = include.color | default: data.color | default: 'primary' %}
 
 {% if data %}
-	<div class="ratio ratio-{{ include.ratio | default: '4x3' }}">
-		<div>
-			<div id="map-{{ id }}" class="w-100 h-100"></div>
-		</div>
+<div class="ratio ratio-{{ include.ratio | default: '4x3' }}">
+	<div>
+		<div id="map-{{ id }}" class="w-100 h-100"></div>
 	</div>
+</div>
 
-	{% capture script %}
-	<script>
-		{% if environment == 'development' %}window.tabler_map_vector = window.tabler_map_vector || {};{% endif %}
+{% capture script %}
+{% removeemptylines %}
+<script>
+	{% if environment == 'development' %}window.tabler_map_vector = window.tabler_map_vector || {};{% endif %}
 
-		document.addEventListener("DOMContentLoaded", function() {
-			const map = {% if environment == 'development' %}window.tabler_map_vector["map-{{ id }}"] = {% endif %}new jsVectorMap({
-				selector: '#map-{{ id }}',
-				map: '{{ data.map }}',
-				backgroundColor: 'transparent',
-				regionStyle: {
-					initial: {
-						{% unless data.filled %}
-						fill: 'var(--tblr-bg-surface-secondary)',
-						stroke: 'var(--tblr-border-color)',
-						strokeWidth: 2,
-						{% else %}
-						fill: 'var(--tblr-bg-surface-secondary)',
-						stroke: '#fff',
-						strokeWidth: 1,
-						{% endunless %}
-					}
-				},
-				zoomOnScroll: {% if data.zoom %}true{% else %}false{% endif %},
-				zoomButtons: {% if data.zoom %}true{% else %}false{% endif %},
-				{% if data.values %}
-				series: {
-					regions: [{
-						attribute: "fill",
-						scale: {
-							{% for i in (1..10) %}
-							scale{{ i }}: 'color-mix(in srgb, transparent, var(--tblr-primary) {{ i | times: 10 }}%)',
-							{% endfor %}
-						},
-						values: {{ data.values | json }},
-					}]
+	document.addEventListener("DOMContentLoaded", function() {
+		const map = {% if environment == 'development' %}window.tabler_map_vector["map-{{ id }}"] = {% endif %}new jsVectorMap({
+			selector: '#map-{{ id }}',
+			map: '{{ data.map }}',
+			backgroundColor: 'transparent',
+			regionStyle: {
+				initial: {
+					{% unless data.filled %}
+					fill: 'var(--tblr-bg-surface-secondary)',
+					stroke: 'var(--tblr-border-color)',
+					strokeWidth: 2,
+					{% else %}
+					fill: 'var(--tblr-bg-surface-secondary)',
+					stroke: '#fff',
+					strokeWidth: 1,
+					{% endunless %}
 				}
-				{% endif %}
-				{% if data.markers %}
-				markers: [
-					{% for marker in data.markers %}
-					{
-						coords: [{{ marker.coords }}],
-						name: "{{ marker.name }}",
-					},
-					{% endfor %}
-				],
-				markerStyle: {
-					initial: {
-						r: 4,
-						stroke: '#fff',
-						opacity: 1,
-						strokeWidth: 3,
-						stokeOpacity: .5,
-						fill: 'var(--tblr-{{ color }})'
+			},
+			zoomOnScroll: {% if data.zoom %}true{% else %}false{% endif %},
+			zoomButtons: {% if data.zoom %}true{% else %}false{% endif %},
+			{% if data.values %}
+			series: {
+				regions: [{
+					attribute: "fill",
+					scale: {
+						{% for i in (1..10) %}
+						scale{{ i }}: 'color-mix(in srgb, transparent, var(--tblr-primary) {{ i | times: 10 }}%)',
+						{% endfor %}
 					},
-					hover: {
-						fill: 'var(--tblr-{{ color }})',
-						stroke: 'var(--tblr-{{ color }})'
-					}
+					values: {{ data.values | json }},
+				}]
+			}
+			{% endif %}
+			{% if data.markers %}
+			markers: [
+				{% for marker in data.markers %}
+				{
+					coords: [{{ marker.coords }}],
+					name: "{{ marker.name }}",
 				},
-				markerLabelStyle: {
-					initial: {
-						fontSize: 10
-					},
+				{% endfor %}
+			],
+			markerStyle: {
+				initial: {
+					r: 4,
+					stroke: '#fff',
+					opacity: 1,
+					strokeWidth: 3,
+					stokeOpacity: .5,
+					fill: 'var(--tblr-{{ color }})'
 				},
-				labels: {
-					markers: {
-						render: function(marker) {
-							return marker.name
-						},
-					},
+				hover: {
+					fill: 'var(--tblr-{{ color }})',
+					stroke: 'var(--tblr-{{ color }})'
+				}
+			},
+			markerLabelStyle: {
+				initial: {
+					fontSize: 10
 				},
-				{% endif %}
-				{% if data.lines %}
-				lines: [
-					{% for line in data.lines %}
-					{
-						from: "{{ line.from }}",
-						to: "{{ line.to }}"
+			},
+			labels: {
+				markers: {
+					render: function(marker) {
+						return marker.name
 					},
-					{% endfor %}
-				],
-				lineStyle: {
-					strokeDasharray:"4 4",
-					animation: true,
-					stroke: "rgba(98, 105, 118, .75)",
-					strokeWidth: .5,
 				},
-				{% endif %}
-			});
+			},
+			{% endif %}
+			{% if data.lines %}
+			lines: [
+				{% for line in data.lines %}
+				{
+					from: "{{ line.from }}",
+					to: "{{ line.to }}"
+				},
+				{% endfor %}
+			],
+			lineStyle: {
+				strokeDasharray:"4 4",
+				animation: true,
+				stroke: "rgba(98, 105, 118, .75)",
+				strokeWidth: .5,
+			},
+			{% endif %}
+		});
 
-			window.addEventListener("resize", () => {
-				map.updateSize();
-			});
+		window.addEventListener("resize", () => {
+			map.updateSize();
 		});
-	</script>
-	{%- endcapture %}
+	});
+{% endremoveemptylines %}
+</script>
+{%- endcapture %}
 
-	{% if include.show-scripts %}
-		{{ script }}
-	{% else %}
-		{% capture_script %}
-			{{ script }}
-		{% endcapture_script %}
-	{% endif %}
+{% capture_script %}
+	{{ script }}
+{% endcapture_script %}
 {% endif %}
+{% endremoveemptylines %}

+ 36 - 3
shared/layouts/docs/default.html

@@ -178,9 +178,8 @@
 		</div>
 	</div>
 
-	{% if docs-libs -%}
 	{% for lib in libs.js -%}
-	{% if docs-libs contains lib[0] or libs.global-libs contains lib[0] -%}
+	{% if docs-libs contains lib[0] or libs.global-libs contains lib[0] or lib[0] == "clipboard" -%}
 	{% for file in lib[1] -%}
 	<script
 		src="{% if file contains 'http://' or file contains 'https://' %}{{ file | replace: 'GOOGLE_MAPS_KEY', google-maps-key }}{% else %}/libs/{% if environment != 'development' %}{{ file | replace: '@', '' }}{% else %}{{ file }}{% endif %}{% if environment != 'development' %}?{{ 'now' | date: '%s' }}{% endif %}{% endif %}"
@@ -188,7 +187,41 @@
 	{% endfor -%}
 	{% endif -%}
 	{% endfor -%}
-	{% endif -%}
+	
+	<script>
+	document.addEventListener('DOMContentLoaded', function () {
+		const elements = document.querySelectorAll('[data-clipboard-text]');
+
+		elements.forEach(function (element) {
+			const clipboard = new ClipboardJS(element, {
+				text: function (trigger) {
+					return element.getAttribute('data-clipboard-text');
+				}
+			});
+
+			clipboard.on('success', function (e) {
+				e.clearSelection();
+				e.trigger.classList.add('btn-success');
+				e.trigger.classList.remove('btn-dark');
+				e.trigger.children[0].classList.add('d-none');
+				e.trigger.children[1].classList.remove('d-none');
+
+				setTimeout(function () {
+					e.trigger.classList.remove('btn-success');
+					e.trigger.classList.add('btn-dark');
+					
+					e.trigger.children[0].classList.remove('d-none');
+					e.trigger.children[1].classList.add('d-none');
+				}, 2000);
+			});
+
+			clipboard.on('error', function (e) {
+				console.error('Error copying text: ', e);
+			});
+		});
+		
+	})
+	</script>
 
 	<script src="/dist/js/tabler{% if environment != 'development' %}.min{% endif %}.js"></script>
 	<script src="/js/docs{% if environment != 'development' %}.min{% endif %}.js" defer></script>