דילוג לתוכן
uiify

Segmented control

שורת מקטעים לבחירת אפשרות אחת בדיוק.

דפדפנים
Chrome 123+Firefox 121+Safari 17.5+
שכבה
0
גודל חבילה דחוסה
1.38 kB
מגבלת פריסה כפויה
0 ms
מגבלת Axe
0
תואם SSR
כן
מבוסס על
elements/choice
חוזה מפורסם
סביבת בדיקות

מגרש ניסויים

import { SegmentedControl } from "@gunkin/uiify";

export default function Example() {
  return (
    <SegmentedControl
      aria-label="Time range"
      className=""
      id="period"
      defaultValue="week"
      slotProps={{
        item: { className: "" },
        input: { className: "" },
        label: { className: "" },
      }}
      items={[
        { value: "day", label: "Day" },
        { value: "week", label: "Week" },
        { value: "month", label: "Month" },
      ]}
    />
  );
}
/* Segmented control — pill toggle group with sliding indicator. Horizontal tracks are as tall
   as a Button (--control-md); the segments fill the track inside its border and padding. */

@layer components {
  :where([data-uiify-segmented-control], [data-uiify-segmented-control]) {
    position: relative;
    display: inline-flex;
    box-sizing: border-box;
    padding: var(--space-xs);
    border: var(--border-width) solid var(--border);
    border-radius: var(--radius-full);
    background-color: var(--muted);
  }

  [data-uiify-segmented-control]:not([data-orientation="vertical"]) {
    block-size: var(--uiify-control-size, var(--control-md));
  }

  [data-uiify-segmented-control][data-full-width] {
    inline-size: 100%;
  }

  [data-uiify-segmented-control][data-orientation="vertical"] {
    flex-direction: column;
    border-radius: var(--radius-xl);
  }

  [data-uiify-segmented-control] [data-part="item"] {
    position: relative;
    display: grid;
  }

  [data-uiify-segmented-control][data-full-width] [data-part="item"] {
    flex: 1 1 0;
  }

  [data-uiify-segmented-control] [data-part="item"] > input {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* The segments are Button-skinned labels (`ghost`); only their place in the track is set
     here. A horizontal segment fills the track instead of keeping the Button's own height. */
  [data-uiify-segmented-control] [data-part="item"] > label {
    z-index: 1;
    min-inline-size: 4rem;
    font-size: var(--uiify-control-font, var(--text-base));
    line-height: var(--leading-normal);
  }

  [data-uiify-segmented-control]:not([data-orientation="vertical"]) [data-part="item"] > label {
    min-block-size: 0;
  }

  [data-uiify-segmented-control][data-full-width] [data-part="item"] > label {
    inline-size: 100%;
  }
}
import { SegmentedControl } from "@gunkin/uiify";

export default function Example() {
  return (
    <SegmentedControl
      aria-label="Time range"
      className="
        relative inline-flex box-border p-xs border-[length:var(--border-width)] border-solid border-border
        rounded-[var(--radius-full)] bg-muted [&:not([data-orientation=vertical])]:[block-size:var(--control-md)]
        data-[full-width]:[inline-size:100%] data-[orientation=vertical]:flex-col data-[orientation=vertical]:rounded-xl
      "
      id="period"
      defaultValue="week"
      slotProps={{
        item: { className: "relative grid" },
        input: {
          className:
            "absolute [inline-size:1px] [block-size:1px] [margin:-1px] overflow-hidden " +
            "[clip-path:inset(50%)] whitespace-nowrap",
        },
        label: {
          className:
            "relative isolate z-[1] inline-flex min-h-0 min-w-10 items-center justify-center " +
            "gap-1.5 rounded-full border-[length:var(--border-width)] border-solid " +
            "border-transparent bg-transparent bg-clip-padding px-5 py-0 text-foreground " +
            "text-base font-medium leading-6 no-underline cursor-pointer " +
            "[transition:var(--transition-colors)] [min-inline-size:4rem] " +
            "[[data-part=item]>input:checked+&]:border-transparent " +
            "[[data-part=item]>input:checked+&]:bg-primary " +
            "[[data-part=item]>input:checked+&]:text-primary-foreground " +
            "[[data-part=item]>input:focus-visible+&]:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_20%,_transparent)]",
        },
      }}
      items={[
        { value: "day", label: "Day" },
        { value: "week", label: "Week" },
        { value: "month", label: "Month" },
      ]}
    />
  );
}

API

SegmentedControl

מאפייןטיפוסברירת מחדלתיאור
size"sm" | "md" | "lg""md"גובה הפקד וגודל הטקסט, בהתאמה ל-Button (32, 40 או 48 px); נכתבים ל-data-size, עם md כשלא הוגדר ערך.
id*string—בסיס למזהים הדטרמיניסטיים ולשם המשותף של קבוצת הרדיו.
items*readonly SegmentedControlItem[]—כל פריט הוא { value, label, disabled? }.
defaultValuestring | undefined—הערך הנבחר בהצגה הראשונה. אינו מבוקר, ולכן נשמר גם ללא JavaScript.
valuestring—הערך המבוקר ב-SegmentedControlClient.
onValueChange(value: string) => void—פונקציית תגובה לשינוי ב-SegmentedControlClient.
disabledbooleanfalseמשבית את כל המקטעים ומסמן את הקבוצה ב-data-disabled.
aria-label / aria-labelledbystring—שם נגיש לקבוצת הרדיו; יש לספק אותו כשאין לקבוצה תווית גלויה.
orientation"horizontal" | "vertical""horizontal"הכיוון שבו המקטעים מסודרים.
fullWidthbooleanfalseמגדיר data-full-width על השורש כדי שהמקטעים יימתחו וימלאו את המכל שלהם.
classNamestring—המחלקה המוחלת על שורש הקבוצה.
slotPropsSegmentedControlSlotProps—מאפיינים מובנים לאלמנטי הפריט, הקלט והתווית שנוצרים; ניתן למקד משבצות חוזרות בפריט לפי ערכו.

מקלדת

מקשפעולה
Tabהעברת המיקוד לקבוצה
Arrow keysמעבר בין מקטעים
Spaceבחירת המקטע הממוקד

נגישות

radiogroup מובנה לבחירה יחידה המבוסס על כפתורי רדיו מוסתרים. השתמשו ב-SegmentedControlClient להתנהגות מבוקרת של value/onValueChange.

נקודות חיבור לעיצוב

data-partdata-disableddata-full-width
דף זה תורגם אוטומטית וטרם נבדק.