A simple row item for displaying title and description.
A block container with icon, title, description, and a custom control slot.
Use TxBlockInput when a settings row needs a standard text-like input while preserving GroupBlock spacing, icons, tags, and disabled state.
Use TxBlockSelect when a settings row should expose a compact TxSelect without rebuilding the row chrome by hand.
A block container with an integrated switch control.
Use :default-expand="false" for first-render collapsed groups. Treat collapsed as an external state input that only applies before stored state or user interaction takes over.
Provide a unique key for memory-name to persist expansion state.
Use the header-extra slot for actions.
Title and description remain side by side when space allows. In narrow containers, the description wraps below the title instead of being squeezed into a fixed column; long commands can wrap without clipping.
Displayed as a clickable link.
loading is forwarded straight to the inner switch: the thumb becomes a spinning ring, the row freezes without dimming, and a shimmer runs across it.
Displayed as a navigation item instead of a switch.
- Use
TxGroupBlock for compact settings and preference clusters; keep each group focused on one product area. - Use unique, stable
memoryName values. Do not reuse the same key across unrelated groups. - Set
collapsible=false for always-visible status or form sections to avoid implying hidden state. - Use
TxBlockLine for read-only values and lightweight navigation links, TxBlockSlot for custom controls, TxBlockInput / TxBlockSelect for standard form rows, and TxBlockSwitch for booleans or guidance rows. - Keep row labels short; move long explanations to the description line or a nearby help pattern instead of adding nested layouts inside rows.
- Rows inside a group are flattened by the group, not by themselves:
TxGroupBlock resets each row's --fake-radius and margin so only the group card is rounded. A row keeps its own 12px radius when used standalone, so do not copy a group's flat look by hard-coding border-radius: 0 on the row.
| Prop | Type | Default | Description |
|---|
name | string | required | Header title for the group. |
description | string | '' | Supporting text displayed below the group title. |
defaultIcon | TxIconSource | string | - | Icon shown when the group is collapsed or when no active icon is provided. |
activeIcon | TxIconSource | string | - | Icon shown while the group is expanded; falls back to defaultIcon. |
iconSize | number | 22 | Header icon size in pixels. |
collapsible | boolean | true | Allow the header to toggle the group body. |
collapsed | boolean | false | External collapsed input watched before stored state or user interaction exists; prefer :default-expand="false" for first-render collapsed groups. |
defaultExpand | boolean | true | Initial expanded state when no stored state exists; set to false for a collapsed first render. |
memoryName | string | '' | Persist expanded state in localStorage under the tuff-block-storage- prefix. |
| Event | Params | Description |
|---|
update:expanded | expanded: boolean | Emitted after a collapsible group changes expansion state. |
toggle | expanded: boolean | Emitted with the same state when the header toggles the group. |
| Slot | Props | Description |
|---|
default | - | Group body rows. |
icon | { active: boolean } | Custom header icon; replaces defaultIcon / activeIcon. |
header-extra | { active: boolean } | Header action area rendered before the collapse chevron. |
| Prop | Type | Default | Description |
|---|
title | string | '' | Row label. |
description | string | '' | Row value text when link=false; can be replaced with the description slot. |
link | boolean | false | Render as a native button with link styling and click emits. |
| Event | Params | Description |
|---|
click | event: MouseEvent | Emitted only when link=true. |
| Slot | Props | Description |
|---|
description | - | Custom row value/link content. |
| Prop | Type | Default | Description |
|---|
title | string | '' | Default label title, replaced when the label slot is provided. |
description | string | '' | Default label description, replaced when the label slot is provided. |
defaultIcon | TxIconSource | string | - | Icon shown when active=false or when no active icon is provided. |
activeIcon | TxIconSource | string | - | Icon shown when active=true; falls back to defaultIcon. |
iconSize | number | 20 | Icon size in pixels. |
active | boolean | false | When true, swaps to activeIcon and passes active into the icon/default slot scope; it does not change the row's visual style. |
disabled | boolean | false | Apply disabled styling and block row click emits. |
| Event | Params | Description |
|---|
click | event: MouseEvent | Emitted when the row is clicked and disabled=false. |
| Slot | Props | Description |
|---|
default | { active: boolean } | Control area aligned to the right side. |
icon | { active: boolean } | Custom icon area. |
label | - | Full custom label block; replaces title and description. |
tags | - | Inline metadata beside the title, or below a custom label. |
| Prop | Type | Default | Description |
|---|
modelValue | string | number | '' | Current input value for v-model. |
title | string | '' | Row title. |
description | string | '' | Row description. |
defaultIcon | TxIconSource | string | - | Icon shown when the input is not focused or when no active icon is provided. |
activeIcon | TxIconSource | string | - | Icon shown while focused. |
disabled | boolean | false | Disable the row and underlying input. |
placeholder | string | '' | Input placeholder. |
clearable | boolean | false | Forwarded to TxInput. |
inputType | 'text' | 'password' | 'number' | 'email' | 'text' | Forwarded as the TxInput type. |
| Event | Params | Description |
|---|
update:modelValue | value: string | number | Emitted when the underlying input model changes. |
input | value: string | number | Mirrors the underlying TxInput input event. |
focus | event: FocusEvent | Emitted when the input gains focus. |
blur | event: FocusEvent | Emitted when the input loses focus. |
| Slot | Props | Description |
|---|
control | { value: string | number, focused: boolean } | Replaces the default TxInput. |
tags | - | Inline metadata forwarded to the row title area. |
| Prop | Type | Default | Description |
|---|
modelValue | string | number | '' | Current select value for v-model. |
title | string | '' | Row title. |
description | string | '' | Row description. |
defaultIcon | TxIconSource | string | - | Icon shown when no value is selected or when no active icon is provided. |
activeIcon | TxIconSource | string | - | Icon shown when a value is selected. |
disabled | boolean | false | Disable the row and underlying select. |
placeholder | string | '' | Select placeholder. |
| Event | Params | Description |
|---|
update:modelValue | value: string | number | Emitted when the selected value changes. |
change | value: string | number | Mirrors the same selected value after change. |
| Slot | Props | Description |
|---|
default | - | TxSelect option children such as TuffSelectItem. |
tags | - | Inline metadata forwarded to the row title area. |
| Prop | Type | Default | Description |
|---|
modelValue | boolean | required | Current switch value for v-model. |
title | string | required | Switch row title. |
description | string | required | Switch row description. |
defaultIcon | TxIconSource | string | - | Icon shown when the switch is off or when no active icon is provided. |
activeIcon | TxIconSource | string | - | Icon shown when the switch is on; falls back to defaultIcon. |
disabled | boolean | false | Disable the row and underlying switch. |
guidance | boolean | false | Render as a navigation row with a chevron instead of a switch. |
loading | boolean | false | Forwarded to the inner TuffSwitch loading prop: the thumb becomes a spinning ring, the row gains a shimmer, and switch interaction is temporarily disabled. |
| Event | Params | Description |
|---|
update:modelValue | value: boolean | Emitted by the underlying switch when the value changes. |
change | value: boolean | Mirrors the switch change event after user interaction. |
click | event: MouseEvent | Emitted only in guidance mode. |
| Slot | Props | Description |
|---|
tags | - | Inline metadata forwarded to the row title area. |
None. Use props, update:expanded, toggle, and the row-specific events instead of imperative handles.
memoryName wins over initial defaults; stored state is saved as { expand: boolean } in localStorage.defaultExpand drives first render when no stored state exists. collapsed is then watched as an external input until the user toggles the group.- After the user toggles a group, later
collapsed / defaultExpand prop changes no longer overwrite the chosen state. - Group bodies stay mounted; expansion only animates height, opacity, and display.
TxBlockLine renders a non-interactive div by default and a native button type="button" only when link=true.TxBlockLine uses the same 16px row inset as other settings rows; its description wraps to a second row when the title and value cannot fit side by side.TxBlockSlot pins every control slot at flex-shrink: 0 so fixed-size controls never squash. TxBlockInput lifts that for itself: its field shrinks toward min-width: 120px instead of holding 180px and squeezing the row's title, which in a 240px container left the title 10px.TxBlockSlot blocks click emits when disabled; TxBlockSwitch freezes the whole row's pointer events while loading=true too, but the row is not dimmed — tx-block-switch--loading:not(.tx-block-switch--disabled) takes back the slot's opacity: .5 so busy and disabled stay visually distinct.TxBlockSwitch shows the busy cue in exactly one place: loading is forwarded to the inner TuffSwitch, whose thumb becomes a spinning ring. The row only adds a shimmer and no longer renders a separate spinner.TxBlockSwitch guidance mode replaces the switch with a chevron and only emits click; it does not mutate modelValue.
- Reviewed against
packages/tuffex/packages/components/src/group-block/src/types.ts and all six Vue entry points in the group-block package. TxBlockLine only becomes interactive when link=true; do not describe it as a generic clickable row.TxBlockSwitch loading mode blocks mutation, while guidance mode emits only click and should be documented as navigation, not a boolean toggle.- Busy-state ownership: the loading visual belongs to the inner
TuffSwitch (is-loading + aria-busy); TxBlockSwitch only owns the row shimmer and the un-dimming. Changing the switch's loading treatment means updating both components' docs. - Collapsed demos intentionally use
:default-expand="false"; current source watches collapsed only before storage or user interaction changes the group state. - Flattening selector: the reset that squares off rows is a plain descendant selector.
TxGroupBlock's <style> is unscoped, where :deep() is passed through untransformed and the browser discards the rule — a package-wide test now fails on :deep() in any unscoped block. - Verified coverage: persisted expansion, static-group behavior, semantic link rows, disabled slot-click blocking, guidance mode, loading-state value-change guards, and that a loading row carries
is-loading / aria-busy on the switch itself with no second spinner. - Component sources:
packages/tuffex/packages/components/src/group-block/src/TxGroupBlock.vue, TxBlockLine.vue, TxBlockSlot.vue, TxBlockInput.vue, TxBlockSelect.vue, and TxBlockSwitch.vue. - Types:
packages/tuffex/packages/components/src/group-block/src/types.ts. - Coverage:
packages/tuffex/packages/components/src/group-block/__tests__/group-block.test.ts verifies persistence, static groups, semantic link rows, slot click blocking, guidance mode, and loading-state value guards.
查看源码packages/tuffex/packages/components/src/group-block/index.ts
| Theme token | Used for |
|---|
--tx-border-color-lighter | Group card border and header divider. |
--tx-fill-color-dark / --tx-fill-color / --tx-fill-color-light | Header, row, hover, and touch-blur surfaces. |
--tx-text-color-primary / --tx-text-color-secondary | Group titles, row labels, descriptions, guidance arrows, and the switch loading ring. |
--tx-color-primary / --tx-color-primary-dark-2 | TxBlockLine link color and hover color. |
--tx-color-white | Loading shimmer highlight mixed into TxBlockSwitch loading overlay. |