@ciromaciel/dashboard-kit 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/SidebarShell.jsx +70 -38
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionIcon, Box, ScrollArea, Stack, Text, TextInput } from '@mantine/core'
|
|
1
|
+
import { ActionIcon, Box, Group, ScrollArea, Stack, Text, TextInput, Tooltip } from '@mantine/core'
|
|
2
2
|
import { IconSearch, IconX } from '@tabler/icons-react'
|
|
3
3
|
|
|
4
4
|
import { GroupLabel } from './GroupLabel'
|
|
@@ -39,6 +39,35 @@ import { NavItem } from './NavItem'
|
|
|
39
39
|
* Nada de quota entra aqui. O painel resolve o gate e passa `createAllowed`
|
|
40
40
|
* booleano — a coluna não sabe o que é um plano.
|
|
41
41
|
*/
|
|
42
|
+
/** O botão de criar na linha da busca: quadrado de 43px, preto; em contorno cinza no limite do plano. */
|
|
43
|
+
function CreateSquare({ icon: Icon, label, isAllowed, onClick }) {
|
|
44
|
+
return (
|
|
45
|
+
<Tooltip
|
|
46
|
+
label={label}
|
|
47
|
+
position="bottom"
|
|
48
|
+
withArrow={false}
|
|
49
|
+
>
|
|
50
|
+
<ActionIcon
|
|
51
|
+
data-create
|
|
52
|
+
onClick={onClick}
|
|
53
|
+
aria-label={label}
|
|
54
|
+
size={43}
|
|
55
|
+
radius={0}
|
|
56
|
+
variant={isAllowed ? 'filled' : 'default'}
|
|
57
|
+
color="gray.9"
|
|
58
|
+
// O realce do Mantine puxa o preto para um azul; aqui ele fica no cinza do sistema.
|
|
59
|
+
style={{ flex: 'none', '--ai-hover': 'var(--mantine-color-gray-7)' }}
|
|
60
|
+
>
|
|
61
|
+
<Icon
|
|
62
|
+
size={18}
|
|
63
|
+
stroke={2}
|
|
64
|
+
style={isAllowed ? undefined : { color: 'var(--mantine-color-gray-5)' }}
|
|
65
|
+
/>
|
|
66
|
+
</ActionIcon>
|
|
67
|
+
</Tooltip>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
42
71
|
export function SidebarShell({
|
|
43
72
|
// ── fora do recurso ──────────────────────────────────────────────────
|
|
44
73
|
items = [],
|
|
@@ -94,6 +123,7 @@ export function SidebarShell({
|
|
|
94
123
|
const mostrarBusca = searchThreshold !== null && !activeResource && (items.length >= searchThreshold || Boolean(term))
|
|
95
124
|
|
|
96
125
|
const faixas = partition ? partition(filtrados) : null
|
|
126
|
+
const criar = { icon: createIcon, label: createAllowed ? createLabel : createBlockedLabel, isAllowed: createAllowed, onClick: createAllowed ? onCreate : onCreateBlocked }
|
|
97
127
|
|
|
98
128
|
return (
|
|
99
129
|
<Stack
|
|
@@ -106,21 +136,45 @@ export function SidebarShell({
|
|
|
106
136
|
>
|
|
107
137
|
{header}
|
|
108
138
|
|
|
139
|
+
{/*
|
|
140
|
+
A busca tem a geometria de um item da coluna: mesma borda
|
|
141
|
+
esquerda, ícone de 18 na mesma coluna (12px da borda), texto onde
|
|
142
|
+
começa o rótulo de um item (42px) e a altura de um item (43px).
|
|
143
|
+
Recuada e mais baixa, ela fazia três bordas esquerdas numa coluna
|
|
144
|
+
só.
|
|
145
|
+
|
|
146
|
+
CRIAR MORA NA LINHA DA BUSCA: um quadrado preto de 43px com o
|
|
147
|
+
ícone, colado à direita do campo (escolha do Ciro em 10/10/2026,
|
|
148
|
+
entre cinco opções). Buscar e criar viram uma faixa só de
|
|
149
|
+
ferramentas, e a lista começa limpa logo abaixo. O preto aqui não
|
|
150
|
+
se confunde com o item aberto: aquele é uma faixa larga com texto,
|
|
151
|
+
este é um quadrado que só um botão tem. O nome da ação vai no
|
|
152
|
+
rótulo de acessibilidade e na dica ao passar o mouse.
|
|
153
|
+
|
|
154
|
+
Criar fica ANTES da lista: com muitos recursos a lista rola, e uma
|
|
155
|
+
ação no fim de uma área de rolagem é uma ação que se procura. No
|
|
156
|
+
limite do plano o botão NÃO some — ele leva para os planos, em
|
|
157
|
+
contorno cinza em vez de preto. Escondê-lo deixaria o limite
|
|
158
|
+
invisível.
|
|
159
|
+
*/}
|
|
109
160
|
{mostrarBusca && (
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
pb={
|
|
161
|
+
<Group
|
|
162
|
+
gap={6}
|
|
163
|
+
pb={6}
|
|
113
164
|
w="100%"
|
|
165
|
+
wrap="nowrap"
|
|
114
166
|
>
|
|
115
167
|
<TextInput
|
|
168
|
+
style={{ flex: 1, minWidth: 0 }}
|
|
116
169
|
value={term}
|
|
117
170
|
onChange={e => onTermChange?.(e.currentTarget.value)}
|
|
118
171
|
onKeyDown={e => e.key === 'Escape' && onTermChange?.('')}
|
|
119
172
|
placeholder={searchPlaceholder}
|
|
120
173
|
aria-label={searchPlaceholder}
|
|
174
|
+
leftSectionWidth={42}
|
|
121
175
|
leftSection={
|
|
122
176
|
<IconSearch
|
|
123
|
-
size={
|
|
177
|
+
size={18}
|
|
124
178
|
stroke={1.5}
|
|
125
179
|
/>
|
|
126
180
|
}
|
|
@@ -140,9 +194,10 @@ export function SidebarShell({
|
|
|
140
194
|
</ActionIcon>
|
|
141
195
|
) : null
|
|
142
196
|
}
|
|
143
|
-
styles={{ input: { fontSize:
|
|
197
|
+
styles={{ input: { height: 43, minHeight: 43, fontSize: 13, background: 'var(--mantine-color-gray-1)' } }}
|
|
144
198
|
/>
|
|
145
|
-
|
|
199
|
+
{onCreate && <CreateSquare {...criar} />}
|
|
200
|
+
</Group>
|
|
146
201
|
)}
|
|
147
202
|
|
|
148
203
|
{activeResource ? (
|
|
@@ -153,37 +208,14 @@ export function SidebarShell({
|
|
|
153
208
|
/>
|
|
154
209
|
) : (
|
|
155
210
|
<>
|
|
156
|
-
{/*
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
upgrade.
|
|
165
|
-
|
|
166
|
-
O CONTORNO É O QUE O SEPARA DA NAVEGAÇÃO. Na coluna, sem
|
|
167
|
-
moldura é um lugar para ir, preenchido de preto é onde você
|
|
168
|
-
está, e com contorno é algo que você cria. Preto sólido
|
|
169
|
-
diria "você está aqui"; cor gastaria a única exceção do
|
|
170
|
-
sistema, o vermelho de perda. A borda é a mesma linha fina
|
|
171
|
-
dos contadores ao lado dos itens.
|
|
172
|
-
*/}
|
|
173
|
-
{onCreate && (
|
|
174
|
-
<Box
|
|
175
|
-
w="100%"
|
|
176
|
-
mb={4}
|
|
177
|
-
data-create
|
|
178
|
-
style={{ border: '1px solid var(--mantine-color-gray-3)' }}
|
|
179
|
-
>
|
|
180
|
-
<NavItem
|
|
181
|
-
icon={createIcon}
|
|
182
|
-
label={<span style={{ fontWeight: 700 }}>{createAllowed ? createLabel : createBlockedLabel}</span>}
|
|
183
|
-
muted={!createAllowed}
|
|
184
|
-
onClick={createAllowed ? onCreate : onCreateBlocked}
|
|
185
|
-
/>
|
|
186
|
-
</Box>
|
|
211
|
+
{/* Sem busca (o Monitors, painéis sem lista longa), criar volta a ser um item da coluna. */}
|
|
212
|
+
{onCreate && !mostrarBusca && (
|
|
213
|
+
<NavItem
|
|
214
|
+
icon={criar.icon}
|
|
215
|
+
label={criar.label}
|
|
216
|
+
muted={!createAllowed}
|
|
217
|
+
onClick={criar.onClick}
|
|
218
|
+
/>
|
|
187
219
|
)}
|
|
188
220
|
|
|
189
221
|
{groupLabel && <GroupLabel>{groupLabel}</GroupLabel>}
|