forlogic-core 1.16.6 → 1.16.8
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/.note/memory/components/dialog-sizes-and-structure.md +3 -1
- package/.note/memory/ui/components/combo-tree.md +16 -0
- package/dist/assets/AccordionDoc-BVPUJk8G.js +31 -0
- package/dist/assets/ActionButtonDoc-DLJ_K9ib.js +47 -0
- package/dist/assets/AlertDoc-CY1ybZeG.js +37 -0
- package/dist/assets/AppHeaderDoc-Crkw4dA9.js +67 -0
- package/dist/assets/AppSidebarDoc-ET-4j6wV.js +204 -0
- package/dist/assets/AuthDoc-B4v4Nci5.js +192 -0
- package/dist/assets/AvatarDoc-BLdMoyJd.js +11 -0
- package/dist/assets/BadgeDoc-CSNM1b6b.js +36 -0
- package/dist/assets/BaseFormDoc-DXiYuN6-.js +169 -0
- package/dist/assets/BodyContentDoc-Bp6YmUWX.js +83 -0
- package/dist/assets/BreadcrumbDoc-D7tqqTvo.js +75 -0
- package/dist/assets/ButtonDoc-C4JwIvU3.js +41 -0
- package/dist/assets/ButtonGroupDoc-QFfjC7Pm.js +7 -0
- package/dist/assets/CalendarDoc-COlEKqmv.js +81 -0
- package/dist/assets/CardDoc-BVhMoC2w.js +49 -0
- package/dist/assets/ChartDoc-BJ14EjI2.js +111 -0
- package/dist/assets/CheckboxDoc-Bcqpln9_.js +55 -0
- package/dist/assets/ColorPickerDoc-CcfmSwyC.js +10 -0
- package/dist/assets/ColorsFoundationDoc-uO6IiJbS.js +13 -0
- package/dist/assets/ComboTreeDoc-R4qE6XwB.js +46 -0
- package/dist/assets/ComboboxDoc-JIo_-gSN.js +134 -0
- package/dist/assets/ComponentDocTemplate-CRbRY-v5.js +1 -0
- package/dist/assets/ContextMenuDoc-C4-_0NLp.js +182 -0
- package/dist/assets/ContextsDoc-Cj9Aaoyo.js +184 -0
- package/dist/assets/CreateCrudPageDoc-D_SnMRJ2.js +106 -0
- package/dist/assets/CrudActionBarDoc-BYqtIabp.js +112 -0
- package/dist/assets/CrudGridDoc-DspxQrq5.js +85 -0
- package/dist/assets/CrudOverviewDoc-DLcOL_HZ.js +14 -0
- package/dist/assets/CrudPrimitivesDoc-BRS86nWg.js +164 -0
- package/dist/assets/CrudTableDoc-Daw8u2G_.js +113 -0
- package/dist/assets/DataListDoc-BrgVNhhR.js +13 -0
- package/dist/assets/DesignSystemHome-BFBNqq1J.js +1 -0
- package/dist/assets/DialogDoc-DCpRy4rg.js +981 -0
- package/dist/assets/DropdownMenuDoc-DT6LBa8Z.js +175 -0
- package/dist/assets/EmptyStateDoc-wydc09gG.js +35 -0
- package/dist/assets/EnvironmentsDoc-amIriwDD.js +96 -0
- package/dist/assets/ErrorBoundaryDoc-BEixy_Gl.js +111 -0
- package/dist/assets/FormDoc-DxoRt6p7.js +81 -0
- package/dist/assets/FoundationOverview-CxSbumIt.js +1 -0
- package/dist/assets/GridDoc-BpQqCMUE.js +28 -0
- package/dist/assets/HooksDoc-JNODhbaF.js +665 -0
- package/dist/assets/HoverCardDoc-CdqiYrIb.js +31 -0
- package/dist/assets/I18nDoc-B6LMXnE3.js +232 -0
- package/dist/assets/IconPickerDoc-BRdy58IC.js +10 -0
- package/dist/assets/IconsFoundationDoc-CrymfxTI.js +33 -0
- package/dist/assets/InputDoc-BK-SdpJ7.js +211 -0
- package/dist/assets/LabelDoc-DHvgzhaJ.js +42 -0
- package/dist/assets/LeadershipDoc-DRiB0spL.js +416 -0
- package/dist/assets/MediaDoc-B_vqnf72.js +459 -0
- package/dist/assets/MenubarDoc-Zvgczxe2.js +165 -0
- package/dist/assets/ModuleAccessDoc-Nuxb4S27.js +153 -0
- package/dist/assets/ModulesDialogDoc-iJWLkOZo.js +46 -0
- package/dist/assets/NavigationMenuDoc-CeWun1VF.js +116 -0
- package/dist/assets/OnboardingDialogDoc-xBL-rXeZ.js +55 -0
- package/dist/assets/PaginationDoc-CfvwxCMe.js +98 -0
- package/dist/assets/PaginationDoc-DqtRgXnF.js +27 -0
- package/dist/assets/PlacesDoc-nckioEzg.js +226 -0
- package/dist/assets/PopoverDoc-C3o2CZCT.js +64 -0
- package/dist/assets/ProgressDoc-BmWBNMPA.js +29 -0
- package/dist/assets/QualiexUserFieldDoc-CE1e4mx6.js +149 -0
- package/dist/assets/RadioGroupDoc-DMZH6NmR.js +57 -0
- package/dist/assets/RadiusDoc-BOZD3gPV.js +7 -0
- package/dist/assets/RequiredFieldsCounterDoc-CG-lmSSy.js +58 -0
- package/dist/assets/ResizableDoc-CqGkv6Cd.js +104 -0
- package/dist/assets/RichTextEditorDoc-m50ll-Od.js +24 -0
- package/dist/assets/ScrollAreaDoc-BzJ-APXo.js +28 -0
- package/dist/assets/SecurityDoc-B34gVeiV.js +204 -0
- package/dist/assets/SelectDoc-DXRv7QHK.js +80 -0
- package/dist/assets/SeparatorDoc-DcNh8k0P.js +4 -0
- package/dist/assets/ServicesDoc-8aXBd6yg.js +308 -0
- package/dist/assets/ShadowsDoc-Brl4hIDI.js +9 -0
- package/dist/assets/SignDoc-BdwerR-2.js +66 -0
- package/dist/assets/SkeletonDoc-BWgqgbDY.js +54 -0
- package/dist/assets/SliderDoc-E-NjbYVk.js +41 -0
- package/dist/assets/SpacingDoc-BzburM-r.js +12 -0
- package/dist/assets/SplitButtonDoc-BYUysmJp.js +53 -0
- package/dist/assets/StepSelectorDoc-PB1k4v7F.js +41 -0
- package/dist/assets/SwitchDoc-BLOG6kfj.js +56 -0
- package/dist/assets/TableDoc-Dwcs-lop.js +128 -0
- package/dist/assets/TabsDoc-Ovkh8ArV.js +42 -0
- package/dist/assets/TextareaDoc-DsBYxmbr.js +46 -0
- package/dist/assets/ToastDoc-BbZaFE_A.js +157 -0
- package/dist/assets/ToggleDoc-C28vbvhp.js +51 -0
- package/dist/assets/TooltipDoc-DL5cnLak.js +58 -0
- package/dist/assets/TruncatedCellDoc-BuDA8QcY.js +12 -0
- package/dist/assets/TypographyFoundationDoc-CPdH4PHa.js +7 -0
- package/dist/assets/UtilitiesDoc-CrQhyEfz.js +145 -0
- package/dist/assets/blocks-DO93nPjs.js +1 -0
- package/dist/assets/calendar-days-cMfwBSZx.js +1 -0
- package/dist/assets/circle-plus-D3NftMzS.js +1 -0
- package/dist/assets/circle-x-BVAVJ_oz.js +1 -0
- package/dist/assets/crown-B2MTZDnM.js +1 -0
- package/dist/assets/date-picker-zhJU-_kM.js +1 -0
- package/dist/assets/disabled-menu-item-C16xsaVs.js +1 -0
- package/dist/assets/drawer-oTqCOtsC.js +3 -0
- package/dist/assets/file-pen-line-CXv-Eye-.js +1 -0
- package/dist/assets/git-branch-V6-h6P9K.js +1 -0
- package/dist/assets/globe-CaUBIJU8.js +1 -0
- package/dist/assets/hash-B4MTXppl.js +1 -0
- package/dist/assets/hover-card-DEuucfxP.js +1 -0
- package/dist/assets/index-CE0k7Rdh.js +312 -0
- package/dist/assets/index-Cx3adT_u.css +1 -0
- package/dist/assets/life-buoy-BRndExxh.js +1 -0
- package/dist/assets/lucide-react-t7dCa4lv.js +1 -0
- package/dist/assets/monitor-Dg3HKTSE.js +1 -0
- package/dist/assets/package-3G45ARQh.js +1 -0
- package/dist/assets/pen-BYSSwjK4.js +1 -0
- package/dist/assets/pin-CMYagNhs.js +1 -0
- package/dist/assets/radio-group-BVun_Tmt.js +1 -0
- package/dist/assets/server-p0Sb0mKI.js +1 -0
- package/dist/assets/share-2-D-ZhCCq2.js +1 -0
- package/dist/assets/shield-x-Q7hAXWsG.js +1 -0
- package/dist/assets/step-selector-DHxgT2FL.js +1 -0
- package/dist/assets/text-align-start-6aYQqbX4.js +1 -0
- package/dist/assets/trash-DveAOiLF.js +1 -0
- package/dist/assets/useMockCrud-GY0KxHXr.js +1 -0
- package/dist/assets/user-check-CoGNBfIk.js +1 -0
- package/dist/assets/user-plus-Bad2xWIT.js +1 -0
- package/dist/components/layout/SidebarActionTrigger.d.ts +15 -3
- package/dist/components/modules/ModuleAccessGuard.d.ts +24 -2
- package/dist/components/ui/combo-tree.d.ts +4 -0
- package/dist/crud/components/ColumnSettingsPopover.d.ts +17 -0
- package/dist/crud/components/CrudActionBar.d.ts +2 -1
- package/dist/crud/components/CrudTable.d.ts +5 -1
- package/dist/crud/components/GroupDropZone.d.ts +16 -0
- package/dist/crud/components/InlineRowActions.d.ts +15 -0
- package/dist/crud/hooks/useColumnDragReorder.d.ts +19 -0
- package/dist/crud/hooks/useColumnManager.d.ts +56 -0
- package/dist/crud/primitives/Table.d.ts +1 -1
- package/dist/crud/primitives/TreeTable.d.ts +2 -0
- package/dist/crud/primitives/index.d.ts +2 -1
- package/dist/crud/primitives/types.d.ts +33 -0
- package/dist/exports/crud.d.ts +2 -1
- package/dist/hooks/useDerivedContractedModules.d.ts +8 -0
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +1 -1
- package/dist/index.html +35 -0
- package/dist/index.js +1 -1
- package/dist/types/sidebar.d.ts +2 -0
- package/dist/types.d.ts +4 -0
- package/dist/vite/index.esm.js +3 -1
- package/dist/vite/index.js +3 -1
- package/docs/DESIGN_SYSTEM.md +33 -13
- package/package.json +2 -4
|
@@ -8,7 +8,9 @@ Dialog possui 3 tamanhos opcionais (sem default) e estrutura obrigatória:
|
|
|
8
8
|
| (nenhum) | Auto (className controla) | Auto | Quando classes Tailwind definem o tamanho |
|
|
9
9
|
| `sm` | 30vw (320-480px) | 320px | Confirmações rápidas |
|
|
10
10
|
| `md` | 50vw (480-720px) | 70vh | Formulários padrão |
|
|
11
|
-
| `lg` | 85vw (
|
|
11
|
+
| `lg` | 85vw (max 1440px) | 900px | Tabelas, conteúdo extenso |
|
|
12
|
+
|
|
13
|
+
**Mobile (<640px):** Todos os tamanhos são sobrepostos para ocupar `calc(100vw-2rem)` x `calc(100dvh-2rem)` com padding reduzido (`p-4`).
|
|
12
14
|
|
|
13
15
|
**Regra de prioridade:** Quando `size` é informado, inline styles são aplicados e vencem sobre className. Sem `size`, className controla livremente.
|
|
14
16
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Memory: ui/components/combo-tree
|
|
2
|
+
Updated: today
|
|
3
|
+
|
|
4
|
+
O componente `ComboTree` permite a seleção de dados hierárquicos com busca recursiva e separação entre expansão (chevron) e seleção (label). Suporta ícones customizados por nó:
|
|
5
|
+
|
|
6
|
+
- `icon` — ícone padrão (nó colapsado e não selecionado)
|
|
7
|
+
- `iconOpen` — ícone quando o nó está **expandido** (fallback para `icon`)
|
|
8
|
+
- `iconSelected` — ícone quando o nó está **selecionado** (fallback para `iconOpen` se expandido, senão `icon`)
|
|
9
|
+
|
|
10
|
+
Prioridade de resolução:
|
|
11
|
+
- Selecionado + Expandido → `iconSelected ?? iconOpen ?? icon`
|
|
12
|
+
- Selecionado + Colapsado → `iconSelected ?? icon`
|
|
13
|
+
- Não selecionado + Expandido → `iconOpen ?? icon`
|
|
14
|
+
- Não selecionado + Colapsado → `icon`
|
|
15
|
+
|
|
16
|
+
A busca preserva e auto-expande o caminho dos ancestrais para os itens encontrados.
|
|
@@ -0,0 +1,31 @@
|
|
|
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-CE0k7Rdh.js";import{C as he}from"./ComponentDocTemplate-CRbRY-v5.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 De(){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{De as AccordionDoc};
|
|
@@ -0,0 +1,47 @@
|
|
|
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-CE0k7Rdh.js";import{C as l}from"./ComponentDocTemplate-CRbRY-v5.js";import{T as u}from"./trash-DveAOiLF.js";function x(){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(u,{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{x as ActionButtonDoc};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import{j as e,aA as a,aB as s,aC as i}from"./index-CE0k7Rdh.js";import{C as r}from"./ComponentDocTemplate-CRbRY-v5.js";function n(){return e.jsx(r,{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(s,{children:"Informação"}),e.jsx(i,{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(s,{children:"Informação"}),e.jsx(i,{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(s,{children:"Atenção"}),e.jsx(i,{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(s,{children:"Erro"}),e.jsxs(i,{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(s,{children:"Sucesso"}),e.jsx(i,{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(s,{children:"Alerta sem ícone"}),e.jsx(i,{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{n as AlertDoc};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import{j as e,c0 as o,I as i,f as s,bZ as a,x as u,P as n,aN as d,a7 as l,ci as c,r as x,B as p}from"./index-CE0k7Rdh.js";import{C as h}from"./ComponentDocTemplate-CRbRY-v5.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 b(){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{b as AppHeaderDoc};
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import{j as e,B as l,f as t,bp as j,P as c,g as I,bx as d,h as b,l as i,cf as n,bG as U,w as D,v as L,c3 as z,a7 as G,G as A,bl as P,F as B,bq as H,r as m,c$ as F,et as k,d0 as p,d1 as x,d2 as u,c5 as q,bJ as W,bR as O}from"./index-CE0k7Rdh.js";import{C as V}from"./ComponentDocTemplate-CRbRY-v5.js";import{P as M,a as E}from"./pin-CMYagNhs.js";const Q=[{icon:d,label:"Visão geral"},{icon:q,label:"Showcase"},{icon:n,label:"Liderança"},{icon:W,label:"Locais"},{icon:L,label:"Gestão",children:[{icon:n,label:"Usuários"},{icon:z,label:"Permissões"}]},{icon:O,label:"Design System"}];function J(){const[a,r]=m.useState(!0),[N,h]=m.useState(!0),[y,g]=m.useState("Visão geral"),[T,R]=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(M,{className:"inline h-3 w-3 mr-1"}):e.jsx(E,{className:"inline h-3 w-3 mr-1"}),N?"Pinada":"Despinada"]})]}),e.jsx(F,{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:k.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:k.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(c,{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(c,{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(I,{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:Q.map(s=>{const w=s.label===y,f="children"in s&&s.children,S=T.includes(s.label),C=()=>{R(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",S&&"rotate-90")})]}),S&&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===y;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(l,{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(l,{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(c,{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(l,{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(I,{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(l,{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(d,{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(l,{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
|
+
│ ├── variant='button' (padrão)
|
|
8
|
+
│ │ ├── Ação única → executa direto
|
|
9
|
+
│ │ └── Múltiplas → dropdown
|
|
10
|
+
│ └── variant='split-button'
|
|
11
|
+
│ ├── Primeira ação → botão principal
|
|
12
|
+
│ └── Demais ações → dropdown
|
|
13
|
+
│
|
|
14
|
+
├── Separator + Pin/Unpin button
|
|
15
|
+
│
|
|
16
|
+
└── SidebarContent
|
|
17
|
+
└── NavigationItems
|
|
18
|
+
├── Item simples (Link)
|
|
19
|
+
├── Item com permissionCheck
|
|
20
|
+
└── Item com children
|
|
21
|
+
└── Collapsible > SidebarMenuSub`})]})]})}function $(){return e.jsx("div",{className:"flex gap-4 items-start flex-wrap",children:[{title:"Ativo",className:"bg-primary/10 text-primary font-medium",icon:d,label:"Início"},{title:"Hover",className:"bg-muted",icon:n,label:"Usuários"},{title:"Desabilitado",className:"opacity-50 cursor-not-allowed border",icon:U,label:"Admin"},{title:"Carregando",className:"opacity-50 border",icon:D,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 X(){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(d,{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(L,{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:n,label:"Perfil",active:!0},{icon:z,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 Y(){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(c,{className:"h-4 w-4"}),"Novo Processo"]}),e.jsx("div",{className:"border-t pt-2 space-y-1",children:[{icon:d,label:"Início",active:!0},{icon:n,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(c,{className:"h-4 w-4"}),"Criar",e.jsx(G,{className:"ml-auto h-4 w-4 rotate-180"})]}),e.jsx("div",{className:"border rounded-md bg-popover p-1 shadow-md",children:[{icon:A,label:"Novo Documento"},{icon:P,label:"Nova Pasta"},{icon:n,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))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm font-medium text-center",children:"Split Button"}),e.jsxs("div",{className:"w-56 bg-background border rounded-lg p-3 space-y-3",children:[e.jsx(B,{label:"Novo Documento",onClick:()=>{},icon:A,variant:"outline",actions:[{id:"folder",label:"Nova Pasta",icon:P,onClick:()=>{}},{id:"group",label:"Novo Grupo",icon:n,onClick:()=>{}}],className:"w-full",menuAlign:"start"}),e.jsx("div",{className:"border-t pt-2 space-y-1",children:[{icon:d,label:"Início",active:!0},{icon:n,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))})]})]})]})}function Z(){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(H,{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
|
|
22
|
+
config={sidebarConfig}
|
|
23
|
+
resizable={true}
|
|
24
|
+
minWidth={224} // padrão: 224px (14rem)
|
|
25
|
+
maxWidth={384} // padrão: 384px (24rem)
|
|
26
|
+
/>`})]})}function _(){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(M,{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(E,{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 ee(){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(l,{variant:a.variant,className:"shrink-0",children:a.badge}),e.jsx("span",{className:"text-sm text-muted-foreground",children:a.text})]},a.badge))})}function re(){return e.jsxs(V,{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(J,{}),usage:`import { AppLayout } from 'forlogic-core';
|
|
27
|
+
import type { SidebarConfig } from 'forlogic-core';
|
|
28
|
+
import { Home, Users, Settings, Shield, Plus, FileText, Folder } from 'lucide-react';
|
|
29
|
+
|
|
30
|
+
const sidebarConfig: SidebarConfig = {
|
|
31
|
+
appName: 'Minha Aplicação',
|
|
32
|
+
|
|
33
|
+
// Ações do módulo (opcional)
|
|
34
|
+
moduleActions: {
|
|
35
|
+
triggerLabel: 'Criar',
|
|
36
|
+
triggerIcon: Plus,
|
|
37
|
+
actions: [
|
|
38
|
+
{ id: 'new-doc', label: 'Novo Documento', icon: FileText, onClick: () => {} },
|
|
39
|
+
{ id: 'new-folder', label: 'Nova Pasta', icon: Folder, onClick: () => {} },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
// Navegação (com suporte a hierarquia)
|
|
44
|
+
navigation: [
|
|
45
|
+
{ label: 'Início', path: '/', icon: Home },
|
|
46
|
+
{ label: 'Usuários', path: '/users', icon: Users },
|
|
47
|
+
{
|
|
48
|
+
label: 'Configurações',
|
|
49
|
+
path: '/settings',
|
|
50
|
+
icon: Settings,
|
|
51
|
+
children: [
|
|
52
|
+
{ label: 'Perfil', path: '/settings/profile', icon: Users },
|
|
53
|
+
{ label: 'Segurança', path: '/settings/security', icon: Shield },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Uso via AppLayout (recomendado)
|
|
60
|
+
<AppLayout sidebarConfig={sidebarConfig}>
|
|
61
|
+
<Routes>...</Routes>
|
|
62
|
+
</AppLayout>
|
|
63
|
+
|
|
64
|
+
// Uso direto (casos avançados)
|
|
65
|
+
<AppSidebar
|
|
66
|
+
config={sidebarConfig}
|
|
67
|
+
resizable={true}
|
|
68
|
+
minWidth={224}
|
|
69
|
+
maxWidth={384}
|
|
70
|
+
/>`,tocItems:[{id:"tipos-typescript",label:"Tipos TypeScript"},{id:"componente-base",label:"Componente Base: Sidebar"}],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
|
|
71
|
+
<Sidebar collapsible="icon">
|
|
72
|
+
├── SidebarHeader (Logo + ModulesButton)
|
|
73
|
+
├── SidebarActionTrigger (ações de módulo)
|
|
74
|
+
├── Separator + Pin/Unpin button (borda)
|
|
75
|
+
└── SidebarContent
|
|
76
|
+
└── NavigationItems
|
|
77
|
+
├── Item simples (Link)
|
|
78
|
+
├── Item com permissionCheck
|
|
79
|
+
└── Item com children (Collapsible)
|
|
80
|
+
└── 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($,{}),code:`// Matching de rota ativa (hierárquico)
|
|
81
|
+
const isActive = (path: string) =>
|
|
82
|
+
location.pathname === path ||
|
|
83
|
+
location.pathname.startsWith(path + '/');
|
|
84
|
+
|
|
85
|
+
// Item com verificação de permissão assíncrona
|
|
86
|
+
{
|
|
87
|
+
label: 'Gestão',
|
|
88
|
+
path: '/management',
|
|
89
|
+
icon: Settings,
|
|
90
|
+
permissionCheck: async () => {
|
|
91
|
+
return await checkUserPermission('management');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// → Exibe Loader2 (spin) enquanto verifica
|
|
95
|
+
// → 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(X,{}),code:`const navigation: SidebarNavigationItem[] = [
|
|
96
|
+
{ label: 'Início', path: '/', icon: Home },
|
|
97
|
+
{
|
|
98
|
+
label: 'Configurações',
|
|
99
|
+
path: '/settings',
|
|
100
|
+
icon: Settings,
|
|
101
|
+
children: [
|
|
102
|
+
{ label: 'Perfil', path: '/settings/profile', icon: Users },
|
|
103
|
+
{ label: 'Segurança', path: '/settings/security', icon: Shield },
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
];`},{title:"Ações de Módulo (SidebarActionTrigger)",description:'Suporta duas variantes: "button" (padrão) com ação direta ou dropdown, e "split-button" com ação principal + dropdown de ações secundárias. No modo colapsado, ambas exibem ícone com tooltip.',preview:e.jsx(Y,{}),code:`// variant='button' (padrão) — ação única ou dropdown
|
|
107
|
+
moduleActions: {
|
|
108
|
+
triggerLabel: 'Criar',
|
|
109
|
+
triggerIcon: Plus,
|
|
110
|
+
actions: [
|
|
111
|
+
{ id: 'new-doc', label: 'Novo Documento', icon: FileText, onClick: handleNewDoc },
|
|
112
|
+
{ id: 'new-folder', label: 'Nova Pasta', icon: Folder, onClick: handleNewFolder },
|
|
113
|
+
],
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// variant='split-button' — primeira ação = botão principal, demais = dropdown
|
|
117
|
+
moduleActions: {
|
|
118
|
+
variant: 'split-button',
|
|
119
|
+
actions: [
|
|
120
|
+
{ id: 'new-doc', label: 'Novo Documento', icon: FileText, onClick: handleNewDoc },
|
|
121
|
+
{ id: 'new-folder', label: 'Nova Pasta', icon: Folder, onClick: handleNewFolder },
|
|
122
|
+
{ id: 'import', label: 'Importar', icon: Upload, onClick: handleImport },
|
|
123
|
+
],
|
|
124
|
+
}`},{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(_,{}),code:`// Internamente o AppSidebar usa:
|
|
125
|
+
import { getSidebarPinnedPreference, setSidebarPinnedPreference }
|
|
126
|
+
from './sidebar-utils';
|
|
127
|
+
|
|
128
|
+
// Persistência em localStorage ('forlogic-sidebar-pinned')
|
|
129
|
+
// Botão circular usa bg-primary com ChevronLeft/Right
|
|
130
|
+
// 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(Z,{}),code:`// useSidebarResize hook
|
|
131
|
+
import { useSidebarResize } from 'forlogic-core';
|
|
132
|
+
|
|
133
|
+
const resize = useSidebarResize({
|
|
134
|
+
minWidth: 224, // Mínimo (14rem)
|
|
135
|
+
maxWidth: 384, // Máximo (24rem)
|
|
136
|
+
defaultWidth: 240, // Padrão (15rem)
|
|
137
|
+
storageKey: 'app-sidebar-width',
|
|
138
|
+
isOpen: true,
|
|
139
|
+
onResize: (width) => console.log(width),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// resize.width, resize.isDragging,
|
|
143
|
+
// resize.dragRef, resize.handleMouseDown`},{title:"Comportamento Responsivo",description:"A sidebar adapta-se automaticamente ao tamanho da tela.",preview:e.jsx(ee,{}),code:`// O AppSidebar usa collapsible="icon"
|
|
144
|
+
// Em desktop: colapsa para 16px (ícones apenas)
|
|
145
|
+
// Em mobile: comportamento de drawer
|
|
146
|
+
|
|
147
|
+
// useSidebar() hook disponível para controle externo
|
|
148
|
+
import { useSidebar } from 'forlogic-core';
|
|
149
|
+
|
|
150
|
+
const { open, setOpen, state, toggleSidebar } = useSidebar();
|
|
151
|
+
// 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"],children:[e.jsxs("div",{id:"tipos-typescript",className:"space-y-6 scroll-mt-4",children:[e.jsx("h2",{className:"text-2xl font-semibold tracking-tight border-b pb-2",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 {
|
|
152
|
+
appName?: string;
|
|
153
|
+
navigation?: SidebarNavigationItem[];
|
|
154
|
+
moduleActions?: SidebarActionsConfig;
|
|
155
|
+
}`})]}),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 {
|
|
156
|
+
label: string; // Texto do item
|
|
157
|
+
path: string; // Rota de navegação
|
|
158
|
+
icon: LucideIcon; // Ícone obrigatório
|
|
159
|
+
complementaryText?: string; // Texto complementar
|
|
160
|
+
permissionCheck?: () => Promise<boolean>; // Verificação assíncrona
|
|
161
|
+
children?: SidebarNavigationItem[]; // Subitens (máx. 2 níveis)
|
|
162
|
+
}`})]}),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 {
|
|
163
|
+
triggerLabel?: string; // Rótulo do gatilho (default: 'Criar')
|
|
164
|
+
triggerIcon?: LucideIcon; // Ícone do gatilho (default: Plus)
|
|
165
|
+
actions: SidebarModuleAction[];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
interface SidebarModuleAction {
|
|
169
|
+
id: string; // ID único
|
|
170
|
+
label: string; // Texto exibido
|
|
171
|
+
icon?: LucideIcon; // Ícone opcional
|
|
172
|
+
onClick: () => void; // Callback
|
|
173
|
+
disabled?: boolean; // Desabilitar ação
|
|
174
|
+
permissionCheck?: () => Promise<boolean>; // Verificação de permissão
|
|
175
|
+
}`})]})]}),e.jsxs("div",{id:"componente-base",className:"space-y-6 scroll-mt-4",children:[e.jsx("h2",{className:"text-2xl font-semibold tracking-tight border-b pb-2",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 {
|
|
176
|
+
Sidebar, SidebarProvider, SidebarHeader, SidebarContent,
|
|
177
|
+
SidebarFooter, SidebarGroup, SidebarGroupLabel,
|
|
178
|
+
SidebarGroupContent, SidebarMenu, SidebarMenuItem,
|
|
179
|
+
SidebarMenuButton, SidebarTrigger,
|
|
180
|
+
} from 'forlogic-core';
|
|
181
|
+
|
|
182
|
+
<SidebarProvider>
|
|
183
|
+
<Sidebar collapsible="icon">
|
|
184
|
+
<SidebarHeader>Logo</SidebarHeader>
|
|
185
|
+
<SidebarContent>
|
|
186
|
+
<SidebarGroup>
|
|
187
|
+
<SidebarGroupLabel>Menu</SidebarGroupLabel>
|
|
188
|
+
<SidebarGroupContent>
|
|
189
|
+
<SidebarMenu>
|
|
190
|
+
<SidebarMenuItem>
|
|
191
|
+
<SidebarMenuButton isActive>
|
|
192
|
+
<Home className="mr-2" /> Home
|
|
193
|
+
</SidebarMenuButton>
|
|
194
|
+
</SidebarMenuItem>
|
|
195
|
+
</SidebarMenu>
|
|
196
|
+
</SidebarGroupContent>
|
|
197
|
+
</SidebarGroup>
|
|
198
|
+
</SidebarContent>
|
|
199
|
+
</Sidebar>
|
|
200
|
+
<main>
|
|
201
|
+
<SidebarTrigger />
|
|
202
|
+
{/* Content */}
|
|
203
|
+
</main>
|
|
204
|
+
</SidebarProvider>`})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:"Props do Sidebar Base"}),e.jsx("div",{className:"rounded-lg border",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b bg-muted/50",children:[e.jsx("th",{className:"px-4 py-3 text-left text-sm font-semibold",children:"Prop"}),e.jsx("th",{className:"px-4 py-3 text-left text-sm font-semibold",children:"Tipo"}),e.jsx("th",{className:"px-4 py-3 text-left text-sm font-semibold",children:"Padrão"}),e.jsx("th",{className:"px-4 py-3 text-left text-sm font-semibold",children:"Descrição"})]})}),e.jsxs("tbody",{children:[e.jsxs("tr",{className:"border-b",children:[e.jsx("td",{className:"px-4 py-3 font-mono text-sm font-medium",children:"side"}),e.jsx("td",{className:"px-4 py-3 font-mono text-sm text-muted-foreground",children:'"left" | "right"'}),e.jsx("td",{className:"px-4 py-3 font-mono text-sm text-muted-foreground",children:'"left"'}),e.jsx("td",{className:"px-4 py-3 text-sm",children:"Lado da tela"})]}),e.jsxs("tr",{className:"border-b",children:[e.jsx("td",{className:"px-4 py-3 font-mono text-sm font-medium",children:"variant"}),e.jsx("td",{className:"px-4 py-3 font-mono text-sm text-muted-foreground",children:'"sidebar" | "floating" | "inset"'}),e.jsx("td",{className:"px-4 py-3 font-mono text-sm text-muted-foreground",children:'"sidebar"'}),e.jsx("td",{className:"px-4 py-3 text-sm",children:"Estilo visual"})]}),e.jsxs("tr",{className:"border-b last:border-0",children:[e.jsx("td",{className:"px-4 py-3 font-mono text-sm font-medium",children:"collapsible"}),e.jsx("td",{className:"px-4 py-3 font-mono text-sm text-muted-foreground",children:'"offcanvas" | "icon" | "none"'}),e.jsx("td",{className:"px-4 py-3 font-mono text-sm text-muted-foreground",children:'"offcanvas"'}),e.jsx("td",{className:"px-4 py-3 text-sm",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{re as AppSidebarDoc};
|