Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/volto-govrs-ds/news/23.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Implementação do componente Tag dispensáveis ( Default) e Variantes:
Tag Texto, Tag Persistente, Tag Status, Tag Icone e Tag de Contagem(@Gabriel-SAbreu)
238 changes: 238 additions & 0 deletions packages/volto-govrs-ds/src/components/Tag/Tag.stories.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
import Tag from './index';
import Persistente from './variants/Persistente';
export default {
title: 'Components/Tag',
component: Tag,
};

export const TagDocs = () => (
<>
<div style={{ padding: 16, maxWidth: 720 }}>
<h1>Tag - Documentação</h1>
<p>
O componente <code>Tag</code> permite escolher a variante através da
prop <code>variant</code>. Isso facilita a utilização quando se deseja
alternar entre diferentes tipos de tags dinamicamente.
</p>
</div>
<h2>Tag de Interação</h2>
<p>
Possuem uma ação ao serem clicadas/tocadas. De acordo com o tipo de
interação podemos ter tags interativas dispensáveis e persistentes.
<br />
Tags aceitam as props <code>content</code>, <code>disabled</code> e{' '}
<code>showIcon</code>
</p>
<h3>Dispensáveis</h3>
<div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
<Tag variant="default" content="Label 1" />
<Tag variant="default" content="Label 2" />
<Tag variant="default" content="Label 3" />
<Tag variant="default" disabled content="Label" />
</div>
<pre
style={{
background: '#f7f7f7',
padding: 12,
borderRadius: 4,
overflowX: 'auto',
marginTop: 8,
}}
>
<code>{`<Tag variant="default" content="Label" />`}</code> <br />
<code>{`<Tag variant="default" disabled content="Label" />`}</code>
</pre>

<p>
Ao utilizar a prop <code>showIcon</code>, a tag não exibe o ícone.
</p>

<div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
<Tag variant="default" showIcon={false} content="Label 1" />
<Tag variant="default" showIcon={false} disabled content="Label" />
</div>

<pre className="showCode">
<code>{`<Tag variant="default" showIcon={false} content="Label 1" />`}</code>{' '}
<br />
<code>{`<Tag variant="default" showIcon={false} disabled content="Label" />`}</code>
</pre>

<h3>Texto</h3>
<p>
A tag pode não possuir nenhum tipo de interação, serrvindo apenas para
exibição de um texto, nesse caso, pode possuir icone e texto ou somente
texto. Optando pela segunda opção utilizasse a prop <code>showClose</code>{' '}
como <code>false</code>.
</p>

<div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
<Tag variant="default" showClose={false} content="Label 1" />
<Tag
variant="default"
showClose={false}
showIcon={false}
content="Label 1"
/>
<Tag variant="default" showClose={false} disabled content="Label" />
<Tag
variant="default"
showIcon={false}
showClose={false}
disabled
content="Label"
/>
</div>

<pre className="showCode">
<code>{`<Tag variant="default" showClose={false} content="Label 1" />`}</code>{' '}
<br />
<code>{`<Tag variant="default" showClose={false} showIcon={false} content="Label 1" />`}</code>
<br />
<code>{`<Tag variant="default" showClose={false} disabled content="Label" />`}</code>
<br />
<code>{`<Tag variant="default" showIcon={false} showClose={false} disabled content="Label" /> `}</code>
</pre>

<h3>Persistentes</h3>
<p>
Tags persistentes não podem ser dispensadas, apenas indicam um estado ou
categoria.
</p>
<p>
As props <code>content</code>, <code>disabled</code> e{' '}
<code>showIcon</code> são aceitas.
</p>

<p>
{' '}
<em>ATENÇÃO:</em> nas tags persistentes que serão selecionadas por padrão,
utilize a prop <code>defaultChecked</code> juntamente com a prop{' '}
<code>disabled</code>.
</p>
<div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
<Tag variant="persistente" content="Label 1" />
<Tag variant="persistente" content="Label 2" showIcon={false} />
<Tag
variant="persistente"
disabled
content="Label"
defaultChecked={true}
/>
</div>

<pre className="showCode">
<code>{`<Tag variant="persistente" content="Label 1" />`}</code> <br />
<code>{`<Tag variant="persistente" content="Label 2" showIcon={false}/>`}</code>
<br />
<code>{`<Tag variant="persistente" disabled content="Label" defaultChecked={true} `}</code>
</pre>

<h4>Persistente — Grupo (radio)</h4>
<p>
Variação para seleção única entre várias tags. Cada tag precisa ter um{' '}
<code>id</code> único.
</p>
<p>
Para selecionar uma tag por padrão, utilize a prop{' '}
<code>defaultSelected</code> com o valor do <code>id</code> da tag
desejada.
</p>

<div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
<Tag variant="persistenteGroup" radio defaultSelected="null">
<Persistente id="tag1" content="Tag 1" />
<Persistente id="tag2" content="Tag 2" />
<Persistente id="tag3" content="Tag 3" />
</Tag>
</div>
<pre className="showCode">
<code>{`<Tag variant="persistenteGroup" radio defaultSelected="null">`}</code>{' '}
<br />
<code>{` <Persistente id="tag1" content="Tag 1" />`}</code>
<br />
<code>{` <Persistente id="tag2" content="Tag 2" />`}</code>
<br />
<code>{` <Persistente id="tag3" content="Tag 3" />`}</code>
<br />
<code>{`</Tag variant="persistenteGroup">`}</code>
</pre>

<h3>Status</h3>
<p>
Tags de status são utilizadas para indicar estados ou categorias
específicas. Elas não possuem interação de clique.
</p>
<div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
<Tag variant="status" status="Online" Label="Online" />
<Tag variant="status" status="Offline" Label="Offline" />
<Tag variant="status" status="Ausente" Label="Ausente" />
</div>
<pre className="showCode">
<code>{`<Tag variant="status" status="Online" Label="Online" />`}</code>{' '}
<br />
<code>{`<Tag variant="status" status="Offline" Label="Offline" />`}</code>
<br />
<code>{`<Tag variant="status" status="Ausente" Label="Ausente" />`}</code>
</pre>

<p>
Podem ser usadas com Label ou apenas com a superfície circular. <br />{' '}
Para realizar a escolha utilizar a prop<code>Label</code> vazia ou com o
mesmo conteúdo da prop <code>status</code>.
</p>
<div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
<Tag variant="status" status="Online" Label="" />
<Tag variant="status" status="Offline" Label="" />
<Tag variant="status" status="Ausente" Label="" />
</div>
<pre className="showCode">
<code>{`<Tag variant="status" status="Online" Label="" />`}</code> <br />
<code>{`<Tag variant="status" status="Offline" Label="" />`}</code>
<br />
<code>{`<Tag variant="status" status="Ausente" Label="" />`}</code>
</pre>

<h3>Icone</h3>
<p>
Tags de icone possuem a mesma ideia das tags texto, porém utilizando
apenas icone
</p>
<p>
As props <code>ico</code> pode ser utilizada para especificar qual icone
será exibido.
</p>
<div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
<Tag variant="icone" ico="car" />
<Tag variant="icone" ico="search" />
</div>
<pre className="showCode">
<code>{`<Tag variant="icone" ico="car" />`}</code> <br />
<code>{`<Tag variant="icone" ico="search" />`}</code>
</pre>

<h3>Contagem</h3>
<p>
Tags de contagem são utilizadas para exibir um número ou valor associado a
uma tag.
</p>
<p>
Se o valor for maior que 999, será exibido como "999+". Os valores são
atribuidos através da prop <code>label</code>.
</p>
<div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
<Tag variant="contagem" label="9" />
<Tag variant="contagem" label="90" />
<Tag variant="contagem" label="190" />
<Tag variant="contagem" label="999" />
<Tag variant="contagem" label="2000" />
</div>
<pre className="showCode">
<code>{`<Tag variant="contagem" label="9" />`}</code> <br />
<code>{`<Tag variant="contagem" label="90" />`}</code> <br />
<code>{`<Tag variant="contagem" label="190" />`}</code> <br />
<code>{`<Tag variant="contagem" label="999" />`}</code>
<code>{`<Tag variant="contagem" label="2000" />`}</code>
</pre>
</>
);
28 changes: 28 additions & 0 deletions packages/volto-govrs-ds/src/components/Tag/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Default from './variants/Default.jsx';
import Persistente from './variants/Persistente';
import Status from './variants/Status';
import Icone from './variants/Icone';
import Contagem from './variants/Contagem';

const VARIANTS = {
default: Default,
persistente: Persistente,
persistenteGroup: Persistente.Group,
status: Status,
icone: Icone,
contagem: Contagem,
};

export default function Tag({
items = [],
variant,
itemKey = (i) => i.id,
className = '',
...rest
}) {
const v = variant || 'default';
const Variant = VARIANTS[v] || Default;
return (
<Variant items={items} itemKey={itemKey} className={className} {...rest} />
);
}
19 changes: 19 additions & 0 deletions packages/volto-govrs-ds/src/components/Tag/variants/Contagem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import './Contagem.scss';

const Contagem = ({ label }) => {
const n = Number(label);
const displayLabel = Number.isFinite(n)
? n > 999
? '999+'
: String(n)
: label;
return (
<>
<div className="govrs-tag-contagem">
<span>{displayLabel}</span>
</div>
</>
);
};

export default Contagem;
14 changes: 14 additions & 0 deletions packages/volto-govrs-ds/src/components/Tag/variants/Contagem.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.govrs-tag-contagem {
display: inline-flex;
min-width: 24px;
min-height: 24px;
align-items: center;
justify-content: center;
padding: 1px 7px 4px 7px;
border: 1px solid #fff;
border-radius: 999px;
background-color: #d54309;
color: #fff;
font-size: 0.875rem;
gap: 8px;
}
87 changes: 87 additions & 0 deletions packages/volto-govrs-ds/src/components/Tag/variants/Default.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import './Default.scss';

function CarIcon() {
return (
<svg
width="19"
height="16"
viewBox="0 0 19 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.0937 5.5C17.3437 5.5 17.5312 5.75 17.4687 5.96875L17.2812 6.71875C17.25 6.90625 17.0937 7 16.9375 7H16.2812C16.7187 7.375 17 7.90625 17 8.5V10C17 10.5312 16.7812 10.9688 16.5 11.3125V13C16.5 13.5625 16.0312 14 15.5 14H14.5C13.9375 14 13.5 13.5625 13.5 13V12H5.5V13C5.5 13.5625 5.03125 14 4.5 14H3.5C2.9375 14 2.5 13.5625 2.5 13V11.3125C2.1875 10.9688 2 10.5312 2 10V8.5C2 7.90625 2.25 7.375 2.6875 7H2.0625C1.875 7 1.71875 6.90625 1.6875 6.71875L1.5 5.96875C1.4375 5.75 1.625 5.5 1.875 5.5H3.71875L4.25 4.21875C4.78125 2.875 6.0625 2 7.5 2H11.4687C12.9062 2 14.1875 2.875 14.7187 4.21875L15.25 5.5H17.0937ZM6.09375 4.96875L5.5 6.5H13.5L12.875 4.96875C12.625 4.375 12.0937 4 11.4687 4H7.5C6.875 4 6.34375 4.375 6.09375 4.96875ZM4.5 10C5.09375 10 6 10.0938 6 9.5C6 8.90625 5.09375 8 4.5 8C3.875 8 3.5 8.40625 3.5 9C3.5 9.625 3.875 10 4.5 10ZM14.5 10C15.0937 10 15.5 9.625 15.5 9C15.5 8.40625 15.0937 8 14.5 8C13.875 8 13 8.90625 13 9.5C13 10.0938 13.875 10 14.5 10Z"
fill="white"
/>
</svg>
);
}

function CloseIcon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="28"
height="28"
viewBox="0 0 28 28"
fill="none"
>
<path
fill="currentColor"
d="M16.0625 14L19.1875 17.1562C19.5938 17.5312 19.5938 18.1562 19.1875 18.5312L18.5 19.2188C18.125 19.625 17.5 19.625 17.125 19.2188L14 16.0938L10.8438 19.2188C10.4688 19.625 9.84375 19.625 9.46875 19.2188L8.78125 18.5312C8.375 18.1562 8.375 17.5312 8.78125 17.1562L11.9062 14L8.78125 10.875C8.375 10.5 8.375 9.875 8.78125 9.5L9.46875 8.8125C9.84375 8.40625 10.4688 8.40625 10.8438 8.8125L14 11.9375L17.125 8.8125C17.5 8.40625 18.125 8.40625 18.5 8.8125L19.1875 9.5C19.5938 9.875 19.5938 10.5 19.1875 10.875L16.0625 14Z"
/>
</svg>
);
}
const Default = ({
disabled = false,
showClose = true,
content = 'Tag Default',
showIcon = true,
}) => {
const [visible, setVisible] = useState(true);

const handleClose = () => {
if (disabled) return;
setVisible(false);
};

if (!visible) return null;

return (
<>
<span
className={`govrs-tag ${disabled ? 'disable' : ''}`}
aria-disabled={disabled}
disabled={disabled || undefined}
>
{showIcon && <CarIcon />}
{content}

{showClose && (
<button type="button" aria-label="Fechar tag" onClick={handleClose}>
<CloseIcon />
</button>
)}
</span>
</>
);
};

Default.propTypes = {
disabled: PropTypes.bool,
content: PropTypes.node,
showClose: PropTypes.bool,
showIcon: PropTypes.bool,
};

Default.defaultProps = {
disabled: false,
content: 'Tag Default',
showClose: true,
showIcon: true,
};

export default Default;
Loading