@kerkhoff-ict/solora 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.css CHANGED
@@ -1,22 +1,20 @@
1
1
  /* src/components/button.css */
2
- :root {
3
- --color-primary: #0071e3;
4
- --color-secondary: #f5f5f5;
5
- --color-success: #28a745;
6
- --color-warning: #ffc107;
7
- --color-danger: #dc3545;
8
- --color-text-light: #ffffff;
9
- --color-text-dark: #000000;
10
- }
11
2
  .btn {
12
3
  font-weight: 600;
13
4
  border: none;
14
5
  border-radius: 9999px;
15
6
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
16
- border-radius: 9999px;
17
7
  cursor: pointer;
18
8
  transition: background 0.2s, filter 0.2s;
19
9
  }
10
+ .btn-rounded {
11
+ padding: 0 !important;
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: center;
15
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
16
+ cursor: pointer;
17
+ }
20
18
  .btn-sm {
21
19
  padding: 0.1875rem 1rem;
22
20
  font-size: 0.9375rem;
@@ -115,7 +113,7 @@
115
113
  [class*="btn-["]:hover {
116
114
  filter: brightness(0.85);
117
115
  }
118
- @media (prefers-color-scheme: dark) {
116
+ :root.dark {
119
117
  .btn-primary {
120
118
  background: #0558be;
121
119
  color: var(--color-text-light, #fff);
@@ -367,7 +365,7 @@
367
365
  .codeblock pre::-webkit-scrollbar-track {
368
366
  background: transparent;
369
367
  }
370
- @media (prefers-color-scheme: dark) {
368
+ :root.dark {
371
369
  .codeblock {
372
370
  background: #1e1e2f88;
373
371
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
@@ -476,7 +474,7 @@
476
474
  margin-top: 0.5rem;
477
475
  overflow: hidden;
478
476
  overflow-y: auto;
479
- background: rgba(255, 255, 255, 0);
477
+ background: transparent;
480
478
  border: 1px solid rgba(255, 255, 255, 0.3);
481
479
  backdrop-filter: blur(12px);
482
480
  -webkit-backdrop-filter: blur(12px);
@@ -538,44 +536,227 @@
538
536
  color: rgba(0, 0, 0, 0.6);
539
537
  cursor: default;
540
538
  }
541
- @media (prefers-color-scheme: dark) {
542
- .dropdown-btn {
543
- background: #1c1c1e;
544
- color: #f0f0f0;
545
- border: 1px solid rgba(255, 255, 255, 0.2);
546
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
547
- }
548
- .dropdown-btn:hover {
549
- background: rgba(255, 255, 255, 0.05);
550
- }
551
- .dropdown-content {
552
- background: rgba(28, 28, 30, 0.8);
553
- backdrop-filter: blur(12px);
554
- -webkit-backdrop-filter: blur(12px);
555
- box-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
556
- }
557
- .dropdown-item {
558
- color: #f0f0f0;
559
- }
560
- .dropdown-item:hover {
561
- background: rgba(255, 255, 255, 0.08);
562
- }
563
- .dropdown-item.active {
564
- background: rgba(255, 255, 255, 0.12);
565
- }
566
- .dropdown-divider {
567
- background: rgba(255, 255, 255, 0.2);
568
- }
569
- .dropdown-item[aria-disabled=true],
570
- .dropdown-item.placeholder {
571
- color: rgba(255, 255, 255, 0.4);
572
- }
573
- .dropdown-label {
574
- color: rgba(255, 255, 255, 0.6);
575
- }
576
- .dropdown-content::-webkit-scrollbar-thumb {
577
- background: rgba(255, 255, 255, 0.2);
578
- }
539
+ :root.dark .dropdown-btn {
540
+ background: #1c1c1e;
541
+ color: #f0f0f0;
542
+ border: 1px solid rgba(255, 255, 255, 0.2);
543
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
544
+ }
545
+ :root.dark .dropdown-btn:hover {
546
+ background: rgba(255, 255, 255, 0.05);
547
+ }
548
+ :root.dark .dropdown-content {
549
+ background: transparent;
550
+ backdrop-filter: blur(12px);
551
+ -webkit-backdrop-filter: blur(12px);
552
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
553
+ }
554
+ :root.dark .dropdown-item {
555
+ color: #f0f0f0;
556
+ }
557
+ :root.dark .dropdown-item:hover {
558
+ background: rgba(255, 255, 255, 0.08);
559
+ }
560
+ :root.dark .dropdown-item.active {
561
+ background: rgba(255, 255, 255, 0.12);
562
+ }
563
+ :root.dark .dropdown-divider {
564
+ background: rgba(255, 255, 255, 0.2);
565
+ }
566
+ :root.dark .dropdown-item[aria-disabled=true],
567
+ :root.dark .dropdown-item.placeholder {
568
+ color: rgba(255, 255, 255, 0.4);
569
+ }
570
+ :root.dark .dropdown-label {
571
+ color: rgba(255, 255, 255, 0.6);
572
+ }
573
+ :root.dark .dropdown-content::-webkit-scrollbar-thumb {
574
+ background: rgba(255, 255, 255, 0.2);
579
575
  }
580
576
 
577
+ /* src/components/input.css */
578
+ .sol-input-group {
579
+ display: flex;
580
+ flex-direction: column;
581
+ gap: 0.4rem;
582
+ font-family:
583
+ -apple-system,
584
+ BlinkMacSystemFont,
585
+ "Segoe UI",
586
+ Roboto,
587
+ Helvetica,
588
+ Arial,
589
+ sans-serif;
590
+ width: 100%;
591
+ }
592
+ .sol-label {
593
+ font-size: 0.85rem;
594
+ font-weight: 500;
595
+ color: var(--color-text-dark, #000);
596
+ opacity: 0.6;
597
+ margin-left: 0.2rem;
598
+ }
599
+ .sol-input {
600
+ appearance: none;
601
+ -webkit-appearance: none;
602
+ width: 100%;
603
+ padding: 0.3rem 0.4rem;
604
+ font-size: 0.95rem;
605
+ border-radius: 12px;
606
+ border: 1px solid rgba(0, 0, 0, 0.1);
607
+ background: var(--color-bg, #fefefe);
608
+ color: var(--color-text-dark, #000);
609
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.05), 0 2px 8px rgba(0, 0, 0, 0.05);
610
+ transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);
611
+ outline: none;
612
+ }
613
+ .sol-input::placeholder {
614
+ color: var(--color-text-dark, #000);
615
+ opacity: 0.3;
616
+ }
617
+ .sol-input:hover {
618
+ border-color: rgba(0, 0, 0, 0.2);
619
+ background: var(--color-bg-hover, #ffffff);
620
+ }
621
+ .sol-input:focus {
622
+ border-color: var(--color-primary, #0071e3);
623
+ box-shadow: 0 0 0 4px var(--color-focus-glow, rgba(0, 113, 227, 0.15)), 0 2px 8px rgba(0, 0, 0, 0.05);
624
+ background: var(--color-bg-hover, #ffffff);
625
+ }
626
+ .sol-input:disabled {
627
+ background: var(--color-secondary, #f5f5f5);
628
+ color: var(--color-text-dark, #000);
629
+ opacity: 0.5;
630
+ cursor: not-allowed;
631
+ box-shadow: none;
632
+ }
633
+ .sol-input-error {
634
+ border-color: var(--color-danger, #dc3545) !important;
635
+ }
636
+ .sol-input-error:focus {
637
+ box-shadow: 0 0 0 4px var(--color-error-glow, rgba(220, 53, 69, 0.15)) !important;
638
+ }
639
+ :root.dark .sol-label {
640
+ color: var(--color-text-light, #fff);
641
+ opacity: 0.6;
642
+ }
643
+ :root.dark .sol-input {
644
+ background: rgba(28, 28, 30, 0.8);
645
+ color: var(--color-text-light, #fff);
646
+ border: 1px solid rgba(255, 255, 255, 0.15);
647
+ backdrop-filter: blur(12px);
648
+ -webkit-backdrop-filter: blur(12px);
649
+ box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.05), 0 4px 12px rgba(0, 0, 0, 0.4);
650
+ }
651
+ :root.dark .sol-input::placeholder {
652
+ color: var(--color-text-light, #fff);
653
+ opacity: 0.3;
654
+ }
655
+ :root.dark .sol-input:hover {
656
+ background: rgba(44, 44, 46, 0.9);
657
+ border-color: rgba(255, 255, 255, 0.25);
658
+ }
659
+ :root.dark .sol-input:focus {
660
+ background: rgba(44, 44, 46, 1);
661
+ border-color: var(--color-primary-dark, #0a84ff);
662
+ box-shadow: 0 0 0 4px var(--color-focus-glow-dark, rgba(10, 132, 255, 0.2)), 0 4px 12px rgba(0, 0, 0, 0.5);
663
+ }
664
+ :root.dark .sol-input-error {
665
+ border-color: var(--color-danger, #ff453a) !important;
666
+ }
667
+
668
+ /* src/components/contextMenu.css */
669
+ .sol-context-menu {
670
+ position: fixed;
671
+ display: none;
672
+ z-index: 9999;
673
+ min-width: 180px;
674
+ background: transparent;
675
+ backdrop-filter: blur(12px) saturate(180%);
676
+ -webkit-backdrop-filter: blur(12px) saturate(180%);
677
+ border: 1px solid rgba(0, 0, 0, 0.1);
678
+ border-radius: 12px;
679
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
680
+ padding: 5px;
681
+ font-family:
682
+ -apple-system,
683
+ BlinkMacSystemFont,
684
+ "Segoe UI",
685
+ Roboto,
686
+ Helvetica,
687
+ Arial,
688
+ sans-serif;
689
+ user-select: none;
690
+ opacity: 0;
691
+ transform: translateY(-10px) scale(0.95);
692
+ transition: opacity 0.15s ease, transform 0.15s cubic-bezier(0.25, 0.8, 0.25, 1);
693
+ }
694
+ .sol-context-menu.visible {
695
+ display: block;
696
+ opacity: 1;
697
+ transform: translateY(0) scale(1);
698
+ }
699
+ .sol-menu-item {
700
+ display: flex;
701
+ align-items: center;
702
+ justify-content: space-between;
703
+ padding: 0.2rem 0.3rem;
704
+ font-size: 0.85rem;
705
+ color: var(--color-text-dark, #000);
706
+ border-radius: 8px;
707
+ cursor: pointer;
708
+ transition: background 0.1s, color 0.1s;
709
+ }
710
+ .sol-menu-item:hover {
711
+ background: var(--color-primary, #007aff);
712
+ color: #fff;
713
+ }
714
+ .sol-menu-shortcut {
715
+ font-size: 0.75rem;
716
+ opacity: 0.5;
717
+ margin-left: 20px;
718
+ }
719
+ .sol-menu-item:hover .sol-menu-shortcut {
720
+ color: #fff;
721
+ opacity: 0.8;
722
+ }
723
+ .sol-menu-divider {
724
+ height: 1px;
725
+ background: rgba(0, 0, 0, 0.08);
726
+ margin: 4px 0;
727
+ }
728
+ :root.dark .sol-context-menu {
729
+ background: rgba(28, 28, 30, 0.8);
730
+ border: 1px solid rgba(255, 255, 255, 0.1);
731
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
732
+ }
733
+ :root.dark .sol-menu-item {
734
+ color: var(--color-text-light, #f0f0f0);
735
+ }
736
+ :root.dark .sol-menu-divider {
737
+ background: rgba(255, 255, 255, 0.1);
738
+ }
739
+
740
+ /* src/components/darkToggle.css */
741
+
581
742
  /* src/index.css */
743
+ :root {
744
+ --font-body:
745
+ -apple-system,
746
+ BlinkMacSystemFont,
747
+ "SF Pro Text",
748
+ "Helvetica Neue",
749
+ Arial,
750
+ sans-serif;
751
+ --font-display:
752
+ "SF Pro Display",
753
+ -apple-system,
754
+ BlinkMacSystemFont,
755
+ "Helvetica Neue",
756
+ sans-serif;
757
+ --font-mono:
758
+ "SF Mono",
759
+ "Menlo",
760
+ "Consolas",
761
+ monospace;
762
+ }
package/dist/index.js CHANGED
@@ -1917,16 +1917,362 @@ function initDropdowns() {
1917
1917
  });
1918
1918
  }
1919
1919
 
1920
+ // src/components/contextMenu.js
1921
+ function initContextMenu() {
1922
+ let menu = document.querySelector(".sol-context-menu");
1923
+ if (!menu) {
1924
+ menu = document.createElement("div");
1925
+ menu.className = "sol-context-menu";
1926
+ document.body.appendChild(menu);
1927
+ }
1928
+ let contextTarget = null;
1929
+ const showMenu = (e) => {
1930
+ e.preventDefault();
1931
+ contextTarget = e.target;
1932
+ const selection = window.getSelection().toString().trim();
1933
+ const link = e.target.closest("a");
1934
+ const img = e.target.closest("img");
1935
+ const input = e.target.closest("input, textarea, [contenteditable]");
1936
+ const isEditable = input || e.target.isContentEditable;
1937
+ const isTextInput = input && (input.type === "text" || input.type === "search" || input.type === "email" || input.type === "password" || input.tagName === "TEXTAREA" || input.isContentEditable);
1938
+ let menuHtml = "";
1939
+ if (selection.length > 0) {
1940
+ menuHtml += `
1941
+ <div class="sol-menu-label">Selectie</div>
1942
+ <div class="sol-menu-item" data-action="copy">
1943
+ Kopieer <span class="sol-menu-shortcut">\u2318C</span>
1944
+ </div>
1945
+ ${isEditable ? `
1946
+ <div class="sol-menu-item" data-action="cut">
1947
+ Knippen <span class="sol-menu-shortcut">\u2318X</span>
1948
+ </div>` : ""}
1949
+ <div class="sol-menu-item" data-action="search-google">
1950
+ Zoek op Google: <em>"${selection.slice(0, 20)}${selection.length > 20 ? "\u2026" : ""}"</em>
1951
+ </div>
1952
+ <div class="sol-menu-item" data-action="search-wiki">
1953
+ Zoek op Wikipedia\u2026
1954
+ </div>
1955
+ <div class="sol-menu-item" data-action="translate">
1956
+ Vertaal selectie\u2026
1957
+ </div>
1958
+ <div class="sol-menu-divider"></div>
1959
+ `;
1960
+ }
1961
+ if (isTextInput) {
1962
+ menuHtml += `
1963
+ <div class="sol-menu-label">Tekstveld</div>
1964
+ ${selection.length > 0 ? `
1965
+ <div class="sol-menu-item" data-action="cut">
1966
+ Knippen <span class="sol-menu-shortcut">\u2318X</span>
1967
+ </div>
1968
+ <div class="sol-menu-item" data-action="copy">
1969
+ Kopieer <span class="sol-menu-shortcut">\u2318C</span>
1970
+ </div>` : ""}
1971
+ <div class="sol-menu-item" data-action="paste">
1972
+ Plakken <span class="sol-menu-shortcut">\u2318V</span>
1973
+ </div>
1974
+ <div class="sol-menu-item" data-action="select-all">
1975
+ Alles selecteren <span class="sol-menu-shortcut">\u2318A</span>
1976
+ </div>
1977
+ <div class="sol-menu-item" data-action="clear-field">
1978
+ Veld wissen
1979
+ </div>
1980
+ <div class="sol-menu-divider"></div>
1981
+ `;
1982
+ }
1983
+ if (img) {
1984
+ menuHtml += `
1985
+ <div class="sol-menu-label">Afbeelding</div>
1986
+ <div class="sol-menu-item" data-action="open-img" data-url="${img.src}">
1987
+ Afbeelding openen in nieuw tabblad
1988
+ </div>
1989
+ <div class="sol-menu-item" data-action="copy-img-url" data-url="${img.src}">
1990
+ Kopieer afbeeldings-URL
1991
+ </div>
1992
+ <div class="sol-menu-item" data-action="download-img" data-url="${img.src}" data-filename="${img.alt || "afbeelding"}">
1993
+ Afbeelding opslaan\u2026
1994
+ </div>
1995
+ ${img.alt ? `
1996
+ <div class="sol-menu-item" data-action="copy-alt" data-text="${img.alt}">
1997
+ Kopieer alt-tekst
1998
+ </div>` : ""}
1999
+ <div class="sol-menu-divider"></div>
2000
+ `;
2001
+ }
2002
+ if (link) {
2003
+ menuHtml += `
2004
+ <div class="sol-menu-label">Link</div>
2005
+ <div class="sol-menu-item" data-action="open-tab" data-url="${link.href}">
2006
+ Open in nieuw tabblad
2007
+ </div>
2008
+ <div class="sol-menu-item" data-action="open-window" data-url="${link.href}">
2009
+ Open in nieuw venster
2010
+ </div>
2011
+ <div class="sol-menu-item" data-action="copy-link" data-url="${link.href}">
2012
+ Kopieer link-adres
2013
+ </div>
2014
+ <div class="sol-menu-divider"></div>
2015
+ `;
2016
+ }
2017
+ menuHtml += `
2018
+ <div class="sol-menu-label">Navigatie</div>
2019
+ <div class="sol-menu-item${!history.length || history.state === null ? " disabled" : ""}" data-action="go-back">
2020
+ \u2190 Vorige pagina
2021
+ </div>
2022
+ <div class="sol-menu-item" data-action="go-forward">
2023
+ \u2192 Volgende pagina
2024
+ </div>
2025
+ <div class="sol-menu-item" data-action="reload">
2026
+ Vernieuwen <span class="sol-menu-shortcut">\u2318R</span>
2027
+ </div>
2028
+ <div class="sol-menu-item" data-action="hard-reload">
2029
+ Geforceerd vernieuwen <span class="sol-menu-shortcut">\u21E7\u2318R</span>
2030
+ </div>
2031
+ <div class="sol-menu-divider"></div>
2032
+ `;
2033
+ menuHtml += `
2034
+ <div class="sol-menu-label">Pagina</div>
2035
+ <div class="sol-menu-item" data-action="copy-page-url">
2036
+ Kopieer pagina-URL
2037
+ </div>
2038
+ <div class="sol-menu-item" data-action="view-source">
2039
+ Bekijk paginabron <span class="sol-menu-shortcut">\u2318U</span>
2040
+ </div>
2041
+ <div class="sol-menu-item" data-action="print">
2042
+ Printen <span class="sol-menu-shortcut">\u2318P</span>
2043
+ </div>
2044
+ <div class="sol-menu-item" data-action="save-page">
2045
+ Pagina opslaan <span class="sol-menu-shortcut">\u2318S</span>
2046
+ </div>
2047
+ <div class="sol-menu-item" data-action="scroll-top">
2048
+ Naar boven scrollen
2049
+ </div>
2050
+ <div class="sol-menu-divider"></div>
2051
+ `;
2052
+ menuHtml += `
2053
+ <div class="sol-menu-label">Ontwikkelaar</div>
2054
+ <div class="sol-menu-item" data-action="inspect">
2055
+ Inspecteer element <span class="sol-menu-shortcut">\u2325\u2318I</span>
2056
+ </div>
2057
+ <div class="sol-menu-item" data-action="copy-selector">
2058
+ Kopieer CSS-selector
2059
+ </div>
2060
+ <div class="sol-menu-item" data-action="log-element">
2061
+ Log element in console
2062
+ </div>
2063
+ `;
2064
+ menu.innerHTML = menuHtml;
2065
+ menu.style.display = "block";
2066
+ let posX = e.clientX;
2067
+ let posY = e.clientY;
2068
+ const menuWidth = menu.offsetWidth;
2069
+ const menuHeight = menu.offsetHeight;
2070
+ posX = Math.max(0, posX);
2071
+ posY = Math.max(0, posY);
2072
+ menu.style.left = `${posX}px`;
2073
+ menu.style.top = `${posY}px`;
2074
+ requestAnimationFrame(() => menu.classList.add("visible"));
2075
+ };
2076
+ const hideMenu = () => {
2077
+ menu.classList.remove("visible");
2078
+ setTimeout(() => {
2079
+ if (!menu.classList.contains("visible")) menu.style.display = "none";
2080
+ }, 150);
2081
+ };
2082
+ const getCssSelector = (el) => {
2083
+ if (!el) return "";
2084
+ const parts = [];
2085
+ while (el && el.nodeType === Node.ELEMENT_NODE) {
2086
+ let selector = el.nodeName.toLowerCase();
2087
+ if (el.id) {
2088
+ selector += `#${el.id}`;
2089
+ parts.unshift(selector);
2090
+ break;
2091
+ }
2092
+ if (el.className) {
2093
+ selector += "." + [...el.classList].join(".");
2094
+ }
2095
+ const siblings = el.parentNode ? [...el.parentNode.children].filter((s) => s.nodeName === el.nodeName) : [];
2096
+ if (siblings.length > 1) {
2097
+ selector += `:nth-of-type(${siblings.indexOf(el) + 1})`;
2098
+ }
2099
+ parts.unshift(selector);
2100
+ el = el.parentNode;
2101
+ }
2102
+ return parts.join(" > ");
2103
+ };
2104
+ document.addEventListener("contextmenu", showMenu);
2105
+ document.addEventListener("click", hideMenu);
2106
+ window.addEventListener("scroll", hideMenu);
2107
+ document.addEventListener("keydown", (e) => {
2108
+ if (e.key === "Escape") hideMenu();
2109
+ });
2110
+ menu.addEventListener("click", (e) => {
2111
+ const item = e.target.closest(".sol-menu-item");
2112
+ if (!item || item.classList.contains("disabled")) return;
2113
+ const action = item.dataset.action;
2114
+ const url = item.dataset.url;
2115
+ const text = item.dataset.text;
2116
+ const filename = item.dataset.filename;
2117
+ const sel = window.getSelection().toString().trim();
2118
+ switch (action) {
2119
+ // Tekst
2120
+ case "copy":
2121
+ document.execCommand("copy");
2122
+ break;
2123
+ case "cut":
2124
+ document.execCommand("cut");
2125
+ break;
2126
+ case "paste":
2127
+ navigator.clipboard.readText().then((t) => document.execCommand("insertText", false, t));
2128
+ break;
2129
+ case "select-all":
2130
+ document.execCommand("selectAll");
2131
+ break;
2132
+ case "clear-field":
2133
+ if (contextTarget?.closest("input, textarea")) contextTarget.closest("input, textarea").value = "";
2134
+ break;
2135
+ // Zoeken & vertalen
2136
+ case "search-google":
2137
+ window.open(`https://www.google.com/search?q=${encodeURIComponent(sel)}`, "_blank");
2138
+ break;
2139
+ case "search-wiki":
2140
+ window.open(`https://nl.wikipedia.org/wiki/Special:Search?search=${encodeURIComponent(sel)}`, "_blank");
2141
+ break;
2142
+ case "translate":
2143
+ window.open(`https://translate.google.com/?sl=auto&tl=nl&text=${encodeURIComponent(sel)}`, "_blank");
2144
+ break;
2145
+ // Afbeelding
2146
+ case "open-img":
2147
+ window.open(url, "_blank");
2148
+ break;
2149
+ case "copy-img-url":
2150
+ navigator.clipboard.writeText(url);
2151
+ break;
2152
+ case "copy-alt":
2153
+ navigator.clipboard.writeText(text);
2154
+ break;
2155
+ case "download-img": {
2156
+ const a = document.createElement("a");
2157
+ a.href = url;
2158
+ a.download = filename || "afbeelding";
2159
+ a.click();
2160
+ break;
2161
+ }
2162
+ // Link
2163
+ case "open-tab":
2164
+ window.open(url, "_blank");
2165
+ break;
2166
+ case "open-window":
2167
+ window.open(url, "_blank", "noopener,noreferrer");
2168
+ break;
2169
+ case "copy-link":
2170
+ navigator.clipboard.writeText(url);
2171
+ break;
2172
+ // Navigatie
2173
+ case "go-back":
2174
+ history.back();
2175
+ break;
2176
+ case "go-forward":
2177
+ history.forward();
2178
+ break;
2179
+ case "reload":
2180
+ location.reload();
2181
+ break;
2182
+ case "hard-reload":
2183
+ location.href = location.href;
2184
+ break;
2185
+ // Pagina
2186
+ case "copy-page-url":
2187
+ navigator.clipboard.writeText(location.href);
2188
+ break;
2189
+ case "view-source":
2190
+ window.open(`view-source:${location.href}`, "_blank");
2191
+ break;
2192
+ case "print":
2193
+ window.print();
2194
+ break;
2195
+ case "save-page":
2196
+ document.execCommand("SaveAs");
2197
+ break;
2198
+ case "scroll-top":
2199
+ window.scrollTo({ top: 0, behavior: "smooth" });
2200
+ break;
2201
+ // Ontwikkelaar
2202
+ case "inspect":
2203
+ console.log("%c[Inspecteer element]", "color:#6c63ff;font-weight:bold", contextTarget);
2204
+ break;
2205
+ case "copy-selector":
2206
+ navigator.clipboard.writeText(getCssSelector(contextTarget));
2207
+ break;
2208
+ case "log-element":
2209
+ console.log("%c[Sol Context Menu] Geselecteerd element:", "color:#6c63ff", contextTarget);
2210
+ console.table({
2211
+ tag: contextTarget?.tagName,
2212
+ id: contextTarget?.id,
2213
+ classes: contextTarget?.className,
2214
+ selector: getCssSelector(contextTarget),
2215
+ innerText: contextTarget?.innerText?.slice(0, 80)
2216
+ });
2217
+ break;
2218
+ }
2219
+ hideMenu();
2220
+ });
2221
+ }
2222
+
2223
+ // src/components/darkToggle.js
2224
+ function initThemeToggle(elementSelector = ".sol-theme-toggle") {
2225
+ const html = document.documentElement;
2226
+ const toggles = document.querySelectorAll(elementSelector);
2227
+ const STORAGE_KEY = "solora-theme";
2228
+ const applyTheme = (theme) => {
2229
+ if (theme === "dark") {
2230
+ html.classList.add("dark");
2231
+ html.classList.remove("light");
2232
+ } else {
2233
+ html.classList.add("light");
2234
+ html.classList.remove("dark");
2235
+ }
2236
+ toggles.forEach((btn) => {
2237
+ btn.innerHTML = `<span>${theme === "dark" ? "\u2600\uFE0F" : "\u{1F319}"}</span>`;
2238
+ btn.setAttribute("aria-label", `Switch to ${theme === "dark" ? "light" : "dark"} mode`);
2239
+ });
2240
+ localStorage.setItem(STORAGE_KEY, theme);
2241
+ };
2242
+ const getInitialTheme = () => {
2243
+ const saved = localStorage.getItem(STORAGE_KEY);
2244
+ if (saved) return saved;
2245
+ const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
2246
+ return prefersDark ? "dark" : "light";
2247
+ };
2248
+ applyTheme(getInitialTheme());
2249
+ toggles.forEach((btn) => {
2250
+ btn.addEventListener("click", () => {
2251
+ const isDark = html.classList.contains("dark");
2252
+ applyTheme(isDark ? "light" : "dark");
2253
+ });
2254
+ });
2255
+ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => {
2256
+ if (!localStorage.getItem(STORAGE_KEY)) {
2257
+ applyTheme(e.matches ? "dark" : "light");
2258
+ }
2259
+ });
2260
+ }
2261
+
1920
2262
  // src/index.js
1921
2263
  if (typeof window !== "undefined") {
1922
2264
  document.addEventListener("DOMContentLoaded", () => {
1923
2265
  initCodeblocks();
1924
2266
  initDropdowns();
2267
+ initContextMenu();
2268
+ initThemeToggle();
1925
2269
  });
1926
2270
  }
1927
2271
  export {
1928
2272
  initCodeblocks,
1929
- initDropdowns
2273
+ initContextMenu,
2274
+ initDropdowns,
2275
+ initThemeToggle
1930
2276
  };
1931
2277
  /*! Bundled license information:
1932
2278
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kerkhoff-ict/solora",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "Simple CSS component library",
5
5
  "main": "dist/index.js",
6
6
  "style": "dist/index.css",