Skip to content

Commit b00fa46

Browse files
Merge pull request #1 from Michal7290/create-pf-lable-group
feat(label-group): change demo
2 parents 0dcec75 + 8cfa3ef commit b00fa46

File tree

5 files changed

+403
-101
lines changed

5 files changed

+403
-101
lines changed
Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,38 @@
1-
<pf-label-group closeable add-label-mode="autoNoEdit">
1+
<pf-label-group id="label-group" closeable>
22
<h2 slot="category">group name</h2>
33
<pf-label color="red" icon="info-circle" removable>label-1</pf-label>
44
<pf-label color="green" icon="info-circle" removable>label-2</pf-label>
55
<pf-label color="blue" icon="info-circle" removable>label-3</pf-label>
6+
7+
<pf-label id="add-button" color="blue" variant="outline" dismissible="false" >
8+
Add label </pf-label>
69
</pf-label-group>
710

11+
812
<script type="module">
913
import '@patternfly/elements/pf-label-group/pf-label-group.js';
1014
import '@patternfly/elements/pf-label/pf-label.js';
1115
import '@patternfly/elements/pf-button/pf-button.js';
1216
import '@patternfly/elements/pf-modal/pf-modal.js';
1317
import '@patternfly/elements/pf-dropdown/pf-dropdown.js';
18+
document.getElementById('add-button').addEventListener('click', () => {
19+
const labelGroup = document.getElementById('label-group');
20+
const newLabel = document.createElement('pf-label');
21+
newLabel.setAttribute('color', 'grey');
22+
newLabel.setAttribute('icon', 'info-circle');
23+
newLabel.setAttribute('removable', 'true');
24+
newLabel.textContent = `new-label`;
25+
const firstLabel = labelGroup.querySelector('pf-label:not([slot])');
26+
if (firstLabel) labelGroup.insertBefore(newLabel, firstLabel);
27+
else labelGroup.appendChild(newLabel);
28+
});
1429
</script>
30+
<style>
31+
#add-button {
32+
cursor: pointer;
33+
align-items: center;
34+
gap: 4px;
35+
transition: border 0.2s ease;
36+
border-radius: 0.99rem;
37+
}
38+
</style>
Lines changed: 285 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,297 @@
1-
<pf-label-group add-label-mode="customForm">
1+
<pf-label-group id="label-group" closeable>
22
<h2 slot="category">group name</h2>
33
<pf-label color="red" icon="info-circle" removable>label-1</pf-label>
44
<pf-label color="green" icon="info-circle" removable>label-2</pf-label>
55
<pf-label color="blue" icon="info-circle" removable>label-3</pf-label>
6+
<pf-label id="add-button" class="add-button" color="blue" variant="outline" dismissible="false" >
7+
Add label </pf-label>
68
</pf-label-group>
79

810
<script type="module">
911
import '@patternfly/elements/pf-label-group/pf-label-group.js';
1012
import '@patternfly/elements/pf-label/pf-label.js';
1113
import '@patternfly/elements/pf-button/pf-button.js';
1214
import '@patternfly/elements/pf-modal/pf-modal.js';
13-
import '@patternfly/elements/pf-dropdown/pf-dropdown.js';
15+
import '@patternfly/elements/pf-select/pf-select.js';
16+
import '@patternfly/elements/pf-icon/pf-icon.js';
17+
18+
const group = document.getElementById('label-group');
19+
const addButton = document.getElementById('add-button');
20+
console.log('addButton', addButton);
21+
22+
23+
24+
// create a modal element with form controls and buttons, return it
25+
function createModal() {
26+
const modal = document.createElement('pf-modal');
27+
modal.id = 'custom-label-modal';
28+
modal.setAttribute('variant', 'small');
29+
modal.setAttribute('aria-describedby', 'custom-label-modal-description');
30+
console.log('modal is created');
31+
32+
modal.innerHTML = `
33+
<h2 slot="header">Add label</h2>
34+
35+
36+
<form id="add-label-form">
37+
<label>
38+
Label text:
39+
<input id="label-text" class="pf-c-form-control" />
40+
</label>
41+
42+
<label>
43+
Color:
44+
<pf-select id="color-select" class="pf-c-form-control">
45+
<pf-option value="Grey" selected>Grey</pf-option>
46+
<pf-option value="Blue">Blue</pf-option>
47+
<pf-option value="Cyan">Cyan</pf-option>
48+
<pf-option value="Green">Green</pf-option>
49+
<pf-option value="Orange">Orange</pf-option>
50+
<pf-option value="Purple">Purple</pf-option>
51+
<pf-option value="Red">Red</pf-option>
52+
<pf-option value="Gold">Gold</pf-option>
53+
</pf-select>
54+
</label>
55+
56+
<label>
57+
Icon:
58+
<pf-select id="icon-select" class="pf-c-form-control">
59+
<pf-option value=""><span style="opacity:.7">No Icon</span></pf-option>
60+
<pf-option value="info-circle"><pf-icon name="info-circle" style="width:1rem;height:1rem;vertical-align:middle;margin-right:0.5rem;"></pf-icon>Info</pf-option>
61+
<pf-option value="check-circle"><pf-icon name="check-circle" style="width:1rem;height:1rem;vertical-align:middle;margin-right:0.5rem;"></pf-icon>Check</pf-option>
62+
<pf-option value="exclamation-circle"><pf-icon name="exclamation-circle" style="width:1rem;height:1rem;vertical-align:middle;margin-right:0.5rem;"></pf-icon>Warning</pf-option>
63+
</pf-select>
64+
</label>
65+
66+
<div class="radio-group">
67+
<label>Dismissable:</label>
68+
<div>
69+
<label><input type="radio" name="dismissable" value="true" /> Yes</label>
70+
<label><input type="radio" name="dismissable" value="false" checked /> No</label>
71+
</div>
72+
</div>
73+
74+
<div class="radio-group">
75+
<label>Label type:</label>
76+
<div>
77+
<label><input type="radio" name="filled" value="true" checked /> Filled</label>
78+
<label><input type="radio" name="filled" value="false" /> Outlined</label>
79+
</div>
80+
</div>
81+
</form>
82+
83+
<div slot="footer" style="display:flex; justify-content:flex-end; gap:0.5rem;">
84+
<pf-button id="modal-add" variant="primary">Save</pf-button>
85+
<pf-button id="modal-cancel" variant="secondary">Cancel</pf-button>
86+
</div>
87+
`;
88+
console.log('modal innerHTML set');
89+
return modal;
90+
}
91+
92+
93+
94+
function resetForm(form) {
95+
const inputText = form.querySelector('#label-text');
96+
const selectColor = form.querySelector('#color-select');
97+
const selectIcon = form.querySelector('#icon-select');
98+
if (inputText) inputText.value = '';
99+
if (selectColor) selectColor.value = 'Grey';
100+
if (selectIcon) selectIcon.value = '';
101+
const dismissNo = form.querySelector('input[name="dismissable"][value="false"]');
102+
const filledYes = form.querySelector('input[name="filled"][value="true"]');
103+
if (dismissNo) dismissNo.checked = true;
104+
if (filledYes) filledYes.checked = true;
105+
}
106+
107+
function openModal() {
108+
const modal = createModal();
109+
document.body.appendChild(modal);
110+
111+
const form = modal.querySelector('#add-label-form');
112+
const inputText = modal.querySelector('#label-text');
113+
const selectColor = modal.querySelector('#color-select');
114+
const selectIcon = modal.querySelector('#icon-select');
115+
const modalAdd = modal.querySelector('#modal-add');
116+
const modalCancel = modal.querySelector('#modal-cancel');
117+
118+
resetForm(form);
119+
120+
function cleanup() {
121+
try { modal.remove(); } catch (e) {}
122+
requestAnimationFrame(() => addButton.focus());
123+
}
124+
125+
modal.addEventListener('close', cleanup, { once: true });
126+
127+
modalCancel.addEventListener('click', () => {
128+
modal.open = false;
129+
}, { once: true });
130+
131+
modalAdd.addEventListener('click', () => {
132+
const text = (inputText.value || '').trim() || 'New label';
133+
const color = selectColor.value.toLowerCase();
134+
const icon = selectIcon.value;
135+
const dismissable = !!form.querySelector('input[name="dismissable"]:checked') &&
136+
form.querySelector('input[name="dismissable"]:checked').value === 'true';
137+
const filled = !!form.querySelector('input[name="filled"]:checked') &&
138+
form.querySelector('input[name="filled"]:checked').value === 'true';
139+
140+
const newLabel = document.createElement('pf-label');
141+
newLabel.textContent = text;
142+
if (color) newLabel.setAttribute('color', color);
143+
if (icon) newLabel.setAttribute('icon', icon);
144+
if (dismissable) newLabel.setAttribute('removable', 'true');
145+
if (!filled) newLabel.setAttribute('variant', 'outline');
146+
147+
const firstLabel = group.querySelector('pf-label:not([slot])');
148+
if (firstLabel) group.insertBefore(newLabel, firstLabel);
149+
else group.appendChild(newLabel);
150+
151+
group.dispatchEvent(new CustomEvent('label-added', { detail: { text, color, icon, dismissable, filled }, bubbles: true }));
152+
153+
modal.open = false;
154+
}, { once: true });
155+
156+
// open and focus
157+
modal.open = true;
158+
requestAnimationFrame(() => {
159+
const first = modal.querySelector('#label-text');
160+
if (first) first.focus();
161+
});
162+
}
163+
164+
addButton.addEventListener('click', openModal);
14165
</script>
166+
<style>
167+
#add-button {
168+
cursor: pointer;
169+
align-items: center;
170+
gap: 4px;
171+
transition: border 0.2s ease;
172+
173+
border-radius: 0.99rem;
174+
}
175+
pf-modal#custom-label-modal {
176+
--pf-c-modal--BoxShadow: 0 0 15px rgba(0,0,0,0.2);
177+
--pf-c-modal-box--BorderRadius: 8px;
178+
--pf-c-modal-box--Padding: 1rem;
179+
180+
font-size: 0.875rem;
181+
}
182+
183+
184+
pf-modal#custom-label-modal h2[slot="header"] {
185+
margin: 0;
186+
font-size: 1.5rem;
187+
}
188+
189+
#add-label-form {
190+
display: flex;
191+
flex-direction: column;
192+
gap: 1rem;
193+
margin-top: 0.5rem;
194+
}
195+
#label-text {
196+
font-family: var(--pf-global--FontFamily--sans-serif, "RedHatTextUpdated", "Overpass", overpass, helvetica, arial, sans-serif);
197+
font-size: var(--pf-global--FontSize--md, 16px);
198+
font-weight: var(--pf-global--FontWeight--normal, 400);
199+
line-height: 1.6;
200+
color: var(--pf-global--Color--100, #151515);
201+
202+
background-color: var(--pf-theme--color--surface--lightest, #fff);
203+
border: 1px solid var(--pf-global--BorderColor--100, #d2d2d2);
204+
border-radius: 0.25rem;
205+
box-shadow: 0 0 0 1px var(--pf-c-select__toggle--focus--before--BorderBottomColor, rgb(54, 57, 59));
206+
padding: var(--pf-global--spacer--xs, 0.25rem) var(--pf-global--spacer--sm, 0.5rem);
207+
min-height: 44px;
208+
min-width: 44px;
209+
210+
width: 100%;
211+
box-sizing: border-box;
212+
}
213+
#label-text:focus {
214+
outline: none;
215+
border-bottom-color: var(--pf-c-select__toggle--focus--before--BorderBottomColor, #06c);
216+
border-bottom-width: var(--pf-c-select__toggle--focus--before--BorderBottomWidth, 2px);
217+
218+
}
219+
220+
221+
#add-label-form input{
222+
padding: 0.25rem 0.25rem;
223+
font-size: 1rem;
224+
border: 1px solid #d2d2d2;
225+
border-radius: 4px;
226+
box-sizing: border-box;
227+
}
228+
229+
#add-label-form .radio-group {
230+
display: flex;
231+
flex-direction: column;
232+
align-items: flex-start;
233+
gap: 0.5rem;
234+
margin-top: 0.25rem;
235+
}
236+
237+
#add-label-form .radio-group > label {
238+
display: inline-flex;
239+
flex-direction: row;
240+
align-items: center;
241+
gap: 0.25rem;
242+
cursor: pointer;
243+
width: auto;
244+
}
245+
246+
/* #add-label-form .radio-group > label input[type="radio"] {
247+
margin: 0;
248+
flex: 0 0 auto;
249+
width: auto;
250+
height: auto;
251+
appearance: auto;
252+
} */
253+
254+
#add-label-form .radio-group > label input[type="radio"] {
255+
accent-color: var(--pf-global--primary-color--100, #0066cc);
256+
}
257+
258+
#add-label-form .radio-group > label .radio-text {
259+
display: inline-block;
260+
white-space: nowrap;
261+
}
262+
263+
pf-modal #custom-label-modal [slot="footer"] {
264+
display: flex;
265+
justify-content: flex-end;
266+
gap: 0.5rem;
267+
margin-top: 1rem;
268+
position: static;
269+
}
270+
271+
pf-modal#custom-label-modal pf-button {
272+
font-size: 0.85rem;
273+
padding: 0.25rem 0.5rem;
274+
}
275+
276+
#add-label-form label {
277+
font-weight: bold;
278+
font-size: 0.875rem;
279+
display: flex;
280+
flex-direction: column;
281+
margin-bottom: 0.05rem;
282+
margin-top: 0.15rem;
283+
}
284+
285+
#add-label-form pf-select {
286+
display: inline-block;
287+
width: fit-content;
288+
}
289+
290+
#color-select {
291+
min-width: 7rem;
292+
}
293+
294+
#icon-select {
295+
min-width: 12rem;
296+
}
297+
</style>

0 commit comments

Comments
 (0)