Team Ai
Apppublic

WalisonCruz/function-gemma

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