इस पेज का अनुवाद मशीन द्वारा किया गया है और इसमें त्रुटियाँ हो सकती हैं। मूल अंग्रेज़ी पढ़ें

एलिमेंट

Switch

Switch किसी सेटिंग को चालू या बंद करता है, और बदलाव तुरंत लागू हो जाता है। व्यवहार उसी का है: प्रेस, कीबोर्ड से सक्रियण, disabled स्थिति, और स्क्रीन रीडर के लिए switch role व उसका मान। रूप ऐप का है: Switch के अपने कोई रंग, आकार, motion या label नहीं होते। यह एक track से बना है जिसके अंदर एक thumb होता है, फिर उसके children (एक label)। ऐप हर भाग को स्टाइल करता है, checked: और disabled: classes के साथ जो switch का अनुसरण करती हैं।

el-switch.tsx
el-switch.tsxLive
import { mount, signal, Text, View } from "nsh";
import { Switch } from "nsh/base";
import { desktop, focusRing, hoverFill, Log, Panel, size, Split, ui } from "./palette";

// The parts: geometry and motion in classes (`checked:` moves the thumb,
// `disabled:` dims the row, both following the switch), colors from the
// palette by the value the app owns. A pointer gets the compact size; the
// pointer's hover and the keyboard's focus ring come from the palette, and
// the thumb and track stay still with reduced motion.
const row = `flex-row-reverse items-center justify-between gap-3 ${desktop ? "px-3 py-2" : "px-4 py-3"} active:opacity-70 disabled:opacity-40`;
const track = `${desktop ? "w-9" : "w-12"} rounded-full p-0.5 transition-colors motion-reduce:transition-none`;
const thumb = desktop ? "size-4 rounded-full transition-transform motion-reduce:transition-none checked:translate-x-4" : "size-5.5 rounded-full transition-transform motion-reduce:transition-none checked:translate-x-5";

function Setting(props: { label: string; detail: string; checked: boolean; disabled?: boolean; onChange: (e: { checked: boolean }) => void }) {
  return (
    <Switch
      checked={props.checked}
      disabled={props.disabled}
      onChange={props.onChange}
      class={row}
      hoverStyle={props.disabled ? undefined : hoverFill()}
      focusStyle={focusRing()}
      trackClass={track}
      trackStyle={props.checked ? ui().accentFill : ui().inset}
      thumbClass={thumb}
      thumbStyle={props.checked ? { backgroundColor: ui().onAccent } : ui().raised}
    >
      <View style={{ flex: 1, gap: 2 }}>
        <Text style={{ fontSize: size.label, fontWeight: "500", color: ui().text }}>{props.label}</Text>
        <Text style={{ fontSize: size.detail, color: ui().muted }}>{props.detail}</Text>
      </View>
    </Switch>
  );
}

function App() {
  const wifi = signal(true);
  const bluetooth = signal(false);
  const ask = signal(true);
  const events = signal<string[]>([]);
  const change = (name: string, value: { set: (v: boolean) => void }) => ({ checked }: { checked: boolean }) => {
    value.set(checked);
    events.set([`${name} → ${checked}`, ...events()].slice(0, 3));
  };
  const line = () => <View style={{ height: 1, marginLeft: desktop ? 12 : 16, backgroundColor: ui().line }} />;
  return (
    <View style={{ flex: 1, backgroundColor: ui().page, padding: 20, paddingTop: 24, gap: 14 }}>
      <Text style={{ fontSize: 22, fontWeight: "700", color: ui().text }}>switch</Text>
      <Text style={{ color: ui().muted }}>
        {desktop ? "Click a row, or Tab to a switch and press Space" : "Tap a row: the label toggles it too"}
      </Text>

      <Split
        gap={14}
        inspector={
          <>
            <Panel title="checked · disabled">
              <Text style={{ fontSize: 13, color: ui().text }}>
                Wi-Fi {wifi() ? "on" : "off"} · ask {ask() ? "on" : "off"}
                {wifi() ? "" : " (disabled)"} · Bluetooth {bluetooth() ? "on" : "off"}
              </Text>
            </Panel>
            <Log title="onChange({ checked })" lines={events()} minHeight={92} />
          </>
        }
      >
        <View style={{ ...ui().card, borderRadius: 16, overflow: "hidden" }}>
          <Setting label="Wi-Fi" detail={wifi() ? "Connected to Studio" : "Off"} checked={wifi()} onChange={change("Wi-Fi", wifi)} />
          {line()}
          <Setting
            label="Ask to join networks"
            detail={wifi() ? "Known networks join on their own" : "Turn on Wi-Fi first"}
            checked={ask()}
            disabled={!wifi()}
            onChange={change("Ask to join", ask)}
          />
          {line()}
          <Setting label="Bluetooth" detail={bluetooth() ? "Discoverable as “Desk”" : "Off"} checked={bluetooth()} onChange={change("Bluetooth", bluetooth)} />
        </View>
      </Split>
    </View>
  );
}

mount(App);
use nsh_base::{switch, theme};
use nsh_core::prelude::*;

fn wifi() -> impl IntoElement {
    let on = signal(false);
    switch()
        .checked(on)
        .on_change(move |next: &bool| on.set(*next))
        .flex_row()
        .items_center()
        .gap_3()
        .track_style(|s| {
            s.w(px(44.0))
                .p(px(2.0))
                .rounded_full()
                .bg(move || theme().muted)
                .transition_colors()
                .checked(|s| s.bg(move || theme().primary))
        })
        .thumb_style(|s| {
            s.size(px(20.0))
                .rounded_full()
                .bg(move || theme().background)
                .shadow_sm()
                .transition_transform()
                .checked(|s| s.translate_x(px(20.0)))
        })
        .child(text("Wi-Fi"))
}

Switch nsh/base से आता है, जो Rust में nsh-base crate है। मान ऐप का है: प्रेस onChange के साथ अगला मान रिपोर्ट करता है, और switch वही checked दिखाता है जो ऐप वापस देता है। Rust में switch() इसे बनाता है: हर prop के लिए एक setter (.checked(..), .track_style(..)), हर event के लिए एक listener (.on_change(..)), switch के लिए typed style methods, और उसके label के लिए .child(..)। किसी भाग की style में state methods (.checked(..), .disabled_style(..)) होते हैं जो switch का अनुसरण करते हैं।

#Props

PropRustप्रकारडिफ़ॉल्टविवरण
checked.checked(..)booleanfalseचालू या बंद। प्रेस onChange के साथ अगला मान रिपोर्ट करता है; switch वही मान दिखाता है जो ऐप वापस देता है।
disabled.disabled(..)booleanfalseकोई प्रेस नहीं और प्रेस का कोई फ़ीडबैक नहीं; disabled: styles switch और उसके भागों पर लागू होती हैं, और स्क्रीन रीडर बताते हैं कि यह dimmed है।
checkedStyle.checked_style(|s| ..)StyleProp<ViewStyle>कोई नहींchecked होने पर और disabled न होने पर switch की style, checked: classes के रूप में।
accessibilityLabel.accessibility_label(..)stringकोई नहींस्क्रीन रीडर क्या बोलते हैं: switch क्या चालू करता है, जब उसके children में इसे बताने वाला कोई टेक्स्ट न हो।
trackClass, trackStyle.track_style(|s| ..)string, StyleProp<ViewStyle>कोई नहींtrack, यानी वह भाग जिस पर thumb चलता है।
thumbClass, thumbStyle.thumb_style(|s| ..)string, StyleProp<ViewStyle>कोई नहींthumb, जो track के अंदर होता है।
hitSlop.hit_slop(..)number | Partial<Edges>कोई नहींअपनी सीमाओं के कितना बाहर तक प्रेस अब भी गिने जाते हैं, points में: सभी तरफ़ के लिए एक संख्या, या नामित तरफ़ें। जैसा view के hitSlop में होता है।
children.child(..)JSX.Elementकोई नहींtrack के बाद की सामग्री: एक label, जिसे स्क्रीन रीडर बोलते हैं।
class, stylestyle methodsstring, StyleProp<ViewStyle>कोई नहींस्वयं switch: track और label के आसपास की row।
activeStyle, hoverStyle, focusStyle, disabledStyle.active(|s| ..), .hover(..), .focus(..), .disabled_style(..)StyleProp<ViewStyle>कोई नहींpressed, hovered, focused या disabled होने पर switch की style, <state>: classes के रूप में।

#Events

EventRustविवरण
onChange.on_change(|checked: &bool| ..)switch को दबाया गया: tap, click, फ़ोकस होने पर Space या Return, या स्क्रीन रीडर का सक्रियण। यह वह मान checked के रूप में रिपोर्ट करता है जो switch माँगता है, यानी उसके मौजूदा checked का उल्टा।

Disabled switch कुछ रिपोर्ट नहीं करता।

#भाग

भागअंदरस्टाइल का तरीकाStates
Switchclass, stylechecked:, disabled:, active:, hover:, focus: (या checkedStyle, disabledStyle, …)
Trackswitch, सबसे पहलेtrackClass, trackStylechecked:, disabled: switch का अनुसरण करते हैं
ThumbtrackthumbClass, thumbStylechecked:, disabled: switch का अनुसरण करते हैं
Labelswitch, track के बादअपने elements (children)group-checked: और अन्य group-*: variants, switch के class पर group के साथ

Thumb अपनी checked: styles से चलता है: translation (checked:translate-x-5), या margin या track का alignment (track पर checked:justify-end)। transition-* class बदलाव को native रूप से animate करती है। label को track से पहले रखने के लिए row को उल्टा करें: class="flex-row-reverse justify-between"।

#Disabled

Disabled switch कोई प्रेस नहीं लेता, और स्क्रीन रीडर उसे dimmed बताते हैं। उसकी disabled: classes और उसके track व thumb की classes लागू होती हैं, उनकी checked: classes के ऊपर:

<Switch
  checked={on()}
  disabled={!online()}
  onChange={({ checked }) => on.set(checked)}
  class="flex-row items-center gap-3 disabled:opacity-50"
  trackClass="w-11 rounded-full bg-muted p-0.5 checked:bg-primary disabled:bg-muted"
  thumbClass="size-5 rounded-full bg-background checked:translate-x-5"
>
  <Text>Sync over cellular</Text>
</Switch>

#hitSlop के साथ छोटा लक्ष्य

जिस switch के बगल में कोई label नहीं है, वह उँगली से छोटा हो सकता है। hitSlop उसके पास पड़ने वाले प्रेस को भी गिनता है, हर तरफ़ से points में, उसके layout या रूप को बदले बिना: सभी तरफ़ के लिए एक संख्या, या नामित तरफ़ें ({ top: 8, bottom: 8 }), जैसे view का hitSlop इन्हें लेता है।

<Switch
  checked={on()}
  hitSlop={{ top: 8, bottom: 8 }}
  accessibilityLabel="Notifications"
  onChange={({ checked }) => on.set(checked)}
  trackClass="w-9 rounded-full bg-muted p-0.5 checked:bg-primary"
  thumbClass="size-4 rounded-full bg-background checked:translate-x-4"
/>

#एक्सेसिबिलिटी

  • स्क्रीन रीडर के लिए switch एक ही element है, जिसका role "switch" है और जिसका मान (चालू या बंद) बताया जाता है; track और thumb उसके भाग हैं। उसका label उसके children का टेक्स्ट है; अगर कोई टेक्स्ट नहीं है तो accessibilityLabel दें।
  • disabled को वैसे ही बोला जाता है जैसे प्लेटफ़ॉर्म बोलता है (VoiceOver, TalkBack, UI Automation, ब्राउज़र का accessibility tree)।
  • macOS और web पर switch कीबोर्ड फ़ोकस का एक पड़ाव है: Tab से उस तक पहुँचा जाता है, Space और Return उसे टॉगल करते हैं, और focus: styles दिखाती हैं कि फ़ोकस कहाँ है।

labels, roles और announcements के बारे में सामान्य जानकारी के लिए एक्सेसिबिलिटी देखें।

#प्लेटफ़ॉर्म नोट्स

  • iOS, Android और Mac Catalyst: प्रेस एक tap है जो switch पर ही खत्म होता है, उसके label सहित।
  • डेस्कटॉप (macOS, Windows, Linux, GPUI) और web: प्रेस एक click है। macOS और web पर, Space और Return भी उस switch को टॉगल करते हैं जिस पर कीबोर्ड फ़ोकस है।
  • हर प्लेटफ़ॉर्म वही बनाता है जो ऐप स्टाइल करता है; thumb वैसे ही चलता है जैसा ऐप की styles और transitions कहती हैं।