Quellcode durchsuchen

🎨 Form tweaks, Accessibility upgrades and JS Refactors

Edgar Pérez vor 7 Monaten
Ursprung
Commit
ccd6ea07a9

+ 9 - 1
dist/css/actions.css

@@ -52,14 +52,18 @@
 }
 
 .p-action--intern{
+  width: 100%;
   display:block;
   margin:auto;
+  font-size: 1rem;
+  font-weight: 600;
   text-align:center;
   padding: 15px 0;
+  border: 0;
   border-bottom: 1px solid #bfbfbf;
-  font-weight: 500;
   color: #0f75f5;
   text-decoration:none;
+  background-color: transparent;
 }
 
 .p-action-destructive{
@@ -138,4 +142,8 @@
 
 .p-action-big-container.active .p-action-container {
   backdrop-filter: saturate(180%) blur(10px);
+}
+
+.p-action-big-container[aria-hidden="true"] .p-action--intern {
+  display: none;
 }

+ 50 - 9
dist/css/forms.css

@@ -7,14 +7,14 @@
   --p-checkbox-border: rgba(0, 0, 0, 0.2);
   --p-checkbox-border-active: rgba(0, 0, 0, 0.12);
   --p-checkbox-bg: transparent;
-  --p-checkbox-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.15), inset 0px 0px 2px rgba(0, 0, 0, 0.05);
+  --p-checkbox-shadow: inset 0px 1px 2px rgba(0, 0, 0, 0.15), inset 0px 0px 2px rgba(0, 0, 0, 0.10);
 
   --p-input-bg:#fff;
-  --p-input-color:#000;
-  --p-input-color-plac:#cdcdcd;
+  --p-input-color: rgba(0,0,0,.85);
+  --p-input-color-plac:rgba(0,0,0,0.25);
 
   --p-input-color:#808080;
-  --p-input-bd:#808080;
+  --p-input-bd:rgba(0,0,0,0.15);
   --bg-hover-color:#f9f9f9;
   --bg-front-col:#000;
   --invalid-color:#d6513c;
@@ -91,16 +91,17 @@
 .p-form-text {
   color: var(--p-input-color);
   -webkit-appearance: none;
-  box-shadow: none;
   background: var(--p-input-bg);
   border: 1px solid var(--p-input-bd);
   border-radius: 5px;
   font-family: -apple-system, "Inter", sans-serif;
+  font-size: 13px;
   margin: 10px;
   outline: 0;
-  padding: 10px 5px;
+  padding: 3px 7px;
   resize: none;
   transition: border-color 200ms;
+  box-shadow: 0px 0.5px 2.5px rgba(0,0,0,.3), 0px 0px 0px rgba(0,0,0,.1);
 }
 
 .p-form-text-alt {
@@ -124,8 +125,15 @@
   color: var(--p-input-color-plac);
 }
 
+.p-form-text:active,
+.p-form-text:focus
+{
+  outline: 3px solid rgb(0 122 255 / 50%);
+}
+
 .p-form-text-alt:focus {
   outline: 0;
+  outline: 3px solid rgb(0 122 255 / 50%);
   border-color: #3689e6;
 }
 
@@ -136,7 +144,7 @@
 }
 
 .p-form-text:focus {
-  border-color: #3689e6;
+  border-color: rgb(0 122 255);
 }
 
 textarea.p-form-text {
@@ -165,6 +173,10 @@ textarea.p-form-text {
   display: inline-block;
 }
 
+.p-form-label{
+  font-size: 11px;
+}
+
 .p-form-label-inline {
   background: var(--p-input-bg);
   padding: 5px;
@@ -226,6 +238,15 @@ textarea.p-form-text {
   width: 20px;
 }
 
+.p-form-radio-cont > input + span{
+  box-shadow: inset 0px 1px 2px rgba(0,0,0,0.10), inset 0px 0px 2px rgba(0,0,0,0.10);
+}
+
+.p-form-radio-cont > input:focus + span,
+.p-form-checkbox-cont > input:focus + span{
+  outline: 3px solid rgb(0 122 255 / 50%);
+}
+
 .p-form-radio-cont:hover > input + span{
   background: #f9f9f9;
 }
@@ -254,6 +275,7 @@ textarea.p-form-text {
 
 .p-form-radio-cont > input:checked + span {
   background: #0f75f5;
+  box-shadow: 0px 1px 2.5px 1px rgba(0, 122, 255, 0.24), inset 0px 0px 0px 0.5px rgba(0, 122, 255, 0.12);
 }
 
 .p-form-radio-cont > input:checked + span::after {
@@ -271,7 +293,7 @@ textarea.p-form-text {
 .p-form-checkbox-cont > input:checked + span {
   background: var(--p-checkbox-gradient);
   border: 0.5px solid var(--p-checkbox-border-active);
-  box-shadow: none;
+  box-shadow: 0px 1px 2.5px rgba(0, 122, 255, 0.24), 0px 0px 0px 0.5px rgba(0, 122, 255, 0.12);
 }
 
 .p-form-checkbox-cont > input + span::before{
@@ -284,12 +306,27 @@ textarea.p-form-text {
   top: 0%;
   opacity: 0;
   transition: opacity 0.2s;
-  background-image: url("data:image/svg+xml,%3Csvg width='10' height='10' viewBox='0 0 10 10' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg filter='url(%23a)'%3E%3Cpath d='m2 5 2.25 2.5L8.5 1' stroke='%23fff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/g%3E%3Cdefs%3E%3Cfilter id='a' x='.75' y='.25' width='9' height='9' filterUnits='userSpaceOnUse' color-interpolation-filters='sRGB'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeColorMatrix in='SourceAlpha' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0' result='hardAlpha'/%3E%3CfeOffset dy='.5'/%3E%3CfeGaussianBlur stdDeviation='.25'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0'/%3E%3CfeBlend in2='BackgroundImageFix' result='effect1_dropShadow_201_11690'/%3E%3CfeBlend in='SourceGraphic' in2='effect1_dropShadow_201_11690' result='shape'/%3E%3C/filter%3E%3C/defs%3E%3C/svg%3E");
+  background-image: url("data:image/svg+xml,%3Csvg width='10' height='8' viewBox='0 0 10 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.10791 7.81299C3.83545 7.81299 3.6084 7.70459 3.42676 7.48779L1.15918 4.74121C1.08008 4.65039 1.02441 4.5625 0.992188 4.47754C0.959961 4.39258 0.943848 4.30469 0.943848 4.21387C0.943848 4.00586 1.0127 3.83447 1.15039 3.69971C1.29102 3.56201 1.4668 3.49316 1.67773 3.49316C1.91211 3.49316 2.10693 3.58838 2.26221 3.77881L4.10791 6.04297L7.68066 0.368652C7.77148 0.230957 7.86523 0.134277 7.96191 0.0786133C8.06152 0.0200195 8.18311 -0.00927734 8.32666 -0.00927734C8.5376 -0.00927734 8.71191 0.0581055 8.84961 0.192871C8.9873 0.327637 9.05615 0.497559 9.05615 0.702637C9.05615 0.778809 9.04297 0.85791 9.0166 0.939941C8.99023 1.02197 8.94922 1.10693 8.89355 1.19482L4.80225 7.45703C4.64111 7.69434 4.40967 7.81299 4.10791 7.81299Z' fill='white'/%3E%3C/svg%3E%0A");
   background-size: 70%;
   background-position: center;
   background-repeat: no-repeat;
 }
 
+.p-form-checkbox-cont > input + span::after{
+  content: '';
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 9;
+} 
+
+.p-form-checkbox-cont > input + span:active::after{
+  border-radius: 5px;
+  backdrop-filter: brightness(1.2);
+} 
+
 .p-form-checkbox-cont > input:checked + span::before{
   opacity: 1;
 }
@@ -406,6 +443,10 @@ textarea.p-form-text {
   text-align:center;
 }
 
+.p-chip:focus-within span{
+  outline: 2px solid #64baff;
+}
+
 .p-chip svg{
   display:block;
   margin:auto;

+ 1 - 1
dist/css/layout.css

@@ -25,7 +25,7 @@
 
 .p-layout .link,
 .p-layout input {
-  font-size: 1.14rem;
+  font-size: 0.813rem;
 }
 
 .p-callout {

+ 8 - 4
dist/css/modals.css

@@ -57,15 +57,19 @@
   display: flex;
 }
 
-.p-modal-button-container > a {
+.p-modal-button-container > a, .p-modal-button-container > button {
+  cursor: pointer;
+  background: transparent;
+  border: 0;
   border-top: 1px solid var(--p-modal-bd-color);
   color: var(--primary-col-ac);
   padding: 30px 0%;
   text-decoration: none;
   width: 100%;
+  font-size: 1rem;
 }
 
-.p-modal-button-container > a:not(:first-child){
+.p-modal-button-container > *:not(:first-child){
   border-left: 1px solid var(--p-modal-bd-color);
 }
 
@@ -98,12 +102,12 @@
     display: block;
   }
 
-  .p-modal-button-container > a {
+  .p-modal-button-container > a, .p-modal-button-container > button {
     border-left: 0;
     display: block;
     padding: 2vh 0%;
   }
-  .p-modal-button-container > a:not(:first-child){
+  .p-modal-button-container > *:not(:first-child){
     border-left: 0px;
   }
 }

+ 11 - 7
dist/css/segmented-controls.css

@@ -14,7 +14,11 @@
   overflow: hidden;
   width: 100%;
 }
-.p-segmented-controls a {
+.p-segmented-controls a, .p-segmented-controls button {
+  background: transparent;
+  border: 0;
+  cursor: pointer;
+  font-size: 1rem;
   color: var(--color-segmented);
   flex: 1;
   padding: 10px;
@@ -23,11 +27,11 @@
   transition: 0.5s color, 0.5s background, 0.5s border-color;
   -webkit-tap-highlight-color: transparent;
 }
-.p-segmented-controls a.active {
+.p-segmented-controls a.active, .p-segmented-controls button.active  {
   background: var(--color-segmented);
   color: var(--p-segmented-bg);
 }
-.p-segmented-controls a:not(:first-child) {
+.p-segmented-controls>*:not(:first-child) {
   border-left: 1px solid currentColor;
 }
 
@@ -41,10 +45,10 @@
   border-radius: 30px;
 }
 
-.p-segmented-controls-alt a:not(:first-child) {
+.p-segmented-controls-alt>*:not(:first-child) {
   border: 0;
 }
-.p-segmented-controls-alt a.active {
+.p-segmented-controls-alt>*.active {
   background: var(--color-lighter-segment);
   color: var(--color-segmented);
   font-weight: bold;
@@ -64,11 +68,11 @@
 .p-segmented-controls-outline-alt {
   border-radius: 30px;
 }
-.p-segmented-controls-outline-alt a {
+.p-segmented-controls-outline-alt a, .p-segmented-controls-outline-alt button {
   border: 2px solid transparent;
   border-radius: 30px;
 }
-.p-segmented-controls-outline-alt a.active {
+.p-segmented-controls-outline-alt a.active, .p-segmented-controls-outline-alt button.active {
   background: var(--p-segmented-bg);
   border-color: var(--color-segmented);
   border-radius: 30px;

+ 4 - 0
dist/css/shadows.css

@@ -39,21 +39,25 @@
 }
 
 .p-blur-1{
+  -webkit-backdrop-filter: saturate(180%) blur(20px);
   backdrop-filter: saturate(180%) blur(20px);
   background: rgba(0,0,0,.1);
 }
 
 .p-blur-2{
+  -webkit-backdrop-filter: saturate(200%) blur(30px);
   backdrop-filter: saturate(200%) blur(30px);
   background: rgba(0,0,0,.1);
 }
 
 .p-blur-3{
+  -webkit-backdrop-filter: saturate(200%) blur(45px);
   backdrop-filter: saturate(200%) blur(45px);
   background: rgba(0,0,0,.1);
 }
 
 .p-blur-4{
+  -webkit-backdrop-filter: saturate(200%) blur(81px);
   backdrop-filter: saturate(200%) blur(81px);
   background: rgba(0,0,0,.1);
 }

+ 7 - 3
dist/css/tabs.css

@@ -153,16 +153,20 @@
   text-align: center;
 }
 
-.p-mobile-tabs a {
+.p-mobile-tabs a, .p-mobile-tabs button {
+  background: transparent;
+  border: 0;
   text-decoration: none;
   color: var(--p-mobile-tabs-color);
   transition: color 0.5s;
   font-size: 0.5rem; 
   padding: 0 20px;
   display: block;
+  width: -webkit-fill-available;
+  cursor: pointer;
 }
 
-.p-mobile-tabs a.active {
+.p-mobile-tabs a.active, .p-mobile-tabs button.active {
   color: var(--primary-col-ac);
   font-weight: 600;
 }
@@ -173,7 +177,7 @@
   margin-bottom: 0.2rem;
 }
 
-.p-mobile-tabs a.active svg{
+.p-mobile-tabs a.active svg, .p-mobile-tabs button.active svg{
   stroke-width:2.5;
 }
 

+ 112 - 69
docs/examples/actions.html

@@ -8,6 +8,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta charset="utf-8" />
     <meta
       name="viewport"
@@ -33,7 +34,7 @@
   <body class="p-layout">
 
 <div class="p-action-background">
-    <div class="p-action-big-container" id="actions" data-p-close-on-outside="true">
+    <div class="p-action-big-container" id="actions" data-p-close-on-outside="true" aria-hidden="true">
       <div class="p-action-container">
         <div class="p-action-title">
           <h3 class="p-action-title--intern">What do you want to do?</h3>
@@ -48,7 +49,7 @@
       </div>
     </div>
 
-    <div class="p-action-big-container" id="actions2" data-p-close-on-outside="true">
+    <div class="p-action-big-container" id="actions2" data-p-close-on-outside="true" aria-hidden="true">
       <div class="p-action-container">
         <div class="p-action-title">
           <h3 class="p-action-title--intern">What do you want to do?</h3>
@@ -62,7 +63,7 @@
       </div>
     </div>
 
-    <div class="p-action-big-container" id="actions_basic" data-p-close-on-outside="true">
+    <div class="p-action-big-container" id="actions_basic" data-p-close-on-outside="true" aria-hidden="true">
       <div class="p-action-container">
         <div class="p-action-title">
           <h3 class="p-action-title--intern">Welcome to actions</h3>
@@ -93,7 +94,7 @@
     <h1>Actions</h1>
     <div class="master">
       <p>
-        Actions are a big part of iOS, and we couldn't stop thinking of adding them. That's why we added it into Puppertino! To use actions, you can
+        Actions are a fundamental part of iOS design, so we couldn’t resist bringing them to Puppertino. Now, you can enjoy their intuitive functionality within your projects! To use actions, you can
         <a
           href="https://github.com/codedgar/Puppertino/blob/master/dist/css/actions.css"
           target="_blank"
@@ -111,18 +112,18 @@
           target="_blank"
           >Full CSS</a
         >
-        and
-        <a
-          href="https://github.com/codedgar/Puppertino/blob/master/dist/js/full.js"
-          target="_blank"
-          >Full JS</a
-        >
+        and currently, there's not full JS.
       </p>
 
+      <div class="talk-about-it">
+        <h3>Note on Previous Versions</h3>
+        <p>In earlier versions of Puppertino, actions were exclusively links. In the latest version, you now have the option to use either <strong>Buttons</strong> or <strong>Links</strong>, offering greater flexibility for appropriate actions while maintaining proper semantics and accessibility.</p>
+      </div>
+
       <div class="talk-about-it">
         <h2>Let's talk about actions!</h2>
         <p>
-          Actions in Puppertino are very similar to modals. They prompt the user to take an decision. The difference is that Actions can feature multiple decisions and are easier to acccess than modals.
+          Actions in Puppertino function similarly to modals, prompting users to make a decision. The difference is that Actions can feature multiple decisions and are easier to acccess than modals.
         </p>
 
 
@@ -135,11 +136,11 @@
     <div class="talk-about-it">
       <h2>General usage.</h2>
       <p>
-        The usage it's the practically the same as modals. You need a container for the Actions and the button that you want to toggle actions needs to have the attribute <code class="code">data-p-open-actions</code> with the #id of the actions you want to open. And the actions with the according ID.
+        Using Actions in Puppertino is nearly identical to Modals. To set up an Action, you need a container for the elements and a button to toggle it. The button should include the attribute <code class="code">data-p-open-actions</code> with the <code class="code">#id</code> of the Action you want to open, while the Action itself should have a matching ID.
         <br><br>
-        There are also variants so you can arrange the elements differently, but <strong>please</strong> try to use just one variant at a time, one action with icon, then another one without action and so on can cause confusion on users and it also looks visually unpleasant, so handle with care.
+        Actions come with several layout variants, allowing you to arrange elements differently. However, it’s important to stick with one style per Action. Mixing variants, like combining options with icons and without, can confuse users and disrupt the visual flow, so it’s best to maintain consistency.
         <br><br>
-        Actions also support the attribute <code class="code">data-p-close-on-outside="true"</code> to close the action on click outside of the area.
+        For added functionality, Actions also support the <code class="code">data-p-close-on-outside="true"</code> attribute, which automatically closes the Action when the user clicks outside its area.
       </p>
 
       <button class="p-btn" data-p-open-actions="#actions">
@@ -174,7 +175,7 @@
       &#60;a href="#" class="p-action--intern">New tab&#60;/a>
     &#60;/div>
     &#60;div class="p-action-container">
-      &#60;a href="#" class="p-action--intern p-action-cancel" data-p-cancel-action="true">Cancel&#60;/a>
+      &#60;button class="p-action--intern p-action-cancel" data-p-cancel-action="true">Cancel&#60;/button>
     &#60;/div>
   &#60;/div>
 
@@ -206,6 +207,101 @@
       </div>
     </div>
 
+    <div class="talk-about-it">
+      <section id="api-methods">
+        <h2>JS API Methods</h2>
+        <p>In newer versions, the old JavaScript has been replaced with the PuppertinoActionsMan class—a lightweight utility for managing action cards within the Puppertino framework.
+          <br><br>
+          While the way you use action cards remains unchanged thanks to automatic initialization, this class introduces programmatic methods for Opening or Closing action cards, and handling user interactions. <br><br> Here's what currently possible using Puppertino's Actions Manager.</p>
+        <article id="open-action" class="d-flex align-bottom mt-4">
+          <div class="flex-1 w-100">
+            <h3>openAction(selector)</h3>
+            <p>Opens the action card specified by the CSS selector.</p>
+            <p><strong>Parameters:</strong></p>
+            <ul>
+              <li><code class="code">selector</code> (string): CSS selector for the action card to open.</li>
+            </ul>
+          </div>
+          <div class="flex-1 w-100">
+            <p><strong>Usage:</strong></p>
+            <div class="code">
+<pre>
+<code>  
+    PuppertinoActionsManager.openAction("#exampleAction");
+</code>
+</pre>
+            </div>
+          </div>
+        </article>
+    
+        <article id="close-active-action" class="d-flex align-bottom mt-4">
+          <div class="flex-1 w-100">
+            <h3>closeActiveAction()</h3>
+            <p>Closes the currently active (open) action card.</p>
+          </div>
+          <div class="flex-1 w-100">
+            <p><strong>Usage:</strong></p>
+            <div class="code">
+<pre>
+<code>
+    PuppertinoActionsManager.closeActiveAction();
+</code>
+</pre>
+            </div>
+          </div>
+        </article>
+    
+        <article id="close-action" class="d-flex align-bottom mt-4">
+          <div class="flex-1 w-100">
+            <h3>closeAction(selector)</h3>
+            <p>Closes a specific action card specified by the CSS selector.</p>
+            <p><strong>Parameters:</strong></p>
+            <ul>
+              <li><code class="code">selector</code> (string): CSS selector for the action card to close.</li>
+            </ul>
+          </div>
+          <div class="flex-1 w-100">
+            <p><strong>Usage:</strong></p>
+            <div class="code">
+<pre>
+<code>
+    PuppertinoActionsManager.closeAction("#exampleAction");
+</code>
+</pre>
+            </div>
+          </div>
+        </article>
+    
+        <article id="is-action-open" class="d-flex align-bottom mt-4">
+          <div class="flex-1 w-100">
+            <h3>isActionOpen(selector)</h3>
+            <p>Checks if a specific action card is currently open.</p>
+            <p><strong>Parameters:</strong></p>
+            <ul>
+              <li><code class="code">selector</code> (string): CSS selector for the action card to check.</li>
+            </ul>
+            <p><strong>Returns:</strong></p>
+            <ul>
+              <li><code class="code">true</code> if the action card is open, <code>false</code> otherwise.</li>
+            </ul>
+          </div>
+          <div class="flex-1 w-100">
+            <p><strong>Usage:</strong></p>
+            <div class="code">
+<pre>
+<code>
+    if (PuppertinoActionsManager.isActionOpen("#exampleAction")) {
+      console.log("The action card is open.");
+    }
+</code>
+</pre>
+            </div>
+          </div>
+        </article>
+      </section>
+    </div>
+    
+
  
 </body>
 
@@ -217,58 +313,5 @@
   <script>
     hljs.initHighlightingOnLoad();
   </script>
-  <script type="text/javascript">
-    (function (document) {
-
-  var p_actions = document.querySelectorAll("[data-p-open-actions]");
-  var actions = document.querySelectorAll(".p-action-big-container");
-  var cancel_action = document.querySelectorAll("[data-p-cancel-action]");
-
-  for (var item of p_actions) {
-    item.addEventListener("click", function (event) {
-      event.preventDefault();
-      var selector = this.getAttribute("data-p-open-actions");
-      if (selector.length == 0) {
-        console.warn(
-          "Error. The data-p-open-action attribute is empty, please add the ID of the action you want to open."
-        );
-        return false;
-      }
-      document.querySelector(".p-action-background").classList.add("nowactive");
-      document.body.classList.add("p-modal-opened");
-      document.querySelector(selector).classList.add("active");
-    });
-  }
-
-  for (var element of cancel_action) {
-    element.addEventListener("click", function (event) {
-      event.preventDefault();
-      document.querySelector(".p-action-big-container.active").classList.remove("active");
-      document.querySelector(".p-action-background").classList.remove("nowactive");
-      document.body.classList.remove("p-modal-opened");
-    });
-  }
-
-  document
-    .querySelector(".p-action-background")
-    .addEventListener("click", function (event) {
-      event.preventDefault();
-      var opened_action = document.querySelector(".p-action-big-container.active");
-      if (opened_action.getAttribute("data-p-close-on-outside") == "true") {
-        event.stopPropagation();
-        opened_action.classList.remove("active");
-        document
-          .querySelector(".p-action-background")
-          .classList.remove("nowactive");
-        document.body.classList.remove("p-modal-opened");
-      }
-    });
-
-  for (var action of actions) {
-      action.addEventListener("click", function (event) {
-      event.stopPropagation();
-    });
-  }
-})(document)
-  </script>
+  <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/src/js/actions.js"></script>
 </html>

+ 18 - 13
docs/examples/buttons.html

@@ -10,6 +10,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta charset="utf-8" />
     <meta
       name="viewport"
@@ -66,7 +67,9 @@
       <div class="talk-about-it">
         <h2>Push Buttons.</h2>
         <p>
-          Push buttons come in several variations to suit different scenarios. They can be implemented as <code class="code">&#60;a></code> or <code class="code">&#60;button></code>elements, depending on the context. For cases where buttons need to be disabled, the disabled attribute can be applied to prevent user interaction. This ensures that the buttons are visually and functionally consistent with your design while maintaining clear communication with users about available actions.
+          Push buttons come in several variations to suit different scenarios. They can be implemented as <code class="code">&#60;a></code> or <code class="code">&#60;button></code> elements, depending on the context.
+          <br><br>
+          For cases where buttons need to be disabled, the <strong>disabled</strong> and the <strong>tabindex="-1"</strong> attributes can be applied to prevent user interaction. This ensures that the buttons are visually and functionally consistent with your design while maintaining clear communication with users about available actions.
         </p>
         <div class="row">
           <div class="col-md-6 mt-lg-5">
@@ -102,7 +105,7 @@
 
 &#60;button class="p-btn p-btn-destructive">Destructive&#60;/button>
 
-&#60;a href="#" class="p-btn p-btn-disabled">Disabled&#60;/a>
+&#60;a href="#" class="p-btn p-btn-disabled" disabled>Disabled&#60;/a>
     
 &#60;a href="#" class="p-btn p-prim-col">Primary&#60;/a>
     
@@ -192,25 +195,27 @@
         <p>
           The Icon Button, previously known as the "Help Button", is a circular button that contains an icon. You can use a letter, font-based icons (such as Font Awesome), or an SVG. For more details on available icons, refer to the <a href="https://codedgar.github.io/Puppertino/examples/icons.html">icons section</a>.
           <br><br>
+          For accessibility, always make sure to add descriptive text to the icon button using the <strong>aria-label</strong> attribute.
+          <br><br>
           Customization is straightforward: you can modify the border and icon colors using the <code class="code">color</code> property or by applying classes from the <a href="/docs/examples/color_palette.html">Color palette</a>. If you'd like to remove the button's borders, simply add the <code class="code">p-btn-icon-no-border</code> class.
         </p>
-        <a href="#" class="p-btn-icon">?</a>
+        <a href="#" class="p-btn-icon" aria-label="Help Button">?</a>
 
-        <a href="#" class="p-btn-icon p-lime-color">🐶</a>
+        <a href="#" class="p-btn-icon p-lime-color" aria-label="Dog Button">🐶</a>
 
-        <a href="#" class="p-btn-icon p-bubblegum-color">
+        <a href="#" class="p-btn-icon p-bubblegum-color" aria-label="Like button">
           <svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>
         </a>
 
-        <a href="#" class="p-btn-icon p-strawberry-color">
+        <a href="#" class="p-btn-icon p-strawberry-color" aria-label="Delete button">
           <svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>
         </a>
 
-        <a href="#" class="p-btn-icon p-orange p-silver-100-color p-btn-icon-no-border">
+        <a href="#" class="p-btn-icon p-orange p-silver-100-color p-btn-icon-no-border" aria-label="Delete User Button">
           <svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><line x1="23" y1="11" x2="17" y2="11"></line></svg>
         </a>
 
-        <a href="#" class="p-btn-icon p-mint p-silver-100-color">
+        <a href="#" class="p-btn-icon p-mint p-silver-100-color" aria-label="Bold Text Button">
           <svg viewBox="0 0 24 24" width="13" height="13" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path></svg>
         </a>
 
@@ -218,11 +223,11 @@
         <div class="code">
           <pre>
 				<code class="html">
-&#60;a href="#" class="p-btn-icon">?&#60;/a>
+&#60;a href="#" class="p-btn-icon" aria-label="Help Button">?&#60;/a>
 
-&#60;a href="#" class="p-btn-icon">&#60;!-- SVG ICON HERE -->&#60;/a>
+&#60;a href="#" class="p-btn-icon" aria-label="Custom Button">&#60;!-- SVG ICON HERE -->&#60;/a>
 
-&#60;a href="#" class="p-btn-icon p-mint p-silver-100-color">Custom Color&#60;/a>
+&#60;a href="#" class="p-btn-icon p-mint p-silver-100-color" aria-label="Custom Color Button">Custom Color&#60;/a>
 				</code>
 			</pre>
         </div>
@@ -242,7 +247,7 @@
 
         <a href="#" class="p-btn p-btn-scope p-btn-scope-unactive">Unactive</a>
 
-        <a href="#" class="p-btn p-btn-scope p-btn-disabled">Disabled</a>
+        <a href="#" class="p-btn p-btn-scope p-btn-disabled" disabled="true" tabindex="-1">Disabled</a>
 
         <a href="#" class="p-btn p-btn-scope p-btn-scope-outline">Action</a>
 
@@ -256,7 +261,7 @@
 
 &#60;a href="#" class="p-btn p-btn-scope p-btn-scope-unactive">Unactive&#60;/a>
 
-&#60;a href="#" class="p-btn p-btn-scope p-btn-disabled">Disabled&#60;/a>
+&#60;a href="#" class="p-btn p-btn-scope p-btn-disabled" disabled="true" tabindex="-1">Disabled&#60;/a>
 
 &#60;a href="#" class="p-btn p-btn-scope p-btn-scope-outline">Action&#60;/a>
 				</code>

+ 1 - 0
docs/examples/color_palette.html

@@ -13,6 +13,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta
       name="viewport"
       content="width=device-width, initial-scale=1, shrink-to-fit=no"

+ 1 - 0
docs/examples/dark_mode.html

@@ -9,6 +9,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta
       name="viewport"
       content="width=device-width, initial-scale=1, shrink-to-fit=no"

+ 22 - 0
docs/examples/doc.css

@@ -208,6 +208,10 @@ pre {
   flex-wrap: wrap;
 }
 
+.w-100{
+  width: 100%;
+}
+
 .mw-300{
   width: 300px;
   position: relative;
@@ -344,4 +348,22 @@ pre {
   background-color: transparent;
   border-color: transparent;
   margin-top: 30px;
+}
+
+.deprecated-code{
+  border: 2px solid currentColor;
+  color: var(--p-banana-700);
+  background: transparent;
+}
+
+.flex-1{
+  flex: 1;
+}
+
+.align-bottom{
+  align-items: end;
+}
+
+.mt-4{
+  margin-top: 30px;
 }

+ 67 - 62
docs/examples/forms.html

@@ -6,6 +6,7 @@
 	<link href="https://rsms.me/inter/inter.css" rel="stylesheet">
     <!-- <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/puppertino.css"> -->
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     
   	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
   	<meta http-equiv="x-ua-compatible" content="ie=edge">
@@ -32,11 +33,26 @@
 	</div>
 	<h1>Forms</h1>
 	<div class="master">
-		<p>Forms are one of the things that move forward the interface, that's why in Puppertino, form elements come with ready-to-work, native validation. You can use the Forms using the <a href="https://github.com/codedgar/Puppertino/blob/master/dist/css/forms.css" target="_blank">CSS of Forms</a> or <a href="https://github.com/codedgar/Puppertino/blob/master/dist/css/newfull.css" target="_blank">downloading the full CSS</a> (Not recommended if you are just going to use this component).</p>
+		<p>Forms are an essential part of any user interface. In Puppertino, form elements are designed to be both functional and intuitive, featuring built-in native validation for seamless user experiences.
+      <br><br>
+      You can use the Forms using the <a href="https://github.com/codedgar/Puppertino/blob/master/dist/css/forms.css" target="_blank">CSS of Forms</a> or <a href="https://github.com/codedgar/Puppertino/blob/master/dist/css/newfull.css" target="_blank">downloading the full CSS</a> (Not recommended if you are just going to use this component).</p>
 
 		<div class="talk-about-it">
 			<h2>Select.</h2>
-			<p>The select box works exactly as expected, and you can change the width and height without affecting the overall composition of the element without problems. The select does not have native validation, but you can still add the <code class="code">p-form-invalid</code> and <code class="code">p-form-valid</code> classes respectively.</p>
+			<p>
+        The select box in Puppertino is designed to behave as expected while offering flexibility in customization. You can adjust the width and height without compromising the overall composition or functionality of the element.
+        
+        <br><br>
+        <strong>Note</strong>: The select box does not include native validation. However, you can manually apply validation states by adding the following classes:
+      </p>
+      <ul>
+        <li>
+          <code class="code">p-form-invalid</code>: Indicates an invalid input.
+        </li>
+        <li>
+          <code class="code">p-form-valid</code>: Indicates a valid input.
+        </li>
+      </ul>
 
 			<div class="p-form-select">
 			    <select>
@@ -65,29 +81,25 @@
       <div class="talk-about-it">
         <h2>Text fields.</h2>
         <p>
-          Text fields are everything that gets text into it, maybe passwords,
-          emails, messages, anything you want. They can have validation,
-          truncated text, or be just plain without any of those things. The
-          <strong>validated input</strong> relies on native HTML validation, so
-          things like <code class="code">min-length</code> or
-          <code class="code">type</code> will work perfectly on it. The
-          validation will be visible once the user changes the focus out of the
-          element, and I prefer it this way to avoid users getting confused
-          while they type. The no-validated input retains its style whenever
-          the input is invalid or valid. The truncated text, adds three dots
-          (...) at the end when of the input if the text overflows from it. The
-          appearance of the dots takes place after the user changes the focus
-          out of the element. The truncated text does not disable the validation.
-          <br />
-          It is also possible to add labels to every type of input without it
-          affecting in any way the functionality of the input.
-          <br />
-          About the validation: You should always include a placeholder if you were intending
-          to use validation. If you don't intend to validate the input
-          text, you can add the class
-          <code class="code">p-form-no-validate</code>.<br />
-          Text fields can be textareas or inputs.
+          Text fields are versatile elements for capturing user input such as passwords, emails, messages, or any type of text data. Puppertino provides flexible options for text fields, supporting validation, truncation, and plain (non-validated) inputs.
         </p>
+
+        <p><strong>Features of Text Fields</strong></p>
+        <ul>
+          <li>
+            <strong>Validation</strong>: Supports native HTML validation (e.g., min-length, type). Feedback is shown after focus leaves the field. Use p-form-no-validate to disable validation styling.
+          </li>
+          <li>
+            <strong>Truncated Text</strong>: Adds an ellipsis (...) when text overflows, visible after focus shifts. Compatible with validation.
+          </li>
+          <li>
+            <strong>Plain Inputs</strong>: Keeps consistent styling regardless of validity, ideal for non-validated fields.
+          </li>
+          <li>
+            <strong>Labels</strong>: Fully compatible with all input types for enhanced accessibility.
+          </li>
+          
+        </ul>
         <input
           type="email"
           class="p-form-text"
@@ -133,8 +145,9 @@
       <div class="talk-about-it">
         <h2>Alternate inputs.</h2>
         <p>
-          Alternate inputs are bigger versions of the original inputs. The intended usage of this is login or registration forms.<br><br>
-          The alternate inputs work similarly to the default input. The only thing that changes is the class, but validation and others work exactly as expected.
+          Alternate inputs are larger versions of the standard text fields, ideal for use in login or registration forms.
+          <br><br>
+          They function identically to default inputs, with the same validation and styling options. The only difference is the class applied to the element.
         </p>
         <input
           type="email"
@@ -193,12 +206,7 @@
       <div class="talk-about-it">
         <h2>Radio Buttons.</h2>
         <p>
-          Radio buttons are similar to checkboxes, the main difference between
-          radio buttons and checkboxes, is that radio buttons can only one of
-          them in a group of radio buttons can be checked. Radio buttons do
-          not provide any type of validation. And come with a nice, simple
-          animation. You can change the width and height of the radio buttons
-          without being worried about breaking the composition.
+          Radio buttons resemble checkboxes but allow only one selection per group. They lack validation but feature a smooth animation. Width and height can be adjusted without compromising their layout.
         </p>
 
         <label class="p-form-radio-cont">
@@ -238,9 +246,7 @@
       <div class="talk-about-it">
         <h2>Checkboxes.</h2>
         <p>
-          Checkboxes, allow the users to select several predefined values.
-          Checkboxes in puppertino, just as Radio buttons, support changing the
-          width and height without damaging the composition of the checkbox.
+          Checkboxes let users select multiple predefined options. Like radio buttons, Puppertino checkboxes support adjustable width and height without affecting their layout.
         </p>
 
         <label class="p-form-checkbox-cont">
@@ -280,7 +286,7 @@
       <div class="talk-about-it">
         <h2>Chips.</h2>
         <p>
-          Chips are essentially checkboxes, but cooler. This makes it easier and more interactive for the user to select multiple items or filter information. They come in several flavors and also have support for icons.
+          Chips are an enhanced, interactive alternative to checkboxes, offering a more engaging way for users to select multiple items or filter information. They come in various styles and support the inclusion of icons for added functionality.
         </p>
 
         <label class="p-chip">
@@ -386,17 +392,9 @@
       <div class="talk-about-it">
         <h2>Switches.</h2>
         <p>
-          Switches are part of those elements that are popular in iOS devices.
-          And I wasn't going to add them until version 2.0 (Since I wanted to
-          create a custom element) But a friend gave me the starter code and I
-          just cleaned it a bit and made it look like the aesthetic of
-          Puppertino. So big shotout to <strong>Ivanot</strong> because he
-          essentially created this element :)<br /><br />
-          The Switch is essentially a checkbox, so you have to expect it to work
-          as one. You can change the width and height of the switch changing the
-          variable <code class="code">--width</code> inside the class
-          <code class="code">p-form-switch</code>. Everything in the element
-          will resize automatically so don't worry about breaking it on resize.
+          Switches are inspired by popular iOS design elements and were introduced to Puppertino with help from a friend and contributor, <a href="https://github.com/ivanotOrozco" target="_blank" rel="nofollow">Ivanot</a>. A special thanks to him for providing the foundation for this component!<br /><br />
+          
+          Switches function like checkboxes and are styled to fit the Puppertino aesthetic. You can adjust their size by modifying the <code class="code">--width</code> variable within the <code class="code">p-form-switch</code> class. The element resizes automatically, ensuring consistent appearance and functionality.
         </p>
 
         <label class="p-form-switch showcaseme_bro">
@@ -420,10 +418,9 @@
       </div>
 
       <div class="talk-about-it">
-        <h2>Buttons.</h2>
+        <h2>Buttons. <code class="code deprecated-code">Deprecated</code></h2>
         <p>
-          These buttons are a really small version of the buttons component of
-          Puppertino, just to add send and cancel buttons.
+          These are smaller versions of the Puppertino button component, designed for simple actions like "Send" or "Cancel." However, this component will be removed in future versions. We recommend transitioning to the <a href="https://codedgar.github.io/Puppertino/examples/buttons.html">full button component</a> for better support and functionality.
         </p>
 
         <input type="submit" class="p-form-button p-form-send" value="Send" />
@@ -445,19 +442,27 @@
       </div>
 
       <div class="talk-about-it">
-        <h2>More about validation.</h2>
+        <h2>Custom Validation.</h2>
+        <p>
+          Need to handle a type of validation that HTML doesn’t natively support? Puppertino has you covered.<br /><br />
+
+          <strong>How to Use Puppertino Validation</strong>
+        </p>
+
+        <ul>
+          <li>
+            Use the <code class="code">p-form-invalid</code> and <code class="code">p-form-valid</code> classes to indicate validation states.
+          </li>
+          <li>
+            Add or remove these classes as needed, but never apply both simultaneously.
+          </li>
+          <li>
+            Validation feedback appears after the user moves focus out of the input field, ensuring a smoother experience.
+          </li>
+        </ul>
+
         <p>
-          Let's say that you are working on a type of validation that can't be
-          done with native HTML validation, can you use the validation of
-          Puppertino? Of course, you can.<br /><br />
-          To use validations in your code, you can use the classes
-          <code class="code">p-form-invalid</code> and
-          <code class="code">p-form-valid</code> respectively. You can add or
-          remove these classes as you may need. But don't add both at the same
-          time. Also, here in Puppertino we don't encourage validation in
-          real-time. Since we think is better for the user to see the validation
-          once he changes the focus of the input.<br />Please be aware that
-          using these classes will disable the default validation.
+          <strong>Important</strong>: Applying these classes disables default HTML validation, so use them when custom validation logic is required.
         </p>
 
         <input

+ 1 - 0
docs/examples/getting-started.html

@@ -9,6 +9,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta
       name="viewport"
       content="width=device-width, initial-scale=1, shrink-to-fit=no"

+ 1 - 0
docs/examples/icons.html

@@ -13,6 +13,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta
       name="viewport"
       content="width=device-width, initial-scale=1, shrink-to-fit=no"

+ 1 - 0
docs/examples/index.html

@@ -13,6 +13,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta
       name="viewport"
       content="width=device-width, initial-scale=1, shrink-to-fit=no"

+ 1 - 0
docs/examples/layout.html

@@ -12,6 +12,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta
       name="viewport"
       content="width=device-width, initial-scale=1, shrink-to-fit=no"

+ 121 - 13
docs/examples/modals.html

@@ -9,6 +9,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta
       name="viewport"
       content="width=device-width, initial-scale=1, shrink-to-fit=no"
@@ -33,12 +34,12 @@
   <body class="p-layout">
     <div class="p-modal-background">
       <div class="p-modal" id="normal-modal" data-p-close-on-outside="true">
-        <h2>Sup!</h2>
+        <h2>Hello!</h2>
         <p>This modal has 3 buttons, please don't add more than 3 :)</p>
         <div class="p-modal-button-container">
           <a href="#"><strong>Confirm</strong></a>
           <a href="#">Settings</a>
-          <a href="#" data-p-cancel>Cancel</a>
+          <button data-p-cancel>Cancel</button>
         </div>
       </div>
 
@@ -92,9 +93,8 @@
     <h1>Modals</h1>
     <div class="master">
       <p>
-        Modals are one of the most emblematic items of iOS, so I added the
-        modals of iOS instead of adding dialog boxes like in macOS. To
-        use modals, you need 2 components:
+        Modals are iconic in iOS design, making them a natural addition to Puppertino. Unlike macOS-style dialog boxes (planned for future versions), these modals are currently categorized under mobile components.
+        <br><br>To implement modals, you’ll need:
         <a
           href="https://github.com/codedgar/Puppertino/blob/master/dist/css/modals.css"
           target="_blank"
@@ -118,14 +118,19 @@
       </p>
 
       <div class="talk-about-it">
-        <h2>Before jumping on it.</h2>
+        <h3>Note on Previous Versions</h3>
+        <p>In earlier versions of Puppertino, modal actions were exclusively links. In the latest version, you now have the option to use either <strong>Buttons</strong> or <strong>Links</strong>, offering greater flexibility for appropriate actions while maintaining proper semantics and accessibility.</p>
+      </div>
+
+      <div class="talk-about-it">
+        <h2>Modals: Limitations</h2>
         <p>
-          I wanted to make modals not only as easy to use as possible, but UX
-          optimized as I could. That's why I'm calling it now, adding form
-          elements in modals <span class="lmao_codedgar_b_dumb">is not supported</span> <sttrong>will be added in the next release</sttrong>, and also opening several modals is
-          not supported either.<br />
-          Now onto modals and types:
+          Puppertino modals are designed for simplicity and optimized user experience. However, there are current limitations to be aware of:
         </p>
+        <ul>
+          <li>Adding form elements within modals is <strong>not supported</strong> (planned for the next release).</li>
+          <li>Opening multiple modals simultaneously is not supported to maintain usability.</li>
+        </ul>
 
         <button data-p-open-modal="#normal-modal" class="p-btn">
           Three button modal
@@ -195,7 +200,7 @@
 		&#60;h2>Hey!&#60;/h2>
 		&#60;p>This is an example modal!&#60;/p>
 		&#60;div class="p-modal-button-container">
-			&#60;a href="#" data-p-cancel>OK&#60;/a>
+			&#60;button data-p-cancel>OK&#60;/button>
 		&#60;/div>
 	&#60;/div>
 
@@ -236,6 +241,109 @@
       </div>
     </div>
 
+    <div class="talk-about-it">
+      <section id="api-methods">
+        <h2>JS API Methods</h2>
+        <p>In newer versions, the old JavaScript has been replaced with the PuppertinoModalMan class—a lightweight utility for managing modals within the Puppertino framework.
+          <br><br>
+          While the way you use modals remains unchanged thanks to automatic initialization, this class introduces programmatic methods for Opening or Closing modals, and handling user interactions. <br><br> Here's what currently possible using Puppertino's Modal Manager</p>
+        <article id="open-modal" class="d-flex align-bottom mt-4">
+          <div class="flex-1 w-100">
+            <h3>openModal(selector)</h3>
+            <p>Opens the modal specified by the CSS selector.</p>
+            <p><strong>Parameters:</strong></p>
+            <ul>
+              <li><code class="code">selector</code> (string): CSS selector for the modal to open.</li>
+            </ul>
+          </div>
+          <div class="flex-1 w-100">
+            <p><strong>Usage:</strong></p>
+
+          <div class="code" >
+<pre>
+  <code>  
+PuppertinoModalManager.openModal("#exampleModal");
+</code>
+</pre>
+</div>
+</div>
+
+        </article>
+      
+        <article id="close-active-modal" class="d-flex align-bottom mt-4">
+          <div class="flex-1 w-100">
+            <h3>closeActiveModal()</h3>
+            <p>Closes the currently active (open) modal.</p>
+          </div>
+          <div class="flex-1 w-100">
+            <p><strong>Usage:</strong></p>
+            <div class="code">
+<pre>
+  <code>
+PuppertinoModalManager.closeActiveModal();
+</code>
+</pre>
+            </div>
+          </div>
+          
+        </article>
+      
+        <article id="close-modal" class="d-flex align-bottom mt-4">
+          <div class="flex-1 w-100">
+            <h3>closeModal(selector)</h3>
+            <p>Closes a specific modal specified by the CSS selector.</p>
+            <p><strong>Parameters:</strong></p>
+            <ul>
+              <li><code class="code">selector</code> (string): CSS selector for the modal to close.</li>
+            </ul>
+          </div>
+          <div class="flex-1 w-100">
+            <p><strong>Usage:</strong></p>
+            <div class="code">
+
+<pre>
+  <code>
+PuppertinoModalManager.closeModal("#exampleModal");
+  </code>
+</pre>
+
+</div>
+
+          </div>
+
+        </article>
+      
+        <article id="is-modal-open" class="d-flex align-bottom mt-4">
+          <div class="flex-1 w-100">
+            <h3>isModalOpen(selector)</h3>
+            <p>Checks if a specific modal is currently open.</p>
+            <p><strong>Parameters:</strong></p>
+            <ul>
+              <li><code class="code">selector</code> (string): CSS selector for the modal to check.</li>
+            </ul>
+            <p><strong>Returns:</strong></p>
+            <ul>
+              <li><code class="code">true</code> if the modal is open, <code>false</code> otherwise.</li>
+            </ul>
+          </div>
+          <div class="flex-1 w-100">
+            <p><strong>Usage:</strong></p>
+            <div class="code">
+<pre>
+  <code>
+if (PuppertinoModalManager.isModalOpen("#exampleModal")) {
+  console.log("The modal is open.");
+}
+</code>
+</pre>
+            </div>
+            
+          </div>
+          
+        </article>
+      </section>
+    </div>
+
     <div class="talk-about-it">
       <h2>Support for blur on Firefox.</h2>
       <p>
@@ -249,7 +357,7 @@
 </body>
 
   <script src="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/src/js/dakmode_manager.js"></script>
-  <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/codedgar/Puppertino/src/js/modals.js"></script>
+  <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/src/js/modals.js"></script>
   <script
     type="text/javascript"
     src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"

+ 8 - 2
docs/examples/segmented_controls.html

@@ -9,6 +9,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta
       name="viewport"
       content="width=device-width, initial-scale=1, shrink-to-fit=no"
@@ -68,6 +69,11 @@
         > of the component.
       </p>
 
+      <div class="talk-about-it">
+        <h3>Note on Previous Versions</h3>
+        <p>In earlier versions of Puppertino, segmented controls were exclusively links. In the latest version, you now have the option to use either <strong>Buttons</strong> or <strong>Links</strong>, offering greater flexibility for appropriate actions while maintaining proper semantics and accessibility.</p>
+      </div>
+
       <div class="talk-about-it">
         <h2>General Usage of the segmented controls.</h2>
         <p>
@@ -79,7 +85,7 @@
           <div class="mw-300">
             <div class="p-segmented-controls">
               <a href="#" class="active">Roadmap</a>
-              <a href="#">Satelite</a>
+              <button>Satelite</button>
             </div>
           </div>
         </div>
@@ -266,5 +272,5 @@
   <script defer>
     hljs.initHighlightingOnLoad();
   </script>
-  <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/codedgar/Puppertino/src/js/segmented_controls.js"></script>
+  <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/src/js/segmented_controls.js"></script>
 </html>

+ 1 - 0
docs/examples/shadows.html

@@ -13,6 +13,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta
       name="viewport"
       content="width=device-width, initial-scale=1, shrink-to-fit=no"

+ 11 - 5
docs/examples/tabs.html

@@ -8,6 +8,7 @@
     />
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta charset="utf-8" />
     <meta
       name="viewport"
@@ -68,6 +69,11 @@
         (Not recommended if you are just going to use this component).
       </p>
 
+      <div class="talk-about-it">
+        <h3>Note on Previous Versions</h3>
+        <p>In earlier versions of Puppertino, tabs were exclusively links. In the latest version, you now have the option to use either <strong>Buttons</strong> or <strong>Links</strong>, offering greater flexibility for appropriate actions while maintaining proper semantics and accessibility.</p>
+      </div>
+
       <div class="talk-about-it">
         <h2>Desktop tabs.</h2>
         <p>
@@ -153,10 +159,10 @@
                 
                 <div class="p-mobile-tabs">
                 <div>
-                  <a href="#" class="active" data-p-mobile-toggle="#demo1">
+                  <button class="active" data-p-mobile-toggle="#demo1">
                     <svg viewBox="0 0 24 24" width="19" height="19" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
                     Home
-                  </a>
+                  </button>
                 </div>
                 <div>
                   <a href="#" data-p-mobile-toggle="#demo2">
@@ -203,10 +209,10 @@
   
   &#60;div class="p-mobile-tabs">
   &#60;div>
-    &#60;a href="#" class="active" data-p-mobile-toggle="#demo1">
+    &#60;button class="active" data-p-mobile-toggle="#demo1">
       &#60;!-- SVG ICON -->
       Home
-    &#60;/a>
+    &#60;/button>
   &#60;/div>
   &#60;div>
     &#60;a href="#" data-p-mobile-toggle="#demo2">
@@ -246,5 +252,5 @@
   <script defer>
     hljs.initHighlightingOnLoad();
   </script>
-  <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/codedgar/Puppertino/src/js/tabs.js"></script>
+  <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/src/js/tabs.js"></script>
 </html>

+ 1 - 0
docs/index.html

@@ -4,6 +4,7 @@
     <title>Home - Puppertino Framework</title>
     
     <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/codedgar/Puppertino@latest/dist/css/newfull.css" />
+
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta http-equiv="x-ua-compatible" content="ie=edge" />

+ 119 - 51
src/js/actions.js

@@ -1,52 +1,120 @@
-    (function (document) {
-
-        var p_actions = document.querySelectorAll("[data-p-open-actions]");
-        var actions = document.querySelectorAll(".p-action-big-container");
-        var cancel_action = document.querySelectorAll("[data-p-cancel-action]");
-
-        for (var item of p_actions) {
-            item.addEventListener("click", function (event) {
-                event.preventDefault();
-                var selector = this.getAttribute("data-p-open-actions");
-                if (selector.length == 0) {
-                    console.warn(
-                        "Error. The data-p-open-action attribute is empty, please add the ID of the action you want to open."
-                    );
-                    return false;
-                }
-                document.querySelector(".p-action-background").classList.add("nowactive");
-                document.body.classList.add("p-modal-opened");
-                document.querySelector(selector).classList.add("active");
-            });
+class PuppertinoActionsMan {
+    constructor() {
+      this.init();
+    }
+  
+    init() {
+      this.attachOpenActionListeners();
+      this.attachCloseActionListeners();
+      this.attachOutsideClickListener();
+      this.preventActionClickPropagation();
+    }
+  
+    attachOpenActionListeners() {
+      const openActionButtons = document.querySelectorAll("[data-p-open-actions]");
+      openActionButtons.forEach(button => {
+        button.addEventListener("click", (event) => {
+          event.preventDefault();
+          const selector = button.getAttribute("data-p-open-actions");
+  
+          if (!selector || selector.trim().length === 0) {
+            console.warn(
+              "Error: The data-p-open-actions attribute is empty. Please specify the ID or selector of the action card you want to open."
+            );
+            return;
+          }
+  
+          this.openAction(selector);
+        });
+      });
+    }
+  
+    attachCloseActionListeners() {
+      const closeActionButtons = document.querySelectorAll("[data-p-cancel-action]");
+      closeActionButtons.forEach(button => {
+        button.addEventListener("click", (event) => {
+          event.preventDefault();
+          this.closeActiveAction();
+        });
+      });
+    }
+  
+    attachOutsideClickListener() {
+      const actionBackground = document.querySelector(".p-action-background");
+      if (actionBackground) {
+        actionBackground.addEventListener("click", (event) => {
+          event.preventDefault();
+          const activeAction = document.querySelector(".p-action-big-container.active");
+  
+          if (
+            activeAction &&
+            activeAction.getAttribute("data-p-close-on-outside") === "true"
+          ) {
+            this.closeActiveAction();
+          }
+        });
+      }
+    }
+  
+    preventActionClickPropagation() {
+      const actions = document.querySelectorAll(".p-action-big-container");
+      actions.forEach(action => {
+        action.addEventListener("click", (event) => {
+          event.stopPropagation();
+        });
+      });
+    }
+  
+    openAction(selector) {
+      const action = document.querySelector(selector);
+  
+      if (!action) {
+        console.warn(
+          `Error: No action card found matching selector "${selector}". Ensure the selector is correct.`
+        );
+        return;
+      }
+  
+      document.querySelector(".p-action-background").classList.add("nowactive");
+      document.body.classList.add("p-modal-opened");
+      action.classList.add("active");
+      action.setAttribute("aria-hidden", "false");
+    }
+  
+    closeActiveAction() {
+      const activeAction = document.querySelector(".p-action-big-container.active");
+      if (activeAction) {
+        activeAction.classList.remove("active");
+        activeAction.setAttribute("aria-hidden", "true");
+      }
+  
+      const actionBackground = document.querySelector(".p-action-background");
+      if (actionBackground) {
+        actionBackground.classList.remove("nowactive");
+      }
+  
+      document.body.classList.remove("p-modal-opened");
+    }
+  
+    closeAction(selector) {
+      const action = document.querySelector(selector);
+      if (action && action.classList.contains("active")) {
+        action.classList.remove("active");
+        action.setAttribute("aria-hidden", "true");
+        const actionBackground = document.querySelector(".p-action-background");
+        if (actionBackground) {
+          actionBackground.classList.remove("nowactive");
         }
-
-        for (var element of cancel_action) {
-            element.addEventListener("click", function (event) {
-                event.preventDefault();
-                document.querySelector(".p-action-big-container.active").classList.remove("active");
-                document.querySelector(".p-action-background").classList.remove("nowactive");
-                document.body.classList.remove("p-modal-opened");
-            });
-        }
-
-        document
-            .querySelector(".p-action-background")
-            .addEventListener("click", function (event) {
-                event.preventDefault();
-                var opened_action = document.querySelector(".p-action-big-container.active");
-                if (opened_action.getAttribute("data-p-close-on-outside") == "true") {
-                    event.stopPropagation();
-                    opened_action.classList.remove("active");
-                    document
-                        .querySelector(".p-action-background")
-                        .classList.remove("nowactive");
-                    document.body.classList.remove("p-modal-opened");
-                }
-            });
-
-        for (var action of actions) {
-            action.addEventListener("click", function (event) {
-                event.stopPropagation();
-            });
-        }
-    })(document)
+        document.body.classList.remove("p-modal-opened");
+      }
+    }
+  
+    isActionOpen(selector) {
+      const action = document.querySelector(selector);
+      return action ? action.classList.contains("active") : false;
+    }
+  }
+  
+  // Initialize the PuppertinoActionsMan instance
+  const PuppertinoActionsManager = new PuppertinoActionsMan();
+  

+ 106 - 41
src/js/modals.js

@@ -1,51 +1,116 @@
-(function (document) {
-  var p_selector_modal = document.querySelectorAll("[data-p-open-modal]");
-  var modals = document.querySelectorAll(".p-modal");
-  var cancel_button = document.querySelectorAll("[data-p-cancel]");
-
-  for (var item of p_selector_modal) {
-    item.addEventListener("click", function (event) {
-      event.preventDefault();
-      var selector = this.getAttribute("data-p-open-modal");
-      if (selector.length == 0) {
-        console.warn(
-          "Error. The data-p-open-modal attribute is empty, please add the ID of the modal you want to open."
-        );
-        return false;
-      }
-      document.querySelector(".p-modal-background").classList.add("nowactive");
-      document.body.classList.add("p-modal-opened");
-      document.querySelector(selector).classList.add("active");
+class PuppertinoModalMan {
+  constructor() {
+    this.init();
+  }
+
+  init() {
+    this.attachOpenModalListeners();
+    this.attachCloseModalListeners();
+    this.attachOutsideClickListener();
+    this.preventModalClickPropagation();
+  }
+
+  attachOpenModalListeners() {
+    const openModalButtons = document.querySelectorAll("[data-p-open-modal]");
+    openModalButtons.forEach(button => {
+      button.addEventListener("click", (event) => {
+        event.preventDefault();
+        const selector = button.getAttribute("data-p-open-modal");
+
+        if (!selector || selector.trim().length === 0) {
+          console.warn(
+            "Error: The data-p-open-modal attribute is empty. Please specify the ID or selector of the modal you want to open."
+          );
+          return;
+        }
+
+        this.openModal(selector);
+      });
     });
   }
 
-  for (var element of cancel_button) {
-    element.addEventListener("click", function (event) {
-      event.preventDefault();
-      document.querySelector(".p-modal.active").classList.remove("active");
-      document.querySelector(".p-modal-background").classList.remove("nowactive");
-      document.body.classList.remove("p-modal-opened");
+  attachCloseModalListeners() {
+    const closeModalButtons = document.querySelectorAll("[data-p-cancel]");
+    closeModalButtons.forEach(button => {
+      button.addEventListener("click", (event) => {
+        event.preventDefault();
+        this.closeActiveModal();
+      });
     });
   }
 
-  document
-    .querySelector(".p-modal-background")
-    .addEventListener("click", function (event) {
-      event.preventDefault();
-      var opened_modal = document.querySelector(".p-modal.active");
-      if (opened_modal.getAttribute("data-p-close-on-outside") == "true") {
+  attachOutsideClickListener() {
+    const modalBackground = document.querySelector(".p-modal-background");
+    if (modalBackground) {
+      modalBackground.addEventListener("click", (event) => {
+        event.preventDefault();
+        const activeModal = document.querySelector(".p-modal.active");
+
+        if (
+          activeModal &&
+          activeModal.getAttribute("data-p-close-on-outside") === "true"
+        ) {
+          this.closeActiveModal();
+        }
+      });
+    }
+  }
+
+  preventModalClickPropagation() {
+    const modals = document.querySelectorAll(".p-modal");
+    modals.forEach(modal => {
+      modal.addEventListener("click", (event) => {
         event.stopPropagation();
-        opened_modal.classList.remove("active");
-        document
-          .querySelector(".p-modal-background")
-          .classList.remove("nowactive");
-        document.body.classList.remove("p-modal-opened");
-      }
+      });
     });
+  }
 
-  for (var modal of modals) {
-    modal.addEventListener("click", function (event) {
-      event.stopPropagation();
-    });
+  openModal(selector) {
+    const modal = document.querySelector(selector);
+
+    if (!modal) {
+      console.warn(
+        `Error: No modal found matching selector "${selector}". Ensure the selector is correct.`
+      );
+      return;
+    }
+
+    document.querySelector(".p-modal-background").classList.add("nowactive");
+    document.body.classList.add("p-modal-opened");
+    modal.classList.add("active");
   }
-})(document)
+
+  closeActiveModal() {
+    const activeModal = document.querySelector(".p-modal.active");
+    if (activeModal) {
+      activeModal.classList.remove("active");
+    }
+
+    const modalBackground = document.querySelector(".p-modal-background");
+    if (modalBackground) {
+      modalBackground.classList.remove("nowactive");
+    }
+
+    document.body.classList.remove("p-modal-opened");
+  }
+
+  closeModal(selector) {
+    const modal = document.querySelector(selector);
+    if (modal && modal.classList.contains("active")) {
+      modal.classList.remove("active");
+      const modalBackground = document.querySelector(".p-modal-background");
+      if (modalBackground) {
+        modalBackground.classList.remove("nowactive");
+      }
+      document.body.classList.remove("p-modal-opened");
+    }
+  }
+
+  isModalOpen(selector) {
+    const modal = document.querySelector(selector);
+    return modal ? modal.classList.contains("active") : false;
+  }
+}
+
+// Initialize the PuppertinoModalMan instance
+const PuppertinoModalManager = new PuppertinoModalMan();

+ 30 - 8
src/js/segmented_controls.js

@@ -1,11 +1,33 @@
-(function (document) {
-  var p_segmented_controls = document.querySelectorAll(".p-segmented-controls a");
-  for (var item of p_segmented_controls) {
-    item.addEventListener("click", function (event) {
-      event.preventDefault();
-      this.parentElement.querySelector("a.active").classList.remove("active");
-      this.classList.add("active");
+class PuppertinoSegmentedCon {
+  constructor() {
+    this.init();
+  }
+
+  init() {
+    this.attachSegmentedControlListeners();
+  }
+
+  attachSegmentedControlListeners() {
+    const segmentedControls = document.querySelectorAll(".p-segmented-controls a, .p-segmented-controls button");
+    segmentedControls.forEach(control => {
+      control.addEventListener("click", (event) => {
+        event.preventDefault();
+        this.activateControl(control);
+      });
     });
   }
 
-})(document)
+  activateControl(control) {
+    const parent = control.parentElement;
+    const activeElement = parent.querySelector(".active");
+
+    if (activeElement) {
+      activeElement.classList.remove("active");
+    }
+
+    control.classList.add("active");
+  }
+}
+
+// Initialize the PuppertinoSegmentedCon instance
+const segmentedControlManager = new PuppertinoSegmentedCon();

+ 76 - 27
src/js/tabs.js

@@ -1,31 +1,80 @@
-(function (d) {
-  d.addEventListener("click", (e) => {
-    let idTabs = Array.from(document.querySelectorAll(".p-tabs-container"));
-    let identifier = e.target.parentElement.parentElement.id;
-
-    idTabs.forEach((element) => {
-      if (element.id === identifier) {
-        let tabs = Array.from(element.children[0].children);
-        let panels = Array.from(element.children[1].children);
-        let i = tabs.indexOf(e.target);
-        tabs.map((tab) => tab.classList.remove("p-is-active"));
-        tabs[i].classList.add("p-is-active");
-        panels.map((panel) => panel.classList.remove("p-is-active"));
-        panels[i].classList.add("p-is-active");
+class PuppertinoTabsMan {
+  constructor() {
+    this.init();
+  }
+
+  init() {
+    this.attachDesktopTabListeners();
+    this.attachMobileTabListeners();
+  }
+
+  attachDesktopTabListeners() {
+    document.addEventListener("click", (event) => {
+      const tabsContainer = event.target.closest(".p-tabs-container");
+      if (!tabsContainer) return;
+
+      const tabs = Array.from(tabsContainer.querySelector(".p-tabs").children);
+      const panels = Array.from(tabsContainer.querySelector(".p-panels").children);
+      const clickedIndex = tabs.indexOf(event.target);
+
+      if (clickedIndex !== -1) {
+        this.activateTabByIndex(`#${tabsContainer.id}`, clickedIndex);
       }
     });
-  });
-})(document);
-
-let mobile_tabs_pupper = document.querySelectorAll('.p-mobile-tabs a');
-
-for (var item of mobile_tabs_pupper) {
-    item.addEventListener("click", function (event) {
-      event.preventDefault();
-      var remover_pupper = this.parentNode.parentNode;
-      remover_pupper.querySelector('.active').classList.remove('active');
-      this.classList.add('active');
-      remover_pupper.parentNode.querySelector('.p-mobile-tabs--content.active').classList.remove('active');
-      document.querySelector(this.getAttribute('data-p-mobile-toggle')).classList.add('active');
+  }
+
+  attachMobileTabListeners() {
+    const mobileTabs = document.querySelectorAll(".p-mobile-tabs a, .p-mobile-tabs button");
+
+    mobileTabs.forEach(tab => {
+      tab.addEventListener("click", (event) => {
+        event.preventDefault();
+
+        const parentContainer = tab.closest(".p-mobile-tabs");
+        const contentContainer = document.querySelector(
+          `.p-mobile-tabs--content.active`
+        );
+        const targetPanel = document.querySelector(tab.getAttribute("data-p-mobile-toggle"));
+
+        if (parentContainer) {
+          const activeTab = parentContainer.querySelector(".active");
+          if (activeTab) activeTab.classList.remove("active");
+          tab.classList.add("active");
+        }
+
+        if (contentContainer) {
+          contentContainer.classList.remove("active");
+        }
+
+        if (targetPanel) {
+          targetPanel.classList.add("active");
+        }
+      });
     });
+  }
+
+  activateTabByIndex(containerSelector, index) {
+    const container = document.querySelector(containerSelector);
+    if (!container) {
+      console.warn(`Container not found: ${containerSelector}`);
+      return;
+    }
+
+    const tabs = Array.from(container.querySelector(".p-tabs").children);
+    const panels = Array.from(container.querySelector(".p-panels").children);
+
+    if (index < 0 || index >= tabs.length || index >= panels.length) {
+      console.warn(`Invalid index: ${index}`);
+      return;
+    }
+
+    tabs.forEach(tab => tab.classList.remove("p-is-active"));
+    panels.forEach(panel => panel.classList.remove("p-is-active"));
+
+    tabs[index].classList.add("p-is-active");
+    panels[index].classList.add("p-is-active");
+  }
 }
+
+// Initialize the PuppertinoTabsMan instance
+const tabsManager = new PuppertinoTabsMan();