Data View
<gstock-data-view>
|
GstockDataView
Examples
El componente Data View es un orquestador que alterna entre una vista de lista (tabla) y una vista de grid (tarjetas) para mostrar datos. El consumidor controla el modo de visualización mediante la propiedad viewMode — el componente no renderiza ningún toggle de vista propio.
En modo list, renderiza internamente un gstock-data-grid. En modo grid, renderiza un gstock-data-cards.
<div class="view-toggle">
<gstock-button id="btn-list" variant="solid" size="small">
<gstock-icon name="list" slot="prefix"></gstock-icon>
Lista
</gstock-button>
<gstock-button id="btn-grid" variant="outlined" size="small">
<gstock-icon name="grid" slot="prefix"></gstock-icon>
Grid
</gstock-button>
</div>
<gstock-data-view view-mode="list"></gstock-data-view>
<script type="module">
customElements.whenDefined('gstock-data-view').then(() => {
const view = document.querySelector('gstock-data-view');
const btnList = document.querySelector('#btn-list');
const btnGrid = document.querySelector('#btn-grid');
view.columns = [
{ key: 'name', title: 'Nombre', sortable: true },
{ key: 'email', title: 'Correo electrónico' },
{ key: 'role', title: 'Rol' },
{ key: 'status', title: 'Estado', align: 'center' },
];
view.data = [
{
id: 1,
name: 'Juan Pérez',
email: 'juan.perez@example.com',
role: 'Administrador',
status: 'Activo',
},
{
id: 2,
name: 'María García',
email: 'maria.garcia@example.com',
role: 'Usuario',
status: 'Activo',
},
{
id: 3,
name: 'Carlos López',
email: 'carlos.lopez@example.com',
role: 'Editor',
status: 'Inactivo',
},
{
id: 4,
name: 'Ana Rodríguez',
email: 'ana.rodriguez@example.com',
role: 'Usuario',
status: 'Activo',
},
{
id: 5,
name: 'Luis Martín',
email: 'luis.martin@example.com',
role: 'Editor',
status: 'Activo',
},
];
view.cardRenderer = (row, index, options) => {
return `
<div class="user-card">
<div class="user-card__header">
<gstock-avatar initials="${row.name.charAt(0)}" size="medium"></gstock-avatar>
<div class="user-card__info">
<strong>${row.name}</strong>
<span class="user-card__role">${row.role}</span>
</div>
</div>
<div class="user-card__body">
<div class="user-card__field">
<gstock-icon name="mail" library="default"></gstock-icon>
<span>${row.email}</span>
</div>
<gstock-tag size="small" variant="${row.status === 'Activo' ? 'success' : 'neutral'}">
${row.status}
</gstock-tag>
</div>
</div>
`;
};
function updateButtons(mode) {
btnList.variant = mode === 'list' ? 'solid' : 'outlined';
btnGrid.variant = mode === 'grid' ? 'solid' : 'outlined';
}
btnList.addEventListener('click', () => {
view.viewMode = 'list';
updateButtons('list');
});
btnGrid.addEventListener('click', () => {
view.viewMode = 'grid';
updateButtons('grid');
});
});
</script>
<style>
.view-toggle {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
}
.user-card {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.user-card__header {
display: flex;
align-items: center;
gap: 0.75rem;
}
.user-card__info {
display: flex;
flex-direction: column;
}
.user-card__info strong {
font-size: 0.9375rem;
}
.user-card__role {
font-size: 0.8125rem;
color: var(--gstock-color-text-subtle);
}
.user-card__body {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.user-card__field {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.8125rem;
color: var(--gstock-color-text-subtle);
}
.user-card__field gstock-icon {
font-size: 1rem;
}
</style>
Con selección
La selección se preserva al cambiar entre modos de vista. Seleccione elementos en un modo y cambie al otro para verificar que la selección se mantiene.
<gstock-data-view view-mode="list" selectable multi-select></gstock-data-view>
Con paginación
La paginación funciona en ambos modos de vista. Al cambiar de modo, la paginación se mantiene sincronizada.
<div class="view-toggle">
<gstock-button id="btn-list" variant="solid" size="small">
<gstock-icon name="list" slot="prefix"></gstock-icon>
Lista
</gstock-button>
<gstock-button id="btn-grid" variant="outlined" size="small">
<gstock-icon name="grid" slot="prefix"></gstock-icon>
Grid
</gstock-button>
</div>
<gstock-data-view view-mode="list" paginated page-size="4" show-page-size-selector></gstock-data-view>
<script type="module">
customElements.whenDefined('gstock-data-view').then(() => {
const view = document.querySelector('gstock-data-view');
const btnList = document.querySelector('#btn-list');
const btnGrid = document.querySelector('#btn-grid');
view.columns = [
{ key: 'name', title: 'Nombre', sortable: true },
{ key: 'sku', title: 'SKU' },
{ key: 'price', title: 'Precio', align: 'right' },
{ key: 'category', title: 'Categoría' },
];
view.data = Array.from({ length: 16 }, (_, i) => ({
id: i + 1,
name: `Producto ${i + 1}`,
sku: `PRD-${String(i + 1).padStart(3, '0')}`,
price: `€${(Math.random() * 99 + 1).toFixed(2)}`,
category: ['Bebidas', 'Alimentación', 'Limpieza', 'Otros'][i % 4],
}));
view.cardRenderer = row => {
return `
<div class="item-card">
<div class="item-card__header">
<strong>${row.name}</strong>
<code>${row.sku}</code>
</div>
<div class="item-card__footer">
<span class="item-card__price">${row.price}</span>
<gstock-tag size="small" variant="neutral">${row.category}</gstock-tag>
</div>
</div>
`;
};
function updateButtons(mode) {
btnList.variant = mode === 'list' ? 'solid' : 'outlined';
btnGrid.variant = mode === 'grid' ? 'solid' : 'outlined';
}
btnList.addEventListener('click', () => {
view.viewMode = 'list';
updateButtons('list');
});
btnGrid.addEventListener('click', () => {
view.viewMode = 'grid';
updateButtons('grid');
});
});
</script>
<style>
.view-toggle {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
}
.item-card {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.item-card__header {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.item-card__header code {
font-size: 0.75rem;
color: var(--gstock-color-text-subtlest);
}
.item-card__footer {
display: flex;
justify-content: space-between;
align-items: center;
}
.item-card__price {
font-weight: 700;
color: var(--gstock-color-text-brand);
}
</style>
Con ordenamiento
El ordenamiento se aplica en la vista de lista mediante las columnas configuradas como sortable. Al cambiar a vista de grid, el estado de ordenamiento se preserva y se aplica a las tarjetas.
<gstock-data-view view-mode="list" sortable hoverable></gstock-data-view>