Initial commit

This commit is contained in:
syntaxbullet
2026-02-09 12:54:10 +01:00
commit bfefaa0055
23 changed files with 9076 additions and 0 deletions

View File

@@ -0,0 +1,152 @@
---
interface Props {
id: string;
label: string;
options: string[];
value?: string;
title?: string;
}
const { id, label, options, value = options[0], title = "" } = Astro.props;
---
<div class="tui-segment" data-segment-id={id} title={title}>
<span class="tui-segment-label">{label}</span>
<div class="tui-segment-options" id={id} data-value={value}>
{
options.map((opt, i) => (
<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: 8px;
font-size: 11px;
user-select: none;
}
.tui-segment-label {
min-width: 3ch;
font-weight: bold;
opacity: 0.7;
}
.tui-segment-options {
display: flex;
border: 1px solid rgba(255, 103, 0, 0.3);
}
.tui-segment-option {
background: none;
border: none;
border-right: 1px solid rgba(255, 103, 0, 0.2);
color: var(--text-color);
font-family: inherit;
font-size: inherit;
padding: 2px 8px;
cursor: pointer;
opacity: 0.5;
transition: all 0.15s;
min-width: 3ch;
text-align: center;
}
.tui-segment-option:last-child {
border-right: none;
}
.tui-segment-option:hover {
opacity: 0.8;
background: rgba(255, 103, 0, 0.1);
}
.tui-segment-option.active {
background: var(--text-color);
color: #000;
opacity: 1;
font-weight: bold;
}
/* Hover the whole group */
.tui-segment:hover .tui-segment-label {
opacity: 1;
}
.tui-segment:hover .tui-segment-options {
border-color: var(--text-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>