Skip to content

Commit 3f6b68a

Browse files
committed
feat: add plugin credit component to icon sets and settings pages
1 parent 721e003 commit 3f6b68a

File tree

3 files changed

+235
-1
lines changed

3 files changed

+235
-1
lines changed
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
{#
2+
# Plugin Credit Component
3+
# Reusable LindemannRock logo credit for plugin settings pages
4+
#
5+
# @link https://lindemannrock.com
6+
# @copyright Copyright (c) 2025 LindemannRock
7+
#}
8+
<hr/>
9+
<div id="lr-plugin-footer">
10+
<div class="lr-footer-left"></div>
11+
<div class="lr-footer-right">
12+
<a class="lr-brand-credit" href="https://lindemannrock.com" target="_blank">
13+
<div class="lr-brand-pill">
14+
<div class="lr-brand-mask">
15+
<div class="lr-brand-wrap">
16+
<span class="lr-brand-text">LINDEMANN ROCK</span>
17+
</div>
18+
<div class="lr-brand-logo">
19+
<svg width="25px" height="13px" xmlns="http://www.w3.org/2000/svg" viewbox="0 -.186 1350.04 682.02">
20+
<g>
21+
<path d="M1.01 19.05l262.32 653.89c2.11 5.26 7.21 8.71 12.88 8.71h256.56c5.73 0 10.87-3.52 12.94-8.86l126.36-325.54c1.25-3.22 1.25-6.79.01-10.01L545.71 8.9c-2.06-5.36-7.21-8.9-12.96-8.9H13.9c-9.83 0-16.55 9.93-12.89 19.05Z"></path>
22+
<path d="M1073.82 0H817.26c-5.73 0-10.87 3.52-12.94 8.86L677.96 334.4c-1.25 3.22-1.25 6.79-.01 10.01l126.39 328.35c2.06 5.36 7.21 8.9 12.96 8.9h518.86c9.83 0 16.54-9.93 12.88-19.05L1086.71 8.71C1084.6 3.45 1079.5 0 1073.82 0Z"></path>
23+
</g>
24+
</svg>
25+
</div>
26+
</div>
27+
</div>
28+
</a>
29+
</div>
30+
</div>
31+
32+
<style>
33+
#lr-plugin-footer {
34+
display: flex;
35+
justify-content: space-between;
36+
align-items: center;
37+
}
38+
39+
.lr-footer-left {
40+
flex: 1;
41+
}
42+
43+
.lr-footer-right {
44+
display: flex;
45+
align-items: center;
46+
}
47+
48+
.lr-brand-credit {
49+
position: relative;
50+
width: 46px;
51+
height: 38px;
52+
display: block;
53+
text-decoration: none;
54+
overflow: visible;
55+
transition: width 0.3s ease;
56+
}
57+
58+
.lr-brand-credit:hover {
59+
width: 195px;
60+
text-decoration: none;
61+
}
62+
63+
.lr-brand-pill {
64+
width: 100%;
65+
height: 38px;
66+
background: #e5e7eb;
67+
border-radius: 0.6rem;
68+
display: flex;
69+
align-items: center;
70+
justify-content: center;
71+
transition: all 0.3s ease;
72+
overflow: hidden;
73+
}
74+
75+
.lr-brand-credit:hover .lr-brand-pill {
76+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
77+
}
78+
79+
.lr-brand-mask {
80+
width: 100%;
81+
height: 100%;
82+
display: flex;
83+
align-items: center;
84+
justify-content: space-between;
85+
position: relative;
86+
padding: 0 12px;
87+
white-space: nowrap;
88+
}
89+
90+
.lr-brand-wrap {
91+
display: flex;
92+
align-items: center;
93+
justify-content: flex-start;
94+
flex: 1;
95+
padding-left: 0;
96+
}
97+
98+
.lr-brand-logo {
99+
display: flex;
100+
align-items: center;
101+
justify-content: center;
102+
position: absolute;
103+
right: 11px;
104+
top: 50%;
105+
transform: translateY(-50%);
106+
}
107+
108+
.lr-brand-text {
109+
font-size: 15px;
110+
font-weight: 600;
111+
color: #4b5563;
112+
opacity: 0;
113+
transform: translateX(-10px);
114+
transition: opacity 0.15s ease, transform 0.3s ease 0.1s;
115+
font-family: system-ui, -apple-system, sans-serif;
116+
white-space: nowrap;
117+
text-transform: uppercase;
118+
text-decoration: none;
119+
padding-right: 40px;
120+
}
121+
122+
.lr-brand-credit:hover .lr-brand-text {
123+
opacity: 1;
124+
transform: translateX(0);
125+
transition: all 0.3s ease 0.1s;
126+
}
127+
128+
.lr-brand-logo svg {
129+
width: 25px;
130+
height: 13px;
131+
}
132+
133+
.lr-brand-logo svg g {
134+
fill: #6b7280;
135+
transition: fill 0.3s ease;
136+
}
137+
</style>
138+
139+
<script>
140+
document.addEventListener('DOMContentLoaded', function () { // Bright colors that look good as backgrounds
141+
const brightColors = [
142+
'#E52521', // LindemannRock Red
143+
'#3B82F6', // Blue
144+
'#10B981', // Emerald
145+
'#8B5CF6', // Purple
146+
'#F59E0B', // Amber
147+
'#EF4444', // Red
148+
'#EC4899', // Pink
149+
'#06B6D4', // Cyan
150+
'#84CC16', // Lime
151+
'#F97316', // Orange
152+
'#6366F1', // Indigo
153+
'#14B8A6', // Teal
154+
'#F43F5E', // Rose
155+
'#A855F7', // Violet
156+
'#EAB308', // Yellow
157+
'#DC2626', // Dark Red
158+
'#7C3AED', // Purple Alt
159+
'#059669', // Dark Green
160+
'#0EA5E9', // Sky Blue
161+
'#D97706' // Dark Orange
162+
];
163+
164+
// Function to calculate luminance
165+
function getLuminance(hex) {
166+
const rgb = parseInt(hex.slice(1), 16);
167+
const r = (rgb >> 16) & 0xff;
168+
const g = (rgb >> 8) & 0xff;
169+
const b = (rgb >> 0) & 0xff;
170+
171+
const [rs, gs, bs] = [r, g, b].map(c => {
172+
c = c / 255;
173+
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
174+
});
175+
176+
return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
177+
}
178+
179+
// Function to get accessible text color (WCAG AA compliant)
180+
function getAccessibleTextColor(bgColor) {
181+
const bgLuminance = getLuminance(bgColor);
182+
const whiteContrast = (1 + 0.05) / (bgLuminance + 0.05);
183+
const blackContrast = (bgLuminance + 0.05) / (0 + 0.05);
184+
185+
return whiteContrast >= 4.5 ? '#ffffff' : '#000000';
186+
}
187+
188+
const pluginCredit = document.querySelector('.lr-brand-credit');
189+
if (pluginCredit) {
190+
const pill = pluginCredit.querySelector('.lr-brand-pill');
191+
const text = pluginCredit.querySelector('.lr-brand-text');
192+
const svg = pluginCredit.querySelector('.lr-brand-logo svg g');
193+
194+
pluginCredit.addEventListener('mouseenter', function () { // Pick random color
195+
const randomColor = brightColors[Math.floor(Math.random() * brightColors.length)];
196+
const textColor = getAccessibleTextColor(randomColor);
197+
198+
// Apply colors
199+
pill.style.backgroundColor = randomColor;
200+
if (text)
201+
text.style.color = textColor;
202+
203+
204+
205+
if (svg)
206+
svg.style.fill = textColor;
207+
208+
209+
210+
});
211+
212+
pluginCredit.addEventListener('mouseleave', function () { // Reset to default colors
213+
pill.style.backgroundColor = '';
214+
if (text)
215+
text.style.color = '';
216+
217+
218+
219+
if (svg)
220+
svg.style.fill = '';
221+
222+
223+
224+
});
225+
}
226+
});
227+
</script>

src/templates/icon-sets/index.twig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
{% else %}
7272
<p>{{ 'No icon sets exist yet.'|t('icon-manager') }}</p>
7373
{% endif %}
74+
75+
{% include 'icon-manager/_components/plugin-credit.twig' %}
7476
{% endblock %}
7577

7678
{% js %}

src/templates/settings.twig

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
value: settings.pluginName ?? 'Icon Manager',
2424
placeholder: 'Icon Manager',
2525
warning: settings.isOverridden('pluginName') ? 'This is being overridden by the `pluginName` setting in the `config/icon-manager.php` file.'|t('icon-manager'),
26-
disabled: settings.isOverridden('pluginName')
26+
disabled: settings.isOverridden('pluginName'),
27+
fieldAttributes: {
28+
style: 'margin-top: 0;'
29+
}
2730
}) }}
2831

2932
<hr>
@@ -114,4 +117,6 @@
114117
warning: settings.isIconTypeOverridden('material-icons') ? 'This is being overridden by the `enabledIconTypes[\'material-icons\']` setting in the `config/icon-manager.php` file.'|t('icon-manager'),
115118
disabled: settings.isIconTypeOverridden('material-icons')
116119
}) }}
120+
121+
{% include 'icon-manager/_components/plugin-credit.twig' %}
117122
{% endblock %}

0 commit comments

Comments
 (0)