delsj/function-gemma
0
1import gradio as gr2 3from gradio.events import Dependency4 5class ColoredCheckboxGroup(gr.HTML):6 def __init__(7 self,8 choices: list[str] | None = None,9 *,10 value: list[str] | None = None,11 colors: list[str] | None = None,12 label: str | None = None,13 **kwargs,14 ):15 html_template = """16 <div class="colored-checkbox-container">17 <div class="header-row">18 <label class="checkbox-label select-all-label">19 <input type="checkbox" class="select-all-input">20 </label>21 ${label ? `<span class="container-label">${label}</span>` : ''}22 </div>23 <div class="colored-checkbox-group">24 ${choices.map((choice, i) => `25 <label class="checkbox-label item-checkbox">26 <input type="checkbox" value="${choice}" ${(value || []).includes(choice) ? 'checked' : ''}>27 <span class="color-dot" style="background: ${colors[i]};"></span>28 ${choice}29 </label>30 `).join('')}31 </div>32 </div>33 """34 35 css_template = """36 .colored-checkbox-container {37 border: 1px solid var(--border-color-primary);38 border-radius: var(--radius-lg);39 padding: var(--spacing-lg);40 background-color: var(--block-background-fill);41 }42 .header-row {43 display: flex;44 align-items: center;45 margin-bottom: var(--spacing-md);46 }47 .container-label {48 color: var(--block-title-text-color);49 }50 .colored-checkbox-group {51 display: flex;52 flex-direction: column;53 gap: 6px;54 max-height: 280px;55 overflow-y: auto;56 }57 .checkbox-label { display: flex; align-items: center; cursor: pointer; }58 .checkbox-label input { margin-right: 8px; }59 .color-dot {60 width: 10px;61 height: 10px;62 border-radius: 50%;63 margin-right: 6px;64 flex-shrink: 0;65 }66 """67 68 js_on_load = """69 function getCheckboxes() {70 return element.querySelectorAll('.item-checkbox input[type="checkbox"]');71 }72 73 function getSelectAllInput() {74 return element.querySelector('.select-all-input');75 }76 77 function updateSelectAllState() {78 const checkboxes = getCheckboxes();79 const selectAllInput = getSelectAllInput();80 if (!selectAllInput) return;81 const total = checkboxes.length;82 const checked = Array.from(checkboxes).filter(cb => cb.checked).length;83 if (checked === total && total > 0) {84 selectAllInput.checked = true;85 selectAllInput.indeterminate = false;86 } else if (checked > 0) {87 selectAllInput.checked = false;88 selectAllInput.indeterminate = true;89 } else {90 selectAllInput.checked = false;91 selectAllInput.indeterminate = false;92 }93 }94 95 function updateValue() {96 const checkboxes = getCheckboxes();97 props.value = Array.from(checkboxes)98 .filter(cb => cb.checked)99 .map(cb => cb.value);100 updateSelectAllState();101 trigger('input');102 }103 104 element.addEventListener('change', (e) => {105 if (e.target.classList.contains('select-all-input')) {106 const shouldCheck = e.target.checked;107 getCheckboxes().forEach(cb => { cb.checked = shouldCheck; });108 updateValue();109 } else if (e.target.closest('.item-checkbox')) {110 updateValue();111 }112 });113 114 const observer = new MutationObserver(() => {115 updateSelectAllState();116 });117 observer.observe(element, { childList: true, subtree: true, attributes: true });118 119 updateSelectAllState();120 """121 122 super().__init__(123 value=value or [],124 html_template=html_template,125 css_template=css_template,126 js_on_load=js_on_load,127 choices=choices,128 colors=colors,129 label=label,130 **kwargs,131 )132 133 def api_info(self):134 return {135 "items": {"enum": self.props["choices"], "type": "string"},136 "title": "Checkbox Group",137 "type": "array",138 }139 from typing import Callable, Literal, Sequence, Any, TYPE_CHECKING140 from gradio.blocks import Block141 if TYPE_CHECKING:142 from gradio.components import Timer143 from gradio.components.base import Component144 145 146if __name__ == "__main__":147 148 def generate_color_variants(color: str, count: int):149 if color.startswith("rgb"):150 rgb_values = (151 color.replace("rgba", "").replace("rgb", "").strip("()").split(",")152 )153 r, g, b = (154 int(float(rgb_values[0])),155 int(float(rgb_values[1])),156 int(float(rgb_values[2])),157 )158 else:159 r = int(color[1:3], 16)160 g = int(color[3:5], 16)161 b = int(color[5:7], 16)162 163 colors = []164 for i in range(count):165 factor = 0.3 + (0.7 * i / max(count - 1, 1))166 nr = int(r * factor + (255 - r * factor) * (1 - factor) * 0.3)167 ng = int(g * factor + (255 - g * factor) * (1 - factor) * 0.3)168 nb = int(b * factor + (255 - b * factor) * (1 - factor) * 0.3)169 nr, ng, nb = min(255, nr), min(255, ng), min(255, nb)170 colors.append(f"#{nr:02x}{ng:02x}{nb:02x}")171 return colors172 173 def update_colors(color: str, s: int):174 items = [f"Item {i + 1} ({s + 1})" for i in range(12)]175 colors = generate_color_variants(color, len(items))176 return ColoredCheckboxGroup(177 choices=items,178 colors=colors,179 label=f"Runs ({s + 1})",180 ), s + 1181 182 with gr.Blocks() as demo:183 s = gr.State(0)184 with gr.Row():185 with gr.Column():186 cp = gr.ColorPicker(value="#FF0000")187 with gr.Column(scale=2):188 items = [f"Item {i + 1}" for i in range(15)]189 colors = generate_color_variants("#FF0000", len(items))190 cg = ColoredCheckboxGroup(191 choices=items,192 colors=colors,193 label="Runs",194 )195 gr.Interface(196 fn=lambda x: " ".join(x),197 inputs=cg,198 outputs=gr.Textbox(label="output"),199 )200 cp.change(201 update_colors, inputs=[cp, s], outputs=[cg, s], show_progress="hidden"202 )203 demo.launch()