193 lines
4.9 KiB
Plaintext
193 lines
4.9 KiB
Plaintext
---
|
|
interface Props {
|
|
id: string;
|
|
label: string;
|
|
abbr?: string;
|
|
options: string[];
|
|
value?: string;
|
|
title?: string;
|
|
description?: string;
|
|
}
|
|
|
|
const {
|
|
id,
|
|
label,
|
|
abbr,
|
|
options,
|
|
value = options[0],
|
|
title = "",
|
|
description = "",
|
|
} = Astro.props;
|
|
---
|
|
|
|
<div
|
|
class="tui-segment"
|
|
data-segment-id={id}
|
|
data-tooltip-title={title}
|
|
data-tooltip-desc={description}
|
|
>
|
|
<span class:list={["tui-segment-label", { "has-abbr": !!abbr }]}>
|
|
<span class="full">{label}</span>
|
|
{abbr && <span class="abbr">{abbr}</span>}
|
|
</span>
|
|
<div class="tui-segment-options" id={id} data-value={value}>
|
|
{
|
|
options.map((opt) => (
|
|
<button
|
|
type="button"
|
|
class:list={[
|
|
"tui-segment-option",
|
|
{ active: opt === value },
|
|
]}
|
|
data-value={opt}
|
|
>
|
|
{opt}
|
|
</button>
|
|
))
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.tui-segment {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
font-size: 11px;
|
|
user-select: none;
|
|
}
|
|
|
|
.tui-segment-label {
|
|
min-width: 3ch;
|
|
font-weight: 700;
|
|
font-family: var(--font-mono);
|
|
color: #fff;
|
|
opacity: 0.7;
|
|
display: flex;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.tui-segment-label .abbr {
|
|
display: none;
|
|
}
|
|
|
|
@media (max-width: 1400px) {
|
|
.tui-segment-label.has-abbr .full {
|
|
display: none;
|
|
}
|
|
.tui-segment-label.has-abbr .abbr {
|
|
display: inline;
|
|
}
|
|
}
|
|
|
|
.tui-segment-options {
|
|
display: flex;
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
background: rgba(255, 255, 255, 0.02);
|
|
border-radius: 2px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.tui-segment-option {
|
|
background: transparent;
|
|
border: none;
|
|
border-right: 1px solid rgba(255, 255, 255, 0.05);
|
|
color: #fff;
|
|
opacity: 0.6;
|
|
font-family: inherit;
|
|
font-size: inherit;
|
|
padding: 4px 10px;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
min-width: 3ch;
|
|
text-align: center;
|
|
}
|
|
|
|
.tui-segment-option:last-child {
|
|
border-right: none;
|
|
}
|
|
|
|
.tui-segment-option:hover {
|
|
color: var(--accent-color);
|
|
opacity: 1;
|
|
background: color-mix(in srgb, var(--accent-color), transparent 95%);
|
|
}
|
|
|
|
.tui-segment-option.active {
|
|
background: var(--accent-color);
|
|
color: #fff;
|
|
font-weight: 700;
|
|
opacity: 1;
|
|
}
|
|
|
|
/* Hover the whole group */
|
|
.tui-segment:hover .tui-segment-label {
|
|
opacity: 1;
|
|
color: var(--accent-color);
|
|
}
|
|
|
|
.tui-segment:hover .tui-segment-options {
|
|
border-color: var(--accent-color);
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
function initSegments() {
|
|
document
|
|
.querySelectorAll(".tui-segment")
|
|
.forEach((segmentContainer) => {
|
|
const optionsContainer = segmentContainer.querySelector(
|
|
".tui-segment-options",
|
|
) as HTMLElement;
|
|
const buttons = segmentContainer.querySelectorAll(
|
|
".tui-segment-option",
|
|
);
|
|
|
|
if (!optionsContainer) return;
|
|
|
|
buttons.forEach((btn) => {
|
|
btn.addEventListener("click", (e) => {
|
|
e.stopPropagation();
|
|
const value = (btn as HTMLElement).dataset.value;
|
|
|
|
// Update active state
|
|
buttons.forEach((b) => b.classList.remove("active"));
|
|
btn.classList.add("active");
|
|
|
|
// Update data attribute
|
|
optionsContainer.dataset.value = value;
|
|
|
|
// Dispatch custom event
|
|
optionsContainer.dispatchEvent(
|
|
new CustomEvent("segment-change", {
|
|
detail: { value },
|
|
bubbles: true,
|
|
}),
|
|
);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", initSegments);
|
|
initSegments();
|
|
|
|
// Expose update function globally
|
|
(window as any).updateSegmentValue = function (
|
|
segmentId: string,
|
|
newValue: string,
|
|
) {
|
|
const container = document.getElementById(segmentId) as HTMLElement;
|
|
if (container) {
|
|
const buttons = container.querySelectorAll(".tui-segment-option");
|
|
buttons.forEach((btn) => {
|
|
btn.classList.toggle(
|
|
"active",
|
|
(btn as HTMLElement).dataset.value === newValue,
|
|
);
|
|
});
|
|
container.dataset.value = newValue;
|
|
}
|
|
};
|
|
</script>
|