@ciromaciel/dashboard-kit 1.2.1 → 1.3.1
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 +66 -42
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 36px, 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={36}
|
|
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={16}
|
|
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
|
|
@@ -107,18 +137,35 @@ export function SidebarShell({
|
|
|
107
137
|
{header}
|
|
108
138
|
|
|
109
139
|
{/*
|
|
110
|
-
A busca
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
140
|
+
A busca se alinha com a lista: mesma borda esquerda, ícone
|
|
141
|
+
centrado na coluna dos ícones dos itens e texto onde começa o
|
|
142
|
+
rótulo de um item (42px). A altura é a de um campo, 36px, menor
|
|
143
|
+
que um item (43px): com a altura de um item, busca e criar
|
|
144
|
+
pesavam mais que a lista que servem (Ciro, 10/10/2026).
|
|
145
|
+
|
|
146
|
+
CRIAR MORA NA LINHA DA BUSCA: um quadrado preto de 36px 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.
|
|
115
159
|
*/}
|
|
116
160
|
{mostrarBusca && (
|
|
117
|
-
<
|
|
161
|
+
<Group
|
|
162
|
+
gap={6}
|
|
118
163
|
pb={6}
|
|
119
164
|
w="100%"
|
|
165
|
+
wrap="nowrap"
|
|
120
166
|
>
|
|
121
167
|
<TextInput
|
|
168
|
+
style={{ flex: 1, minWidth: 0 }}
|
|
122
169
|
value={term}
|
|
123
170
|
onChange={e => onTermChange?.(e.currentTarget.value)}
|
|
124
171
|
onKeyDown={e => e.key === 'Escape' && onTermChange?.('')}
|
|
@@ -127,7 +174,7 @@ export function SidebarShell({
|
|
|
127
174
|
leftSectionWidth={42}
|
|
128
175
|
leftSection={
|
|
129
176
|
<IconSearch
|
|
130
|
-
size={
|
|
177
|
+
size={16}
|
|
131
178
|
stroke={1.5}
|
|
132
179
|
/>
|
|
133
180
|
}
|
|
@@ -147,9 +194,10 @@ export function SidebarShell({
|
|
|
147
194
|
</ActionIcon>
|
|
148
195
|
) : null
|
|
149
196
|
}
|
|
150
|
-
styles={{ input: { height:
|
|
197
|
+
styles={{ input: { height: 36, minHeight: 36, fontSize: 13, background: 'var(--mantine-color-gray-1)' } }}
|
|
151
198
|
/>
|
|
152
|
-
|
|
199
|
+
{onCreate && <CreateSquare {...criar} />}
|
|
200
|
+
</Group>
|
|
153
201
|
)}
|
|
154
202
|
|
|
155
203
|
{activeResource ? (
|
|
@@ -160,38 +208,14 @@ export function SidebarShell({
|
|
|
160
208
|
/>
|
|
161
209
|
) : (
|
|
162
210
|
<>
|
|
163
|
-
{/*
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
upgrade.
|
|
172
|
-
|
|
173
|
-
O CONTORNO É O QUE O SEPARA DA NAVEGAÇÃO. Na coluna, sem
|
|
174
|
-
moldura é um lugar para ir, preenchido de preto é onde você
|
|
175
|
-
está, e com contorno é algo que você cria. Preto sólido
|
|
176
|
-
diria "você está aqui"; cor gastaria a única exceção do
|
|
177
|
-
sistema, o vermelho de perda. A borda é a mesma linha fina
|
|
178
|
-
dos contadores ao lado dos itens, desenhada por dentro (sombra
|
|
179
|
-
inset) para o item manter a altura dos outros.
|
|
180
|
-
*/}
|
|
181
|
-
{onCreate && (
|
|
182
|
-
<Box
|
|
183
|
-
w="100%"
|
|
184
|
-
mb={4}
|
|
185
|
-
data-create
|
|
186
|
-
style={{ boxShadow: 'inset 0 0 0 1px var(--mantine-color-gray-3)' }}
|
|
187
|
-
>
|
|
188
|
-
<NavItem
|
|
189
|
-
icon={createIcon}
|
|
190
|
-
label={<span style={{ fontWeight: 700 }}>{createAllowed ? createLabel : createBlockedLabel}</span>}
|
|
191
|
-
muted={!createAllowed}
|
|
192
|
-
onClick={createAllowed ? onCreate : onCreateBlocked}
|
|
193
|
-
/>
|
|
194
|
-
</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
|
+
/>
|
|
195
219
|
)}
|
|
196
220
|
|
|
197
221
|
{groupLabel && <GroupLabel>{groupLabel}</GroupLabel>}
|