<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:layout-master-set>
    <fo:simple-page-master 
	margin-right="1.5cm"
	margin-left="1.5cm"
	margin-bottom="2cm"
	margin-top="1cm"
	page-width="21cm"
	page-height="17cm"
	master-name="first">
      <fo:region-before extent="1cm"/>
      <fo:region-body margin-top="1cm"/>
      <fo:region-after extent="1.5cm"/>
    </fo:simple-page-master>
  </fo:layout-master-set>
  
  <fo:page-sequence master-name="first">
    <fo:static-content flow-name="xsl-region-before">
      <fo:block line-height="14pt" font-size="10pt" 
		text-align="end">table examples</fo:block>
    </fo:static-content>
    <fo:static-content flow-name="xsl-region-after">
      <fo:block line-height="14pt" font-size="10pt" 
		text-align="end">Page <fo:page-number/></fo:block>
    </fo:static-content>
    
    <fo:flow flow-name="xsl-region-body">

      <fo:block space-before.optimum="3pt" space-after.optimum="15pt">
      Tests for keeps on table rows and the occurance of page breaks.
      </fo:block>

      <fo:block space-before.optimum="280pt" space-after.optimum="15pt">
      Table 1: basic keep with next
      </fo:block>

      <fo:table border-width="0.5pt" border-color="red">
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="3cm"/>

    <fo:table-body>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      first row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      second row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	</fo:table-body>
      </fo:table>

      <fo:block space-before.optimum="280pt" space-after.optimum="15pt">
      Table 1: basic keep with previous
      </fo:block>

      <fo:table border-width="0.5pt" border-color="red">
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="3cm"/>

    <fo:table-body>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      first row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-previous="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      second row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      previous
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	</fo:table-body>
      </fo:table>

      <fo:block space-before.optimum="270pt" space-after.optimum="15pt">
      Table 1: basic keep with next and keep with previous
      </fo:block>

      <fo:table border-width="0.5pt" border-color="red">
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="3cm"/>

    <fo:table-body>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      first row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      second row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-previous="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      third row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      previous
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	</fo:table-body>
      </fo:table>

      <fo:block space-before.optimum="200pt" space-after.optimum="15pt">
      Table 1: basic multiple keep with next after normal row
      </fo:block>

      <fo:table border-width="0.5pt" border-color="red">
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="3cm"/>

    <fo:table-body>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	</fo:table-body>
      </fo:table>

      <fo:block space-before.optimum="160pt" space-after.optimum="15pt">
      Table 1: basic multiple keep (next and previous) after normal row
      </fo:block>

      <fo:table border-width="0.5pt" border-color="red">
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="6cm"/>

    <fo:table-body>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-next="always" keep-with-previous="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next and previous
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	</fo:table-body>
      </fo:table>

      <fo:block space-before.optimum="160pt" space-after.optimum="15pt">
      Table 1: basic multiple keep with next after normal row with normal row in middle
      </fo:block>

      <fo:table border-width="0.5pt" border-color="red">
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="3cm"/>
	<fo:table-column column-width="6cm"/>

    <fo:table-body>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt" keep-with-next="always">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      keep with
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      next
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	  <fo:table-row border-width="0.5pt">
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      normal
	      </fo:block>
	    </fo:table-cell>
	    <fo:table-cell>
	      <fo:block text-align="center">
	      row
	      </fo:block>
	    </fo:table-cell>
	  </fo:table-row>
	</fo:table-body>
      </fo:table>

    </fo:flow>
  </fo:page-sequence>
</fo:root>
a id='n184' href='#n184'>184</a>
<a id='n185' href='#n185'>185</a>
<a id='n186' href='#n186'>186</a>
<a id='n187' href='#n187'>187</a>
<a id='n188' href='#n188'>188</a>
<a id='n189' href='#n189'>189</a>
<a id='n190' href='#n190'>190</a>
<a id='n191' href='#n191'>191</a>
<a id='n192' href='#n192'>192</a>
<a id='n193' href='#n193'>193</a>
<a id='n194' href='#n194'>194</a>
<a id='n195' href='#n195'>195</a>
<a id='n196' href='#n196'>196</a>
<a id='n197' href='#n197'>197</a>
<a id='n198' href='#n198'>198</a>
<a id='n199' href='#n199'>199</a>
<a id='n200' href='#n200'>200</a>
<a id='n201' href='#n201'>201</a>
<a id='n202' href='#n202'>202</a>
<a id='n203' href='#n203'>203</a>
<a id='n204' href='#n204'>204</a>
<a id='n205' href='#n205'>205</a>
<a id='n206' href='#n206'>206</a>
<a id='n207' href='#n207'>207</a>
<a id='n208' href='#n208'>208</a>
<a id='n209' href='#n209'>209</a>
<a id='n210' href='#n210'>210</a>
<a id='n211' href='#n211'>211</a>
<a id='n212' href='#n212'>212</a>
<a id='n213' href='#n213'>213</a>
<a id='n214' href='#n214'>214</a>
<a id='n215' href='#n215'>215</a>
<a id='n216' href='#n216'>216</a>
<a id='n217' href='#n217'>217</a>
<a id='n218' href='#n218'>218</a>
<a id='n219' href='#n219'>219</a>
<a id='n220' href='#n220'>220</a>
<a id='n221' href='#n221'>221</a>
<a id='n222' href='#n222'>222</a>
<a id='n223' href='#n223'>223</a>
<a id='n224' href='#n224'>224</a>
<a id='n225' href='#n225'>225</a>
<a id='n226' href='#n226'>226</a>
<a id='n227' href='#n227'>227</a>
<a id='n228' href='#n228'>228</a>
<a id='n229' href='#n229'>229</a>
<a id='n230' href='#n230'>230</a>
<a id='n231' href='#n231'>231</a>
<a id='n232' href='#n232'>232</a>
<a id='n233' href='#n233'>233</a>
<a id='n234' href='#n234'>234</a>
<a id='n235' href='#n235'>235</a>
<a id='n236' href='#n236'>236</a>
<a id='n237' href='#n237'>237</a>
<a id='n238' href='#n238'>238</a>
<a id='n239' href='#n239'>239</a>
<a id='n240' href='#n240'>240</a>
<a id='n241' href='#n241'>241</a>
<a id='n242' href='#n242'>242</a>
<a id='n243' href='#n243'>243</a>
<a id='n244' href='#n244'>244</a>
<a id='n245' href='#n245'>245</a>
<a id='n246' href='#n246'>246</a>
<a id='n247' href='#n247'>247</a>
<a id='n248' href='#n248'>248</a>
<a id='n249' href='#n249'>249</a>
<a id='n250' href='#n250'>250</a>
<a id='n251' href='#n251'>251</a>
<a id='n252' href='#n252'>252</a>
<a id='n253' href='#n253'>253</a>
<a id='n254' href='#n254'>254</a>
<a id='n255' href='#n255'>255</a>
<a id='n256' href='#n256'>256</a>
<a id='n257' href='#n257'>257</a>
<a id='n258' href='#n258'>258</a>
<a id='n259' href='#n259'>259</a>
<a id='n260' href='#n260'>260</a>
<a id='n261' href='#n261'>261</a>
<a id='n262' href='#n262'>262</a>
<a id='n263' href='#n263'>263</a>
<a id='n264' href='#n264'>264</a>
<a id='n265' href='#n265'>265</a>
<a id='n266' href='#n266'>266</a>
<a id='n267' href='#n267'>267</a>
<a id='n268' href='#n268'>268</a>
<a id='n269' href='#n269'>269</a>
<a id='n270' href='#n270'>270</a>
<a id='n271' href='#n271'>271</a>
<a id='n272' href='#n272'>272</a>
<a id='n273' href='#n273'>273</a>
<a id='n274' href='#n274'>274</a>
<a id='n275' href='#n275'>275</a>
<a id='n276' href='#n276'>276</a>
<a id='n277' href='#n277'>277</a>
<a id='n278' href='#n278'>278</a>
<a id='n279' href='#n279'>279</a>
<a id='n280' href='#n280'>280</a>
<a id='n281' href='#n281'>281</a>
<a id='n282' href='#n282'>282</a>
<a id='n283' href='#n283'>283</a>
<a id='n284' href='#n284'>284</a>
<a id='n285' href='#n285'>285</a>
<a id='n286' href='#n286'>286</a>
<a id='n287' href='#n287'>287</a>
<a id='n288' href='#n288'>288</a>
<a id='n289' href='#n289'>289</a>
<a id='n290' href='#n290'>290</a>
<a id='n291' href='#n291'>291</a>
<a id='n292' href='#n292'>292</a>
<a id='n293' href='#n293'>293</a>
<a id='n294' href='#n294'>294</a>
<a id='n295' href='#n295'>295</a>
<a id='n296' href='#n296'>296</a>
<a id='n297' href='#n297'>297</a>
<a id='n298' href='#n298'>298</a>
<a id='n299' href='#n299'>299</a>
<a id='n300' href='#n300'>300</a>
<a id='n301' href='#n301'>301</a>
<a id='n302' href='#n302'>302</a>
<a id='n303' href='#n303'>303</a>
<a id='n304' href='#n304'>304</a>
<a id='n305' href='#n305'>305</a>
<a id='n306' href='#n306'>306</a>
<a id='n307' href='#n307'>307</a>
<a id='n308' href='#n308'>308</a>
<a id='n309' href='#n309'>309</a>
<a id='n310' href='#n310'>310</a>
<a id='n311' href='#n311'>311</a>
<a id='n312' href='#n312'>312</a>
<a id='n313' href='#n313'>313</a>
<a id='n314' href='#n314'>314</a>
<a id='n315' href='#n315'>315</a>
<a id='n316' href='#n316'>316</a>
<a id='n317' href='#n317'>317</a>
<a id='n318' href='#n318'>318</a>
<a id='n319' href='#n319'>319</a>
<a id='n320' href='#n320'>320</a>
<a id='n321' href='#n321'>321</a>
<a id='n322' href='#n322'>322</a>
<a id='n323' href='#n323'>323</a>
<a id='n324' href='#n324'>324</a>
<a id='n325' href='#n325'>325</a>
<a id='n326' href='#n326'>326</a>
<a id='n327' href='#n327'>327</a>
<a id='n328' href='#n328'>328</a>
<a id='n329' href='#n329'>329</a>
<a id='n330' href='#n330'>330</a>
<a id='n331' href='#n331'>331</a>
<a id='n332' href='#n332'>332</a>
<a id='n333' href='#n333'>333</a>
<a id='n334' href='#n334'>334</a>
<a id='n335' href='#n335'>335</a>
<a id='n336' href='#n336'>336</a>
<a id='n337' href='#n337'>337</a>
<a id='n338' href='#n338'>338</a>
<a id='n339' href='#n339'>339</a>
<a id='n340' href='#n340'>340</a>
<a id='n341' href='#n341'>341</a>
<a id='n342' href='#n342'>342</a>
<a id='n343' href='#n343'>343</a>
<a id='n344' href='#n344'>344</a>
<a id='n345' href='#n345'>345</a>
<a id='n346' href='#n346'>346</a>
<a id='n347' href='#n347'>347</a>
<a id='n348' href='#n348'>348</a>
<a id='n349' href='#n349'>349</a>
<a id='n350' href='#n350'>350</a>
<a id='n351' href='#n351'>351</a>
<a id='n352' href='#n352'>352</a>
<a id='n353' href='#n353'>353</a>
<a id='n354' href='#n354'>354</a>
<a id='n355' href='#n355'>355</a>
<a id='n356' href='#n356'>356</a>
<a id='n357' href='#n357'>357</a>
<a id='n358' href='#n358'>358</a>
<a id='n359' href='#n359'>359</a>
<a id='n360' href='#n360'>360</a>
<a id='n361' href='#n361'>361</a>
<a id='n362' href='#n362'>362</a>
<a id='n363' href='#n363'>363</a>
<a id='n364' href='#n364'>364</a>
<a id='n365' href='#n365'>365</a>
<a id='n366' href='#n366'>366</a>
<a id='n367' href='#n367'>367</a>
<a id='n368' href='#n368'>368</a>
<a id='n369' href='#n369'>369</a>
<a id='n370' href='#n370'>370</a>
<a id='n371' href='#n371'>371</a>
<a id='n372' href='#n372'>372</a>
<a id='n373' href='#n373'>373</a>
<a id='n374' href='#n374'>374</a>
<a id='n375' href='#n375'>375</a>
<a id='n376' href='#n376'>376</a>
<a id='n377' href='#n377'>377</a>
<a id='n378' href='#n378'>378</a>
<a id='n379' href='#n379'>379</a>
<a id='n380' href='#n380'>380</a>
<a id='n381' href='#n381'>381</a>
<a id='n382' href='#n382'>382</a>
<a id='n383' href='#n383'>383</a>
<a id='n384' href='#n384'>384</a>
<a id='n385' href='#n385'>385</a>
<a id='n386' href='#n386'>386</a>
<a id='n387' href='#n387'>387</a>
<a id='n388' href='#n388'>388</a>
</pre></td>
<td class='lines'><pre><code><style>pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span>---
title: Designing UIs Declaratively
order: 3
layout: page
---

[[application.declarative]]
= Designing UIs Declaratively

Declarative definition of composites and even entire UIs makes it easy for
developers and especially graphical designers to work on visual designs without
any coding. Designs can be modified even while the application is running, as
can be the associated themes. A design is a representation of a component
hierarcy, which can be accessed from Java code to implement dynamic UI logic, as
well as data binding.

For example, considering the following layout in Java:


[source, java]
----
VerticalLayout vertical = new VerticalLayout ();
vertical.addComponent(new TextField(&quot;Name&quot;));
vertical.addComponent(new TextField(&quot;Street address&quot;));
vertical.addComponent(new TextField(&quot;Postal code&quot;));
layout.addComponent(vertical);
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#layout.orderedlayout.basic[on-line example, window=&quot;_blank&quot;].

You could define it declaractively with the following equivalent design:

[source, html]
----
&lt;vaadin-vertical-layout&gt;
  &lt;vaadin-text-field caption=&quot;Name&quot;/&gt;
  &lt;vaadin-text-field caption=&quot;Street address&quot;/&gt;
  &lt;vaadin-text-field caption=&quot;Postal code&quot;/&gt;
&lt;/vaadin-vertical-layout&gt;
----
ifdef::web[]
See the http://demo.vaadin.com/book-examples-vaadin7/book#layout.orderedlayout.basic[on-line example, window=&quot;_blank&quot;].
endif::web[]

Declarative designs can be crafted by hand, but are most conveniently created
with the Vaadin Designer.

In the following, we first go through the syntax of the declarative design
files, and then see how to use them in applications by binding them to data and
handling user interaction events.

[[application.declarative.syntax]]
== Declarative Syntax

A design is an HTML document with custom elements for representing components
and their configuration. A design has a single root component inside the HTML
body element. Enclosing [literal]#++&lt;html&gt;++#, [literal]#++&lt;head&gt;++#, and
[literal]#++&lt;body&gt;++# are optional, but necessary if you need to make namespace
definitions for custom components. Other regular HTML elements may not be used
in the file, except inside components that specifically accept HTML content.

In a design, each nested element corresponds to a Vaadin component in a
component tree. Components can have explicitly given IDs to enable binding them
to variables in the Java code, as well as optional attributes.

[source, html]
----
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;body&gt;
    &lt;vaadin-vertical-layout size-full&gt;
      &lt;!-- Label with HTML content --&gt;
      &lt;vaadin-label&gt;&lt;b&gt;Hello!&lt;/b&gt; -
                    How are you?&lt;/vaadin-label&gt;

      &lt;vaadin-horizontal-layout size-full :expand&gt;
       &lt;vaadin-tree _id=&quot;mytree&quot; caption=&quot;My Tree&quot;
                    width-auto height-full/&gt;
       &lt;vaadin-table _id=&quot;mytable&quot; caption=&quot;My Table&quot;
                     size-full :expand/&gt;
      &lt;/vaadin-horizontal-layout&gt;
    &lt;/vaadin-vertical-layout&gt;
  &lt;/body&gt;
&lt;/html&gt;
----

The DOCTYPE is not required, neither is the [literal]#++&lt;html&gt;++#, or
[literal]#++&lt;body&gt;++# elements. Nevertheless, there may only be one design root
element.

The above design defines the same UI layout as done earlier with Java code, and
illustrated in
&lt;&lt;dummy/../../../framework/application/application-architecture#figure.application.architecture.example,&quot;Simple
Hierarchical UI&quot;&gt;&gt;.


[[application.declarative.elements]]
== Component Elements

HTML elements of the declarative syntax are directly mapped to Vaadin components according to their Java class names.
The tag of a component element has a namespace prefix separated by a dash.
Vaadin core components, which are defined in the [package]#com.vaadin.ui# package, have [literal]#++vaadin-++# prefix.
The rest of an element tag is determined from the Java class name of the component, by making it lower-case, while adding a dash (`-`) before every previously upper-case letter as a word separator.
For example, [classname]#ComboBox# component has declarative element tag [vaadinelement]#vaadin-combo-box#.

[[application.declarative.elements.prefix]]
=== Component Prefix to Package Mapping

You can use any components in a design: components extending Vaadin components,
composite components, and add-on components. To do so, you need to define a
mapping from an element prefix to the Java package of the component. The prefix
is used as a sort of a namespace.

The mappings are defined in `&lt;meta name=&quot;package-mapping&quot; ...&gt;`
elements in the HTML head. A [parameter]#content# attribute defines a mapping,
in notation with a prefix separated from the corresponding Java package name
with a colon, such as `my:com.example.myapp`.

For example, consider that you have the following composite class
[classname]#com.example.myapp.ExampleComponent#:

[source, java]
----
package com.example.myapp;

public class ExampleComponent extends CustomComponent {
    public ExampleComponent() {
        setCompositionRoot(new Label(&quot;I am an example.&quot;));
    }
}
----

You would make the package prefix mapping and then use the component as follows:

[subs=&quot;normal&quot;]
----
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    **&amp;lt;meta name=&quot;package-mapping&quot;
          content=&quot;my:com.example.myapp&quot; /&amp;gt;**
  &amp;lt;/head&amp;gt;

  &amp;lt;body&amp;gt;
    &amp;lt;vaadin-vertical-layout&amp;gt;
      &amp;lt;vaadin-label&amp;gt;&amp;lt;b&amp;gt;Hello!&amp;lt;/b&amp;gt; -
                How are you?&amp;lt;/vaadin-label&amp;gt;

      &amp;lt;!-- Use it here --&amp;gt;
      **&amp;lt;my-example-component/&amp;gt;**
    &amp;lt;/vaadin-vertical-layout&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
----

[[application.declarative.elements.inline]]
=== Inline Content and Data

The element content can be used for certain default attributes, such as a button
caption. For example:


[source, html]
----
&lt;vaadin-button&gt;&lt;b&gt;OK&lt;/b&gt;&lt;/vaadin-button&gt;
----

Some components, such as selection components, allow defining inline data within
the element. For example:


[source, html]
----
&lt;vaadin-native-select&gt;
  &lt;option&gt;Mercury&lt;/option&gt;
  &lt;option&gt;Venus&lt;/option&gt;
  &lt;option selected&gt;Earth&lt;/option&gt;
&lt;/vaadin-native-select&gt;
----

The declarative syntax of each component type is described in the JavaDoc API
documentation of Vaadin.



[[application.declarative.attributes]]
== Component Attributes

[[application.declarative.attributes.mapping]]
=== Attribute-to-Property Mapping

Component properties are directly mapped to the attributes of the HTML elements
according to the names of the properties. Attributes are written in lower-case
letters and dash is used for word separation instead of upper-case letters in
the Java methods, so that [literal]#++input-prompt++# attribute is equivalent to
[methodname]#setInputPrompt()#.

For example, the __caption__ property, which you can set with
[methodname]#setCaption()#, is represented as [literal]#++caption++# attribute.
You can find the component properties by the setter methods in the
link:https://vaadin.com/api/[JavaDoc API documentation] of the component
classes.


[source, html]
----
&lt;vaadin-text-field caption=&quot;Name&quot; input-prompt=&quot;Enter Name&quot;/&gt;
----


[[application.declarative.attributes.parameters]]
=== Attribute Values

Attribute parameters must be enclosed in quotes and the value given as a string
must be convertible to the type of the property (string, integer, boolean, or
enumeration). Object types are not supported.

Some attribute names are given by a shorthand. For example,
[parameter]#alternateText# property of the [classname]#Image# component, which
you would set with [methodname]#setAlternateText()#, is given as the
[literal]#++alt++# attribute.

Boolean values must be either `true` or `false`.
The value can be omitted, in which case `true` is assumed.
For example, the [literal]#++enabled++# attribute is boolean and has default value &quot;`true`&quot;, so `enabled=&quot;true&quot;` and `enabled` and equivalent.

[source, html]
----
&lt;vaadin-button enabled=&quot;false&quot;&gt;OK&lt;/vaadin-button&gt;
----


[[application.declarative.attributes.parent]]
=== Parent Component Settings

Certain settings, such as a component&#39;s alignment in a layout, are not done in
the component itself, but in the layout. Attributes prefixed with colon (
[literal]#++:++#) are passed to the containing component, with the component as
a target parameter. For example, [literal]#++:expand=&quot;1&quot;++# given for a
component [parameter]#c# is equivalent to calling [methodname]#setExpandRatio(c,
1)# for the containing layout.

[subs=&quot;normal&quot;]
----
&amp;lt;vaadin-vertical-layout size-full&amp;gt;
  &amp;lt;!-- Align right in the containing layout --&amp;gt;
  &amp;lt;vaadin-label width-auto **:right**&amp;gt;Hello!&amp;lt;/vaadin-label&amp;gt;

  &amp;lt;!-- Expands to take up all remaining vertical space --&amp;gt;
  &amp;lt;vaadin-horizontal-layout size-full **:expand**&amp;gt;
    &amp;lt;!-- Automatic width - shrinks horizontally --&amp;gt;
    &amp;lt;vaadin-tree width-auto height-full/&amp;gt;

    &amp;lt;!-- Expands horizontally to take remaining space --&amp;gt;
    &amp;lt;vaadin-table size-full **:expand**/&amp;gt;
  &amp;lt;/vaadin-horizontal-layout&amp;gt;
&amp;lt;/vaadin-vertical-layout&amp;gt;
----
Again, compare the above declaration to the Java code given in
&lt;&lt;dummy/../../../framework/application/application-architecture#application.architecture,&quot;Building
the UI&quot;&gt;&gt;.



[[application.declarative.identifiers]]
== Component Identifiers

Components can be identified by either an identifier or a caption. There are two
types of identifiers: page-global and local. This allows accessing them from
Java code and binding them to components, as described later in
&lt;&lt;application.declarative.composite&gt;&gt;.

The [literal]#++id++# attribute can be used to define a page-global identifier,
which must be unique within the page. Another design or UI shown simultaneously
in the same page may not have components sharing the same ID. Using global
identifiers is therefore not recommended, except in special cases where
uniqueness is ensured.

The [literal]#++_id++# attribute defines a local identifier used only within the
design. This is the recommended way to identifying components.


[source, html]
----
&lt;vaadin-tree _id=&quot;mytree&quot; caption=&quot;My Tree&quot;/&gt;
----


[[application.declarative.composite]]
== Using Designs in Code

The main use of declarative designs is in building application views, sub-views,
dialogs, and forms through composition. The two main tasks are filling the
designs with application data and handling user interaction events.

[[application.declarative.composite.designroot]]
=== Binding to a Design Root

You can bind any component container as the root component of a design with the
[classname]#@DesignRoot# annotation. The class must match or extend the class of
the root element in the design.

The member variables are automatically initialized from the design according to
the component identifiers (see &lt;&lt;application.declarative.identifiers&gt;&gt;), which
must match the variable names.

For example, the following class could be used to bind the design given earlier.


[source, java]
----
@DesignRoot
public class MyViewDesign extends VerticalLayout {
    Tree mytree;
    Table mytable;

    public MyViewDesign() {
        Design.read(&quot;MyDeclarativeUI.html&quot;, this);

        // Show some (example) data
        mytree.setContainerDataSource(
            TreeExample.createTreeContent());
        mytable.setContainerDataSource(
            TableExample.generateContent());

        // Some interaction
        mytree.addItemClickListener(event -&gt; // Java 8
            Notification.show(&quot;Selected &quot; +
                event.getItemId()));
    }
}
----
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.declarative.designroot[on-line example, window=&quot;_blank&quot;].

The design root class must match or extend the root element class of the design.
For example, earlier we had [literal]#++&lt;vaadin-vertical-layout&gt;++# element in the
HTML file, which can be bound to a class extending [classname]#VerticalLayout#.


[[application.declarative.composite.using]]
=== Using a Design

The fact that a component is defined declaratively is not visible in its API, so
you can create and use such it just like any other component.

For example, to use the previously defined design root component as the content
of the entire UI:


[source, java]
----
public class DeclarativeViewUI extends UI {
    @Override
    protected void init(VaadinRequest request) {
        setContent(new MyViewDesign());
    }
}
----


[[application.declarative.composite.viewnavigation]]
=== Designs in View Navigation

To use a design in view navigation, as described in
&lt;&lt;dummy/../../../framework/advanced/advanced-navigator#advanced.navigator,&quot;Navigating
in an Application&quot;&gt;&gt;, you just need to implement the [interfacename]#View#
interface.


[source, java]
----
@DesignRoot
public class MainView extends VerticalLayout
                      implements View {
    public MainView() {
        Design.read(this);
        ...
    }
    ...
}

...
// Use the view by precreating it
navigator.addView(MAINVIEW, new MainView());
----

See
&lt;&lt;dummy/../../../framework/advanced/advanced-navigator#advanced.navigator.urifragment,&quot;Handling
URI Fragment Path&quot;&gt;&gt; for a complete example.
</pre></div>
</code></pre></td></tr></table>
</div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit v1.2.3</a> (<a href='https://git-scm.com/'>git 2.39.1</a>) at 2025-08-06 08:20:53 +0000</div>
</div> <!-- id=cgit -->
</body>
</html>
