浏览代码

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);
     border: 1px solid var(--#{$prefix}border-color);
   }
   }
 
 
-  > pre {
+  pre {
     max-height: 20rem;
     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.
 The default badges are square and come in the basic set of colors.
 
 
 {% capture html -%}
 {% 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 %}
 {%- endcapture %}
 {% include "docs/example.html" html=html centered %}
 {% include "docs/example.html" html=html centered %}
 
 
 ## Headings
 ## 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 -%}
 {% 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 %}
 {%- endcapture %}
 {% include "docs/example.html" html=html %}
 {% 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 -%}
 {% 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 %}
 {%- endcapture %}
 {% include "docs/example.html" html=html centered %}
 {% 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.
 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 -%}
 {% 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 %}
 {%- endcapture %}
 {% include "docs/example.html" html=html centered %}
 {% 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
 ## 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 -%}
 {% capture html -%}
 <button type="button" class="btn">
 <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>
 <button type="button" class="btn">
 <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>
 </button>
 {%- endcapture %}
 {%- endcapture %}
 {% include "docs/example.html" html=html centered %}
 {% 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.
 Look at the example below to see how breadcrumbs work in practice.
 
 
 {% capture html -%}
 {% 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 %}
 {%- endcapture %}
-{% include "docs/example.html" html=html vertical separated %}
+{% include "docs/example.html" html=html centered %}
 
 
 ## Different separators
 ## 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.
 This example shows how to use different breadcrumb styles.
 
 
 {% capture html -%}
 {% 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 %}
 {%- endcapture %}
-{% include "docs/example.html" html=html vertical separated %}
+{% include "docs/example.html" html=html vertical separated centered %}
 
 
 ## With icon
 ## With icon
 
 
 You can use icons in breadcrumbs to make them more visually appealing. The example below demonstrates how to use icons in breadcrumbs.
 You can use icons in breadcrumbs to make them more visually appealing. The example below demonstrates how to use icons in breadcrumbs.
 
 
 {% capture html -%}
 {% 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 %}
 {%- endcapture %}
 {% include "docs/example.html" html=html vertical separated %}
 {% 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.
 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 -%}
 {% 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 %}
 {%- endcapture %}
 {% include "docs/example.html" html=html %}
 {% 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="page-header">
   <div class="row align-items-center mw-100">
   <div class="row align-items-center mw-100">
     <div class="col">
     <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">
       <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>
       </h2>
     </div>
     </div>
     <div class="col-auto">
     <div class="col-auto">
@@ -151,5 +72,5 @@ You can use breadcrumbs in headers to show the current page location and provide
   </div>
   </div>
 </div>
 </div>
 {%- endcapture %}
 {%- 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="submit" class="btn" value="Submit" />
 <input type="reset" class="btn" value="Reset" />
 <input type="reset" class="btn" value="Reset" />
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 
 ## Default button
 ## Default button
 
 
@@ -25,7 +25,7 @@ The standard button creates a white background and subtle hover animation. It's
 {% capture html -%}
 {% capture html -%}
 <a href="#" class="btn" role="button">Link</a>
 <a href="#" class="btn" role="button">Link</a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 
 ## Button variations
 ## 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-dark">Dark</a>
 <a href="#" class="btn btn-light">Light</a>
 <a href="#" class="btn btn-light">Light</a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated centered -%}
+{%- include "docs/example.html" html=html separated centered %}
 
 
 ## Disabled buttons
 ## 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-dark disabled">Dark</a>
 <a href="#" class="btn btn-light disabled">Light</a>
 <a href="#" class="btn btn-light disabled">Light</a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated centered -%}
+{%- include "docs/example.html" html=html separated centered %}
 
 
 ## Color variations
 ## 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-teal">Teal</a>
 <a href="#" class="btn btn-cyan">Cyan</a>
 <a href="#" class="btn btn-cyan">Cyan</a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated centered -%}
+{%- include "docs/example.html" html=html separated centered %}
 
 
 ## Ghost buttons
 ## 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>
   <a href="#" class="btn btn-ghost-light">Light</a>
 </div>
 </div>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated vertical -%}
+{%- include "docs/example.html" html=html separated vertical %}
 
 
 ## Square buttons
 ## Square buttons
 
 
@@ -104,7 +104,7 @@ Use the `.btn-square` class to remove the border radius, if you want the corners
 {% capture html -%}
 {% capture html -%}
 <a href="#" class="btn btn-square">Square button</a>
 <a href="#" class="btn btn-square">Square button</a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 
 ## Pill buttons
 ## 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 -%}
 {% capture html -%}
 <a href="#" class="btn btn-pill">Pill button</a>
 <a href="#" class="btn btn-pill">Pill button</a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 
 ## Outline buttons
 ## 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-dark">Dark</a>
 <a href="#" class="btn btn-outline-light">Light</a>
 <a href="#" class="btn btn-outline-light">Light</a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 
 ## Button size
 ## 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-primary btn-lg">Large button</button>
 <button type="button" class="btn btn-lg">Large button</button>
 <button type="button" class="btn btn-lg">Large button</button>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 
 {% capture html -%}
 {% capture html -%}
 <button type="button" class="btn btn-primary btn-sm">Small button</button>
 <button type="button" class="btn btn-primary btn-sm">Small button</button>
 <button type="button" class="btn btn-sm">Small button</button>
 <button type="button" class="btn btn-sm">Small button</button>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 
 ## Buttons with icons
 ## Buttons with icons
 
 
@@ -179,7 +179,7 @@ See all icons at [tabler.io/icons]({{ site.icons.link }}).
   Comment
   Comment
 </button>
 </button>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 
 ## Social buttons
 ## Social buttons
 
 
@@ -243,7 +243,7 @@ You can use the icons of popular social networking sites, which users are famili
   Tabler
   Tabler
 </a>
 </a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated centered hide-code -%}
+{%- include "docs/example.html" html=html separated centered hide-code %}
 
 
 ```html
 ```html
 <a href="#" class="btn btn-facebook">
 <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" -%}
   {%- include "ui/icon.html" icon="brand-tabler" -%}
 </a>
 </a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated vertical hide-code -%}
+{%- include "docs/example.html" html=html separated vertical hide-code %}
 
 
 ```html
 ```html
 <a href="#" class="btn btn-facebook btn-icon" aria-label="Button">
 <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" -%}
   {%- include "ui/icon.html" icon="git-merge" -%}
 </a>
 </a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html separated centered hide-code -%}
+{%- include "docs/example.html" html=html separated centered hide-code %}
 
 
 ```html
 ```html
 <a href="#" class="btn btn-primary btn-icon" aria-label="Button">
 <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>
 </div>
 </div>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered hide-code height="260px" -%}
+{%- include "docs/example.html" html=html centered hide-code height="260px" %}
 
 
 ```html
 ```html
 <div class="dropdown">
 <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
 	Loading button with loooong content
 </a>
 </a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 
 {% capture html -%}
 {% capture html -%}
 <a href="#" class="btn btn-primary">
 <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
   Button
 </a>
 </a>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html centered -%}
+{%- include "docs/example.html" html=html centered %}
 
 
 ## List of buttons
 ## 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>
   <a href="#" class="btn btn-danger">Cancel</a>
 </div>
 </div>
 {%- endcapture -%}
 {%- 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.
 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>
   <a href="#" class="btn">Nineteen</a>
 </div>
 </div>
 {%- endcapture -%}
 {%- 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.
 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>
   <a href="#" class="btn btn-primary">Save changes</a>
 </div>
 </div>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html -%}
+{%- include "docs/example.html" html=html %}
 
 
 {% capture html -%}
 {% capture html -%}
 <div class="btn-list justify-content-end">
 <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>
   <a href="#" class="btn btn-primary">Save changes</a>
 </div>
 </div>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html -%}
+{%- include "docs/example.html" html=html %}
 
 
 {% capture html -%}
 {% capture html -%}
 <div class="btn-list">
 <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>
   <a href="#" class="btn btn-primary">Save changes</a>
 </div>
 </div>
 {%- endcapture -%}
 {%- endcapture -%}
-{%- include "docs/example.html" html=html -%}
+{%- include "docs/example.html" html=html %}
 
 
 ## Buttons with avatars
 ## Buttons with avatars
 
 
@@ -507,4 +507,4 @@ Use buttons with avatars to simplify the process of interaction and make your de
   Avatar
   Avatar
 </a>
 </a>
 {%- endcapture -%}
 {%- 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>
 <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:
 Integrating the vector map into your website is straightforward. Below is a sample implementation for a world map:
 
 
 ```html
 ```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.
 Look at the example below to see how the vector map works with a world map.
 
 
 {% capture html -%}
 {% 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 %}
 {%- endcapture %}
 {% include "docs/example.html" html=html %}
 {% 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:
 You can add markers to the map to highlight specific locations. Below is a sample implementation for a world map with markers:
 
 
 {% capture html -%}
 {% 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 %}
 {%- endcapture %}
 {% include "docs/example.html" html=html %}
 {% include "docs/example.html" html=html %}

+ 11 - 1
docs/eleventy.config.mjs

@@ -163,7 +163,17 @@ export default function (eleventyConfig) {
 				children: []
 				children: []
 			}
 			}
 		}).sort((a, b) => {
 		}).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);
 		return buildCollectionTree(a);

+ 1 - 1
docs/js/docs.js

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

+ 1 - 0
docs/package.json

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

+ 37 - 0
pnpm-lock.yaml

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

+ 1 - 0
preview/package.json

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

+ 1 - 0
shared/data/libs.json

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

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

@@ -1,4 +1,9 @@
 {
 {
+  "empty": {
+    "title": "Empty map",
+    "map": "world",
+    "color": "primary"
+  },
   "world": {
   "world": {
     "title": "World map",
     "title": "World map",
     "map": "world",
     "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) => {
 	eleventyConfig.addFilter("contains", (items, item) => {
 		return items && Array.isArray(items) && items.includes(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
 	// Convert a URL path to an absolute URL
 	eleventyConfig.addFilter("absolute_url", function (url) {
 	eleventyConfig.addFilter("absolute_url", function (url) {
-		// Base URL for the site - change this to your production domain
 		const baseUrl = "https://docs.tabler.io";
 		const baseUrl = "https://docs.tabler.io";
 
 
 		// Ensure url starts with a slash
 		// Ensure url starts with a slash

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

@@ -1,14 +1,22 @@
 <!--EXAMPLE-->
 <!--EXAMPLE-->
 <div
 <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 %}}>
 	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 -%}
 	{%- unless include.raw -%}</div>{%- endunless -%}
 </div>
 </div>
 
 
 {% unless include.hide-code %}
 {% 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
-{{ html }}
+{{ include.html }}
 ```
 ```
+
+</div>
 {% endunless %}
 {% endunless %}
 <!--/EXAMPLE-->
 <!--/EXAMPLE-->

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

@@ -1,5 +1,9 @@
 {%- assign el = 'span' -%}
 {%- 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 -%}
 {%- if include.person-id -%}
     {%- assign person-id = include.person-id | minus: 1 -%}
     {%- assign person-id = include.person-id | minus: 1 -%}
     {%- assign person = people[person-id] -%}
     {%- 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>
 </ol>

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

@@ -1,117 +1,117 @@
+{% removeemptylines %} 
 {% assign id = include.map-id %}
 {% assign id = include.map-id %}
 {% assign data = maps-vector[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 %}
 {% 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>
+</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 %}
 {% endif %}
+{% endremoveemptylines %}

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

@@ -178,9 +178,8 @@
 		</div>
 		</div>
 	</div>
 	</div>
 
 
-	{% if docs-libs -%}
 	{% for lib in libs.js -%}
 	{% 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] -%}
 	{% for file in lib[1] -%}
 	<script
 	<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 %}"
 		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 -%}
 	{% endfor -%}
 	{% endif -%}
 	{% endif -%}
 	{% endfor -%}
 	{% 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="/dist/js/tabler{% if environment != 'development' %}.min{% endif %}.js"></script>
 	<script src="/js/docs{% if environment != 'development' %}.min{% endif %}.js" defer></script>
 	<script src="/js/docs{% if environment != 'development' %}.min{% endif %}.js" defer></script>