# MatchRoundSetList
Round setting list component for displaying multiple match round settings with header and round items.
# Import
import PressMatchRoundSetList from 'press-next/press-match-round-set-list/press-match-round-set-list';
# Usage
# Basic Usage
<PressMatchRoundSetList
:list="roundSetList"
@item-click="onItemClick"
@action-click="onActionClick"
/>
# Custom Style
<PressMatchRoundSetList
custom-class="custom-round-set-list"
:list="roundSetList"
@item-click="onItemClick"
@action-click="onActionClick"
/>
# Custom Column Configuration
<PressMatchRoundSetList
:list="roundSetList"
:columns="customColumns"
@item-click="onItemClick"
@action-click="onActionClick"
/>
// Custom column configuration
const customColumns = [
{ key: 'rounds', title: 'Round', width: '1.5rem', align: 'left' },
{ key: 'settings', title: 'Start Settings', width: '2.5rem', align: 'center' },
{ key: 'ways', title: 'Format', width: '1.8rem', align: 'center' },
{ key: 'operate', title: 'Action', width: '2rem', align: 'center' }
];
# API
# Props
| Attribute | Description | Type | Default |
|---|---|---|---|
| custom-class | Custom style class name | string | '' |
| list | Round setting data list | RoundSetItemData[] | [] |
| columns | Table column configuration | Column[] | getTableColumns() |
# Column Interface
interface Column {
key: string;
title: string;
width?: string;
minWidth?: string;
align?: 'left' | 'center' | 'right';
sortable?: boolean;
}
# RoundSetItemData Structure
interface RoundSetItemData {
roundName: string; // Round name
timeText: string; // Start time text
formatText: string; // Winning format text
actionText: string; // Action text
selected?: boolean; // Whether selected
disabled?: boolean; // Whether disabled
editable?: boolean; // Whether editable
showTimeIcon?: boolean; // Whether to show time icon
showFormatIcon?: boolean; // Whether to show format icon
hasStarted?: boolean; // Whether started
canSetTime?: boolean; // Whether can set time
canSetBo?: boolean; // Whether can set best-of format
bo_type?: number; // Best-of type (1: Best of 1, 3: Best of 3, 5: Best of 5, 7: Best of 7)
}
# Events
| Event | Description | Parameters |
|---|---|---|
| item-click | Triggered when clicking round item | (item: RoundSetItemData, index: number) |
| action-click | Triggered when clicking action button | (item: RoundSetItemData, index: number) |
| time-click | Triggered when clicking time setting | (item: RoundSetItemData, index: number) |
| format-click | Triggered when clicking format setting | (item: RoundSetItemData, index: number) |
| set-round-bo | Triggered when setting round best-of format | (data: { currentRound: RoundSetItemData; value: number }) |
| set-round-time | Triggered when setting round time | (data: { currentRound: RoundSetItemData; value: any }) |
| start-all-round | Triggered when starting entire round | (data: { currentRound: RoundSetItemData }) |
| sort | Triggered when header sorting | (data: { key: string; order: 'asc' \| 'desc' \| null }) |
# Style Customization
# CSS Variables
The component provides rich CSS variables for style customization, all using the --mrsl- prefix:
/* Position Properties */
--mrsl-container-position: relative; /* Container position type */
--mrsl-header-position: relative; /* Header position type */
--mrsl-content-position: relative; /* Content area position type */
/* Box Model Properties */
--mrsl-container-width: 100%; /* Container width */
--mrsl-container-height: auto; /* Container height */
--mrsl-header-width: 100%; /* Header width */
--mrsl-header-height: .7rem; /* Header height */
--mrsl-header-padding: .14rem .22rem; /* Header padding */
--mrsl-content-width: 100%; /* Content area width */
--mrsl-content-height: calc(100% - .7rem); /* Content area height */
--mrsl-header-item-round-min-width: 1.2rem; /* Round header item minimum width */
--mrsl-header-item-time-min-width: 2rem; /* Time header item minimum width */
--mrsl-header-item-format-min-width: 1.4rem; /* Format header item minimum width */
--mrsl-header-item-action-min-width: 1.6rem; /* Action header item minimum width */
/* Border Properties */
--mrsl-container-border-radius: $border-radius-none; /* Container border radius */
/* Background Properties */
--mrsl-container-bg: linear-gradient(91deg, rgba(237, 239, 241, .5) 0%, rgba(252, 252, 252, .5) 100%); /* Container background gradient */
--mrsl-header-bg: url(https://image-1251917893.file.myqcloud.com/general-match-components/img/match-round-set-list/table-header.png); /* Header background image */
--mrsl-header-bg-size: 100% 100%; /* Header background image size */
/* Text Properties */
--mrsl-header-item-color: $color-text-invert-light; /* Header item text color */
--mrsl-header-item-font-size: $font-size-xs; /* Header item font size */
--mrsl-header-item-font-weight: $font-weight-regular; /* Header item font weight */
--mrsl-header-item-time-text-align: center; /* Time header item text alignment */
--mrsl-header-item-format-text-align: center; /* Format header item text alignment */
--mrsl-header-item-action-text-align: right; /* Action header item text alignment */
/* Other Properties */
--mrsl-content-overflow-y: auto; /* Content area vertical overflow */
/* Header Scroll Related */
--mrsl-header-scroll-min-width: calc(1.48rem + 1.94rem + 1.6rem + 1.6rem); /* Header scroll minimum width */
--mrsl-header-scroll-overflow-x: auto; /* Header horizontal scroll */
--mrsl-header-scrollbar-width: none; /* Firefox scrollbar width */
--mrsl-header-scrollbar-style: none; /* IE scrollbar style */
--mrsl-header-webkit-scrollbar-display: none; /* Webkit scrollbar display */
/* Header Cell Related */
--mrsl-header-cell-flex-shrink: 0; /* Header cell flex shrink */
# Theme Customization Examples
/* Dark Theme */
.dark-theme {
--mrsl-container-bg: linear-gradient(91deg, rgba(30, 30, 30, .8) 0%, rgba(50, 50, 50, .8) 100%);
--mrsl-header-item-color: #ffffff;
}
/* Compact Layout */
.compact-layout {
--mrsl-header-height: .6rem;
--mrsl-header-padding: .12rem .18rem;
--mrsl-header-item-font-size: $font-size-xxs;
}
/* Custom Size */
.custom-size {
--mrsl-header-item-round-min-width: 1.2rem;
--mrsl-header-item-time-min-width: 1.4rem;
--mrsl-header-item-format-min-width: 1.3rem;
--mrsl-header-item-action-min-width: 1.3rem;
}
# Design System Integration
The component is fully integrated with the design system using semantic variables:
- Color System: References
$color-text-invert-lightand other semantic variables - Font System: Uses
$font-size-xs,$font-weight-regularstandard font variables - Border System: Uses
$border-radius-nonestandard border radius variables
# Architecture Design
The component uses CSS variable passing to communicate with child components, avoiding :deep() style penetration:
// Parent component passes styles to header component
&__header {
--pmth-header-overflow-x: auto;
--pmth-header-min-width: calc(1.48rem + 1.94rem + 1.6rem + 1.6rem);
--pmth-header-scrollbar-width: none;
--pmth-header-cell-round-min-width: 1.48rem;
--pmth-header-cell-time-min-width: 1.94rem;
// More variables...
}
// Parent component passes styles to round item component for width synchronization
&__content {
--mrsi-round-min-width: 1.48rem;
--mrsi-time-min-width: 1.94rem;
--mrsi-format-min-width: 1.6rem;
--mrsi-action-min-width: 1.6rem;
--mrsi-container-scrollbar-width: none;
// More variables...
}
# Width Synchronization Mechanism
To ensure perfect width synchronization between header cells and content items, the component adopts a dual synchronization strategy:
1. CSS Variable Synchronization (Original Method)
- Unified Variable Source: All widths come from
$mrsl-header-item-*-min-widthvariables - Bidirectional Passing: Simultaneously passed to both header and round item components
- Dynamic Calculation: Container minimum width calculated dynamically through variables
// Dynamic calculation in round item component
min-width: calc(#{$mrsi-round-min-width} + #{$mrsi-time-min-width} + #{$mrsi-format-min-width} + #{$mrsi-action-min-width});
2. Column Configuration Synchronization (New Method)
- Unified Configuration Source: Header and content items use the same
tableColumnsconfiguration - Direct Passing: Pass header column configuration directly to round item components
- Higher Priority: When both exist, column configuration takes precedence over CSS variables
// Table column configuration - consistent with press-match-table-header demo-data
const tableColumns = [
{ key: 'rounds', title: '轮次', width: '1.2rem', align: 'left' },
{ key: 'settings', title: '开赛设置', width: '2rem', align: 'center' },
{ key: 'ways', title: '决胜方式', width: '1.4rem', align: 'center' },
{ key: 'operate', title: '操作', width: '1.6rem', align: 'center' }
];
Advantages of this design:
- ✅ Style Encapsulation: Doesn't break component style isolation
- ✅ Width Synchronization: Ensures perfect alignment between header and content items
- ✅ Compatibility: No need to modify existing child components
- ✅ Maintainability: Avoids maintenance issues from style penetration
- ✅ Performance: Reduces style calculation overhead
- ✅ Extensibility: Facilitates future feature extensions
- ✅ Flexible Configuration: Supports runtime dynamic column width adjustment
# Example
<template>
<div class="demo-container">
<PressMatchRoundSetList
:list="roundSetList"
@item-click="onItemClick"
@action-click="onActionClick"
@time-click="onTimeClick"
@format-click="onFormatClick"
@set-round-bo="onSetRoundBo"
@set-round-time="onSetRoundTime"
@start-all-round="onStartAllRound"
@sort="onSort"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import PressMatchRoundSetList from 'press-next/press-match-round-set-list/press-match-round-set-list';
const roundSetList = ref([
{
roundName: 'Round of 32',
timeText: 'Mar 18 12:00',
formatText: 'Best of 1',
actionText: 'Start Round',
editable: true,
showTimeIcon: true,
showFormatIcon: true,
hasStarted: false,
canSetTime: true,
canSetBo: true,
bo_type: 1,
},
{
roundName: 'Round of 16',
timeText: 'Mar 19 14:00',
formatText: 'Best of 3',
actionText: 'Start Round',
editable: true,
showTimeIcon: true,
showFormatIcon: true,
hasStarted: false,
canSetTime: true,
canSetBo: true,
bo_type: 3,
},
// More data...
]);
const onItemClick = (item, index) => {
console.log('Click round:', item.roundName, index);
};
const onActionClick = (item, index) => {
console.log('Click action:', item.actionText, index);
};
const onTimeClick = (item, index) => {
console.log('Click time setting:', item.timeText, index);
};
const onFormatClick = (item, index) => {
console.log('Click format setting:', item.formatText, index);
};
const onSetRoundBo = (data) => {
console.log('Set best-of format:', data.currentRound.roundName, data.value);
// Update data
data.currentRound.bo_type = data.value;
};
const onSetRoundTime = (data) => {
console.log('Set time:', data.currentRound.roundName, data.value);
// Update data
data.currentRound.timeText = formatTime(data.value);
};
const onStartAllRound = (data) => {
console.log('Start entire round:', data.currentRound.roundName);
// Update status
data.currentRound.hasStarted = true;
};
const onSort = (data) => {
console.log('Sort:', data.key, data.order);
// Handle sorting logic
};
const formatTime = (timestamp) => {
const date = new Date(timestamp);
return `${date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} ${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`;
};
</script>