انتخابگرِ لغزانGlide Select

انتخابگرِ کشویی که فهرستش نرم باز می‌شه و قرصِ برجسته با لغزشِ فنری روی گزینه‌ی بعدی می‌نشینه؛ کشیدنِ انگشت روی فهرست هم کار می‌کنه.

محمدجواد

ساخته شده توسط محمدجواد

سازنده فارسی‌فای، بچه دولوپر

وابستگی‌ها

بدون وابستگی

نوع تعامل

با کلیک یا `Space`/`Enter` فهرست باز می‌شه و قرصِ برجسته روی گزینه‌ی فعال می‌نشینه. با نشانگر یا کلیدهای جهت روی فهرست حرکت کن تا قرص با فنر جابه‌جا شه؛ فشردن و کشیدنِ انگشت هم همون کار رو می‌کنه و با سرعتِ رهاکردن تا چند خونه جلو می‌ره. `Escape` می‌بنده و تایپِ حرفِ اول به گزینه‌ی هم‌نام می‌پره.

پراپ‌ها

گزینه‌هایی که می‌تونی به کامپوننت بدی؛ ستاره‌دارها اجباری‌اند.

options
Array<string | GlideSelectOption>پیش‌فرض: ["One", "Two", "Three"]

گزینه‌ها؛ رشته یا شیءِ `{ value, label, tag }`.

value
string

حالتِ controlled.

defaultValue
string

مقدارِ اولیه توی حالتِ uncontrolled.

onChange
(value: string, option: GlideSelectOption) => void

با انتخاب صدا زده می‌شه و خودِ گزینه رو هم می‌ده.

placeholder
stringپیش‌فرض: "انتخاب کن…"

متنی که وقتی چیزی انتخاب نشده دیده می‌شه.

showTags
booleanپیش‌فرض: true

برچسبِ کوچکِ کنارِ گزینه‌ها نشون داده شه.

نصب

۱. این آدرس رو یک‌بار توی components.json بذار تا shadcn مخزن فارسی‌فای رو بشناسه.

components.jsonjson
{
  "registries": {
    "@farsify": "https://farsify.ir/r/{name}.json"
  }
}

۲. بعد با دستورِ زیر کامپوننت رو نصب کن.

npx shadcn@latest add @farsify/glide-select

پیش‌نیاز: Tailwind CSS v4 و صفحهٔ راست‌به‌چپ dir="rtl".

نمونه

glide-select.tsxtsx
"use client";

import { useState } from "react";
import { GlideSelect, type GlideSelectOption } from "@/components/farsify/glide-select";

const FORMATS: GlideSelectOption[] = [
  { value: "png", label: "PNG", tag: "بدون افتِ کیفیت" },
  { value: "jpg", label: "JPG", tag: "کم‌حجم‌ترین" },
  { value: "webp", label: "WebP", tag: "مدرن" },
  { value: "svg", label: "SVG", tag: "برداری" },
];

export function ExportPicker() {
  const [format, setFormat] = useState("png");

  return (
    <GlideSelect
      options={FORMATS}
      value={format}
      onChange={setFormat}
      ariaLabel="قالبِ خروجی"
    />
  );
}

// بدونِ برچسبِ کنارِ گزینه‌ها و با منوی عریض‌تر
<GlideSelect options={["XS", "S", "M", "L", "XL"]} showTags={false} menuWidth={220} />

// منو بالای دکمه باز شود و به لبه‌ی پایان بچسبد
<GlideSelect options={FORMATS} placement="top" align="right" />

نکته‌ها

  • `tag` جای توضیحِ کوتاهه، نه جای نام: توی دموی قالبِ فایل، `label` همون «PNG» لاتین می‌مونه و `tag` «بدون افتِ کیفیت»ـه. این دو توی دو عنصرِ جدا می‌نشینن و `tag` توی قلمروِ چپ‌به‌راستِ منزویه، پس با متنِ فارسی قاطی نمی‌شه.
  • `align` رو فیزیکی فکر نکن: توی `dir="rtl"` مقدارِ `left` یعنی «به لبه‌ی شروع بچسب» که سمتِ راسته. خودِ کامپوننت آینه می‌کنه و لازم نیست تو دست بزنی.
  • برای فهرستی که بیش از هشت گزینه داره، `menuWidth` رو بزرگ‌تر کن و `tag` نده؛ ردیف‌های تنگ با برچسبِ کنارِ نام شلوغ می‌شن.
  • حرکت فقط با `motion` نیست — بخشِ عمده‌ی باز و بسته شدن کی‌فریمِ CSSـه، پس روی ده‌ها گزینگر توی یه صفحه هم هزینه‌ی محسوسی نداره.

مجوز

کد بعد از نصب مالِ خودته؛ هر تغییری خواستی بده و توی پروژه‌ی خودت نگهش دار. برای پروژه‌های شخصی و تجاری آزاده، حتی اگه کدت بسته باشه. فقط اسم و لینک فارسی‌فای رو یه جا توی پروژه نگه دار.