[{"data":1,"prerenderedAt":1532},["ShallowReactive",2],{"navigation":3,"\u002Fguides\u002Falternative-ui-variants":342,"\u002Fguides\u002Falternative-ui-variants-surround":1527},[4,14,36,69,140,325],{"title":5,"path":6,"stem":7,"children":8},"Introduction","\u002Fgetting-started","1.getting-started\u002F1.index",[9,10],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation",{"title":15,"path":16,"stem":17,"children":18,"page":35},"Guides","\u002Fguides","2.guides",[19,23,27,31],{"title":20,"path":21,"stem":22},"Your First Layout","\u002Fguides\u002Fyour-first-layout","2.guides\u002F1.your-first-layout",{"title":24,"path":25,"stem":26},"Your First Page Template","\u002Fguides\u002Fyour-first-page-template","2.guides\u002F2.your-first-page-template",{"title":28,"path":29,"stem":30},"Your First Component","\u002Fguides\u002Fyour-first-component","2.guides\u002F3.your-first-component",{"title":32,"path":33,"stem":34},"Alternative UI Variants","\u002Fguides\u002Falternative-ui-variants","2.guides\u002F4.alternative-ui-variants",false,{"title":37,"path":38,"stem":39,"children":40,"page":35},"Core Concepts","\u002Fcore-concepts","3.core-concepts",[41,45,49,53,57,61,65],{"title":42,"path":43,"stem":44},"How It All Works","\u002Fcore-concepts\u002Farchitecture","3.core-concepts\u002F1.architecture",{"title":46,"path":47,"stem":48},"The Data Model","\u002Fcore-concepts\u002Fthe-data-model","3.core-concepts\u002F2.the-data-model",{"title":50,"path":51,"stem":52},"Layouts & Pages","\u002Fcore-concepts\u002Flayouts-and-pages","3.core-concepts\u002F3.layouts-and-pages",{"title":54,"path":55,"stem":56},"Dynamic Pages","\u002Fcore-concepts\u002Fdynamic-pages","3.core-concepts\u002F4.dynamic-pages",{"title":58,"path":59,"stem":60},"Components","\u002Fcore-concepts\u002Fcomponents","3.core-concepts\u002F5.components",{"title":62,"path":63,"stem":64},"Draft & Publish Workflow","\u002Fcore-concepts\u002Fdraft-and-publish","3.core-concepts\u002F6.draft-and-publish",{"title":66,"path":67,"stem":68},"The Admin Panel","\u002Fcore-concepts\u002Fadmin-panel","3.core-concepts\u002F7.admin-panel",{"title":70,"path":71,"stem":72,"children":73,"page":35},"Api","\u002Fapi","4.api",[74,78,116,120,124,128,132,136],{"title":75,"path":76,"stem":77},"Bundle Setup","\u002Fapi\u002Fbundle-setup","4.api\u002F1.bundle-setup",{"title":58,"path":79,"stem":80,"children":81,"page":35},"\u002Fapi\u002Fcomponents","4.api\u002F2.components",[82,86,103],{"title":83,"path":84,"stem":85},"Creating Components","\u002Fapi\u002Fcomponents\u002Fcreating-components","4.api\u002F2.components\u002F1.creating-components",{"title":87,"path":88,"stem":89,"children":90,"page":35},"Annotations","\u002Fapi\u002Fcomponents\u002Fannotations","4.api\u002F2.components\u002F2.annotations",[91,95,99],{"title":92,"path":93,"stem":94},"Publishable","\u002Fapi\u002Fcomponents\u002Fannotations\u002Fpublishable","4.api\u002F2.components\u002F2.annotations\u002F1.publishable",{"title":96,"path":97,"stem":98},"Uploadable","\u002Fapi\u002Fcomponents\u002Fannotations\u002Fuploadable","4.api\u002F2.components\u002F2.annotations\u002F2.uploadable",{"title":100,"path":101,"stem":102},"Timestamped","\u002Fapi\u002Fcomponents\u002Fannotations\u002Ftimestamped","4.api\u002F2.components\u002F2.annotations\u002F3.timestamped",{"title":104,"path":105,"stem":106,"children":107,"page":35},"Built Ins","\u002Fapi\u002Fcomponents\u002Fbuilt-ins","4.api\u002F2.components\u002F3.built-ins",[108,112],{"title":109,"path":110,"stem":111},"Collection Component","\u002Fapi\u002Fcomponents\u002Fbuilt-ins\u002Fcollection-component","4.api\u002F2.components\u002F3.built-ins\u002F1.collection-component",{"title":113,"path":114,"stem":115},"Form Component","\u002Fapi\u002Fcomponents\u002Fbuilt-ins\u002Fform-component","4.api\u002F2.components\u002F3.built-ins\u002F2.form-component",{"title":117,"path":118,"stem":119},"Dynamic & Nested Pages","\u002Fapi\u002Fdynamic-pages","4.api\u002F3.dynamic-pages",{"title":121,"path":122,"stem":123},"Users & Security","\u002Fapi\u002Fusers-and-security","4.api\u002F4.users-and-security",{"title":125,"path":126,"stem":127},"Data Fixtures","\u002Fapi\u002Fdata-fixtures","4.api\u002F5.data-fixtures",{"title":129,"path":130,"stem":131},"Configuration Reference","\u002Fapi\u002Fconfiguration","4.api\u002F6.configuration",{"title":133,"path":134,"stem":135},"Console Commands","\u002Fapi\u002Fconsole-commands","4.api\u002F7.console-commands",{"title":137,"path":138,"stem":139},"Debugging & Profiler","\u002Fapi\u002Fdebugging","4.api\u002F8.debugging",{"title":141,"path":142,"stem":143,"children":144,"page":35},"Nuxt Module","\u002Fnuxt-module","5.nuxt-module",[145,149,162,178,203,207,279,304,308],{"title":146,"path":147,"stem":148},"Module Setup","\u002Fnuxt-module\u002Fmodule-setup","5.nuxt-module\u002F1.module-setup",{"title":150,"path":151,"stem":152,"children":153,"page":35},"Configuration","\u002Fnuxt-module\u002Fconfiguration","5.nuxt-module\u002F2.configuration",[154,158],{"title":155,"path":156,"stem":157},"Nuxt Config","\u002Fnuxt-module\u002Fconfiguration\u002Fnuxt-config","5.nuxt-module\u002F2.configuration\u002F1.nuxt-config",{"title":159,"path":160,"stem":161},"Site Config & SEO","\u002Fnuxt-module\u002Fconfiguration\u002Fsite-config-and-seo","5.nuxt-module\u002F2.configuration\u002F2.site-config-and-seo",{"title":163,"path":164,"stem":165,"children":166,"page":35},"Building Your Ui","\u002Fnuxt-module\u002Fbuilding-your-ui","5.nuxt-module\u002F3.building-your-ui",[167,171,175],{"title":168,"path":169,"stem":170},"Layouts","\u002Fnuxt-module\u002Fbuilding-your-ui\u002Fcreating-layouts","5.nuxt-module\u002F3.building-your-ui\u002F1.creating-layouts",{"title":172,"path":173,"stem":174},"Page Templates","\u002Fnuxt-module\u002Fbuilding-your-ui\u002Fcreating-page-templates","5.nuxt-module\u002F3.building-your-ui\u002F2.creating-page-templates",{"title":83,"path":176,"stem":177},"\u002Fnuxt-module\u002Fbuilding-your-ui\u002Fcreating-components","5.nuxt-module\u002F3.building-your-ui\u002F3.creating-components",{"title":179,"path":180,"stem":181,"children":182,"page":35},"Cwa Components","\u002Fnuxt-module\u002Fcwa-components","5.nuxt-module\u002F4.cwa-components",[183,187,191,195,199],{"title":184,"path":185,"stem":186},"\u003CCwaComponentGroup \u002F>","\u002Fnuxt-module\u002Fcwa-components\u002Fcwa-component-group","5.nuxt-module\u002F4.cwa-components\u002F1.cwa-component-group",{"title":188,"path":189,"stem":190},"\u003CCwaPage \u002F>","\u002Fnuxt-module\u002Fcwa-components\u002Fcwa-page","5.nuxt-module\u002F4.cwa-components\u002F2.cwa-page",{"title":192,"path":193,"stem":194},"\u003CCwaLink \u002F>","\u002Fnuxt-module\u002Fcwa-components\u002Fcwa-link","5.nuxt-module\u002F4.cwa-components\u002F3.cwa-link",{"title":196,"path":197,"stem":198},"\u003CCwaImage \u002F>","\u002Fnuxt-module\u002Fcwa-components\u002Fcwa-image","5.nuxt-module\u002F4.cwa-components\u002F4.cwa-image",{"title":200,"path":201,"stem":202},"\u003CCwaDefaultLayout \u002F>","\u002Fnuxt-module\u002Fcwa-components\u002Fcwa-default-layout","5.nuxt-module\u002F4.cwa-components\u002F5.cwa-default-layout",{"title":204,"path":205,"stem":206},"The useCwa() API","\u002Fnuxt-module\u002Fcwa-api","5.nuxt-module\u002F5.cwa-api",{"title":208,"path":209,"stem":210,"children":211,"page":35},"Composables","\u002Fnuxt-module\u002Fcomposables","5.nuxt-module\u002F6.composables",[212,245,262],{"title":213,"path":214,"stem":215,"children":216,"page":35},"Component","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent","5.nuxt-module\u002F6.composables\u002F1.component",[217,221,225,229,233,237,241],{"title":218,"path":219,"stem":220},"Resource","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-resource","5.nuxt-module\u002F6.composables\u002F1.component\u002F1.use-cwa-resource",{"title":222,"path":223,"stem":224},"Collection Resource","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-collection-resource","5.nuxt-module\u002F6.composables\u002F1.component\u002F2.use-cwa-collection-resource",{"title":226,"path":227,"stem":228},"Image Resource","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-image-resource","5.nuxt-module\u002F6.composables\u002F1.component\u002F3.use-cwa-image-resource",{"title":230,"path":231,"stem":232},"Form","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-form","5.nuxt-module\u002F6.composables\u002F1.component\u002F4.use-cwa-form",{"title":234,"path":235,"stem":236},"Form Input","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-form-input","5.nuxt-module\u002F6.composables\u002F1.component\u002F5.use-cwa-form-input",{"title":238,"path":239,"stem":240},"Form Repeated","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-form-repeated","5.nuxt-module\u002F6.composables\u002F1.component\u002F6.use-cwa-form-repeated",{"title":242,"path":243,"stem":244},"Form Collection","\u002Fnuxt-module\u002Fcomposables\u002Fcomponent\u002Fuse-cwa-form-collection","5.nuxt-module\u002F6.composables\u002F1.component\u002F7.use-cwa-form-collection",{"title":246,"path":247,"stem":248,"children":249,"page":35},"Admin Manager","\u002Fnuxt-module\u002Fcomposables\u002Fadmin-manager","5.nuxt-module\u002F6.composables\u002F2.admin-manager",[250,254,258],{"title":251,"path":252,"stem":253},"Manager Tab","\u002Fnuxt-module\u002Fcomposables\u002Fadmin-manager\u002Fuse-cwa-resource-manager-tab","5.nuxt-module\u002F6.composables\u002F2.admin-manager\u002F1.use-cwa-resource-manager-tab",{"title":255,"path":256,"stem":257},"Resource Model","\u002Fnuxt-module\u002Fcomposables\u002Fadmin-manager\u002Fuse-cwa-resource-model","5.nuxt-module\u002F6.composables\u002F2.admin-manager\u002F2.use-cwa-resource-model",{"title":259,"path":260,"stem":261},"Resource Upload","\u002Fnuxt-module\u002Fcomposables\u002Fadmin-manager\u002Fuse-cwa-resource-upload","5.nuxt-module\u002F6.composables\u002F2.admin-manager\u002F3.use-cwa-resource-upload",{"title":263,"path":264,"stem":265,"children":266,"page":35},"Utilities","\u002Fnuxt-module\u002Fcomposables\u002Futilities","5.nuxt-module\u002F6.composables\u002F3.utilities",[267,271,275],{"title":268,"path":269,"stem":270},"Resource Endpoint","\u002Fnuxt-module\u002Fcomposables\u002Futilities\u002Fuse-cwa-resource-endpoint","5.nuxt-module\u002F6.composables\u002F3.utilities\u002F1.use-cwa-resource-endpoint",{"title":272,"path":273,"stem":274},"Query Model","\u002Fnuxt-module\u002Fcomposables\u002Futilities\u002Fuse-query-bound-model","5.nuxt-module\u002F6.composables\u002F3.utilities\u002F2.use-query-bound-model",{"title":276,"path":277,"stem":278},"Resource Route","\u002Fnuxt-module\u002Fcomposables\u002Futilities\u002Fuse-cwa-resource-route","5.nuxt-module\u002F6.composables\u002F3.utilities\u002F3.use-cwa-resource-route",{"title":280,"path":281,"stem":282,"children":283,"page":35},"Component Helpers","\u002Fnuxt-module\u002Fcomponent-helpers","5.nuxt-module\u002F7.component-helpers",[284,288,292,296,300],{"title":285,"path":286,"stem":287},"Images & Media","\u002Fnuxt-module\u002Fcomponent-helpers\u002Fimages-and-uploads","5.nuxt-module\u002F7.component-helpers\u002F1.images-and-uploads",{"title":289,"path":290,"stem":291},"Collections & Pagination","\u002Fnuxt-module\u002Fcomponent-helpers\u002Fcollections-and-pagination","5.nuxt-module\u002F7.component-helpers\u002F2.collections-and-pagination",{"title":293,"path":294,"stem":295},"HTML Content","\u002Fnuxt-module\u002Fcomponent-helpers\u002Fhtml-content","5.nuxt-module\u002F7.component-helpers\u002F3.html-content",{"title":297,"path":298,"stem":299},"Real-Time Updates","\u002Fnuxt-module\u002Fcomponent-helpers\u002Freal-time-updates","5.nuxt-module\u002F7.component-helpers\u002F4.real-time-updates",{"title":301,"path":302,"stem":303},"Forms","\u002Fnuxt-module\u002Fcomponent-helpers\u002Fforms","5.nuxt-module\u002F7.component-helpers\u002F5.forms",{"title":305,"path":306,"stem":307},"Authentication","\u002Fnuxt-module\u002Fauthentication","5.nuxt-module\u002F8.authentication",{"title":309,"path":310,"stem":311,"children":312,"page":35},"Cwa Layer","\u002Fnuxt-module\u002Fcwa-layer","5.nuxt-module\u002F9.cwa-layer",[313,317,321],{"title":314,"path":315,"stem":316},"Overview","\u002Fnuxt-module\u002Fcwa-layer\u002Foverview","5.nuxt-module\u002F9.cwa-layer\u002F1.overview",{"title":318,"path":319,"stem":320},"Auth Pages","\u002Fnuxt-module\u002Fcwa-layer\u002Fauth-pages","5.nuxt-module\u002F9.cwa-layer\u002F2.auth-pages",{"title":322,"path":323,"stem":324},"Admin Panel","\u002Fnuxt-module\u002Fcwa-layer\u002Fadmin-panel","5.nuxt-module\u002F9.cwa-layer\u002F3.admin-panel",{"title":326,"path":327,"stem":328,"children":329,"page":35},"Deployment","\u002Fdeployment","6.deployment",[330,334,338],{"title":331,"path":332,"stem":333},"Docker","\u002Fdeployment\u002Fdocker","6.deployment\u002F1.docker",{"title":335,"path":336,"stem":337},"Kubernetes & Helm","\u002Fdeployment\u002Fkubernetes","6.deployment\u002F2.kubernetes",{"title":339,"path":340,"stem":341},"CI\u002FCD","\u002Fdeployment\u002Fci-cd","6.deployment\u002F3.ci-cd",{"id":343,"title":32,"badge":344,"body":347,"description":1521,"extension":1522,"links":1523,"meta":1524,"navigation":523,"path":33,"seo":1525,"stem":34,"__hash__":1526},"docs\u002F2.guides\u002F4.alternative-ui-variants.md",{"label":345,"color":346},"Draft","amber",{"type":348,"value":349,"toc":1507},"minimark",[350,367,379,382,387,394,951,956,972,988,999,1006,1010,1017,1098,1118,1120,1127,1133,1138,1145,1407,1425,1434,1443,1452,1454,1458,1464,1486,1494,1503],[351,352,353,354,358,359,362,363,366],"p",{},"The same component data can render in multiple visual ways. A ",[355,356,357],"code",{},"NavigationLink"," might be a plain text link, a filled button, or a YouTube icon — all backed by the same ",[355,360,361],{},"label"," and ",[355,364,365],{},"url"," fields. An admin picks the variant from the manager panel.",[351,368,369,370,374,375,378],{},"There are two approaches. Use ",[371,372,373],"strong",{},"style classes"," for variations that are purely CSS differences. Use ",[371,376,377],{},"UI templates"," for variations that need fundamentally different markup.",[380,381],"hr",{},[383,384,386],"h2",{"id":385},"approach-1-style-classes","Approach 1: Style Classes",[351,388,389,390,393],{},"Define named class sets in ",[355,391,392],{},"useCwaResource",". An admin can select one of these styles from the manager panel.",[395,396,401],"pre",{"className":397,"code":398,"language":399,"meta":400,"style":400},"language-vue shiki shiki-themes github-light github-dark material-theme-palenight","\u003Cscript setup lang=\"ts\">\nimport { toRef, computed } from 'vue'\nimport type { IriProp } from '#cwa\u002Fcomposables\u002Fcwa-resource'\nimport { useCwaResource } from '#imports'\n\nconst props = defineProps\u003CIriProp>()\n\nconst { getResource, exposeMeta, getCurrentStyleName } = useCwaResource(toRef(props, 'iri'), {\n  styles: {\n    multiple: false,\n    classes: {\n      'Default': [],\n      'Filled Button': ['bg-blue-600 text-white px-6 py-2 rounded-md'],\n      'Outlined Button': ['border border-blue-600 text-blue-600 px-6 py-2 rounded-md'],\n    }\n  }\n})\n\nconst resource = getResource()\nconst currentStyleName = computed(() => {\n  if (!resource.value?.data) return 'Default'\n  return getCurrentStyleName(resource.value.data)\n})\n\ndefineExpose(exposeMeta)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Ca :href=\"resource?.data?.url || '#'\" :class=\"resource?.data?.uiClassNames\">\n    {{ resource?.data?.label }}\n  \u003C\u002Fa>\n\u003C\u002Ftemplate>\n","vue","",[355,402,403,439,473,497,518,525,556,561,614,626,641,651,670,697,722,728,734,743,748,762,784,823,845,852,857,866,876,881,891,926,932,942],{"__ignoreMap":400},[404,405,408,412,416,420,423,426,430,434,436],"span",{"class":406,"line":407},"line",1,[404,409,411],{"class":410},"sOvfz","\u003C",[404,413,415],{"class":414},"s-h7I","script",[404,417,419],{"class":418},"sGtlX"," setup",[404,421,422],{"class":418}," lang",[404,424,425],{"class":410},"=",[404,427,429],{"class":428},"seSrl","\"",[404,431,433],{"class":432},"sLL54","ts",[404,435,429],{"class":428},[404,437,438],{"class":410},">\n",[404,440,442,446,449,453,456,459,462,465,468,470],{"class":406,"line":441},2,[404,443,445],{"class":444},"sm4w6","import",[404,447,448],{"class":410}," {",[404,450,452],{"class":451},"sPB8G"," toRef",[404,454,455],{"class":410},",",[404,457,458],{"class":451}," computed",[404,460,461],{"class":410}," }",[404,463,464],{"class":444}," from",[404,466,467],{"class":428}," '",[404,469,399],{"class":432},[404,471,472],{"class":428},"'\n",[404,474,476,478,481,483,486,488,490,492,495],{"class":406,"line":475},3,[404,477,445],{"class":444},[404,479,480],{"class":444}," type",[404,482,448],{"class":410},[404,484,485],{"class":451}," IriProp",[404,487,461],{"class":410},[404,489,464],{"class":444},[404,491,467],{"class":428},[404,493,494],{"class":432},"#cwa\u002Fcomposables\u002Fcwa-resource",[404,496,472],{"class":428},[404,498,500,502,504,507,509,511,513,516],{"class":406,"line":499},4,[404,501,445],{"class":444},[404,503,448],{"class":410},[404,505,506],{"class":451}," useCwaResource",[404,508,461],{"class":410},[404,510,464],{"class":444},[404,512,467],{"class":428},[404,514,515],{"class":432},"#imports",[404,517,472],{"class":428},[404,519,521],{"class":406,"line":520},5,[404,522,524],{"emptyLinePlaceholder":523},true,"\n",[404,526,528,532,536,540,544,546,550,553],{"class":406,"line":527},6,[404,529,531],{"class":530},"swB56","const",[404,533,535],{"class":534},"sc2zw"," props",[404,537,539],{"class":538},"sVlFx"," =",[404,541,543],{"class":542},"sKpYG"," defineProps",[404,545,411],{"class":410},[404,547,549],{"class":548},"sRCss","IriProp",[404,551,552],{"class":410},">",[404,554,555],{"class":451},"()\n",[404,557,559],{"class":406,"line":558},7,[404,560,524],{"emptyLinePlaceholder":523},[404,562,564,566,568,571,573,576,578,581,583,585,587,590,593,596,598,600,603,606,609,611],{"class":406,"line":563},8,[404,565,531],{"class":530},[404,567,448],{"class":410},[404,569,570],{"class":534}," getResource",[404,572,455],{"class":410},[404,574,575],{"class":534}," exposeMeta",[404,577,455],{"class":410},[404,579,580],{"class":534}," getCurrentStyleName",[404,582,461],{"class":410},[404,584,539],{"class":538},[404,586,506],{"class":542},[404,588,589],{"class":451},"(",[404,591,592],{"class":542},"toRef",[404,594,595],{"class":451},"(props",[404,597,455],{"class":410},[404,599,467],{"class":428},[404,601,602],{"class":432},"iri",[404,604,605],{"class":428},"'",[404,607,608],{"class":451},")",[404,610,455],{"class":410},[404,612,613],{"class":410}," {\n",[404,615,617,621,624],{"class":406,"line":616},9,[404,618,620],{"class":619},"sDHlG","  styles",[404,622,623],{"class":410},":",[404,625,613],{"class":410},[404,627,629,632,634,638],{"class":406,"line":628},10,[404,630,631],{"class":619},"    multiple",[404,633,623],{"class":410},[404,635,637],{"class":636},"swWMF"," false",[404,639,640],{"class":410},",\n",[404,642,644,647,649],{"class":406,"line":643},11,[404,645,646],{"class":619},"    classes",[404,648,623],{"class":410},[404,650,613],{"class":410},[404,652,654,657,661,663,665,668],{"class":406,"line":653},12,[404,655,656],{"class":428},"      '",[404,658,660],{"class":659},"syBAL","Default",[404,662,605],{"class":428},[404,664,623],{"class":410},[404,666,667],{"class":451}," []",[404,669,640],{"class":410},[404,671,673,675,678,680,682,685,687,690,692,695],{"class":406,"line":672},13,[404,674,656],{"class":428},[404,676,677],{"class":659},"Filled Button",[404,679,605],{"class":428},[404,681,623],{"class":410},[404,683,684],{"class":451}," [",[404,686,605],{"class":428},[404,688,689],{"class":432},"bg-blue-600 text-white px-6 py-2 rounded-md",[404,691,605],{"class":428},[404,693,694],{"class":451},"]",[404,696,640],{"class":410},[404,698,700,702,705,707,709,711,713,716,718,720],{"class":406,"line":699},14,[404,701,656],{"class":428},[404,703,704],{"class":659},"Outlined Button",[404,706,605],{"class":428},[404,708,623],{"class":410},[404,710,684],{"class":451},[404,712,605],{"class":428},[404,714,715],{"class":432},"border border-blue-600 text-blue-600 px-6 py-2 rounded-md",[404,717,605],{"class":428},[404,719,694],{"class":451},[404,721,640],{"class":410},[404,723,725],{"class":406,"line":724},15,[404,726,727],{"class":410},"    }\n",[404,729,731],{"class":406,"line":730},16,[404,732,733],{"class":410},"  }\n",[404,735,737,740],{"class":406,"line":736},17,[404,738,739],{"class":410},"}",[404,741,742],{"class":451},")\n",[404,744,746],{"class":406,"line":745},18,[404,747,524],{"emptyLinePlaceholder":523},[404,749,751,753,756,758,760],{"class":406,"line":750},19,[404,752,531],{"class":530},[404,754,755],{"class":534}," resource",[404,757,539],{"class":538},[404,759,570],{"class":542},[404,761,555],{"class":451},[404,763,765,767,770,772,774,776,779,782],{"class":406,"line":764},20,[404,766,531],{"class":530},[404,768,769],{"class":534}," currentStyleName",[404,771,539],{"class":538},[404,773,458],{"class":542},[404,775,589],{"class":451},[404,777,778],{"class":410},"()",[404,780,781],{"class":530}," =>",[404,783,613],{"class":410},[404,785,787,790,793,796,799,802,805,808,811,814,817,819,821],{"class":406,"line":786},21,[404,788,789],{"class":444},"  if",[404,791,792],{"class":619}," (",[404,794,795],{"class":538},"!",[404,797,798],{"class":451},"resource",[404,800,801],{"class":410},".",[404,803,804],{"class":451},"value",[404,806,807],{"class":410},"?.",[404,809,810],{"class":451},"data",[404,812,813],{"class":619},") ",[404,815,816],{"class":444},"return",[404,818,467],{"class":428},[404,820,660],{"class":432},[404,822,472],{"class":428},[404,824,826,829,831,833,835,837,839,841,843],{"class":406,"line":825},22,[404,827,828],{"class":444},"  return",[404,830,580],{"class":542},[404,832,589],{"class":619},[404,834,798],{"class":451},[404,836,801],{"class":410},[404,838,804],{"class":451},[404,840,801],{"class":410},[404,842,810],{"class":451},[404,844,742],{"class":619},[404,846,848,850],{"class":406,"line":847},23,[404,849,739],{"class":410},[404,851,742],{"class":451},[404,853,855],{"class":406,"line":854},24,[404,856,524],{"emptyLinePlaceholder":523},[404,858,860,863],{"class":406,"line":859},25,[404,861,862],{"class":542},"defineExpose",[404,864,865],{"class":451},"(exposeMeta)\n",[404,867,869,872,874],{"class":406,"line":868},26,[404,870,871],{"class":410},"\u003C\u002F",[404,873,415],{"class":414},[404,875,438],{"class":410},[404,877,879],{"class":406,"line":878},27,[404,880,524],{"emptyLinePlaceholder":523},[404,882,884,886,889],{"class":406,"line":883},28,[404,885,411],{"class":410},[404,887,888],{"class":414},"template",[404,890,438],{"class":410},[404,892,894,897,900,903,905,907,910,912,915,917,919,922,924],{"class":406,"line":893},29,[404,895,896],{"class":410},"  \u003C",[404,898,899],{"class":414},"a",[404,901,902],{"class":418}," :href",[404,904,425],{"class":410},[404,906,429],{"class":428},[404,908,909],{"class":432},"resource?.data?.url || '#'",[404,911,429],{"class":428},[404,913,914],{"class":418}," :class",[404,916,425],{"class":410},[404,918,429],{"class":428},[404,920,921],{"class":432},"resource?.data?.uiClassNames",[404,923,429],{"class":428},[404,925,438],{"class":410},[404,927,929],{"class":406,"line":928},30,[404,930,931],{"class":451},"    {{ resource?.data?.label }}\n",[404,933,935,938,940],{"class":406,"line":934},31,[404,936,937],{"class":410},"  \u003C\u002F",[404,939,899],{"class":414},[404,941,438],{"class":410},[404,943,945,947,949],{"class":406,"line":944},32,[404,946,871],{"class":410},[404,948,888],{"class":414},[404,950,438],{"class":410},[952,953,955],"h3",{"id":954},"how-it-works","How it works",[351,957,958,963,964,967,968,971],{},[371,959,960],{},[355,961,962],{},"styles.classes"," — a map of style names to arrays of Tailwind classes. The name (e.g. ",[355,965,966],{},"'Filled Button'",") appears in the manager panel as an option. The classes are applied to ",[355,969,970],{},"uiClassNames"," on the component.",[351,973,974,979,980,983,984,987],{},[371,975,976],{},[355,977,978],{},"styles.multiple"," — ",[355,981,982],{},"false"," means the admin picks one style. ",[355,985,986],{},"true"," allows multiple styles to be combined.",[351,989,990,995,996,998],{},[371,991,992],{},[355,993,994],{},"getCurrentStyleName(resource.value.data)"," — returns the currently applied style name (e.g. ",[355,997,966],{},"). Use this to drive conditional logic — different icons, different element types, different aria attributes.",[351,1000,1001,1005],{},[371,1002,1003],{},[355,1004,921],{}," — the actual CSS classes that get applied. Use this on the element you want styled.",[952,1007,1009],{"id":1008},"conditional-rendering-based-on-style","Conditional rendering based on style",[351,1011,1012,1013,1016],{},"For small variations — toggling an icon, changing an aria attribute, adjusting a minor class difference — using ",[355,1014,1015],{},"currentStyleName"," is fine:",[395,1018,1020],{"className":397,"code":1019,"language":399,"meta":400,"style":400},"\u003Ctemplate>\n  \u003C!-- Show an arrow icon only on filled buttons -->\n  \u003Ca :href=\"resource?.data?.url\">\n    {{ resource?.data?.label }}\n    \u003CArrowIcon v-if=\"currentStyleName === 'Filled Button'\" \u002F>\n  \u003C\u002Fa>\n\u003C\u002Ftemplate>\n",[355,1021,1022,1030,1036,1055,1059,1082,1090],{"__ignoreMap":400},[404,1023,1024,1026,1028],{"class":406,"line":407},[404,1025,411],{"class":410},[404,1027,888],{"class":414},[404,1029,438],{"class":410},[404,1031,1032],{"class":406,"line":441},[404,1033,1035],{"class":1034},"sTBSN","  \u003C!-- Show an arrow icon only on filled buttons -->\n",[404,1037,1038,1040,1042,1044,1046,1048,1051,1053],{"class":406,"line":475},[404,1039,896],{"class":410},[404,1041,899],{"class":414},[404,1043,902],{"class":418},[404,1045,425],{"class":410},[404,1047,429],{"class":428},[404,1049,1050],{"class":432},"resource?.data?.url",[404,1052,429],{"class":428},[404,1054,438],{"class":410},[404,1056,1057],{"class":406,"line":499},[404,1058,931],{"class":451},[404,1060,1061,1064,1067,1070,1072,1074,1077,1079],{"class":406,"line":520},[404,1062,1063],{"class":410},"    \u003C",[404,1065,1066],{"class":414},"ArrowIcon",[404,1068,1069],{"class":418}," v-if",[404,1071,425],{"class":410},[404,1073,429],{"class":428},[404,1075,1076],{"class":432},"currentStyleName === 'Filled Button'",[404,1078,429],{"class":428},[404,1080,1081],{"class":410}," \u002F>\n",[404,1083,1084,1086,1088],{"class":406,"line":527},[404,1085,937],{"class":410},[404,1087,899],{"class":414},[404,1089,438],{"class":410},[404,1091,1092,1094,1096],{"class":406,"line":558},[404,1093,871],{"class":410},[404,1095,888],{"class":414},[404,1097,438],{"class":410},[1099,1100,1102],"callout",{"icon":1101},"i-heroicons-exclamation-triangle",[351,1103,1104,1110,1111,1114,1115,1117],{},[371,1105,1106,1107,1109],{},"Don't use ",[355,1108,1015],{}," to conditionally render fundamentally different HTML structure."," If you find yourself showing completely different elements, different component hierarchies, or different semantic markup based on the style name, create a ",[355,1112,1113],{},"ui\u002F"," template instead. Style names can be renamed by the developer; ",[355,1116,1113],{}," filenames are stable identifiers. Conditional markup based on a name that could change is a maintenance hazard.",[380,1119],{},[383,1121,1123,1124,1126],{"id":1122},"approach-2-ui-templates-ui-directory","Approach 2: UI Templates (",[355,1125,1113],{}," directory)",[351,1128,1129,1130,1132],{},"When a variant needs completely different HTML structure — not just different classes — create an alternative Vue file in a ",[355,1131,1113],{}," subdirectory.",[1134,1135],"diagram-file-tree",{":files":1136,"root":1137},"[{\"path\":\"NavigationLink.vue\",\"label\":\"default template\"},{\"path\":\"ui\u002FYouTube.vue\",\"label\":\"alternative template\"}]","app\u002Fcwa\u002Fcomponents\u002FNavigationLink\u002F",[952,1139,1141,1142,1144],{"id":1140},"the-ui-file","The ",[355,1143,1113],{}," file",[395,1146,1148],{"className":397,"code":1147,"language":399,"meta":400,"style":400},"\u003C!-- app\u002Fcwa\u002Fcomponents\u002FNavigationLink\u002Fui\u002FYouTube.vue -->\n\u003Ctemplate>\n  \u003Ca :href=\"resource?.data?.url\">\n    \u003CYouTubeIcon class=\"w-15 h-10\" \u002F>\n  \u003C\u002Fa>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup lang=\"ts\">\nimport { toRef } from 'vue'\nimport type { IriProp } from '#cwa\u002Fcomposables\u002Fcwa-resource'\nimport { useCwaResource } from '#imports'\n\nconst props = defineProps\u003CIriProp>()\nconst { getResource, exposeMeta } = useCwaResource(toRef(props, 'iri'), {\n  name: 'YouTube'   \u002F\u002F must match the filename (without .vue)\n})\nconst resource = getResource()\ndefineExpose(exposeMeta)\n\u003C\u002Fscript>\n",[355,1149,1150,1155,1163,1181,1202,1210,1218,1222,1242,1260,1280,1298,1302,1320,1358,1375,1381,1393,1399],{"__ignoreMap":400},[404,1151,1152],{"class":406,"line":407},[404,1153,1154],{"class":1034},"\u003C!-- app\u002Fcwa\u002Fcomponents\u002FNavigationLink\u002Fui\u002FYouTube.vue -->\n",[404,1156,1157,1159,1161],{"class":406,"line":441},[404,1158,411],{"class":410},[404,1160,888],{"class":414},[404,1162,438],{"class":410},[404,1164,1165,1167,1169,1171,1173,1175,1177,1179],{"class":406,"line":475},[404,1166,896],{"class":410},[404,1168,899],{"class":414},[404,1170,902],{"class":418},[404,1172,425],{"class":410},[404,1174,429],{"class":428},[404,1176,1050],{"class":432},[404,1178,429],{"class":428},[404,1180,438],{"class":410},[404,1182,1183,1185,1188,1191,1193,1195,1198,1200],{"class":406,"line":499},[404,1184,1063],{"class":410},[404,1186,1187],{"class":414},"YouTubeIcon",[404,1189,1190],{"class":418}," class",[404,1192,425],{"class":410},[404,1194,429],{"class":428},[404,1196,1197],{"class":432},"w-15 h-10",[404,1199,429],{"class":428},[404,1201,1081],{"class":410},[404,1203,1204,1206,1208],{"class":406,"line":520},[404,1205,937],{"class":410},[404,1207,899],{"class":414},[404,1209,438],{"class":410},[404,1211,1212,1214,1216],{"class":406,"line":527},[404,1213,871],{"class":410},[404,1215,888],{"class":414},[404,1217,438],{"class":410},[404,1219,1220],{"class":406,"line":558},[404,1221,524],{"emptyLinePlaceholder":523},[404,1223,1224,1226,1228,1230,1232,1234,1236,1238,1240],{"class":406,"line":563},[404,1225,411],{"class":410},[404,1227,415],{"class":414},[404,1229,419],{"class":418},[404,1231,422],{"class":418},[404,1233,425],{"class":410},[404,1235,429],{"class":428},[404,1237,433],{"class":432},[404,1239,429],{"class":428},[404,1241,438],{"class":410},[404,1243,1244,1246,1248,1250,1252,1254,1256,1258],{"class":406,"line":616},[404,1245,445],{"class":444},[404,1247,448],{"class":410},[404,1249,452],{"class":451},[404,1251,461],{"class":410},[404,1253,464],{"class":444},[404,1255,467],{"class":428},[404,1257,399],{"class":432},[404,1259,472],{"class":428},[404,1261,1262,1264,1266,1268,1270,1272,1274,1276,1278],{"class":406,"line":628},[404,1263,445],{"class":444},[404,1265,480],{"class":444},[404,1267,448],{"class":410},[404,1269,485],{"class":451},[404,1271,461],{"class":410},[404,1273,464],{"class":444},[404,1275,467],{"class":428},[404,1277,494],{"class":432},[404,1279,472],{"class":428},[404,1281,1282,1284,1286,1288,1290,1292,1294,1296],{"class":406,"line":643},[404,1283,445],{"class":444},[404,1285,448],{"class":410},[404,1287,506],{"class":451},[404,1289,461],{"class":410},[404,1291,464],{"class":444},[404,1293,467],{"class":428},[404,1295,515],{"class":432},[404,1297,472],{"class":428},[404,1299,1300],{"class":406,"line":653},[404,1301,524],{"emptyLinePlaceholder":523},[404,1303,1304,1306,1308,1310,1312,1314,1316,1318],{"class":406,"line":672},[404,1305,531],{"class":530},[404,1307,535],{"class":534},[404,1309,539],{"class":538},[404,1311,543],{"class":542},[404,1313,411],{"class":410},[404,1315,549],{"class":548},[404,1317,552],{"class":410},[404,1319,555],{"class":451},[404,1321,1322,1324,1326,1328,1330,1332,1334,1336,1338,1340,1342,1344,1346,1348,1350,1352,1354,1356],{"class":406,"line":699},[404,1323,531],{"class":530},[404,1325,448],{"class":410},[404,1327,570],{"class":534},[404,1329,455],{"class":410},[404,1331,575],{"class":534},[404,1333,461],{"class":410},[404,1335,539],{"class":538},[404,1337,506],{"class":542},[404,1339,589],{"class":451},[404,1341,592],{"class":542},[404,1343,595],{"class":451},[404,1345,455],{"class":410},[404,1347,467],{"class":428},[404,1349,602],{"class":432},[404,1351,605],{"class":428},[404,1353,608],{"class":451},[404,1355,455],{"class":410},[404,1357,613],{"class":410},[404,1359,1360,1363,1365,1367,1370,1372],{"class":406,"line":724},[404,1361,1362],{"class":619},"  name",[404,1364,623],{"class":410},[404,1366,467],{"class":428},[404,1368,1369],{"class":432},"YouTube",[404,1371,605],{"class":428},[404,1373,1374],{"class":1034},"   \u002F\u002F must match the filename (without .vue)\n",[404,1376,1377,1379],{"class":406,"line":730},[404,1378,739],{"class":410},[404,1380,742],{"class":451},[404,1382,1383,1385,1387,1389,1391],{"class":406,"line":736},[404,1384,531],{"class":530},[404,1386,755],{"class":534},[404,1388,539],{"class":538},[404,1390,570],{"class":542},[404,1392,555],{"class":451},[404,1394,1395,1397],{"class":406,"line":745},[404,1396,862],{"class":542},[404,1398,865],{"class":451},[404,1400,1401,1403,1405],{"class":406,"line":750},[404,1402,871],{"class":410},[404,1404,415],{"class":414},[404,1406,438],{"class":410},[351,1408,1141,1409,1412,1413,1415,1416,1418,1419,1421,1422,801],{},[355,1410,1411],{},"name"," option in ",[355,1414,392],{}," identifies this as the ",[355,1417,1369],{}," variant. When an admin selects ",[355,1420,1369],{}," in the manager panel, the module renders this file instead of ",[355,1423,1424],{},"NavigationLink.vue",[952,1426,1428,1429,1431,1432],{"id":1427},"when-to-use-ui-vs-stylesclasses","When to use ",[355,1430,1113],{}," vs ",[355,1433,962],{},[351,1435,1436,1442],{},[371,1437,1438,1439,1441],{},"Use a ",[355,1440,1113],{}," template when"," the variant needs different HTML structure — different elements, different child components, fundamentally different markup. The YouTube icon variant above is the classic case: it's not \"NavigationLink but with different classes,\" it's a completely different thing that happens to share the same data.",[351,1444,1445,1451],{},[371,1446,1447,1448,1450],{},"Use ",[355,1449,962],{}," when"," it's the same HTML with different Tailwind classes, or minor conditional logic (toggling an icon, changing an aria label, a small class tweak).",[380,1453],{},[383,1455,1457],{"id":1456},"real-example-navigationlink-from-the-playground","Real Example: NavigationLink from the Playground",[351,1459,1141,1460,1463],{},[355,1461,1462],{},"components-web-app"," playground shows both approaches in a single component:",[351,1465,1466,1470,1471,1473,1474,1477,1478,1481,1482,1485],{},[371,1467,1468],{},[355,1469,1424],{}," uses ",[355,1472,962],{}," with ",[355,1475,1476],{},"'Filled'",", ",[355,1479,1480],{},"'Outlined'",", and ",[355,1483,1484],{},"'Tab Group'"," — each applying different classes and conditionally showing an icon.",[351,1487,1488,1493],{},[371,1489,1490],{},[355,1491,1492],{},"NavigationLink\u002Fui\u002FYouTube.vue"," is an entirely different template that renders a YouTube logo instead of text.",[351,1495,1496,1497,1499,1500,1502],{},"An admin creating a nav region can choose: plain link, filled button, outlined button, tab, or YouTube icon — all backed by the same ",[355,1498,361],{}," + ",[355,1501,365],{}," data.",[1504,1505,1506],"style",{},"html pre.shiki code .sOvfz, html code.shiki .sOvfz{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#89DDFF}html pre.shiki code .s-h7I, html code.shiki .s-h7I{--shiki-light:#22863A;--shiki-default:#85E89D;--shiki-dark:#F07178}html pre.shiki code .sGtlX, html code.shiki .sGtlX{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#C792EA}html pre.shiki code .seSrl, html code.shiki .seSrl{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#89DDFF}html pre.shiki code .sLL54, html code.shiki .sLL54{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#C3E88D}html pre.shiki code .sm4w6, html code.shiki .sm4w6{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sPB8G, html code.shiki .sPB8G{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#BABED8}html pre.shiki code .swB56, html code.shiki .swB56{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#C792EA}html pre.shiki code .sc2zw, html code.shiki .sc2zw{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#BABED8}html pre.shiki code .sVlFx, html code.shiki .sVlFx{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#89DDFF}html pre.shiki code .sKpYG, html code.shiki .sKpYG{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#82AAFF}html pre.shiki code .sRCss, html code.shiki .sRCss{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#FFCB6B}html pre.shiki code .sDHlG, html code.shiki .sDHlG{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#F07178}html pre.shiki code .swWMF, html code.shiki .swWMF{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#FF9CAC}html pre.shiki code .syBAL, html code.shiki .syBAL{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":400,"searchDepth":441,"depth":441,"links":1508},[1509,1513,1520],{"id":385,"depth":441,"text":386,"children":1510},[1511,1512],{"id":954,"depth":475,"text":955},{"id":1008,"depth":475,"text":1009},{"id":1122,"depth":441,"text":1514,"children":1515},"Approach 2: UI Templates (ui\u002F directory)",[1516,1518],{"id":1140,"depth":475,"text":1517},"The ui\u002F file",{"id":1427,"depth":475,"text":1519},"When to use ui\u002F vs styles.classes",{"id":1456,"depth":441,"text":1457},"Give the same component multiple visual styles — using style class names for CSS variation or ui\u002F Vue files for fully different templates.","md",null,{},{"title":32,"description":1521},"RIksRdOdJQPvSApMAxiJGxFGwJtesQzfgmDwXw1j_yI",[1528,1530],{"title":28,"path":29,"stem":30,"description":1529,"children":-1},"Build a complete CWA component from scratch — the PHP entity, the Vue display template, and the admin editing tab.",{"title":42,"path":43,"stem":44,"description":1531,"children":-1},"A high-level map of the CWA — what you get out of the box, what you write yourself, and how the three layers fit together.",1782241278654]