@snksergio/design-system 0.65.0 → 0.66.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/dist-lib/ai/componentes/AppShell.md +13 -8
- package/dist-lib/ai/componentes/SingleMenuSidebar.md +27 -0
- package/dist-lib/ai/manifest.json +2 -2
- package/dist-lib/ai/regras-por-componente.json +3 -2
- package/dist-lib/ai/roteiros/app-builder/roteiro.md +7 -0
- package/dist-lib/chunks/{avatar-CMWPg3A3.cjs → avatar-B7h09dye.cjs} +3 -3
- package/dist-lib/chunks/{avatar-CMWPg3A3.cjs.map → avatar-B7h09dye.cjs.map} +1 -1
- package/dist-lib/chunks/{avatar-CZRLkTxt.mjs → avatar-hOzvQo9K.mjs} +3 -3
- package/dist-lib/chunks/{avatar-CZRLkTxt.mjs.map → avatar-hOzvQo9K.mjs.map} +1 -1
- package/dist-lib/chunks/{input-BQABJR2N.mjs → input-BPsqrMAw.mjs} +2 -2
- package/dist-lib/chunks/{input-BQABJR2N.mjs.map → input-BPsqrMAw.mjs.map} +1 -1
- package/dist-lib/chunks/{input-DqaLFxER.cjs → input-DwQ6HFRu.cjs} +2 -2
- package/dist-lib/chunks/{input-DqaLFxER.cjs.map → input-DwQ6HFRu.cjs.map} +1 -1
- package/dist-lib/chunks/{kpi-delta-iKhYhdD1.mjs → kpi-delta-CU6JxXSb.mjs} +3 -3
- package/dist-lib/chunks/{kpi-delta-iKhYhdD1.mjs.map → kpi-delta-CU6JxXSb.mjs.map} +1 -1
- package/dist-lib/chunks/{kpi-delta-BDrsKM-f.cjs → kpi-delta-ous1beKW.cjs} +3 -3
- package/dist-lib/chunks/{kpi-delta-BDrsKM-f.cjs.map → kpi-delta-ous1beKW.cjs.map} +1 -1
- package/dist-lib/chunks/{page-header-t5hFIp7o.mjs → page-header-CiElo3dw.mjs} +2 -2
- package/dist-lib/chunks/{page-header-t5hFIp7o.mjs.map → page-header-CiElo3dw.mjs.map} +1 -1
- package/dist-lib/chunks/{page-header-sValhWca.cjs → page-header-DEBrPvwk.cjs} +2 -2
- package/dist-lib/chunks/{page-header-sValhWca.cjs.map → page-header-DEBrPvwk.cjs.map} +1 -1
- package/dist-lib/chunks/{panel-BihHQ-sP.cjs → panel-BA-COEiW.cjs} +5 -5
- package/dist-lib/chunks/{panel-BihHQ-sP.cjs.map → panel-BA-COEiW.cjs.map} +1 -1
- package/dist-lib/chunks/{panel-B7uZTYVh.mjs → panel-Ccy88Gnd.mjs} +5 -5
- package/dist-lib/chunks/{panel-B7uZTYVh.mjs.map → panel-Ccy88Gnd.mjs.map} +1 -1
- package/dist-lib/chunks/{sheet-Bjjo4ZaT.mjs → sheet-BBrZkT_x.mjs} +4 -4
- package/dist-lib/chunks/sheet-BBrZkT_x.mjs.map +1 -0
- package/dist-lib/chunks/{sheet-BrYriaDN.cjs → sheet-n_XtAcqI.cjs} +4 -4
- package/dist-lib/chunks/sheet-n_XtAcqI.cjs.map +1 -0
- package/dist-lib/chunks/{toggle-group-DeoBmogo.cjs → toggle-group-CgDOdmWM.cjs} +7 -7
- package/dist-lib/chunks/toggle-group-CgDOdmWM.cjs.map +1 -0
- package/dist-lib/chunks/{toggle-group-XMgZgL-H.mjs → toggle-group-WBUjC4-0.mjs} +7 -7
- package/dist-lib/chunks/toggle-group-WBUjC4-0.mjs.map +1 -0
- package/dist-lib/chunks/{useTheme-N5Nc0jdR.cjs → useTheme-CM-9qLsP.cjs} +7 -3
- package/dist-lib/chunks/{useTheme-N5Nc0jdR.cjs.map → useTheme-CM-9qLsP.cjs.map} +1 -1
- package/dist-lib/chunks/{useTheme-DwhMIlTr.mjs → useTheme-DSHndxZC.mjs} +7 -3
- package/dist-lib/chunks/{useTheme-DwhMIlTr.mjs.map → useTheme-DSHndxZC.mjs.map} +1 -1
- package/dist-lib/index.cjs +8 -8
- package/dist-lib/index.mjs +14 -14
- package/dist-lib/preview/chat.cjs +3 -3
- package/dist-lib/preview/chat.mjs +3 -3
- package/dist-lib/preview/clientes.cjs +6 -6
- package/dist-lib/preview/clientes.mjs +6 -6
- package/dist-lib/preview/dashboard.cjs +4 -4
- package/dist-lib/preview/dashboard.mjs +4 -4
- package/dist-lib/shadcn.cjs +4 -4
- package/dist-lib/shadcn.mjs +4 -4
- package/dist-lib/src/components/ui/AppShell/app-shell.d.ts.map +1 -1
- package/dist-lib/src/components/ui/AppShell/app-shell.types.d.ts +13 -0
- package/dist-lib/src/components/ui/AppShell/app-shell.types.d.ts.map +1 -1
- package/dist-lib/src/components/ui/SingleMenuSidebar/single-menu-sidebar.d.ts +1 -1
- package/dist-lib/src/components/ui/SingleMenuSidebar/single-menu-sidebar.d.ts.map +1 -1
- package/dist-lib/src/components/ui/SingleMenuSidebar/single-menu-sidebar.types.d.ts +12 -0
- package/dist-lib/src/components/ui/SingleMenuSidebar/single-menu-sidebar.types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist-lib/chunks/sheet-Bjjo4ZaT.mjs.map +0 -1
- package/dist-lib/chunks/sheet-BrYriaDN.cjs.map +0 -1
- package/dist-lib/chunks/toggle-group-DeoBmogo.cjs.map +0 -1
- package/dist-lib/chunks/toggle-group-XMgZgL-H.mjs.map +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- ds:regras
|
|
4
4
|
- tem áreas separadas (Comercial, Financeiro…)? → `sidebar="menu"` + `contexts`. Não tem? → `"single"` + `categories`, sem `sidebarModules` nem `sidebarShowSearch`
|
|
5
|
-
- **exceção: o app tem ESCOPO global** (empresa/unidade que recorta TODAS as páginas)? → `sidebarModule` (seletor, não troca menu) + `
|
|
5
|
+
- **exceção: o app tem ESCOPO global** (empresa/unidade que recorta TODAS as páginas)? → `sidebarModule` (seletor, não troca menu) + `sidebarTopSlot` (o multi-select das unidades, montado por você). NÃO é `sidebarModules` (troca as `categories`) nem `sidebarSearchCommand` (aquele é a paleta da BUSCA)
|
|
6
6
|
- NÃO passe `sidebarLogo`: o default é a marca iGreen. Só com marca própria pedida explicitamente
|
|
7
7
|
- `sidebarTitle` = nome do projeto (vai à direita da logo) — pergunte, não invente
|
|
8
8
|
-->
|
|
@@ -69,14 +69,19 @@ sem erro nenhum.
|
|
|
69
69
|
| `sidebarModule` | SingleMenuModule | — | **Seletor de ESCOPO** (empresa, workspace, unidade): ícone + título + subtítulo e, com `options`, dropdown. **Não troca o menu** — é a diferença com o plural acima. Use quando o menu é o mesmo em todas as opções; o plural, quando cada uma tem o seu. Passar os dois é erro: o seletor é um só |
|
|
70
70
|
| `sidebarShowSearch` | boolean | — | Busca no topo da sidebar (é um botão que abre command palette, não um input) |
|
|
71
71
|
| `sidebarSearchPlaceholder` | string | — | Placeholder da busca **da sidebar** — distinto do `searchPlaceholder`, que é do Header |
|
|
72
|
-
| `sidebarSearchCommand` | ReactNode | itens do menu | Conteúdo do `CommandList` da paleta da busca
|
|
72
|
+
| `sidebarSearchCommand` | ReactNode | itens do menu | Conteúdo do `CommandList` da paleta da busca **da sidebar**. Troca a lista de itens do menu por outra lista **de busca**. Exige `sidebarShowSearch`. ⛔ **Não é o lugar de um controle de escopo** — pra isso é `sidebarTopSlot` |
|
|
73
|
+
| `sidebarTopSlot` | ReactNode | — | **Slot livre no topo da sidebar**, entre o seletor de módulo e a busca. É aqui que vai controle de **escopo** que não é seletor único nem busca: multi-select de unidades, filtro de safra, período global. Você monta o controle; o shell reserva o lugar |
|
|
73
74
|
|
|
74
|
-
> **`sidebarModule` + `
|
|
75
|
-
>
|
|
76
|
-
>
|
|
77
|
-
>
|
|
78
|
-
>
|
|
79
|
-
>
|
|
75
|
+
> **`sidebarModule` + `sidebarTopSlot` = escopo global sem componente novo.** É o padrão
|
|
76
|
+
> "empresa no seletor, unidades logo abaixo" de CMS multi-tenant: o topo da sidebar vira o
|
|
77
|
+
> recorte que todas as páginas obedecem, encostado na navegação que ele recorta.
|
|
78
|
+
>
|
|
79
|
+
> ⚠️ **A primeira versão disto usou `sidebarSearchCommand` e ficou ruim.** O gatilho da
|
|
80
|
+
> busca é um botão com lupa e badge `⌘K`, sem prop pra esconder nenhum dos dois: o controle
|
|
81
|
+
> de escopo se apresentava como busca, e o rodapé "Selecionar todas / Limpar" rolava junto
|
|
82
|
+
> com a lista (ele vive dentro do `CommandList`, que É a área de scroll). **Busca é busca.**
|
|
83
|
+
> Conteúdo arbitrário pede slot arbitrário — daí o `sidebarTopSlot` (2026-09-16).
|
|
84
|
+
> Gate: `sidebar-single-escopo.test.tsx`.
|
|
80
85
|
| `defaultActiveContextId` | string | primeiro do array | Workspace inicial (uncontrolled) |
|
|
81
86
|
| `activeContextId` | string | — | Workspace ativo (controlled) |
|
|
82
87
|
| `onContextChange` | (id: string) => void | — | Callback de troca de workspace |
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
- NÃO passe `logo`: o default é a marca iGreen. Só com marca própria pedida explicitamente
|
|
5
5
|
- `title` = nome do projeto (vai à direita da logo) — pergunte, não invente
|
|
6
6
|
- é a escolha quando NÃO há divisão em áreas: `showSearch={false}`, sem `module`/`modules`
|
|
7
|
+
- controle de ESCOPO no topo (multi-select de unidades, filtro de safra, período global)? → `topSlot`. NUNCA `searchCommand`: busca é busca
|
|
7
8
|
-->
|
|
8
9
|
|
|
9
10
|
**O que é** — Sidebar de navegação de **nível único**: categoria → sub-itens em
|
|
@@ -43,6 +44,7 @@ exibido à direita dela.
|
|
|
43
44
|
| `showSearch` | `boolean` | `true` | |
|
|
44
45
|
| `searchCommand` | `ReactNode` | — | |
|
|
45
46
|
| `searchPlaceholder` | `string` | — | |
|
|
47
|
+
| `topSlot` | `ReactNode` | — | slot livre entre o módulo e a busca |
|
|
46
48
|
| `activeItemId` | `string` | — | |
|
|
47
49
|
| `onItemClick` | `(id: string) => void` | — | |
|
|
48
50
|
| `defaultExpanded` | `boolean` | `true` | |
|
|
@@ -55,6 +57,31 @@ abre um `CommandDialog`: você passa o **conteúdo** dele em `searchCommand` e,
|
|
|
55
57
|
texto do placeholder em `searchPlaceholder`. As props `value`/`onChange`/`inputRef` existem
|
|
56
58
|
em `SingleMenuSearchProps`, que é subcomponente interno.
|
|
57
59
|
|
|
60
|
+
### `topSlot` — escopo no topo, e por que não é a busca
|
|
61
|
+
|
|
62
|
+
O bloco do topo tem três lugares, nesta ordem: **seletor de módulo → `topSlot` → busca**.
|
|
63
|
+
|
|
64
|
+
`topSlot` é um slot livre. Ponha ali o controle que responde *"sobre o que estou olhando"*
|
|
65
|
+
e não é um seletor único: multi-select de unidades/filiais, filtro de safra, período global.
|
|
66
|
+
Você monta o controle com os componentes que quiser — o componente só reserva o lugar.
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
<SingleMenuSidebar
|
|
70
|
+
title="iGreen MOB"
|
|
71
|
+
module={{ icon: <Building2 />, title: empresa, subtitle: "Empresa selecionada" }}
|
|
72
|
+
topSlot={<SeletorDeLocais valor={locais} onChange={setLocais} />}
|
|
73
|
+
showSearch={false}
|
|
74
|
+
categories={CATEGORIAS}
|
|
75
|
+
/>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
⛔ **Não use `searchCommand` pra isso.** Aquele troca o conteúdo da paleta da **busca**, e o
|
|
79
|
+
gatilho dela é um `<button>` fixo com lupa e badge `⌘K` — sem prop pra esconder nenhum dos
|
|
80
|
+
dois. Um controle de escopo ali **se apresenta como busca**, e um rodapé de ações ("Selecionar
|
|
81
|
+
todas" / "Limpar") rola junto com a lista, porque ele vive dentro do `CommandList`, que É a
|
|
82
|
+
área de scroll. Medido num consumidor real em 2026-09-16: foi esse desvio que originou o
|
|
83
|
+
`topSlot`. Gate: `AppShell/sidebar-single-escopo.test.tsx`.
|
|
84
|
+
|
|
58
85
|
### Multi-módulo
|
|
59
86
|
|
|
60
87
|
`modules` é a API pra sidebar que troca de contexto: cada `SingleMenuModuleConfig` traz suas
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"AppShell": [
|
|
3
3
|
"tem áreas separadas (Comercial, Financeiro…)? → `sidebar=\"menu\"` + `contexts`. Não tem? → `\"single\"` + `categories`, sem `sidebarModules` nem `sidebarShowSearch`",
|
|
4
|
-
"**exceção: o app tem ESCOPO global** (empresa/unidade que recorta TODAS as páginas)? → `sidebarModule` (seletor, não troca menu) + `
|
|
4
|
+
"**exceção: o app tem ESCOPO global** (empresa/unidade que recorta TODAS as páginas)? → `sidebarModule` (seletor, não troca menu) + `sidebarTopSlot` (o multi-select das unidades, montado por você). NÃO é `sidebarModules` (troca as `categories`) nem `sidebarSearchCommand` (aquele é a paleta da BUSCA)",
|
|
5
5
|
"NÃO passe `sidebarLogo`: o default é a marca iGreen. Só com marca própria pedida explicitamente",
|
|
6
6
|
"`sidebarTitle` = nome do projeto (vai à direita da logo) — pergunte, não invente"
|
|
7
7
|
],
|
|
@@ -69,7 +69,8 @@
|
|
|
69
69
|
"SingleMenuSidebar": [
|
|
70
70
|
"NÃO passe `logo`: o default é a marca iGreen. Só com marca própria pedida explicitamente",
|
|
71
71
|
"`title` = nome do projeto (vai à direita da logo) — pergunte, não invente",
|
|
72
|
-
"é a escolha quando NÃO há divisão em áreas: `showSearch={false}`, sem `module`/`modules`"
|
|
72
|
+
"é a escolha quando NÃO há divisão em áreas: `showSearch={false}`, sem `module`/`modules`",
|
|
73
|
+
"controle de ESCOPO no topo (multi-select de unidades, filtro de safra, período global)? → `topSlot`. NUNCA `searchCommand`: busca é busca"
|
|
73
74
|
],
|
|
74
75
|
"TabsNavigation": [
|
|
75
76
|
"aba de NAVEGADOR (sessão que abre/fecha: conversa, chamado, registro) → `<TabsNavigation>`; filtro de conteúdo dentro da tela → `tabs` do shadcn",
|
|
@@ -70,6 +70,13 @@ existe divisão, o rail da `"menu"` mostra as áreas todas de uma vez, enquanto
|
|
|
70
70
|
ficam atrás de um botão acima da busca. Quer conhecer as outras variações? Mande a página do
|
|
71
71
|
componente — ampliar o leque na entrevista é o que produz escolha errada.
|
|
72
72
|
|
|
73
|
+
**Terceira resposta possível: o app tem ESCOPO global** — uma empresa/unidade que recorta
|
|
74
|
+
**todas** as páginas ("os dados são sempre dos locais selecionados no topo"). Aí é `"single"`
|
|
75
|
+
+ `sidebarModule` (o seletor de escopo — singular, **não** troca o menu) + `sidebarTopSlot`
|
|
76
|
+
(o multi-select das unidades, que você monta). ⛔ **Não** use `sidebarSearchCommand` pra isso:
|
|
77
|
+
aquele é o conteúdo da paleta da **busca**, cujo gatilho tem lupa e `⌘K` fixos — o controle se
|
|
78
|
+
apresenta como busca e o rodapé de ações rola com a lista. Busca é busca.
|
|
79
|
+
|
|
73
80
|
```tsx
|
|
74
81
|
<AppShell
|
|
75
82
|
sidebar="single"
|
|
@@ -1027,7 +1027,7 @@ const CONTAINER_CLASSES = [
|
|
|
1027
1027
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
1028
1028
|
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
|
|
1029
1029
|
"data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
1030
|
-
"origin-[--radix-dropdown-menu-content-transform-origin]"
|
|
1030
|
+
"origin-[var(--radix-dropdown-menu-content-transform-origin)]"
|
|
1031
1031
|
].join(" ");
|
|
1032
1032
|
const MOBILE_SHEET_CLASSES = [
|
|
1033
1033
|
"max-md:w-full max-md:min-w-0 max-md:max-w-none",
|
|
@@ -1212,7 +1212,7 @@ const TooltipContent = React__namespace.forwardRef(({ className, sideOffset = 6,
|
|
|
1212
1212
|
"rounded-radius-md px-pad-lg py-pad-xs",
|
|
1213
1213
|
"text-caption-sm",
|
|
1214
1214
|
"shadow-sh-md",
|
|
1215
|
-
"origin-[--radix-tooltip-content-transform-origin]",
|
|
1215
|
+
"origin-[var(--radix-tooltip-content-transform-origin)]",
|
|
1216
1216
|
"data-[state=delayed-open]:animate-in data-[state=instant-open]:animate-in data-[state=closed]:animate-out",
|
|
1217
1217
|
"data-[state=closed]:fade-out-0 data-[state=delayed-open]:fade-in-0 data-[state=instant-open]:fade-in-0",
|
|
1218
1218
|
"data-[state=closed]:zoom-out-95 data-[state=delayed-open]:zoom-in-95 data-[state=instant-open]:zoom-in-95",
|
|
@@ -1342,4 +1342,4 @@ exports.inputGroupInputVariants = inputGroupInputVariants;
|
|
|
1342
1342
|
exports.inputGroupTextareaVariants = inputGroupTextareaVariants;
|
|
1343
1343
|
exports.inputGroupVariants = inputGroupVariants;
|
|
1344
1344
|
exports.tv = tv;
|
|
1345
|
-
//# sourceMappingURL=avatar-
|
|
1345
|
+
//# sourceMappingURL=avatar-B7h09dye.cjs.map
|