forlogic-core 1.16.3 → 1.16.5

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.
Files changed (134) hide show
  1. package/README.md +113 -109
  2. package/dist/README.md +113 -109
  3. package/dist/components/modules/AccessDeniedDialog.d.ts +41 -0
  4. package/dist/components/modules/ModuleAccessGuard.d.ts +3 -1
  5. package/dist/components/modules/ModuleOfferContent.d.ts +20 -0
  6. package/dist/components/modules/ModulesContent.d.ts +15 -0
  7. package/dist/components/modules/ModulesFooterCards.d.ts +6 -0
  8. package/dist/components/modules/index.d.ts +8 -0
  9. package/dist/components/modules/types.d.ts +2 -0
  10. package/dist/index.css +1 -1
  11. package/dist/index.css.map +1 -1
  12. package/dist/index.esm.js +1 -1
  13. package/dist/index.js +1 -1
  14. package/docs/DESIGN_SYSTEM.md +17 -32
  15. package/package.json +4 -2
  16. package/dist/assets/AccordionDoc-BnfxyOi9.js +0 -31
  17. package/dist/assets/ActionButtonDoc-b4F_J8gn.js +0 -47
  18. package/dist/assets/AlertDoc-PkiHguSJ.js +0 -37
  19. package/dist/assets/AppHeaderDoc-CsFMZGV0.js +0 -67
  20. package/dist/assets/AppSidebarDoc-Bg71N-zq.js +0 -196
  21. package/dist/assets/AuthDoc-DDm57y_J.js +0 -192
  22. package/dist/assets/AvatarDoc-C6wiZIZR.js +0 -11
  23. package/dist/assets/BadgeDoc-Bsg7cfm0.js +0 -36
  24. package/dist/assets/BaseFormDoc-DeIlV273.js +0 -169
  25. package/dist/assets/BodyContentDoc-Q3DGvyN9.js +0 -83
  26. package/dist/assets/BreadcrumbDoc-ChsVFjMF.js +0 -75
  27. package/dist/assets/ButtonDoc-C7Q31Bh3.js +0 -41
  28. package/dist/assets/ButtonGroupDoc-Bn5vhjBq.js +0 -7
  29. package/dist/assets/CalendarDoc-iVjNyxyr.js +0 -81
  30. package/dist/assets/CardDoc-D511dll7.js +0 -49
  31. package/dist/assets/ChartDoc-CQyYOEHL.js +0 -111
  32. package/dist/assets/CheckboxDoc-Cjsy4XAq.js +0 -55
  33. package/dist/assets/ColorPickerDoc-hnYJUWpF.js +0 -10
  34. package/dist/assets/ColorsFoundationDoc-B8Z4tAyZ.js +0 -13
  35. package/dist/assets/ComboTreeDoc-ChEbW4a3.js +0 -21
  36. package/dist/assets/ComboboxDoc-CHWeGE_F.js +0 -134
  37. package/dist/assets/ComponentDocTemplate-BtOCnlM2.js +0 -1
  38. package/dist/assets/ContextMenuDoc-C3mFO_Yx.js +0 -182
  39. package/dist/assets/ContextsDoc-ChEbQxom.js +0 -184
  40. package/dist/assets/CreateCrudPageDoc-C9tXisCF.js +0 -106
  41. package/dist/assets/CrudActionBarDoc-Cp1L4gpO.js +0 -112
  42. package/dist/assets/CrudGridDoc-D-kSFBAQ.js +0 -85
  43. package/dist/assets/CrudOverviewDoc-CeLBwg-B.js +0 -14
  44. package/dist/assets/CrudPrimitivesDoc-B2u1vZog.js +0 -164
  45. package/dist/assets/CrudTableDoc-CvV-II_X.js +0 -95
  46. package/dist/assets/DataListDoc-BLRii0jB.js +0 -13
  47. package/dist/assets/DesignSystemHome-TE0Ubaup.js +0 -1
  48. package/dist/assets/DialogDoc--LC5Jvat.js +0 -981
  49. package/dist/assets/DropdownMenuDoc-oPlEriRY.js +0 -175
  50. package/dist/assets/EmptyStateDoc-rNqfWKok.js +0 -35
  51. package/dist/assets/EnvironmentsDoc-CT7l5s2u.js +0 -96
  52. package/dist/assets/ErrorBoundaryDoc-rPHOUygA.js +0 -111
  53. package/dist/assets/ExampleCard-DfuMYM6E.js +0 -1
  54. package/dist/assets/FormDoc-B0L_QaCT.js +0 -81
  55. package/dist/assets/FoundationOverview-Dbb8rBsU.js +0 -1
  56. package/dist/assets/GridDoc-ifcGA2Yw.js +0 -28
  57. package/dist/assets/HooksDoc-CUOT_3Du.js +0 -665
  58. package/dist/assets/HoverCardDoc-CdTU2QkI.js +0 -31
  59. package/dist/assets/I18nDoc-CMEvFqsz.js +0 -232
  60. package/dist/assets/IconPickerDoc-DF9hEwnJ.js +0 -10
  61. package/dist/assets/IconsFoundationDoc-D4Y0wKbm.js +0 -33
  62. package/dist/assets/InputDoc-d_IL4dsq.js +0 -211
  63. package/dist/assets/LabelDoc-Dr64ISiJ.js +0 -42
  64. package/dist/assets/LeadershipDoc-BnrTuaeV.js +0 -416
  65. package/dist/assets/MediaDoc-CLuVprAr.js +0 -459
  66. package/dist/assets/MenubarDoc-CW7L4QJ4.js +0 -165
  67. package/dist/assets/ModulesDialogDoc-CUb_g4X-.js +0 -71
  68. package/dist/assets/NavigationMenuDoc-Csc0U6bV.js +0 -116
  69. package/dist/assets/OnboardingDialogDoc-3RtjNH1O.js +0 -55
  70. package/dist/assets/PaginationDoc-BGurD4xQ.js +0 -27
  71. package/dist/assets/PaginationDoc-DqFyou6O.js +0 -98
  72. package/dist/assets/PlacesDoc-Dyx8gsqb.js +0 -226
  73. package/dist/assets/PopoverDoc-DHF-ItUX.js +0 -64
  74. package/dist/assets/ProgressDoc-DXKV-fkI.js +0 -29
  75. package/dist/assets/QualiexUserFieldDoc-BbP7w-Pu.js +0 -149
  76. package/dist/assets/RadioGroupDoc-D845uweM.js +0 -57
  77. package/dist/assets/RadiusDoc-vN4tTsay.js +0 -7
  78. package/dist/assets/RequiredFieldsCounterDoc-TzR9r-U9.js +0 -58
  79. package/dist/assets/ResizableDoc-Bkfz_25O.js +0 -104
  80. package/dist/assets/RichTextEditorDoc-BUQrg7M8.js +0 -24
  81. package/dist/assets/ScrollAreaDoc-B6ODYHMX.js +0 -28
  82. package/dist/assets/SecurityDoc-Chbt6w1s.js +0 -204
  83. package/dist/assets/SelectDoc-BhcpBIAO.js +0 -80
  84. package/dist/assets/SeparatorDoc-C3fhatb0.js +0 -4
  85. package/dist/assets/ServicesDoc-_uao-HA_.js +0 -308
  86. package/dist/assets/ShadowsDoc-DpkO_TZQ.js +0 -9
  87. package/dist/assets/SignDoc-BJtnoT6I.js +0 -66
  88. package/dist/assets/SkeletonDoc-BZS07PJh.js +0 -54
  89. package/dist/assets/SliderDoc-D2ApV3XT.js +0 -41
  90. package/dist/assets/SpacingDoc-PNrU24B2.js +0 -12
  91. package/dist/assets/SplitButtonDoc-D5tUF2Ja.js +0 -53
  92. package/dist/assets/StepSelectorDoc-Cj0ALYar.js +0 -41
  93. package/dist/assets/SwitchDoc-DtsT8oh_.js +0 -56
  94. package/dist/assets/TableDoc-BC-jQnXu.js +0 -128
  95. package/dist/assets/TableOfContents-DBMJMbI4.js +0 -1
  96. package/dist/assets/TabsDoc-DtXJ0xY5.js +0 -42
  97. package/dist/assets/TextareaDoc-nuW5tqBQ.js +0 -46
  98. package/dist/assets/ToastDoc-D1aX5zda.js +0 -157
  99. package/dist/assets/ToggleDoc-ILass4CS.js +0 -51
  100. package/dist/assets/TooltipDoc-lPbdWe_9.js +0 -58
  101. package/dist/assets/TruncatedCellDoc-DOAzbF2F.js +0 -12
  102. package/dist/assets/TypographyFoundationDoc-3ZD-rQZw.js +0 -7
  103. package/dist/assets/UtilitiesDoc-D7lkYhuz.js +0 -145
  104. package/dist/assets/blocks-Jy49RoqJ.js +0 -1
  105. package/dist/assets/calendar-days-Cvf2zLJl.js +0 -1
  106. package/dist/assets/circle-plus-MnG9kjyq.js +0 -1
  107. package/dist/assets/circle-x-B9ouupla.js +0 -1
  108. package/dist/assets/crown-BweN5jpI.js +0 -1
  109. package/dist/assets/date-picker-ttyYeYvC.js +0 -1
  110. package/dist/assets/disabled-menu-item-WlpPOqxg.js +0 -1
  111. package/dist/assets/drawer-DvU6_eK5.js +0 -3
  112. package/dist/assets/file-pen-line-C0VV-QjF.js +0 -1
  113. package/dist/assets/git-branch-DCjGGwvF.js +0 -1
  114. package/dist/assets/globe-BdFDFP_k.js +0 -1
  115. package/dist/assets/grip-vertical-CgXp0oI-.js +0 -1
  116. package/dist/assets/hash-BAYi_wfk.js +0 -1
  117. package/dist/assets/index-BtX5DZqb.js +0 -310
  118. package/dist/assets/index-C1So5Sai.css +0 -1
  119. package/dist/assets/life-buoy-BydIgTyJ.js +0 -1
  120. package/dist/assets/lucide-react-ZIMhRYmb.js +0 -1
  121. package/dist/assets/monitor-B6txWJPg.js +0 -1
  122. package/dist/assets/package-DNe3FsCh.js +0 -1
  123. package/dist/assets/pen-CzTmQ16z.js +0 -1
  124. package/dist/assets/pin-CJJgLEBz.js +0 -1
  125. package/dist/assets/radio-group-Btv_BY60.js +0 -1
  126. package/dist/assets/server-XQDXtrjm.js +0 -1
  127. package/dist/assets/share-2-Dz_89MJb.js +0 -1
  128. package/dist/assets/step-selector-D0_Y1dow.js +0 -1
  129. package/dist/assets/text-align-start-WsHo7CNJ.js +0 -1
  130. package/dist/assets/trash-CeK-mWnM.js +0 -1
  131. package/dist/assets/useMockCrud-RV9z9n5x.js +0 -1
  132. package/dist/assets/user-check-CrbWcnPN.js +0 -1
  133. package/dist/assets/user-plus-Dce9DbqQ.js +0 -1
  134. package/dist/index.html +0 -35
@@ -83,7 +83,7 @@ function App() {
83
83
  - [Loading](#skeleton) - Componentes para estados de carregamento: Skeleton (placeholders), Spinner (indicador de loading), e LoadingState (gerenciamento declarativo).
84
84
  - [Media](#media) - Módulo completo para upload, edição e renderização de imagens e vídeos. Inclui editores interativos, renderizadores otimizados e hook genérico de upload.
85
85
  - [Menubar](#menubar) - Barra de menu horizontal com submenus, checkboxes e radio items. Ideal para barras de navegação de aplicações desktop-like, seguindo padrões de aplicações nativas.
86
- - [ModulesDialog](#modulesdialog) - Dialog para navegação entre módulos do sistema, organizado em abas (Qualiex, Clássicos) com separação entre módulos contratados e disponíveis, OnboardingDialog para descoberta e cards informativos no rodapé.
86
+ - [ModulesDialog](#modulesdialog) - Dialog para navegação entre módulos do sistema.
87
87
  - [Navigation Menu](#navigationmenu) - Uma coleção de links para navegação em websites.
88
88
  - [Onboarding Dialog](#onboardingdialog) - Componente para fluxos de onboarding em múltiplos passos. Suporta imagens estáticas, GIFs, navegação entre steps e indicador de progresso com dropdown.
89
89
  - [Pagination](#pagination) - Componente de paginação padronizado com layout de 3 colunas, seletor de itens por página e navegação completa.
@@ -131,7 +131,7 @@ function App() {
131
131
  - [ErrorBoundary](#errorboundary) - Componente de classe React que captura erros de renderização em componentes filhos, evitando que a aplicação inteira quebre.
132
132
  - [Hooks](#hooks) - Hooks utilitários da biblioteca forlogic-core para otimização, dados, formatação e UI. Todos os hooks seguem padrões React e são compatíveis com React Query quando aplicável.
133
133
  - [Internacionalização (i18n)](#i18n) - Sistema de internacionalização usando react-i18next com traduções carregadas de um arquivo JSON estático local (lib/i18n/translations.json). Suporta pt-BR, en-US e es-ES com gerenciamento de preferências do usuário.
134
- - [Controle de Acesso a Módulos](#moduleaccess) - Sistema para verificar e bloquear automaticamente o acesso do usuário a módulos da plataforma Qualiex. Inclui proteção automática de rotas via CoreProviders e hook para verificações programáticas.
134
+ - [Acesso Módulo (ModuleAccess)](#moduleaccess) - Sistema de autorização para verificar e bloquear acesso a módulos da plataforma Qualiex. Proteção automática de rotas via CoreProviders e hook para verificações programáticas.
135
135
  - [Segurança (Vite Config)](#security) - Plugin de segurança para Vite que aplica headers OWASP, CSP configurável, CORS seguro e proteções contra ataques comuns. Configuração centralizada para todos os projetos Forlogic.
136
136
  - [Services](#services) - Serviços utilitários da biblioteca forlogic-core para operações CRUD, envio de emails, tratamento de erros e gerenciamento de traduções. Todos os serviços são singletons prontos para uso.
137
137
  - [Utilities](#utilities) - Funções utilitárias essenciais exportadas pela biblioteca para manipulação de classes CSS, formatação de datas e valores monetários.
@@ -5822,7 +5822,7 @@ const [theme, setTheme] = useState("system");
5822
5822
 
5823
5823
  ### ModulesDialog
5824
5824
 
5825
- Dialog para navegação entre módulos do sistema, organizado em abas (Qualiex, Clássicos) com separação entre módulos contratados e disponíveis, OnboardingDialog para descoberta e cards informativos no rodapé.
5825
+ Dialog para navegação entre módulos do sistema.
5826
5826
 
5827
5827
  **Uso:**
5828
5828
  ```tsx
@@ -5856,21 +5856,12 @@ function App() {
5856
5856
  |------|------|--------|----------|
5857
5857
  | open | `boolean` | `-` | Controla se o dialog está aberto |
5858
5858
  | onOpenChange | `(open: boolean) => void` | `-` | Callback quando o estado muda |
5859
- | onModuleClick | `(module: Module) => void` | `-` | Callback ao clicar em um módulo contratado |
5860
- | contractedModules | `string[]` | `undefined` | Lista de nomes de módulos contratados. Se não fornecido, todos aparecem como contratados. |
5861
- | onModuleInterest | `(module: Module) => void` | `-` | Callback após usuário passar pelo onboarding de módulo não contratado |
5859
+ | onModuleClick | `(module: Module) => void` | `-` | Callback ao clicar em um módulo. Default: navega via URL do módulo |
5862
5860
  | educaUrl | `string` | `https://educa.forlogic.net/` | URL do link do Forlogic Educa |
5863
5861
  | saberGestaoUrl | `string` | `https://sabergestao.com.br/` | URL do link do Saber Gestão |
5864
- | showSettingsLink | `boolean` | `true` | Exibe o card de configurações no rodapé |
5865
- | onSettingsClick | `() => void` | `-` | Callback ao clicar em configurações |
5866
5862
 
5867
5863
  **Exemplos:**
5868
5864
 
5869
- **Com Módulos Contratados:**
5870
- ```tsx
5871
- undefined
5872
- ```
5873
-
5874
5865
  **Integração com AppHeader:**
5875
5866
  ```tsx
5876
5867
  undefined
@@ -5881,19 +5872,13 @@ undefined
5881
5872
  - Navegação por teclado entre abas (Arrow Left/Right)
5882
5873
  - Foco automático no primeiro elemento interativo ao abrir
5883
5874
  - Escape fecha o dialog e retorna o foco ao elemento anterior
5884
- - Módulos clicáveis com role="button" e suporte a Enter/Space
5885
- - Módulos não contratados indicados visualmente com opacidade reduzida
5886
- - OnboardingDialog acessível com navegação por teclado
5887
- - Links externos indicados com aria-label descritivo
5888
- - Cores com contraste adequado (WCAG AA)
5889
5875
 
5890
5876
  **Notas:**
5891
- - 2 Abas de Grupos: Qualiex (19 módulos unificados) e Clássicos (15 módulos)
5877
+ - Para separação entre módulos contratados e disponíveis (contractedModules, onModuleInterest), consulte a documentação de Module Access.
5878
+ - Internamente usa o componente ModulesContent, compartilhado com o AccessDeniedDialog.
5879
+ - 2 Abas de Grupos: Qualiex e Clássicos
5892
5880
  - Grid Responsivo: 4 colunas em XL, 3 em MD, 2 em base
5893
- - Separação Visual: Módulos contratados vs disponíveis para contratação
5894
- - OnboardingDialog: Até 3 steps para descoberta de módulos não contratados
5895
- - Cards no Rodapé: Forlogic Educa, Saber Gestão e Configurações (opcional)
5896
- - Retrocompatível: Props antigas (wikiUrl, allModulesUrl) continuam funcionando
5881
+ - Cards no Rodapé: Forlogic Educa, Saber Gestão e Wiki
5897
5882
 
5898
5883
  ---
5899
5884
 
@@ -11559,20 +11544,20 @@ console.log(format?.description); // "Padrão Brasileiro"
11559
11544
 
11560
11545
  ---
11561
11546
 
11562
- ### Controle de Acesso a Módulos
11547
+ ### Acesso Módulo (ModuleAccess)
11563
11548
 
11564
- Sistema para verificar e bloquear automaticamente o acesso do usuário a módulos da plataforma Qualiex. Inclui proteção automática de rotas via CoreProviders e hook para verificações programáticas.
11549
+ Sistema de autorização para verificar e bloquear acesso a módulos da plataforma Qualiex. Proteção automática de rotas via CoreProviders e hook para verificações programáticas.
11565
11550
 
11566
11551
  **Uso:**
11567
11552
  ```tsx
11568
- present
11569
- ```
11553
+ // Proteção automática via CoreProviders
11554
+ <CoreProviders moduleAlias="occurrences">
11555
+ <App />
11556
+ </CoreProviders>
11570
11557
 
11571
- **Exemplos:**
11572
-
11573
- **Exemplo Interativo:**
11574
- ```tsx
11575
- // Ver seção de exemplos no arquivo
11558
+ // Verificação programática via hook
11559
+ const { hasAccess, hasAccessTo, role } = useModuleAccess();
11560
+ if (hasAccessTo('audit')) { /* ... */ }
11576
11561
  ```
11577
11562
 
11578
11563
  **Acessibilidade:**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forlogic-core",
3
- "version": "1.16.3",
3
+ "version": "1.16.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -40,7 +40,9 @@
40
40
  "build:dev": "vite build --mode development",
41
41
  "build:lib": "rollup -c",
42
42
  "lint": "eslint .",
43
- "preview": "vite preview"
43
+ "preview": "vite preview",
44
+ "version": "npm run docs:ds && git add docs/DESIGN_SYSTEM.md README.md",
45
+ "prepublishOnly": "npm whoami || npm login"
44
46
  },
45
47
  "bin": {
46
48
  "lib-update": "dist/bin/pull-docs.js"
@@ -1,31 +0,0 @@
1
- import{W as l,j as e,X as re,Y,Z as ne,_ as ae,$,a0 as se,a1 as ie,a2 as ce,a3 as le,a4 as de,a5 as q,a6 as pe,r as j,l as S,a7 as me,a8 as ue,a9 as xe,f as fe,aa as Ce,ab as Ae}from"./index-BtX5DZqb.js";import{C as he}from"./ComponentDocTemplate-BtOCnlM2.js";import"./ExampleCard-DfuMYM6E.js";import"./TableOfContents-DBMJMbI4.js";var d="Accordion",ve=["Home","End","ArrowDown","ArrowUp","ArrowLeft","ArrowRight"],[D,be,ge]=re(d),[I]=pe(d,[ge,q]),k=q(),K=l.forwardRef((o,n)=>{const{type:t,...a}=o,s=a,r=a;return e.jsx(D.Provider,{scope:o.__scopeAccordion,children:t==="multiple"?e.jsx(we,{...r,ref:n}):e.jsx(ye,{...s,ref:n})})});K.displayName=d;var[z,je]=I(d),[G,Ie]=I(d,{collapsible:!1}),ye=l.forwardRef((o,n)=>{const{value:t,defaultValue:a,onValueChange:s=()=>{},collapsible:r=!1,...c}=o,[i,p]=Y({prop:t,defaultProp:a??"",onChange:s,caller:d});return e.jsx(z,{scope:o.__scopeAccordion,value:l.useMemo(()=>i?[i]:[],[i]),onItemOpen:p,onItemClose:l.useCallback(()=>r&&p(""),[r,p]),children:e.jsx(G,{scope:o.__scopeAccordion,collapsible:r,children:e.jsx(L,{...c,ref:n})})})}),we=l.forwardRef((o,n)=>{const{value:t,defaultValue:a,onValueChange:s=()=>{},...r}=o,[c,i]=Y({prop:t,defaultProp:a??[],onChange:s,caller:d}),p=l.useCallback(f=>i((u=[])=>[...u,f]),[i]),x=l.useCallback(f=>i((u=[])=>u.filter(w=>w!==f)),[i]);return e.jsx(z,{scope:o.__scopeAccordion,value:c,onItemOpen:p,onItemClose:x,children:e.jsx(G,{scope:o.__scopeAccordion,collapsible:!0,children:e.jsx(L,{...r,ref:n})})})}),[Ne,y]=I(d),L=l.forwardRef((o,n)=>{const{__scopeAccordion:t,disabled:a,dir:s,orientation:r="vertical",...c}=o,i=l.useRef(null),p=ce(i,n),x=be(t),u=le(s)==="ltr",w=de(o.onKeyDown,v=>{if(!ve.includes(v.key))return;const oe=v.target,N=x().filter(O=>!O.ref.current?.disabled),b=N.findIndex(O=>O.ref.current===oe),V=N.length;if(b===-1)return;v.preventDefault();let m=b;const R=0,_=V-1,P=()=>{m=b+1,m>_&&(m=R)},T=()=>{m=b-1,m<R&&(m=_)};switch(v.key){case"Home":m=R;break;case"End":m=_;break;case"ArrowRight":r==="horizontal"&&(u?P():T());break;case"ArrowDown":r==="vertical"&&P();break;case"ArrowLeft":r==="horizontal"&&(u?T():P());break;case"ArrowUp":r==="vertical"&&T();break}const te=m%V;N[te].ref.current?.focus()});return e.jsx(Ne,{scope:t,disabled:a,direction:s,orientation:r,children:e.jsx(D.Slot,{scope:t,children:e.jsx($.div,{...c,"data-orientation":r,ref:p,onKeyDown:a?void 0:w})})})}),g="AccordionItem",[Re,M]=I(g),U=l.forwardRef((o,n)=>{const{__scopeAccordion:t,value:a,...s}=o,r=y(g,t),c=je(g,t),i=k(t),p=ne(),x=a&&c.value.includes(a)||!1,f=r.disabled||o.disabled;return e.jsx(Re,{scope:t,open:x,disabled:f,triggerId:p,children:e.jsx(ae,{"data-orientation":r.orientation,"data-state":Z(x),...i,...s,ref:n,disabled:f,open:x,onOpenChange:u=>{u?c.onItemOpen(a):c.onItemClose(a)}})})});U.displayName=g;var W="AccordionHeader",Q=l.forwardRef((o,n)=>{const{__scopeAccordion:t,...a}=o,s=y(d,t),r=M(W,t);return e.jsx($.h3,{"data-orientation":s.orientation,"data-state":Z(r.open),"data-disabled":r.disabled?"":void 0,...a,ref:n})});Q.displayName=W;var E="AccordionTrigger",B=l.forwardRef((o,n)=>{const{__scopeAccordion:t,...a}=o,s=y(d,t),r=M(E,t),c=Ie(E,t),i=k(t);return e.jsx(D.ItemSlot,{scope:t,children:e.jsx(se,{"aria-disabled":r.open&&!c.collapsible||void 0,"data-orientation":s.orientation,id:r.triggerId,...i,...a,ref:n})})});B.displayName=E;var F="AccordionContent",X=l.forwardRef((o,n)=>{const{__scopeAccordion:t,...a}=o,s=y(d,t),r=M(F,t),c=k(t);return e.jsx(ie,{role:"region","aria-labelledby":r.triggerId,"data-orientation":s.orientation,...c,...a,ref:n,style:{"--radix-accordion-content-height":"var(--radix-collapsible-content-height)","--radix-accordion-content-width":"var(--radix-collapsible-content-width)",...o.style}})});X.displayName=F;function Z(o){return o?"open":"closed"}var _e=K,Pe=U,Te=Q,J=B,ee=X;const H=_e,C=j.forwardRef(({className:o,...n},t)=>e.jsx(Pe,{ref:t,className:S("border-b",o),...n}));C.displayName="AccordionItem";const A=j.forwardRef(({className:o,children:n,...t},a)=>e.jsx(Te,{className:"flex",children:e.jsxs(J,{ref:a,className:S("flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",o),...t,children:[n,e.jsx(me,{className:"h-4 w-4 shrink-0 transition-transform duration-200"})]})}));A.displayName=J.displayName;const h=j.forwardRef(({className:o,children:n,...t},a)=>e.jsx(ee,{ref:a,className:"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",...t,children:e.jsx("div",{className:S("pb-4 pt-0",o),children:n})}));h.displayName=ee.displayName;function Oe(){const[o,n]=j.useState(!1);return e.jsxs(ue,{open:o,onOpenChange:n,className:"w-[350px] space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between space-x-4 px-4",children:[e.jsx("h4",{className:"text-sm font-semibold",children:"@peduarte starred 3 repositories"}),e.jsx(xe,{asChild:!0,children:e.jsx(fe,{variant:"ghost",size:"sm",children:e.jsx(Ce,{className:"h-4 w-4"})})})]}),e.jsxs(Ae,{className:"space-y-2",children:[e.jsx("div",{className:"rounded-md border px-4 py-2 text-sm",children:"@radix-ui/primitives"}),e.jsx("div",{className:"rounded-md border px-4 py-2 text-sm",children:"@radix-ui/colors"}),e.jsx("div",{className:"rounded-md border px-4 py-2 text-sm",children:"@stitches/react"})]})]})}function Me(){return e.jsx(he,{title:"Accordion & Collapsible",description:"Componentes de expansão/colapso para revelar conteúdo. Accordion para múltiplos itens, Collapsible para item único.",component:e.jsxs(H,{type:"single",collapsible:!0,className:"w-full max-w-md",children:[e.jsxs(C,{value:"item-1",children:[e.jsx(A,{children:"Is it accessible?"}),e.jsx(h,{children:"Yes. It adheres to the WAI-ARIA design pattern."})]}),e.jsxs(C,{value:"item-2",children:[e.jsx(A,{children:"Is it styled?"}),e.jsx(h,{children:"Yes. It comes with default styles that matches the other components aesthetic."})]}),e.jsxs(C,{value:"item-3",children:[e.jsx(A,{children:"Is it animated?"}),e.jsx(h,{children:"Yes. It's animated by default, but you can disable it if you prefer."})]})]}),usage:`import {
2
- Accordion,
3
- AccordionContent,
4
- AccordionItem,
5
- AccordionTrigger,
6
- } from "forlogic-core"
7
-
8
- <Accordion type="single" collapsible>
9
- <AccordionItem value="item-1">
10
- <AccordionTrigger>Is it accessible?</AccordionTrigger>
11
- <AccordionContent>
12
- Yes. It adheres to the WAI-ARIA design pattern.
13
- </AccordionContent>
14
- </AccordionItem>
15
- </Accordion>`,examples:[{title:"Multiple Items Open",description:"Permite que múltiplos itens sejam abertos ao mesmo tempo",preview:e.jsxs(H,{type:"multiple",className:"w-full max-w-md",children:[e.jsxs(C,{value:"item-1",children:[e.jsx(A,{children:"Section 1"}),e.jsx(h,{children:"Content for section 1"})]}),e.jsxs(C,{value:"item-2",children:[e.jsx(A,{children:"Section 2"}),e.jsx(h,{children:"Content for section 2"})]})]}),code:`<Accordion type="multiple">
16
- <AccordionItem value="item-1">
17
- <AccordionTrigger>Section 1</AccordionTrigger>
18
- <AccordionContent>Content for section 1</AccordionContent>
19
- </AccordionItem>
20
- </Accordion>`},{title:"Collapsible",description:"Componente simples para expandir/colapsar um único item",preview:e.jsx(Oe,{}),code:`import {
21
- Collapsible,
22
- CollapsibleContent,
23
- CollapsibleTrigger,
24
- } from "forlogic-core"
25
-
26
- <Collapsible>
27
- <CollapsibleTrigger>Toggle</CollapsibleTrigger>
28
- <CollapsibleContent>
29
- Content goes here
30
- </CollapsibleContent>
31
- </Collapsible>`}],props:[{name:"type",type:'"single" | "multiple"',default:"-",description:"Accordion: Determina se um ou múltiplos itens podem ser abertos."},{name:"collapsible",type:"boolean",default:"false",description:'Accordion: Quando type é "single", permite fechar o item aberto.'},{name:"defaultValue",type:"string | string[]",default:"-",description:"O(s) valor(es) ativo(s) padrão."},{name:"value",type:"string | string[]",default:"-",description:"O(s) valor(es) ativo(s) controlado(s)."},{name:"open",type:"boolean",default:"-",description:"Collapsible: O estado aberto controlado."},{name:"defaultOpen",type:"boolean",default:"false",description:"Collapsible: O estado aberto padrão."},{name:"onOpenChange",type:"(open: boolean) => void",default:"-",description:"Collapsible: Manipulador quando o estado muda."}],accessibility:["Acessível por teclado - Espaço ou Enter para alternar","Teclas de seta para navegar entre itens do accordion","Suporte ARIA completo com roles e estados adequados","Gerenciamento de foco e indicadores de foco visíveis"],notes:["**Accordion** é ideal para FAQs e listas de perguntas frequentes","**Collapsible** é melhor para um único elemento expansível","Ambos suportam animações suaves de abertura/fechamento"]})}export{Me as AccordionDoc};
@@ -1,47 +0,0 @@
1
- import{j as e,f as s,m as n,n as a,o as i,A as t,p as r,q as o,s as c,t as d}from"./index-BtX5DZqb.js";import{C as l}from"./ComponentDocTemplate-BtOCnlM2.js";import{T as m}from"./trash-CeK-mWnM.js";import"./ExampleCard-DfuMYM6E.js";import"./TableOfContents-DBMJMbI4.js";function j(){return e.jsx(l,{title:"Action Button",description:"Botão compacto otimizado para ações em linhas de tabela e menus dropdown. OBRIGATÓRIO para todas as ações em tabelas CRUD.",component:e.jsxs("div",{className:"w-full space-y-6",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium mb-2",children:"✅ Uso Correto - ActionButton"}),e.jsxs(a,{children:[e.jsx(i,{asChild:!0,children:e.jsx(t,{})}),e.jsxs(r,{align:"end",children:[e.jsxs(o,{onClick:()=>alert("Editar"),children:[e.jsx(c,{className:"mr-2 h-4 w-4"}),"Editar"]}),e.jsxs(o,{onClick:()=>alert("Visualizar"),children:[e.jsx(d,{className:"mr-2 h-4 w-4"}),"Visualizar"]}),e.jsxs(o,{onClick:()=>alert("Excluir"),className:"text-destructive",children:[e.jsx(m,{className:"mr-2 h-4 w-4"}),"Excluir"]})]})]})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium mb-2",children:"ActionButton com ícone customizado"}),e.jsx(t,{children:e.jsx(c,{size:12})})]}),e.jsxs("div",{className:"border-t pt-4",children:[e.jsx("h3",{className:"text-sm font-medium mb-2 text-destructive",children:"❌ Errado - Não use Button genérico"}),e.jsxs("div",{className:"flex gap-2 opacity-50",children:[e.jsx(s,{variant:"ghost",size:"icon",className:"h-8 w-8",disabled:!0,children:e.jsx(n,{className:"h-4 w-4"})}),e.jsx("span",{className:"text-sm text-muted-foreground self-center",children:"← Nunca use isto em tabelas"})]})]})]}),usage:`import {
2
- ActionButton,
3
- DropdownMenu,
4
- DropdownMenuTrigger,
5
- DropdownMenuContent,
6
- DropdownMenuItem
7
- } from "forlogic-core"
8
- import { Edit, Trash } from 'lucide-react'
9
-
10
- // ✅ CORRETO: Uso padrão em tabelas CRUD
11
- <DropdownMenu>
12
- <DropdownMenuTrigger asChild>
13
- <ActionButton />
14
- </DropdownMenuTrigger>
15
- <DropdownMenuContent align="end">
16
- <DropdownMenuItem onClick={() => handleEdit(item)}>
17
- <Edit className="mr-2 h-4 w-4" />
18
- Editar
19
- </DropdownMenuItem>
20
- <DropdownMenuItem onClick={() => handleDelete(item)}>
21
- <Trash className="mr-2 h-4 w-4" />
22
- Excluir
23
- </DropdownMenuItem>
24
- </DropdownMenuContent>
25
- </DropdownMenu>
26
-
27
- // ✅ CORRETO: Com ícone customizado
28
- <ActionButton>
29
- <Edit size={12} />
30
- </ActionButton>`,examples:[{title:"❌ Errado - Não use Button genérico",preview:e.jsxs("div",{className:"flex gap-2 opacity-50",children:[e.jsx(s,{variant:"ghost",size:"icon",className:"h-8 w-8",disabled:!0,children:e.jsx(n,{className:"h-4 w-4"})}),e.jsx("span",{className:"text-sm text-muted-foreground self-center",children:"← Nunca use isto"})]}),code:`// ❌ NUNCA faça isso em tabelas CRUD
31
- <Button variant="ghost" size="icon" className="h-8 w-8">
32
- <MoreHorizontal className="h-4 w-4" />
33
- </Button>
34
-
35
- // ❌ NUNCA faça isso
36
- <Button variant="outline" size="sm">
37
- <EllipsisVertical size={12} />
38
- </Button>`},{title:"✅ Correto - Sempre use ActionButton",preview:e.jsxs(a,{children:[e.jsx(i,{asChild:!0,children:e.jsx(t,{})}),e.jsxs(r,{align:"end",children:[e.jsx(o,{children:"Editar"}),e.jsx(o,{children:"Excluir"})]})]}),code:`// ✅ SEMPRE use ActionButton em tabelas
39
- <DropdownMenu>
40
- <DropdownMenuTrigger asChild>
41
- <ActionButton />
42
- </DropdownMenuTrigger>
43
- <DropdownMenuContent align="end">
44
- <DropdownMenuItem>Editar</DropdownMenuItem>
45
- <DropdownMenuItem>Excluir</DropdownMenuItem>
46
- </DropdownMenuContent>
47
- </DropdownMenu>`}],props:[{name:"children",type:"ReactNode",default:"<EllipsisVertical />",description:"Conteúdo customizado (ícone padrão: três pontos verticais)."},{name:"className",type:"string",default:"-",description:"Classes CSS adicionais."},{name:"onClick",type:"() => void",default:"-",description:"Handler de clique."}],accessibility:["Tamanho compacto (height: 28px, padding: 8px)","Ícone padrão: EllipsisVertical (três pontos verticais)",'variant="action" com estilo consistente do tema',"Perfeito para menus de ação em linhas de tabela"],notes:["⚠️ OBRIGATÓRIO: Use ActionButton para TODAS as ações em linhas de tabela CRUD",'❌ PROIBIDO: Usar Button variant="ghost" ou variant="icon" para ações de tabela',"O ActionButton garante consistência visual e acessibilidade em todo o sistema","Para ações padrão (editar/excluir), considere usar TableRowActions que já encapsula tudo","O ícone padrão é EllipsisVertical (não MoreHorizontal) para manter consistência"]})}export{j as ActionButtonDoc};
@@ -1,37 +0,0 @@
1
- import{j as e,aA as a,aB as i,aC as r}from"./index-BtX5DZqb.js";import{C as s}from"./ComponentDocTemplate-BtOCnlM2.js";import"./ExampleCard-DfuMYM6E.js";import"./TableOfContents-DBMJMbI4.js";function c(){return e.jsx(s,{title:"Alert",description:"Exibe uma mensagem de destaque para chamar a atenção do usuário. O componente inclui ícone automático baseado na variante.",component:e.jsxs(a,{variant:"info",className:"max-w-md",children:[e.jsx(i,{children:"Informação"}),e.jsx(r,{children:"Esta é uma mensagem informativa para o usuário."})]}),usage:`import { Alert, AlertDescription, AlertTitle } from "forlogic-core"
2
-
3
- <Alert variant="info">
4
- <AlertTitle>Informação</AlertTitle>
5
- <AlertDescription>
6
- Esta é uma mensagem informativa para o usuário.
7
- </AlertDescription>
8
- </Alert>`,examples:[{title:"Informativo (info)",description:"Alerta neutro para informações gerais. Ícone: Info.",preview:e.jsxs(a,{variant:"info",className:"max-w-md",children:[e.jsx(i,{children:"Informação"}),e.jsx(r,{children:"Você pode adicionar componentes e dependências ao seu app usando o CLI."})]}),code:`<Alert variant="info">
9
- <AlertTitle>Informação</AlertTitle>
10
- <AlertDescription>
11
- Você pode adicionar componentes e dependências ao seu app usando o CLI.
12
- </AlertDescription>
13
- </Alert>`},{title:"Alerta (warning)",description:"Alerta de atenção para avisos. Ícone: Info.",preview:e.jsxs(a,{variant:"warning",className:"max-w-md",children:[e.jsx(i,{children:"Atenção"}),e.jsx(r,{children:"Sua sessão expira em 5 minutos. Salve suas alterações."})]}),code:`<Alert variant="warning">
14
- <AlertTitle>Atenção</AlertTitle>
15
- <AlertDescription>
16
- Sua sessão expira em 5 minutos. Salve suas alterações.
17
- </AlertDescription>
18
- </Alert>`},{title:"Perigo (danger)",description:"Alerta de erro ou perigo. Ícone: AlertTriangle.",preview:e.jsxs(a,{variant:"danger",className:"max-w-md",children:[e.jsx(i,{children:"Erro"}),e.jsxs(r,{children:[e.jsx("p",{children:"Não foi possível processar seu pagamento."}),e.jsxs("ul",{className:"mt-2 list-disc list-inside text-sm",children:[e.jsx("li",{children:"Verifique os dados do cartão"}),e.jsx("li",{children:"Confirme se há saldo suficiente"})]})]})]}),code:`<Alert variant="danger">
19
- <AlertTitle>Erro</AlertTitle>
20
- <AlertDescription>
21
- <p>Não foi possível processar seu pagamento.</p>
22
- <ul className="mt-2 list-disc list-inside text-sm">
23
- <li>Verifique os dados do cartão</li>
24
- <li>Confirme se há saldo suficiente</li>
25
- </ul>
26
- </AlertDescription>
27
- </Alert>`},{title:"Sucesso (success)",description:"Alerta de sucesso para confirmações. Ícone: CheckCircle.",preview:e.jsxs(a,{variant:"success",className:"max-w-md",children:[e.jsx(i,{children:"Sucesso"}),e.jsx(r,{children:"Suas alterações foram salvas com sucesso."})]}),code:`<Alert variant="success">
28
- <AlertTitle>Sucesso</AlertTitle>
29
- <AlertDescription>
30
- Suas alterações foram salvas com sucesso.
31
- </AlertDescription>
32
- </Alert>`},{title:"Sem ícone",description:"Use showIcon={false} para ocultar o ícone automático.",preview:e.jsxs(a,{variant:"info",showIcon:!1,className:"max-w-md",children:[e.jsx(i,{children:"Alerta sem ícone"}),e.jsx(r,{children:"Este alerta não exibe o ícone padrão da variante."})]}),code:`<Alert variant="info" showIcon={false}>
33
- <AlertTitle>Alerta sem ícone</AlertTitle>
34
- <AlertDescription>
35
- Este alerta não exibe o ícone padrão da variante.
36
- </AlertDescription>
37
- </Alert>`}],props:[{name:"variant",type:'"info" | "warning" | "danger" | "success"',default:'"info"',description:"O estilo visual e ícone do alerta."},{name:"showIcon",type:"boolean",default:"true",description:"Se deve exibir o ícone padrão da variante."},{name:"className",type:"string",default:"-",description:"Classes CSS adicionais."}],accessibility:['Usa role="alert" para anunciar automaticamente aos leitores de tela',"A cor não é o único meio de transmitir informações - ícones fornecem contexto adicional","Estrutura HTML semântica com título e descrição claramente definidos","Contraste de cores adequado para acessibilidade visual"]})}export{c as AlertDoc};
@@ -1,67 +0,0 @@
1
- import{j as e,bW as o,I as i,f as s,bT as a,x as u,P as n,aN as d,a7 as l,c9 as c,r as x,B as p}from"./index-BtX5DZqb.js";import{C as h}from"./ComponentDocTemplate-BtOCnlM2.js";import"./ExampleCard-DfuMYM6E.js";import"./TableOfContents-DBMJMbI4.js";function f(){const[t,r]=x.useState("");return e.jsx("div",{className:"w-full bg-background border rounded-lg",children:e.jsx("header",{className:"px-4 py-2",children:e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("div",{className:"flex-shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("h1",{className:"text-lg font-semibold",children:"Usuários"}),e.jsx(p,{className:"bg-primary text-primary-foreground text-xs px-2 py-0.5",children:"Módulo"})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Gerenciamento de usuários"})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-1 max-w-md",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(o,{className:"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-4 w-4"}),e.jsx(i,{placeholder:"Buscar...",value:t,onChange:m=>r(m.target.value),className:"w-full pl-10 pr-8"}),t&&e.jsx(s,{variant:"ghost",size:"sm",className:"absolute right-1 top-1/2 transform -translate-y-1/2 h-6 w-6 p-0",onClick:()=>r(""),children:e.jsx(c,{className:"h-3.5 w-3.5"})})]}),e.jsx(s,{variant:"outline",size:"icon",className:"h-10 w-10",children:e.jsx(a,{className:"h-4 w-4"})})]}),e.jsxs("div",{className:"flex-shrink-0 ml-auto flex items-center gap-3",children:[e.jsxs(s,{size:"sm",children:[e.jsx(n,{className:"h-4 w-4 mr-1"}),"Novo"]}),e.jsx(s,{variant:"ghost",className:"h-auto p-2",children:e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsxs("div",{className:"text-left",children:[e.jsx("p",{className:"text-sm font-medium",children:"João Silva"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Empresa XYZ"})]}),e.jsx("div",{className:"w-8 h-8 bg-primary rounded-full flex items-center justify-center",children:e.jsx(d,{className:"h-4 w-4 text-primary-foreground"})}),e.jsx(l,{className:"h-4 w-4"})]})})]})]})})})}function g(){return e.jsxs("div",{className:"w-full",children:[e.jsxs("div",{className:"flex items-center justify-between h-14 px-4 border rounded-lg bg-background",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"bg-primary/10 text-primary px-2 py-1 rounded text-xs font-medium",children:"TÍTULO"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"←"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"→"}),e.jsx("div",{className:"bg-secondary/50 text-secondary-foreground px-2 py-1 rounded text-xs font-medium",children:"BUSCA"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"←"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"→"}),e.jsx("div",{className:"bg-accent/50 text-accent-foreground px-2 py-1 rounded text-xs font-medium",children:"AÇÕES"}),e.jsx("div",{className:"bg-muted text-muted-foreground px-2 py-1 rounded text-xs font-medium",children:"PERFIL"})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground text-center mt-2",children:"Diagrama das áreas internas do AppHeader (altura fixa: 56px)"})]})}function v(){return e.jsxs("div",{className:"flex gap-8 items-start",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium",children:'variant="dropdown"'}),e.jsx("div",{className:"border rounded-lg p-2 bg-background",children:e.jsx(s,{variant:"ghost",className:"h-auto p-2",children:e.jsxs("div",{className:"flex items-center space-x-2",children:[e.jsxs("div",{className:"text-left",children:[e.jsx("p",{className:"text-sm font-medium",children:"João Silva"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Empresa XYZ"})]}),e.jsx("div",{className:"w-8 h-8 bg-primary rounded-full flex items-center justify-center",children:e.jsx(d,{className:"h-4 w-4 text-primary-foreground"})}),e.jsx(l,{className:"h-4 w-4"})]})})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium",children:"Menu aberto"}),e.jsxs("div",{className:"border rounded-lg p-2 w-48 bg-background shadow-lg",children:[e.jsxs("div",{className:"py-1.5 px-2 hover:bg-muted rounded flex items-center gap-2 cursor-pointer",children:[e.jsx(a,{className:"h-4 w-4"}),e.jsx("span",{className:"text-sm",children:"Alterar Unidade"})]}),e.jsx("div",{className:"h-px bg-border my-1"}),e.jsxs("div",{className:"py-1.5 px-2 hover:bg-muted rounded flex items-center gap-2 cursor-pointer text-destructive",children:[e.jsx(c,{className:"h-4 w-4"}),e.jsx("span",{className:"text-sm",children:"Sair"})]})]})]})]})}function y(){return e.jsx(h,{title:"AppHeader",description:"Header principal da aplicação com título dinâmico, busca global integrada ao CRUD, ações customizáveis e informações do usuário. Altura fixa de 56px (h-14).",component:e.jsx(f,{}),usage:`import { AppLayout } from 'forlogic-core';
2
- import { usePageMetadataContext } from 'forlogic-core';
3
-
4
- // O AppHeader é renderizado automaticamente pelo AppLayout
5
- <AppLayout sidebarConfig={sidebarConfig}>
6
- <Routes>...</Routes>
7
- </AppLayout>
8
-
9
- // Para configurar título e ações, use o PageMetadataContext
10
- function UsersPage() {
11
- const { setHeaderActions, setMetadata } = usePageMetadataContext();
12
-
13
- useEffect(() => {
14
- setMetadata({ title: 'Usuários', subtitle: 'Gerenciamento' });
15
- setHeaderActions(
16
- <Button size="sm" onClick={() => setIsAddDialogOpen(true)}>
17
- <Plus className="h-4 w-4 mr-1" />
18
- Novo Usuário
19
- </Button>
20
- );
21
-
22
- return () => {
23
- setMetadata({});
24
- setHeaderActions(null);
25
- };
26
- }, []);
27
- }`,examples:[{title:"Estrutura do Componente",description:"O AppHeader possui 4 áreas internas: Título (esquerda), Busca (centro), Ações (direita) e Perfil (extrema direita).",preview:e.jsx(g,{}),code:`// Áreas do AppHeader
28
- // 1. Título: Título da página + Subtítulo + Badge do módulo
29
- // 2. Busca: Input de busca global (visível quando habilitado)
30
- // 3. Ações: Botões customizáveis via PageMetadataContext
31
- // 4. Perfil: UserInfo com dropdown de usuário
32
-
33
- // Altura fixa: 56px (h-14 no Tailwind)`},{title:"UserInfo Integrado",description:"Dropdown com informações do usuário, troca de unidade e logout.",preview:e.jsx(v,{}),code:`// UserInfo com variantes
34
- <UserInfo variant="dropdown" /> // No header
35
- <UserInfo variant="card" /> // Em páginas
36
-
37
- // Menu do usuário inclui:
38
- // - Alterar Unidade (submenu com todas unidades disponíveis)
39
- // - Sair (Logout)`},{title:"Busca Global",description:"Campo de busca com debounce sincronizado com URL (?search=termo).",preview:e.jsxs("div",{className:"flex items-center gap-2 max-w-md",children:[e.jsxs("div",{className:"relative flex-1",children:[e.jsx(o,{className:"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-4 w-4"}),e.jsx(i,{placeholder:"Buscar...",className:"w-full pl-10 pr-8"})]}),e.jsx(s,{variant:"outline",size:"icon",className:"h-10 w-10",children:e.jsx(a,{className:"h-4 w-4"})})]}),code:`// Configurar campos pesquisáveis no service
40
- const userService = createSimpleService({
41
- tableName: 'users',
42
- schema: 'common',
43
- searchFields: ['name', 'email', 'department'],
44
- });
45
-
46
- // A busca é exibida quando isSearchVisible = true no AuthContext`},{title:"Ações Customizáveis",description:"Botões de ação configurados via PageMetadataContext.",preview:e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(s,{variant:"outline",size:"sm",children:[e.jsx(u,{className:"h-4 w-4 mr-1"}),"Exportar"]}),e.jsxs(s,{size:"sm",children:[e.jsx(n,{className:"h-4 w-4 mr-1"}),"Novo"]})]}),code:`// ✅ CORRETO: Apenas botões de ação
47
- setHeaderActions(
48
- <>
49
- <Button variant="outline" size="sm">
50
- <Download className="h-4 w-4 mr-1" />
51
- Exportar
52
- </Button>
53
- <Button size="sm">
54
- <Plus className="h-4 w-4 mr-1" />
55
- Novo
56
- </Button>
57
- </>
58
- );
59
-
60
- // ❌ INCORRETO: Formulário no header
61
- setHeaderActions(
62
- <form onSubmit={...}>
63
- <Input />
64
- <Select />
65
- <Button type="submit">Salvar</Button>
66
- </form>
67
- );`}],props:[{name:"actions",type:"ReactNode",description:"Botões de ação à direita do header (via PageMetadataContext)"},{name:"variant (UserInfo)",type:'"card" | "dropdown"',default:'"card"',description:"Estilo de exibição do UserInfo"},{name:"selectedUnit (UserInfo)",type:"Company | null",description:"Unidade selecionada"},{name:"onUnitChange (UserInfo)",type:"(unit: Company) => void",description:"Callback ao trocar unidade"}],accessibility:["Busca acessível via teclado (Tab para navegar, Escape para limpar)","UserInfo dropdown acessível via teclado","Botões de ação com foco visível (focus-visible)",'Título da página anunciado por leitores de tela (role="heading")',"Atalho de teclado para busca (/ ou Ctrl+K pode ser implementado)"],notes:["✅ Use PageMetadataContext para ações dinâmicas","✅ Mantenha título curto e descritivo (máx. 3 palavras)","✅ Use um único header por página","✅ Limpe ações no useEffect cleanup","✅ Use ícones do Lucide nos botões de ação","❌ Não adicione múltiplos headers na mesma página","❌ Não modifique a altura do header (fixo em 56px)","❌ Não coloque formulários complexos no header","❌ Não use mais de 3 botões de ação","❌ Não esconda o UserInfo em páginas autenticadas"]})}export{y as AppHeaderDoc};
@@ -1,196 +0,0 @@
1
- import{j as e,B as n,f as t,bm as j,P as l,g as P,bs as c,h as b,l as i,c7 as d,bB as T,w as R,v as k,bZ as I,a7 as U,G,bi as D,r as m,cS as H,ek as A,cT as p,cU as x,cV as u,b$ as B,bE as W}from"./index-BtX5DZqb.js";import{C as q}from"./ComponentDocTemplate-BtOCnlM2.js";import{a as L,b as z,P as F}from"./pin-CJJgLEBz.js";import{G as O}from"./grip-vertical-CgXp0oI-.js";import"./ExampleCard-DfuMYM6E.js";import"./TableOfContents-DBMJMbI4.js";const V=[{icon:c,label:"Visão geral"},{icon:B,label:"Showcase"},{icon:d,label:"Liderança"},{icon:W,label:"Locais"},{icon:k,label:"Gestão",children:[{icon:d,label:"Usuários"},{icon:I,label:"Permissões"}]},{icon:F,label:"Design System"}];function Q(){const[a,r]=m.useState(!0),[N,h]=m.useState(!0),[S,g]=m.useState("Visão geral"),[E,M]=m.useState(["Gestão"]);return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx(t,{variant:a?"primary":"outline",size:"sm",onClick:()=>{r(!0),h(!0)},children:"Expandido"}),e.jsx(t,{variant:a?"outline":"primary",size:"sm",onClick:()=>{r(!1),h(!1)},children:"Colapsado"}),e.jsxs("span",{className:"text-xs text-muted-foreground ml-2",children:[N?e.jsx(L,{className:"inline h-3 w-3 mr-1"}):e.jsx(z,{className:"inline h-3 w-3 mr-1"}),N?"Pinada":"Despinada"]})]}),e.jsx(H,{children:e.jsx("div",{className:"relative inline-block",children:e.jsxs("div",{className:i("bg-background border border-border rounded-lg py-4 space-y-3 transition-all duration-300 overflow-visible relative",a?"w-64 px-3":"w-16 px-1.5"),children:[a?e.jsxs("div",{className:"flex flex-col gap-3 pl-2",children:[e.jsx("div",{className:"flex items-center h-10",children:e.jsx("img",{src:A.logo,alt:"Logo",className:"h-5 object-contain",onError:s=>{s.target.src='data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 24"%3E%3Ctext x="0" y="18" font-family="system-ui" font-size="16" font-weight="bold" fill="%23333"%3EForlogic%3C/text%3E%3C/svg%3E'}})}),e.jsxs(t,{variant:"secondary",size:"default",className:"h-10 gap-2 px-3 justify-start w-full",children:[e.jsx(j,{className:"h-4 w-4 flex-shrink-0"}),e.jsx("span",{className:"truncate",children:"Meu Módulo"})]})]}):e.jsxs("div",{className:"flex flex-col items-center justify-center w-full gap-3",children:[e.jsx("div",{className:"flex items-center justify-center h-10 w-8",children:e.jsx("img",{src:A.smallLogo,alt:"Logo",className:"h-6 w-auto object-contain",onError:s=>{s.target.src='data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 34 34"%3E%3Crect width="34" height="34" rx="6" fill="%23e5e7eb"/%3E%3Ctext x="50%25" y="55%25" text-anchor="middle" font-family="system-ui" font-size="14" font-weight="bold" fill="%23333"%3EF%3C/text%3E%3C/svg%3E'}})}),e.jsxs(p,{children:[e.jsx(x,{asChild:!0,children:e.jsx("button",{className:"flex items-center justify-center h-10 w-8 rounded-md hover:bg-accent hover:text-accent-foreground transition-colors",children:e.jsx(j,{className:"h-4 w-4"})})}),e.jsx(u,{side:"right",children:"Módulos"})]})]}),a?e.jsxs(t,{variant:"outline",className:"w-full gap-2 justify-start h-10",children:[e.jsx(l,{className:"h-4 w-4"}),"Novo Processo"]}):e.jsxs(p,{children:[e.jsx(x,{asChild:!0,children:e.jsx(t,{variant:"outline",size:"icon",className:"w-full h-10",children:e.jsx(l,{className:"h-4 w-4"})})}),e.jsx(u,{side:"right",children:"Novo Processo"})]}),e.jsxs("div",{className:"relative py-2",children:[e.jsx("div",{className:"border-t border-border"}),e.jsxs(p,{children:[e.jsx(x,{asChild:!0,children:e.jsx("button",{onClick:()=>{const s=!a;r(s),h(s)},className:i("absolute top-1/2 -translate-y-1/2 z-[100] h-6 w-6 flex items-center justify-center rounded-full bg-primary hover:bg-primary/90 shadow-md transition-colors",a?"-right-6":"-right-[18px]"),children:a?e.jsx(P,{className:"h-3.5 w-3.5 text-primary-foreground"}):e.jsx(b,{className:"h-3.5 w-3.5 text-primary-foreground"})})}),e.jsx(u,{side:"right",children:e.jsx("p",{children:a?"Recolher":"Expandir"})})]})]}),e.jsx("div",{className:"space-y-1",children:V.map(s=>{const w=s.label===S,f="children"in s&&s.children,y=E.includes(s.label),C=()=>{M(o=>o.includes(s.label)?o.filter(v=>v!==s.label):[...o,s.label])};return a?f?e.jsxs("div",{children:[e.jsxs("div",{onClick:C,className:i("flex items-center justify-between h-10 px-3 rounded-md transition-colors cursor-pointer","hover:bg-muted text-foreground"),children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"flex items-center justify-center h-8 w-8",children:e.jsx(s.icon,{className:"h-4 w-4"})}),e.jsx("span",{className:"text-sm font-medium",children:s.label})]}),e.jsx(b,{className:i("h-4 w-4 transition-transform",y&&"rotate-90")})]}),y&&e.jsx("div",{className:"ml-6 mt-1 space-y-1 border-l border-border pl-3",children:s.children.map(o=>{const v=o.label===S;return e.jsxs("div",{onClick:()=>g(o.label),className:i("flex items-center gap-2 h-8 px-2 rounded-md transition-colors cursor-pointer text-sm",v?"bg-primary/10 text-primary font-medium":"text-muted-foreground hover:bg-muted hover:text-foreground"),children:[e.jsx(o.icon,{className:"h-3.5 w-3.5"}),e.jsx("span",{children:o.label})]},o.label)})})]},s.label):e.jsxs("div",{onClick:()=>g(s.label),className:i("flex items-center gap-3 h-10 px-3 rounded-md transition-colors cursor-pointer",w?"bg-primary/10 text-primary font-medium":"hover:bg-muted text-foreground"),children:[e.jsx("span",{className:"flex items-center justify-center h-8 w-8",children:e.jsx(s.icon,{className:"h-4 w-4"})}),e.jsx("span",{className:"text-sm",children:s.label})]},s.label):e.jsxs(p,{children:[e.jsx(x,{asChild:!0,children:e.jsx("div",{onClick:()=>{f?C():g(s.label)},className:i("flex items-center justify-center h-8 w-8 mx-auto rounded-md transition-colors cursor-pointer",w?"bg-primary/10 text-primary":"hover:bg-accent hover:text-accent-foreground"),children:e.jsx(s.icon,{className:"h-4 w-4"})})}),e.jsxs(u,{side:"right",children:[s.label,f&&" (expandir para ver subitens)"]})]},s.label)})}),a&&e.jsx("div",{className:"absolute inset-y-0 right-0 w-1 hover:bg-primary/20 transition-colors cursor-ew-resize"})]})})})]})}function K(){return e.jsxs("div",{className:"flex gap-8 items-start flex-wrap",children:[e.jsx("div",{className:"relative",children:e.jsxs("div",{className:"w-64 bg-background border border-border rounded-lg py-4 px-3 space-y-3 relative overflow-visible",children:[e.jsxs("div",{className:"flex flex-col gap-2 px-2 py-2 border border-dashed border-primary/50 rounded relative",children:[e.jsx(n,{variant:"outline",className:"absolute -top-2.5 left-2 text-xs bg-background",children:"SidebarHeader"}),e.jsx("div",{className:"h-8 w-14 bg-muted rounded flex items-center justify-center text-[10px]",children:"Logo"}),e.jsxs(t,{variant:"secondary",size:"sm",className:"h-8 text-[10px] gap-2 px-3 justify-start",children:[e.jsx(j,{className:"h-3 w-3"}),"Módulos"]})]}),e.jsxs("div",{className:"border border-dashed border-green-500/50 rounded p-2 relative",children:[e.jsx(n,{variant:"outline",className:"absolute -top-2.5 left-2 text-xs bg-background text-green-600",children:"SidebarActionTrigger"}),e.jsxs(t,{variant:"outline",size:"sm",className:"w-full gap-1 text-xs h-7 justify-start",children:[e.jsx(l,{className:"h-3 w-3"}),"Ação"]})]}),e.jsxs("div",{className:"relative py-2",children:[e.jsx("div",{className:"border-t border-dashed border-blue-500/50 relative",children:e.jsx(n,{variant:"outline",className:"absolute -top-2.5 right-0 text-[8px] bg-background text-blue-600 whitespace-nowrap",children:"Pin/Unpin"})}),e.jsx("div",{className:"absolute top-1/2 -translate-y-1/2 -right-5 h-5 w-5 rounded-full bg-primary flex items-center justify-center",children:e.jsx(P,{className:"h-2.5 w-2.5 text-primary-foreground"})})]}),e.jsxs("div",{className:"border border-dashed border-orange-500/50 rounded p-2 relative space-y-1",children:[e.jsx(n,{variant:"outline",className:"absolute -top-2.5 left-2 text-xs bg-background text-orange-600",children:"NavigationItems"}),[{label:"Item simples",active:!0},{label:"Item com children",hasChildren:!0}].map((a,r)=>e.jsxs("div",{className:i("flex items-center justify-between px-2 py-1.5 rounded text-xs",a.active?"bg-primary/10 text-primary":"bg-muted/50"),children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(c,{className:"h-3 w-3"}),e.jsx("span",{children:a.label})]}),a.hasChildren&&e.jsx(b,{className:"h-3 w-3"})]},r))]}),e.jsx("div",{className:"absolute inset-y-0 right-0 w-1 border-r-2 border-dashed border-purple-400/50 rounded-r"}),e.jsx(n,{variant:"outline",className:"absolute top-1/2 -right-16 text-[8px] bg-background text-purple-600 whitespace-nowrap",children:"Resize rail"})]})}),e.jsxs("div",{className:"space-y-2 text-xs",children:[e.jsx("p",{className:"font-medium text-sm mb-3",children:"Hierarquia:"}),e.jsx("pre",{className:"bg-muted p-3 rounded text-xs font-mono leading-relaxed",children:`<Sidebar collapsible="icon">
2
- ├── SidebarHeader
3
- │ ├── Logo / SmallLogo
4
- │ └── ModulesButton (appName)
5
-
6
- ├── SidebarActionTrigger (opcional)
7
- │ ├── Ação única → executa direto
8
- │ └── Múltiplas → dropdown
9
-
10
- ├── Separator + Pin/Unpin button
11
-
12
- └── SidebarContent
13
- └── NavigationItems
14
- ├── Item simples (Link)
15
- ├── Item com permissionCheck
16
- └── Item com children
17
- └── Collapsible > SidebarMenuSub`})]})]})}function Z(){return e.jsx("div",{className:"flex gap-4 items-start flex-wrap",children:[{title:"Ativo",className:"bg-primary/10 text-primary font-medium",icon:c,label:"Início"},{title:"Hover",className:"bg-muted",icon:d,label:"Usuários"},{title:"Desabilitado",className:"opacity-50 cursor-not-allowed border",icon:T,label:"Admin"},{title:"Carregando",className:"opacity-50 border",icon:R,label:"Verificando...",spin:!0}].map(a=>e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs text-muted-foreground mb-2",children:a.title}),e.jsxs("div",{className:i("flex items-center gap-3 px-3 py-2 rounded-md w-40",a.className),children:[e.jsx(a.icon,{className:i("h-4 w-4",a.spin&&"animate-spin")}),e.jsx("span",{className:"text-sm",children:a.label})]})]},a.title))})}function $(){return e.jsxs("div",{className:"p-3 border rounded-md w-56 space-y-1 bg-background",children:[e.jsxs("div",{className:"flex items-center gap-3 h-10 px-3 rounded-md hover:bg-muted",children:[e.jsx("span",{className:"flex items-center justify-center h-8 w-8",children:e.jsx(c,{className:"h-4 w-4"})}),e.jsx("span",{className:"text-sm font-medium",children:"Início"})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between h-10 px-3 rounded-md hover:bg-muted cursor-pointer",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"flex items-center justify-center h-8 w-8",children:e.jsx(k,{className:"h-4 w-4"})}),e.jsx("span",{className:"text-sm font-medium",children:"Configurações"})]}),e.jsx(b,{className:"h-4 w-4 rotate-90"})]}),e.jsx("div",{className:"ml-6 mt-1 space-y-1 border-l border-border pl-3",children:[{icon:d,label:"Perfil",active:!0},{icon:I,label:"Segurança"}].map(a=>e.jsxs("div",{className:i("flex items-center gap-2 h-8 px-2 rounded-md text-sm",a.active?"bg-primary/10 text-primary font-medium":"text-muted-foreground hover:bg-muted"),children:[e.jsx(a.icon,{className:"h-3.5 w-3.5"}),e.jsx("span",{children:a.label})]},a.label))})]})]})}function J(){return e.jsxs("div",{className:"flex gap-6 items-start flex-wrap",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-center",children:"Uma Ação"}),e.jsxs("div",{className:"w-56 bg-background border rounded-lg p-3 space-y-3",children:[e.jsxs(t,{variant:"outline",className:"w-full gap-2 justify-start",children:[e.jsx(l,{className:"h-4 w-4"}),"Novo Processo"]}),e.jsx("div",{className:"border-t pt-2 space-y-1",children:[{icon:c,label:"Início",active:!0},{icon:d,label:"Usuários"}].map((a,r)=>e.jsxs("div",{className:i("flex items-center gap-3 px-3 py-2 rounded-md text-sm",a.active?"bg-primary/10 text-primary font-medium":"hover:bg-muted"),children:[e.jsx(a.icon,{className:"h-4 w-4"}),e.jsx("span",{children:a.label})]},r))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-center",children:"Múltiplas Ações"}),e.jsxs("div",{className:"w-56 bg-background border rounded-lg p-3 space-y-1",children:[e.jsxs(t,{variant:"outline",className:"w-full gap-2 justify-start",children:[e.jsx(l,{className:"h-4 w-4"}),"Criar",e.jsx(U,{className:"ml-auto h-4 w-4 rotate-180"})]}),e.jsx("div",{className:"border rounded-md bg-popover p-1 shadow-md",children:[{icon:G,label:"Novo Documento"},{icon:D,label:"Nova Pasta"},{icon:d,label:"Novo Grupo"}].map((a,r)=>e.jsxs("div",{className:"flex items-center gap-2 px-2 py-1.5 rounded-sm hover:bg-muted cursor-pointer",children:[e.jsx(a.icon,{className:"h-4 w-4"}),e.jsx("span",{className:"text-sm",children:a.label})]},r))})]})]})]})}function X(){return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-3 p-3 border rounded-md bg-muted/30",children:[e.jsx(O,{className:"h-5 w-5 text-muted-foreground"}),e.jsxs("div",{className:"text-sm space-y-1",children:[e.jsx("p",{className:"font-medium",children:"Redimensionamento"}),e.jsxs("p",{className:"text-muted-foreground",children:["Quando ",e.jsx("code",{className:"bg-muted px-1 rounded text-xs",children:"resizable=true"}),", um rail aparece na borda direita. Arraste para redimensionar entre ",e.jsx("code",{className:"bg-muted px-1 rounded text-xs",children:"minWidth"})," e"," ",e.jsx("code",{className:"bg-muted px-1 rounded text-xs",children:"maxWidth"}),"."]}),e.jsxs("p",{className:"text-muted-foreground",children:["A largura é persistida automaticamente em ",e.jsx("code",{className:"bg-muted px-1 rounded text-xs",children:"localStorage"}),"."]})]})]}),e.jsx("pre",{className:"bg-muted p-3 rounded text-xs font-mono",children:`<AppSidebar
18
- config={sidebarConfig}
19
- resizable={true}
20
- minWidth={224} // padrão: 224px (14rem)
21
- maxWidth={384} // padrão: 384px (24rem)
22
- />`})]})}function Y(){return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex gap-4 items-start flex-wrap",children:[e.jsxs("div",{className:"p-3 border rounded-md space-y-2 w-64",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(L,{className:"h-4 w-4 text-primary"}),e.jsx("span",{className:"text-sm font-medium",children:"Pinada"})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Sidebar permanece aberta. Estado salvo em ",e.jsx("code",{className:"bg-muted px-1 rounded",children:"localStorage"}),"."]})]}),e.jsxs("div",{className:"p-3 border rounded-md space-y-2 w-64",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(z,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-sm font-medium",children:"Despinada"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Sidebar inicia colapsada. Expande ao hover (desktop) ou toggle (mobile)."})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["O botão circular na borda do separador controla pin/unpin. Em telas ",e.jsx("code",{className:"bg-muted px-1 rounded",children:"<768px"})," (mobile), o botão é ocultado."]})]})}function _(){return e.jsx("div",{className:"space-y-3 w-full",children:[{badge:"Desktop ≥1024px",variant:"default",text:"Sidebar visível, pode ser pinada ou colapsar"},{badge:"Tablet 768-1023px",variant:"secondary",text:"Sidebar inicia colapsada, expande ao hover/click"},{badge:"Mobile <768px",variant:"outline",text:"Sidebar como drawer/sheet lateral (oculta por padrão)"}].map(a=>e.jsxs("div",{className:"flex gap-4 items-center",children:[e.jsx(n,{variant:a.variant,className:"shrink-0",children:a.badge}),e.jsx("span",{className:"text-sm text-muted-foreground",children:a.text})]},a.badge))})}function te(){return e.jsxs(e.Fragment,{children:[e.jsx(q,{title:"AppSidebar",description:"Sidebar de navegação principal da aplicação com suporte a pin/unpin, permissões assíncronas, ações de módulo (SidebarActionTrigger), redimensionamento e navegação hierárquica.",component:e.jsx(Q,{}),usage:`import { AppLayout } from 'forlogic-core';
23
- import type { SidebarConfig } from 'forlogic-core';
24
- import { Home, Users, Settings, Shield, Plus, FileText, Folder } from 'lucide-react';
25
-
26
- const sidebarConfig: SidebarConfig = {
27
- appName: 'Minha Aplicação',
28
-
29
- // Ações do módulo (opcional)
30
- moduleActions: {
31
- triggerLabel: 'Criar',
32
- triggerIcon: Plus,
33
- actions: [
34
- { id: 'new-doc', label: 'Novo Documento', icon: FileText, onClick: () => {} },
35
- { id: 'new-folder', label: 'Nova Pasta', icon: Folder, onClick: () => {} },
36
- ],
37
- },
38
-
39
- // Navegação (com suporte a hierarquia)
40
- navigation: [
41
- { label: 'Início', path: '/', icon: Home },
42
- { label: 'Usuários', path: '/users', icon: Users },
43
- {
44
- label: 'Configurações',
45
- path: '/settings',
46
- icon: Settings,
47
- children: [
48
- { label: 'Perfil', path: '/settings/profile', icon: Users },
49
- { label: 'Segurança', path: '/settings/security', icon: Shield },
50
- ],
51
- },
52
- ],
53
- };
54
-
55
- // Uso via AppLayout (recomendado)
56
- <AppLayout sidebarConfig={sidebarConfig}>
57
- <Routes>...</Routes>
58
- </AppLayout>
59
-
60
- // Uso direto (casos avançados)
61
- <AppSidebar
62
- config={sidebarConfig}
63
- resizable={true}
64
- minWidth={224}
65
- maxWidth={384}
66
- />`,examples:[{title:"Anatomia do Sidebar",description:"Estrutura hierárquica completa: Header, Actions, Separator com Pin, Navigation, e Resize rail.",preview:e.jsx(K,{}),code:`// Estrutura do AppSidebar
67
- <Sidebar collapsible="icon">
68
- ├── SidebarHeader (Logo + ModulesButton)
69
- ├── SidebarActionTrigger (ações de módulo)
70
- ├── Separator + Pin/Unpin button (borda)
71
- └── SidebarContent
72
- └── NavigationItems
73
- ├── Item simples (Link)
74
- ├── Item com permissionCheck
75
- └── Item com children (Collapsible)
76
- └── SidebarMenuSub`},{title:"Estados Visuais",description:"Itens de navegação possuem 4 estados: Ativo (bg-primary/10), Hover (bg-muted), Desabilitado (opacity-50 + Lock icon), e Carregando (spinner durante permissionCheck).",preview:e.jsx(Z,{}),code:`// Matching de rota ativa (hierárquico)
77
- const isActive = (path: string) =>
78
- location.pathname === path ||
79
- location.pathname.startsWith(path + '/');
80
-
81
- // Item com verificação de permissão assíncrona
82
- {
83
- label: 'Gestão',
84
- path: '/management',
85
- icon: Settings,
86
- permissionCheck: async () => {
87
- return await checkUserPermission('management');
88
- }
89
- }
90
- // → Exibe Loader2 (spin) enquanto verifica
91
- // → Exibe Lock + "Acesso restrito" se false`},{title:"Navegação Hierárquica",description:"Suporte a itens com children (máximo 2 níveis). No modo expandido, usa Collapsible com ChevronRight. No modo colapsado, exibe tooltip.",preview:e.jsx($,{}),code:`const navigation: SidebarNavigationItem[] = [
92
- { label: 'Início', path: '/', icon: Home },
93
- {
94
- label: 'Configurações',
95
- path: '/settings',
96
- icon: Settings,
97
- children: [
98
- { label: 'Perfil', path: '/settings/profile', icon: Users },
99
- { label: 'Segurança', path: '/settings/security', icon: Shield },
100
- ],
101
- },
102
- ];`},{title:"Ações de Módulo (SidebarActionTrigger)",description:"Uma ação executa diretamente; múltiplas ações exibem dropdown. Quando a sidebar está colapsada, mostra apenas ícone com tooltip.",preview:e.jsx(J,{}),code:`// SidebarActionsConfig
103
- moduleActions: {
104
- triggerLabel: 'Criar', // Label do botão (múltiplas ações)
105
- triggerIcon: Plus, // Ícone do gatilho
106
- actions: [
107
- {
108
- id: 'new-document',
109
- label: 'Novo Documento',
110
- icon: FileText,
111
- onClick: () => openDocumentDialog(),
112
- disabled: false, // Opcional
113
- permissionCheck: async () => true, // Opcional
114
- },
115
- ],
116
- }`},{title:"Pin / Unpin",description:"O botão circular na borda do separador controla se a sidebar permanece aberta (pinada) ou colapsa automaticamente.",preview:e.jsx(Y,{}),code:`// Internamente o AppSidebar usa:
117
- import { getSidebarPinnedPreference, setSidebarPinnedPreference }
118
- from './sidebar-utils';
119
-
120
- // Persistência em localStorage ('forlogic-sidebar-pinned')
121
- // Botão circular usa bg-primary com ChevronLeft/Right
122
- // Oculto em mobile (hidden md:block)`},{title:"Redimensionamento",description:"Quando resizable=true, um rail aparece na borda direita para arrastar. A largura é persistida em localStorage.",preview:e.jsx(X,{}),code:`// useSidebarResize hook
123
- import { useSidebarResize } from 'forlogic-core';
124
-
125
- const resize = useSidebarResize({
126
- minWidth: 224, // Mínimo (14rem)
127
- maxWidth: 384, // Máximo (24rem)
128
- defaultWidth: 240, // Padrão (15rem)
129
- storageKey: 'app-sidebar-width',
130
- isOpen: true,
131
- onResize: (width) => console.log(width),
132
- });
133
-
134
- // resize.width, resize.isDragging,
135
- // resize.dragRef, resize.handleMouseDown`},{title:"Comportamento Responsivo",description:"A sidebar adapta-se automaticamente ao tamanho da tela.",preview:e.jsx(_,{}),code:`// O AppSidebar usa collapsible="icon"
136
- // Em desktop: colapsa para 16px (ícones apenas)
137
- // Em mobile: comportamento de drawer
138
-
139
- // useSidebar() hook disponível para controle externo
140
- import { useSidebar } from 'forlogic-core';
141
-
142
- const { open, setOpen, state, toggleSidebar } = useSidebar();
143
- // state: "expanded" | "collapsed"`}],props:[{name:"config",type:"SidebarConfig",description:"Configuração principal: appName, navigation[], moduleActions"},{name:"config.appName",type:"string",description:'Nome exibido no botão de módulos (fallback: "Módulos")'},{name:"config.navigation",type:"SidebarNavigationItem[]",description:"Itens de navegação com label, path, icon e children opcionais"},{name:"config.moduleActions",type:"SidebarActionsConfig",description:"Ações do módulo: triggerLabel, triggerIcon, actions[]"},{name:"customContent",type:"ReactNode",description:"Conteúdo customizado que substitui a navegação padrão"},{name:"resizable",type:"boolean",default:"false",description:"Habilita redimensionamento com drag na borda direita"},{name:"minWidth",type:"number",default:"224",description:"Largura mínima em pixels (resizable=true)"},{name:"maxWidth",type:"number",default:"384",description:"Largura máxima em pixels (resizable=true)"}],accessibility:["Navegação acessível via teclado (Tab, Arrow keys, Enter)","Submenus expansíveis com Enter ou Space (via Collapsible)","Estado ativo comunicado via isActive no SidebarMenuButton","Itens desabilitados com cursor-not-allowed e opacity reduzida","Tooltips em modo colapsado para identificação de todos os itens","Botão pin/unpin oculto em mobile (hidden md:block) para evitar conflito com drawer","Contraste adequado entre estados ativo/inativo usando tokens semânticos"],notes:["✅ Use ícones consistentes do Lucide React para todos os itens","✅ Máximo 2 níveis de aninhamento (item → children)","✅ Labels curtas: 1-3 palavras, máximo 20 caracteres","✅ Agrupe itens relacionados logicamente","✅ Use permissionCheck para controle de acesso assíncrono","✅ Use moduleActions para ações de criação/adição do módulo","✅ Prefira AppLayout ao invés de usar AppSidebar diretamente","❌ Não use mais de 10 itens no nível raiz","❌ Não crie 3+ níveis de submenu (hierarquia profunda)","❌ Não deixe itens sem ícones","❌ Não misture ícones de bibliotecas diferentes","❌ Não use labels com mais de 20 caracteres"]}),e.jsxs("div",{className:"mt-12 pt-8 border-t space-y-6",children:[e.jsx("h2",{className:"text-2xl font-bold",children:"Tipos TypeScript"}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:"SidebarConfig"}),e.jsx("pre",{className:"bg-muted p-4 rounded-lg overflow-x-auto text-sm",children:`interface SidebarConfig {
144
- appName?: string;
145
- navigation?: SidebarNavigationItem[];
146
- moduleActions?: SidebarActionsConfig;
147
- }`})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:"SidebarNavigationItem"}),e.jsx("pre",{className:"bg-muted p-4 rounded-lg overflow-x-auto text-sm",children:`interface SidebarNavigationItem {
148
- label: string; // Texto do item
149
- path: string; // Rota de navegação
150
- icon: LucideIcon; // Ícone obrigatório
151
- complementaryText?: string; // Texto complementar
152
- permissionCheck?: () => Promise<boolean>; // Verificação assíncrona
153
- children?: SidebarNavigationItem[]; // Subitens (máx. 2 níveis)
154
- }`})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:"SidebarActionsConfig"}),e.jsx("pre",{className:"bg-muted p-4 rounded-lg overflow-x-auto text-sm",children:`interface SidebarActionsConfig {
155
- triggerLabel?: string; // Rótulo do gatilho (default: 'Criar')
156
- triggerIcon?: LucideIcon; // Ícone do gatilho (default: Plus)
157
- actions: SidebarModuleAction[];
158
- }
159
-
160
- interface SidebarModuleAction {
161
- id: string; // ID único
162
- label: string; // Texto exibido
163
- icon?: LucideIcon; // Ícone opcional
164
- onClick: () => void; // Callback
165
- disabled?: boolean; // Desabilitar ação
166
- permissionCheck?: () => Promise<boolean>; // Verificação de permissão
167
- }`})]})]}),e.jsxs("div",{className:"mt-12 pt-8 border-t space-y-6",children:[e.jsx("h2",{className:"text-2xl font-bold",children:"Componente Base: Sidebar"}),e.jsxs("p",{className:"text-muted-foreground",children:["O AppSidebar utiliza internamente o componente base ",e.jsx("code",{className:"bg-muted px-1 rounded",children:"Sidebar"})," do Shadcn/Radix. Para sidebars customizadas fora do AppLayout, use o componente base diretamente."]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:"Uso do Base"}),e.jsx("pre",{className:"bg-muted p-4 rounded-lg overflow-x-auto text-sm",children:`import {
168
- Sidebar, SidebarProvider, SidebarHeader, SidebarContent,
169
- SidebarFooter, SidebarGroup, SidebarGroupLabel,
170
- SidebarGroupContent, SidebarMenu, SidebarMenuItem,
171
- SidebarMenuButton, SidebarTrigger,
172
- } from 'forlogic-core';
173
-
174
- <SidebarProvider>
175
- <Sidebar collapsible="icon">
176
- <SidebarHeader>Logo</SidebarHeader>
177
- <SidebarContent>
178
- <SidebarGroup>
179
- <SidebarGroupLabel>Menu</SidebarGroupLabel>
180
- <SidebarGroupContent>
181
- <SidebarMenu>
182
- <SidebarMenuItem>
183
- <SidebarMenuButton isActive>
184
- <Home className="mr-2" /> Home
185
- </SidebarMenuButton>
186
- </SidebarMenuItem>
187
- </SidebarMenu>
188
- </SidebarGroupContent>
189
- </SidebarGroup>
190
- </SidebarContent>
191
- </Sidebar>
192
- <main>
193
- <SidebarTrigger />
194
- {/* Content */}
195
- </main>
196
- </SidebarProvider>`})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:"Props do Sidebar Base"}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm border",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"bg-muted",children:[e.jsx("th",{className:"text-left p-2 border-b",children:"Prop"}),e.jsx("th",{className:"text-left p-2 border-b",children:"Tipo"}),e.jsx("th",{className:"text-left p-2 border-b",children:"Default"}),e.jsx("th",{className:"text-left p-2 border-b",children:"Descrição"})]})}),e.jsxs("tbody",{children:[e.jsxs("tr",{children:[e.jsx("td",{className:"p-2 border-b font-mono text-xs",children:"side"}),e.jsx("td",{className:"p-2 border-b",children:'"left" | "right"'}),e.jsx("td",{className:"p-2 border-b",children:'"left"'}),e.jsx("td",{className:"p-2 border-b",children:"Lado da tela"})]}),e.jsxs("tr",{children:[e.jsx("td",{className:"p-2 border-b font-mono text-xs",children:"variant"}),e.jsx("td",{className:"p-2 border-b",children:'"sidebar" | "floating" | "inset"'}),e.jsx("td",{className:"p-2 border-b",children:'"sidebar"'}),e.jsx("td",{className:"p-2 border-b",children:"Estilo visual"})]}),e.jsxs("tr",{children:[e.jsx("td",{className:"p-2 border-b font-mono text-xs",children:"collapsible"}),e.jsx("td",{className:"p-2 border-b",children:'"offcanvas" | "icon" | "none"'}),e.jsx("td",{className:"p-2 border-b",children:'"offcanvas"'}),e.jsx("td",{className:"p-2 border-b",children:"Comportamento de collapse"})]})]})]})})]}),e.jsx("div",{className:"p-4 bg-muted/50 rounded-lg border",children:e.jsxs("p",{className:"text-sm",children:[e.jsx("strong",{children:"💡 Recomendação:"})," Para a maioria dos casos, prefira"," ",e.jsx("code",{className:"bg-muted px-1 rounded",children:"AppSidebar"})," via"," ",e.jsx("code",{className:"bg-muted px-1 rounded",children:"AppLayout"}),", que já inclui permissões, módulos, resize e pin/unpin. Use o Sidebar base apenas para customizações avançadas."]})})]})]})}export{te as AppSidebarDoc};