@swiftwc/ui 0.0.0-dev.11 → 0.0.0-dev.111

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/css-data/en.json +28 -0
  2. package/generated/buses/alert-dialog.d.ts +2 -0
  3. package/generated/buses/alert-dialog.js +1 -0
  4. package/generated/buses/confirmation-dialog.d.ts +2 -0
  5. package/generated/buses/confirmation-dialog.js +1 -0
  6. package/generated/buses/index.d.ts +6 -0
  7. package/generated/buses/index.js +6 -0
  8. package/generated/buses/lifecycle-observer.d.ts +2 -0
  9. package/generated/buses/lifecycle-observer.js +1 -0
  10. package/generated/client/index.d.ts +24 -10
  11. package/generated/client/index.js +179 -194
  12. package/generated/components/alert-dialog.d.ts +11 -0
  13. package/generated/components/alert-dialog.js +94 -0
  14. package/generated/components/body-view.d.ts +8 -0
  15. package/generated/components/body-view.js +6 -2
  16. package/generated/components/bordered-button.d.ts +10 -0
  17. package/generated/components/bordered-button.js +36 -3
  18. package/generated/components/bordered-prominent-button.d.ts +10 -0
  19. package/generated/components/bordered-prominent-button.js +36 -3
  20. package/generated/components/borderless-button.d.ts +9 -1
  21. package/generated/components/borderless-button.js +29 -11
  22. package/generated/components/color-scheme.d.ts +12 -0
  23. package/generated/components/color-scheme.js +51 -0
  24. package/generated/components/confirmation-dialog.d.ts +4 -1
  25. package/generated/components/confirmation-dialog.js +38 -32
  26. package/generated/components/content-unavailable.d.ts +30 -0
  27. package/generated/components/content-unavailable.js +79 -0
  28. package/generated/components/date-picker.d.ts +21 -15
  29. package/generated/components/date-picker.js +126 -88
  30. package/generated/components/detail-placeholder.d.ts +11 -0
  31. package/generated/components/detail-placeholder.js +15 -0
  32. package/generated/components/disclosure-group.d.ts +8 -0
  33. package/generated/components/disclosure-group.js +18 -7
  34. package/generated/components/fine-tooltip.d.ts +15 -0
  35. package/generated/components/fine-tooltip.js +108 -0
  36. package/generated/components/form-view.d.ts +10 -0
  37. package/generated/components/form-view.js +8 -3
  38. package/generated/components/glass-button.d.ts +10 -0
  39. package/generated/components/glass-button.js +36 -3
  40. package/generated/components/glass-prominent-button.d.ts +10 -0
  41. package/generated/components/glass-prominent-button.js +36 -3
  42. package/generated/components/h-divider.d.ts +11 -0
  43. package/generated/components/h-divider.js +15 -0
  44. package/generated/components/h-stack.d.ts +22 -0
  45. package/generated/components/h-stack.js +24 -0
  46. package/generated/components/image-view.d.ts +18 -0
  47. package/generated/components/image-view.js +65 -0
  48. package/generated/components/index.d.ts +15 -3
  49. package/generated/components/index.js +15 -3
  50. package/generated/components/label-view.d.ts +19 -1
  51. package/generated/components/label-view.js +63 -62
  52. package/generated/components/labeled-content.d.ts +33 -0
  53. package/generated/components/labeled-content.js +160 -0
  54. package/generated/components/list-view.d.ts +14 -0
  55. package/generated/components/list-view.js +12 -17
  56. package/generated/components/menu-view.d.ts +12 -1
  57. package/generated/components/menu-view.js +63 -65
  58. package/generated/components/navigation-large-title.d.ts +11 -0
  59. package/generated/components/navigation-large-title.js +11 -5
  60. package/generated/components/navigation-split-view.d.ts +9 -1
  61. package/generated/components/navigation-split-view.js +10 -6
  62. package/generated/components/navigation-stack.d.ts +9 -1
  63. package/generated/components/navigation-stack.js +13 -11
  64. package/generated/components/navigation-title.d.ts +11 -1
  65. package/generated/components/navigation-title.js +58 -55
  66. package/generated/components/picker-view.d.ts +48 -7
  67. package/generated/components/picker-view.js +971 -261
  68. package/generated/components/plain-button.js +3 -3
  69. package/generated/components/progress-view.d.ts +20 -0
  70. package/generated/components/progress-view.js +120 -0
  71. package/generated/components/screen-view.js +2 -1
  72. package/generated/components/scroll-view-proxy.d.ts +13 -0
  73. package/generated/components/scroll-view-proxy.js +15 -0
  74. package/generated/components/scroll-view.d.ts +13 -1
  75. package/generated/components/scroll-view.js +140 -97
  76. package/generated/components/search-view.d.ts +12 -0
  77. package/generated/components/search-view.js +24 -0
  78. package/generated/components/section-view.d.ts +13 -1
  79. package/generated/components/section-view.js +38 -58
  80. package/generated/components/sheet-view.d.ts +4 -2
  81. package/generated/components/sheet-view.js +10 -39
  82. package/generated/components/sidebar-toggle.d.ts +9 -1
  83. package/generated/components/sidebar-toggle.js +46 -69
  84. package/generated/components/sidebar-view.d.ts +3 -0
  85. package/generated/components/sidebar-view.js +16 -9
  86. package/generated/components/sticky-container.d.ts +6 -1
  87. package/generated/components/sticky-container.js +9 -7
  88. package/generated/components/tab-bar.d.ts +3 -0
  89. package/generated/components/tab-bar.js +17 -13
  90. package/generated/components/tab-item.d.ts +3 -0
  91. package/generated/components/tab-item.js +20 -13
  92. package/generated/components/tab-view.d.ts +13 -4
  93. package/generated/components/tab-view.js +25 -89
  94. package/generated/components/table-view.d.ts +19 -0
  95. package/generated/components/table-view.js +88 -107
  96. package/generated/components/text-field.d.ts +19 -6
  97. package/generated/components/text-field.js +127 -99
  98. package/generated/components/text-view.d.ts +11 -0
  99. package/generated/components/text-view.js +16 -0
  100. package/generated/components/toggle-view.d.ts +43 -0
  101. package/generated/components/toggle-view.js +366 -0
  102. package/generated/components/tool-bar-item-group.d.ts +8 -0
  103. package/generated/components/tool-bar-item-group.js +22 -4
  104. package/generated/components/tool-bar-item.d.ts +12 -1
  105. package/generated/components/tool-bar-item.js +57 -10
  106. package/generated/components/tool-bar.d.ts +19 -0
  107. package/generated/components/tool-bar.js +48 -33
  108. package/generated/components/v-divider.d.ts +11 -0
  109. package/generated/components/v-divider.js +15 -0
  110. package/generated/components/v-keyboard.d.ts +8 -1
  111. package/generated/components/v-keyboard.js +11 -9
  112. package/generated/components/v-stack.d.ts +20 -0
  113. package/generated/components/v-stack.js +18 -2
  114. package/generated/css/index.css +4617 -1266
  115. package/generated/events/alert-dialog.d.ts +13 -0
  116. package/generated/events/alert-dialog.js +1 -0
  117. package/generated/events/confirmation-dialog.d.ts +7 -2
  118. package/generated/events/date-picker.d.ts +6 -1
  119. package/generated/events/index.d.ts +2 -0
  120. package/generated/events/index.js +2 -0
  121. package/generated/events/lifecycle-observer.d.ts +10 -2
  122. package/generated/events/picker-view.d.ts +22 -1
  123. package/generated/events/scroll-view.d.ts +10 -2
  124. package/generated/events/tab-view.d.ts +38 -8
  125. package/generated/events/text-field.d.ts +6 -1
  126. package/generated/events/toggle-view.d.ts +14 -0
  127. package/generated/events/toggle-view.js +1 -0
  128. package/generated/i18n/index.d.ts +19 -10
  129. package/generated/i18n/index.js +79 -54
  130. package/generated/i18n/locales/el.d.ts +16 -0
  131. package/generated/i18n/locales/el.js +16 -0
  132. package/generated/i18n/locales/en.d.ts +16 -0
  133. package/generated/i18n/locales/en.js +16 -0
  134. package/generated/i18n/locales/index.d.ts +4 -0
  135. package/generated/i18n/locales/index.js +4 -0
  136. package/generated/internal/class/css-style-observer.js +2 -2
  137. package/generated/internal/class/form-associated-base.d.ts +0 -4
  138. package/generated/internal/class/form-associated-base.js +22 -39
  139. package/generated/internal/class/mutation-observer-set.d.ts +9 -0
  140. package/generated/internal/class/mutation-observer-set.js +42 -0
  141. package/generated/internal/class/mutation-observer-singleton.js +18 -0
  142. package/generated/internal/class/navigation-view.d.ts +1 -1
  143. package/generated/internal/class/navigation-view.js +36 -43
  144. package/generated/internal/decorators/adaptive-slot.d.ts +1 -0
  145. package/generated/internal/decorators/adaptive-slot.js +47 -0
  146. package/generated/internal/decorators/custom-element.d.ts +1 -1
  147. package/generated/internal/decorators/custom-element.js +2 -1
  148. package/generated/internal/decorators/index.d.ts +6 -0
  149. package/generated/internal/decorators/index.js +6 -0
  150. package/generated/internal/decorators/microtask-on-connected.d.ts +39 -0
  151. package/generated/internal/decorators/microtask-on-connected.js +67 -0
  152. package/generated/internal/flags.d.ts +4 -0
  153. package/generated/internal/flags.js +1 -0
  154. package/generated/internal/privateNamespace.d.ts +10 -0
  155. package/generated/internal/privateNamespace.js +159 -1
  156. package/generated/internal/utils/$.d.ts +9 -0
  157. package/generated/internal/utils/$.js +11 -0
  158. package/generated/internal/utils/compare-big-decimals.js +7 -17
  159. package/generated/internal/utils/debug.d.ts +1 -0
  160. package/generated/internal/utils/debug.js +4 -0
  161. package/generated/internal/utils/define-translations.d.ts +1 -0
  162. package/generated/internal/utils/define-translations.js +3 -0
  163. package/generated/internal/utils/ensure-placeholder.d.ts +1 -0
  164. package/generated/internal/utils/ensure-placeholder.js +41 -0
  165. package/generated/internal/utils/index.d.ts +39 -2
  166. package/generated/internal/utils/index.js +39 -3
  167. package/generated/internal/utils/is-inside.d.ts +1 -0
  168. package/generated/internal/utils/is-inside.js +4 -0
  169. package/generated/internal/utils/kebab-case.js +6 -9
  170. package/generated/internal/utils/list-active.js +67 -12
  171. package/generated/internal/utils/touch-glass.js +5 -5
  172. package/generated/internal/vendor/morphdom.d.ts +6 -0
  173. package/generated/internal/vendor/morphdom.js +720 -0
  174. package/generated/morphdom/index.d.ts +8 -0
  175. package/generated/morphdom/index.js +8 -0
  176. package/generated/morphdom/morph.d.ts +4 -0
  177. package/generated/morphdom/morph.js +10 -0
  178. package/generated/morphdom/query-morph.d.ts +5 -0
  179. package/generated/morphdom/query-morph.js +12 -0
  180. package/generated/morphdom/render-to-string.d.ts +12 -0
  181. package/generated/morphdom/render-to-string.js +48 -0
  182. package/generated/morphdom/unsafe-html.d.ts +2 -0
  183. package/generated/morphdom/unsafe-html.js +4 -0
  184. package/generated/namespace-browser/base.d.ts +12 -3
  185. package/generated/namespace-browser/base.js +41 -18
  186. package/generated/namespace-browser/event.d.ts +10 -0
  187. package/generated/namespace-browser/event.js +1 -0
  188. package/generated/snapshot/index.d.ts +3 -1
  189. package/generated/snapshot/index.js +23 -2
  190. package/generated/tpl/html.d.ts +5 -0
  191. package/generated/tpl/html.js +7 -0
  192. package/generated/tpl/index.d.ts +6 -0
  193. package/generated/tpl/index.js +6 -0
  194. package/generated/tpl/is-template-result.d.ts +3 -0
  195. package/generated/tpl/is-template-result.js +1 -0
  196. package/generated/tpl/render.d.ts +2 -0
  197. package/generated/tpl/render.js +132 -0
  198. package/html-data/en.json +2620 -0
  199. package/package.json +32 -7
  200. package/scss/_components.scss +15 -0
  201. package/scss/_functions.scss +10 -0
  202. package/scss/_maps.scss +293 -0
  203. package/scss/_mixins.scss +4 -0
  204. package/scss/_transitions.scss +6 -1
  205. package/scss/_utils.scss +2 -0
  206. package/scss/_vars.scss +9 -115
  207. package/scss/base/_layout.scss +17 -7
  208. package/scss/base/_reboot.scss +34 -1
  209. package/scss/base/_root.scss +143 -124
  210. package/scss/colors/_index.scss +328 -88
  211. package/scss/components/_alert-dialog.scss +111 -0
  212. package/scss/components/_bordered-button.scss +37 -0
  213. package/scss/components/_bordered-prominent-button.scss +46 -0
  214. package/scss/components/_borderless-button.scss +26 -0
  215. package/scss/components/_confirmation-dialog.scss +41 -49
  216. package/scss/components/_content-unavailable.scss +57 -0
  217. package/scss/components/_date-picker.scss +15 -15
  218. package/scss/components/_detail-placeholder.scss +1 -3
  219. package/scss/components/_disclosure-group.scss +85 -34
  220. package/scss/components/_fine-tooltip.scss +84 -0
  221. package/scss/components/_form-view.scss +63 -24
  222. package/scss/components/_glass-button.scss +37 -0
  223. package/scss/components/_glass-prominent-button.scss +47 -0
  224. package/scss/components/_group-box.scss +27 -0
  225. package/scss/components/_h-flex-stack.scss +23 -0
  226. package/scss/components/_h-stack.scss +6 -17
  227. package/scss/components/_image-view.scss +20 -0
  228. package/scss/components/_index.scss +69 -36
  229. package/scss/components/_label-view copy.scss.txt +420 -0
  230. package/scss/components/_label-view.scss +105 -120
  231. package/scss/components/_label-view.scss.txt +536 -0
  232. package/scss/components/_labeled-content.scss +67 -1
  233. package/scss/components/_list-view.scss +70 -29
  234. package/scss/components/_menu-view.scss +96 -61
  235. package/scss/components/_navigation-large-title.scss +23 -0
  236. package/scss/components/_navigation-split-view.scss +3 -3
  237. package/scss/components/_navigation-title.scss +1 -1
  238. package/scss/components/_picker-view.scss +270 -63
  239. package/scss/components/_plain-button.scss +8 -0
  240. package/scss/components/_progress-view.scss +98 -0
  241. package/scss/components/_scroll-view-proxy.scss +24 -22
  242. package/scss/components/_scroll-view-toolbars.scss +8 -2
  243. package/scss/components/_scroll-view.scss +16 -0
  244. package/scss/components/_search-view.scss +23 -0
  245. package/scss/components/_section-view.scss +23 -22
  246. package/scss/components/_sheet-view.scss +16 -6
  247. package/scss/components/_sidebar-toggle.scss +1 -4
  248. package/scss/components/_sticky-container.scss +1 -1
  249. package/scss/components/_tab-bar.scss +17 -3
  250. package/scss/components/_tab-view.scss +12 -2
  251. package/scss/components/_table-column.scss +4 -2
  252. package/scss/components/_table-row.scss +71 -3
  253. package/scss/components/_table-view.scss +27 -18
  254. package/scss/components/_text-field.scss +37 -17
  255. package/scss/components/_text-view.scss +57 -0
  256. package/scss/components/_toggle-view.scss +171 -0
  257. package/scss/components/_tool-bar-item.scss +34 -82
  258. package/scss/components/_tool-bar.scss +77 -57
  259. package/scss/components/_v-stack.scss +8 -2
  260. package/scss/final/_touch-glass.scss +31 -0
  261. package/scss/mixins/_button.scss +44 -0
  262. package/scss/mixins/_color.scss +16 -0
  263. package/scss/mixins/_dialog.scss +1 -0
  264. package/scss/mixins/_index.scss +73 -5
  265. package/scss/placeholders/_buttons.scss +46 -11
  266. package/scss/placeholders/_lists.scss +159 -126
  267. package/scss/transitions/_alert-dialog.scss +18 -0
  268. package/scss/transitions/_confirmation-dialog.scss +8 -0
  269. package/scss/transitions/_fine-tooltip.scss +21 -0
  270. package/scss/transitions/_menu-view.scss +17 -15
  271. package/scss/transitions/_progress-view.scss +23 -0
  272. package/scss/transitions/_sheet-view.scss +30 -0
  273. package/scss/transitions/_tab-bar.scss +6 -5
  274. package/scss/utils/_background.scss +52 -0
  275. package/scss/utils/_frame.scss +59 -40
  276. package/scss/utils/_index.scss +45 -56
  277. package/scss/utils/_scroll-view.scss +1 -1
  278. package/scss/utils/_spacing.scss +1 -1
  279. package/scss/utils/_stacks.scss +34 -164
  280. package/generated/confirmation-dialog/index.d.ts +0 -1
  281. package/generated/confirmation-dialog/index.js +0 -1
  282. package/generated/internal/utils/cash/index.d.ts +0 -22
  283. package/generated/internal/utils/cash/index.js +0 -23
  284. package/generated/lifecycle-observer/index.d.ts +0 -1
  285. package/generated/lifecycle-observer/index.js +0 -1
  286. package/scss/transitions/_dialog.scss +0 -28
  287. package/web-components.html-data/en.json +0 -330
  288. /package/generated/internal/utils/{cash/ancestors.d.ts → ancestors.d.ts} +0 -0
  289. /package/generated/internal/utils/{cash/ancestors.js → ancestors.js} +0 -0
  290. /package/generated/internal/utils/{cash/next-all.d.ts → next-all.d.ts} +0 -0
  291. /package/generated/internal/utils/{cash/next-all.js → next-all.js} +0 -0
  292. /package/generated/internal/utils/{cash/next.d.ts → next.d.ts} +0 -0
  293. /package/generated/internal/utils/{cash/next.js → next.js} +0 -0
  294. /package/generated/internal/utils/{cash/prev-all.d.ts → prev-all.d.ts} +0 -0
  295. /package/generated/internal/utils/{cash/prev-all.js → prev-all.js} +0 -0
  296. /package/generated/internal/utils/{cash/prev.d.ts → prev.d.ts} +0 -0
  297. /package/generated/internal/utils/{cash/prev.js → prev.js} +0 -0
  298. /package/generated/internal/utils/{cash/prop.d.ts → prop.d.ts} +0 -0
  299. /package/generated/internal/utils/{cash/prop.js → prop.js} +0 -0
  300. /package/generated/internal/utils/{cash/siblings.d.ts → siblings.d.ts} +0 -0
  301. /package/generated/internal/utils/{cash/siblings.js → siblings.js} +0 -0
@@ -1,83 +1,84 @@
1
- import { $ } from '../internal/utils';
1
+ import { $, debug } from '../internal/utils';
2
+ import { queryMorph } from '../morphdom';
3
+ import { html } from '../tpl';
4
+ /**
5
+ * @summary A view that labels items with an icon and a title.
6
+ *
7
+ * @example <label-view><span>Hello world!</span></label-view> — Creating a label using a `span` element
8
+ * @example <label-view title="Hello world!"></label-view> — Creating a label using the `title` attribute
9
+ * @example <label-view system-image="hand-waving"><span>Hello world!</span></label-view> — Creating a label with an icon and a title using the `system-image` attribute
10
+ * @example <label-view><i slot="icon" class="ph ph-duotone ph-hand-waving"></i><span>Hello world!</span></label-view> — Creating a label with an icon and a title using the `icon` slot
11
+ *
12
+ * @attr {@Font} font — Sets the default font for text in this view.
13
+ *
14
+ * @slot — Any children without a `slot` attribute are placed in the title block.
15
+ * @slot icon — Use the `slot="icon"` attribute to place childen in the icon block.
16
+ *
17
+ * @cssprop {length} --label-gap — The gap between the icon and the title.
18
+ * @cssprop {number} --label-image-size — The size of the icon.
19
+ * @cssprop {length}--label-padding-inline — The padding inline of the label.
20
+ *
21
+ */
2
22
  export class LabelView extends HTMLElement {
3
23
  static get observedAttributes() {
4
- return ['system-image', 'title', 'line-limit', 'truncation-mode'];
24
+ return [
25
+ 'system-image',
26
+ 'title',
27
+ 'line-limit',
28
+ /**
29
+ * @type {"tail"}
30
+ */
31
+ 'truncation-mode',
32
+ ];
5
33
  }
6
34
  static #template;
7
35
  static get template() {
8
- return (this.#template ??= $(String.raw `
9
- <div part="root label-image-stack">
10
- <slot name="image"></slot>
11
- </div>
12
- <div part="root label-title-stack">
13
- <slot></slot>
14
- </div>`, ''));
36
+ return (this.#template ??= $(html `
37
+ <slot name="icon"></slot>
38
+ <slot></slot>
39
+ `));
40
+ // String.raw`
41
+ // <div part="root label-image-stack">
42
+ // <slot name="image"></slot>
43
+ // </div>
44
+ // <div part="root label-title-stack">
45
+ // <slot></slot>
46
+ // </div>`
15
47
  }
16
48
  #shadowRoot;
17
- // #imgSlot?: HTMLSlotElement
18
- // #slot?: HTMLSlotElement
49
+ // #reflectScheduled = false
19
50
  constructor() {
20
51
  super();
21
52
  this.#shadowRoot = this.attachShadow({ mode: 'closed' });
22
- // Snapshot.waitReady.then(() => {
23
53
  this.#shadowRoot.appendChild(document.importNode(this.constructor.template, true));
24
- // // this.#imgSlot = this.#shadowRoot.querySelector<HTMLSlotElement>('slot[name=image]') ?? undefined
25
- // // this.#slot = this.#shadowRoot.querySelector<HTMLSlotElement>('slot:not([name])') ?? undefined
26
- //
27
- // // this.#slot?.addEventListener('slotchange', this.#handleSlotchange)
28
- // // // this.#imgSlot?.addEventListener('slotchange', this.#handleSlotchange)
29
- // // // this.#handleSlotchange(new CustomEvent('slotchange'))
30
- // })
31
- }
32
- disconnectedCallback() {
33
- console.debug(`${LabelView.name} ⚡️ disconnect`);
34
- // this.#slot?.removeEventListener('slotchange', this.#handleSlotchange)
35
- }
36
- connectedCallback() {
37
- console.debug(`${LabelView.name} ⚡️ connect`);
38
54
  }
39
55
  attributeChangedCallback(name, oldValue, newValue) {
40
- console.debug(`${LabelView.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
41
- // Snapshot.waitReady.then(() => {
56
+ debug(`${LabelView.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
57
+ if (oldValue === newValue)
58
+ return;
59
+ // this.#scheduleReflect()
42
60
  switch (name) {
61
+ // case 'system-image':
62
+ // case 'title':
63
+ // render(
64
+ // html`${this.getAttribute('title') ? html`<span>${this.getAttribute('title')}</span>` : null}${this.getAttribute('system-image')
65
+ // ? html`<image-view slot="icon" system-name="${this.getAttribute('system-image')}"></image-view>`
66
+ // : null}`,
67
+ // this
68
+ // )
69
+ // break
43
70
  case 'system-image':
44
- let image = this.querySelector(':scope>[slot=image]');
45
- if (newValue) {
46
- image ??= this.appendChild($(`<i slot="image"></i>`));
47
- image.setAttribute('class', `ph ph-${newValue}`);
48
- }
49
- else
50
- image?.remove();
51
- // // const imgSlot = this.#shadowRoot.querySelector<HTMLSlotElement>('slot[name=image]')
52
- // // if (!imgSlot) break
53
- // const assigned = this.#imgSlot!.assignedElements({ flatten: true }) as HTMLElement[]
54
- // let el = assigned[0] as HTMLElement | undefined
55
- // if (!el) {
56
- // el = document.createElement('i')
57
- // el.slot = 'image'
58
- // this.append(el)
59
- // }
60
- // el.setAttribute('class', `ph ph-${newValue}`)
71
+ queryMorph('[slot=icon]', html `<image-view slot="icon" system-name="${newValue}"></image-view>`, this, { removeIf: !newValue });
61
72
  break;
62
73
  case 'title':
63
- let title = this.querySelector(':scope>:not([slot])');
64
- if (newValue) {
65
- title ??= this.appendChild($(`<span></span>`));
66
- title.textContent = newValue;
67
- }
68
- else
69
- title?.remove();
70
- // // const titleSlot = this.#shadowRoot.querySelector<HTMLSlotElement>('slot:not([name])')
71
- // // if (!titleSlot) break
72
- // const title = this.#slot!.assignedElements({ flatten: true }) as HTMLElement[]
73
- // let el2 = title[0] as HTMLElement | undefined
74
- // if (!el2) {
75
- // el2 = document.createElement('span')
76
- // this.append(el2)
77
- // }
78
- // el2.textContent = newValue //el2.replaceChildren(escapeHTMLPolicy.createHTML(newValue))
74
+ queryMorph(':not([slot])', html `<span>${newValue}</span>`, this, { removeIf: !newValue });
79
75
  break;
80
76
  }
81
- // })
77
+ }
78
+ disconnectedCallback() {
79
+ debug(`${LabelView.name} ⚡️ disconnect`);
80
+ }
81
+ connectedCallback() {
82
+ debug(`${LabelView.name} ⚡️ connect`);
82
83
  }
83
84
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @summary A container view that pairs a label with a value.
3
+ *
4
+ * @example <labeled-content label="Label" value="Content"></labeled-content> — Creates a standard labeled element, with a view that conveys the value of the element and a label
5
+ *
6
+ * @example <labeled-content label="Height" value="6" format="unit::unit=foot"></labeled-content> — Creates a labeled element from a formatted value
7
+ *
8
+ * @example <labeled-content value="Content"><label-view slot="label" title="Custom Value"></label-view><label-view slot="label" title="Custom Subtitle Value"></label-view></labeled-content> — Creates a labeled element that displays a custom label and a custom subtitle to the label
9
+ *
10
+ * @slot — The default slot.
11
+ * @slot label — Use the `slot="label"` attribute to place childen in the label block.
12
+ * @slot header
13
+ * @slot footer
14
+ *
15
+ * @csspart labeled-content-container
16
+ * @csspart labeled-content-stack
17
+ * @csspart labeled-content-label-stack
18
+ * @csspart labeled-content-value-stack
19
+ */
20
+ export declare class LabeledContent extends HTMLElement {
21
+ #private;
22
+ static get observedAttributes(): string[];
23
+ static get template(): DocumentFragment;
24
+ constructor();
25
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
26
+ disconnectedCallback(): void;
27
+ connectedCallback(): void;
28
+ }
29
+ declare global {
30
+ interface HTMLElementTagNameMap {
31
+ 'labeled-content': LabeledContent;
32
+ }
33
+ }
@@ -0,0 +1,160 @@
1
+ import { $, debug } from '../internal/utils';
2
+ import { queryMorph } from '../morphdom';
3
+ import { html } from '../tpl';
4
+ /**
5
+ * @summary A container view that pairs a label with a value.
6
+ *
7
+ * @example <labeled-content label="Label" value="Content"></labeled-content> — Creates a standard labeled element, with a view that conveys the value of the element and a label
8
+ *
9
+ * @example <labeled-content label="Height" value="6" format="unit::unit=foot"></labeled-content> — Creates a labeled element from a formatted value
10
+ *
11
+ * @example <labeled-content value="Content"><label-view slot="label" title="Custom Value"></label-view><label-view slot="label" title="Custom Subtitle Value"></label-view></labeled-content> — Creates a labeled element that displays a custom label and a custom subtitle to the label
12
+ *
13
+ * @slot — The default slot.
14
+ * @slot label — Use the `slot="label"` attribute to place childen in the label block.
15
+ * @slot header
16
+ * @slot footer
17
+ *
18
+ * @csspart labeled-content-container
19
+ * @csspart labeled-content-stack
20
+ * @csspart labeled-content-label-stack
21
+ * @csspart labeled-content-value-stack
22
+ */
23
+ export class LabeledContent extends HTMLElement {
24
+ static get observedAttributes() {
25
+ return [
26
+ 'value',
27
+ 'label',
28
+ 'header',
29
+ 'footer',
30
+ /**
31
+ * Use this to force a specific style.
32
+ *
33
+ * @type {vertical|horizontal}
34
+ */
35
+ 'labeled-content-style',
36
+ /**
37
+ * Use this to format the text inside the value attribute. For example `format="currency::currency=USD" value="1234.5"` produces a value of `$1,234.50`.
38
+ *
39
+ * @type {"<format-type>:<locale?>:<format-options?>"}
40
+ */
41
+ 'format',
42
+ ];
43
+ }
44
+ static #template;
45
+ static get template() {
46
+ return (this.#template ??= $(html `
47
+ <div part="root labeled-content-container">
48
+ <slot name="header"></slot>
49
+ <div part="root labeled-content-stack">
50
+ <div part="root labeled-content-label-stack">
51
+ <slot name="label"></slot>
52
+ </div>
53
+ <div part="root labeled-content-value-stack">
54
+ <slot></slot>
55
+ </div>
56
+ </div>
57
+ <slot name="footer"></slot>
58
+ </div>
59
+ `));
60
+ }
61
+ #shadowRoot;
62
+ constructor() {
63
+ super();
64
+ this.#shadowRoot = this.attachShadow({ mode: 'closed' });
65
+ this.#shadowRoot.appendChild(document.importNode(this.constructor.template, true));
66
+ }
67
+ attributeChangedCallback(name, oldValue, newValue) {
68
+ debug(`${LabeledContent.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
69
+ if (oldValue === newValue)
70
+ return;
71
+ switch (name) {
72
+ case 'header':
73
+ queryMorph('[slot=header]', html `<header slot="header">
74
+ <label-view font="callout">
75
+ <span>${newValue}</span>
76
+ </label-view>
77
+ </header>`, this, { removeIf: !newValue });
78
+ break;
79
+ case 'footer':
80
+ queryMorph('[slot=footer]', html `<footer slot="footer">
81
+ <label-view font="callout">
82
+ <span>${newValue}</span>
83
+ </label-view>
84
+ </footer>`, this, { removeIf: !newValue });
85
+ break;
86
+ case 'value': {
87
+ const val = this.#fmt(newValue, this.getAttribute('format'));
88
+ queryMorph('label-view:not([slot])', html `<label-view>${val ? html `<span>${val}</span>` : null}</label-view>`, this);
89
+ break;
90
+ }
91
+ case 'format': {
92
+ const val = this.#fmt(this.getAttribute('value'), newValue);
93
+ queryMorph('label-view:not([slot])', html `<label-view>${val ? html `<span>${val}</span>` : null}</label-view>`, this);
94
+ break;
95
+ }
96
+ case 'label':
97
+ queryMorph('[slot=label]', html `<label-view slot="label">${newValue ? html `<span>${newValue}</span>` : null}</label-view>`, this);
98
+ break;
99
+ }
100
+ }
101
+ disconnectedCallback() {
102
+ debug(`${LabeledContent.name} ⚡️ disconnect`);
103
+ }
104
+ connectedCallback() {
105
+ debug(`${LabeledContent.name} ⚡️ connect`);
106
+ }
107
+ // <type>:<locale>;<option>=<value>;<option>=<value>
108
+ #fmt = (value, format) => {
109
+ const parseFormat = (format) => {
110
+ if (!format)
111
+ return {
112
+ type: 'text',
113
+ locale: navigator.language,
114
+ options: {},
115
+ };
116
+ const [type, locale, opts = {}] = format.split(':', 3), loc = new Intl.Locale(locale || navigator.language), options = Object.fromEntries(new URLSearchParams(opts));
117
+ return {
118
+ type,
119
+ locale: loc.toString(),
120
+ options,
121
+ };
122
+ };
123
+ const { type, locale, options } = parseFormat(format);
124
+ switch (type) {
125
+ case 'currency':
126
+ return new Intl.NumberFormat(locale, { style: 'currency', ...options }).format(Number(value)); // currency:en-US;currency=USD "$1,234.50"
127
+ case 'percent':
128
+ return new Intl.NumberFormat(locale, { style: 'percent' }).format(Number(value)); // percent:en-US "42%"
129
+ case 'unit':
130
+ return new Intl.NumberFormat(locale, { style: 'unit', ...options }).format(Number(value)); // percent:en-US:unit=kilometer-per-hour "50 km/h"
131
+ case 'number':
132
+ return new Intl.NumberFormat(locale, options).format(Number(value)); // number:en-US:notation=compact "1.2M"
133
+ case 'date':
134
+ return new Intl.DateTimeFormat(locale, options).format(new Date(value ?? '2000')); // { dateStyle: 'full', timeStyle: 'short' } "Saturday, July 4, 2026 at 2:30 PM"
135
+ case 'relative-time': {
136
+ const [number = 0, unit = 'day'] = value?.split('~') ?? [];
137
+ return new Intl.RelativeTimeFormat(locale, options).format(Number(number), unit); // -1~day { numeric: 'auto' } "yesterday"
138
+ }
139
+ case 'list':
140
+ return new Intl.ListFormat(locale, options).format(value?.split('~') ?? []); // '' { style: 'long', type: 'conjunction' } "Foo, Bar, and Baz"
141
+ case 'region':
142
+ return value ? new Intl.DisplayNames(locale, { type: 'region' }).of(value) : ''; // "Greece"
143
+ case 'byte-count': {
144
+ const bytes = Number(value);
145
+ if (!Number.isFinite(bytes))
146
+ return value;
147
+ const units = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte', 'exabyte'];
148
+ const index = Math.min(Math.floor(Math.log(Math.abs(bytes)) / Math.log(1024)), units.length - 1);
149
+ return new Intl.NumberFormat(locale, {
150
+ style: 'unit',
151
+ unit: units[Math.max(0, index)],
152
+ unitDisplay: 'short',
153
+ ...options,
154
+ }).format(bytes / 1024 ** Math.max(0, index));
155
+ }
156
+ default:
157
+ return value;
158
+ }
159
+ };
160
+ }
@@ -1,5 +1,19 @@
1
+ /**
2
+ * @summary A container view that arranges rows of data in a single column, optionally letting the user select one or more of them.
3
+ *
4
+ * @attr {hidden} navigation-link-indicator-visibility — Hides accessories like right-arrow-chevron on NavigationLink buttons inside
5
+ * @attr {sidebar} preferred-root-disclosure-style
6
+ *
7
+ * @cssprop {length} --list-row-gap — The gap between rows
8
+ * @cssprop {length} --list--media-inner-padding-inline-start — The inline paddint start for each row
9
+ */
1
10
  export declare class ListView extends HTMLElement {
2
11
  constructor();
3
12
  disconnectedCallback(): void;
4
13
  connectedCallback(): void;
5
14
  }
15
+ declare global {
16
+ interface HTMLElementTagNameMap {
17
+ 'list-view': ListView;
18
+ }
19
+ }
@@ -1,29 +1,24 @@
1
1
  import { CleanupRegistry } from '../internal/class/cleanup-registry';
2
- import { listActive, onoff } from '../internal/utils';
2
+ import { debug, listActive, onoff } from '../internal/utils';
3
+ /**
4
+ * @summary A container view that arranges rows of data in a single column, optionally letting the user select one or more of them.
5
+ *
6
+ * @attr {hidden} navigation-link-indicator-visibility — Hides accessories like right-arrow-chevron on NavigationLink buttons inside
7
+ * @attr {sidebar} preferred-root-disclosure-style
8
+ *
9
+ * @cssprop {length} --list-row-gap — The gap between rows
10
+ * @cssprop {length} --list--media-inner-padding-inline-start — The inline paddint start for each row
11
+ */
3
12
  export class ListView extends HTMLElement {
4
- // static formAssociated = true
5
- // #internals
6
- // #options
7
- // #focusedIndex = 0
8
- // #selected = new Set()
9
13
  constructor() {
10
14
  super();
11
- // this.#internals = this.attachInternals()
12
- // this.tabIndex = 0
13
15
  }
14
16
  disconnectedCallback() {
15
- console.debug(`${ListView.name} ⚡️ disconnect`);
17
+ debug(`${ListView.name} ⚡️ disconnect`);
16
18
  CleanupRegistry.unregister(this);
17
19
  }
18
20
  connectedCallback() {
19
- console.debug(`${ListView.name} ⚡️ connect`);
21
+ debug(`${ListView.name} ⚡️ connect`);
20
22
  CleanupRegistry.register(this, onoff(listActive(this), this).on());
21
- // this.setAttribute('role', 'listbox')
22
- // this.setAttribute('aria-multiselectable', 'true')
23
- // this.#options = Array.from(this.querySelectorAll('[option]'))
24
- // this.addEventListener('pointerleave', this.#onCancel)
25
- // this.addEventListener('click', this.#onClick)
26
- // this.addEventListener('keydown', this.#onKeyDown)
27
- // this.#updateOptionAttributes()
28
23
  }
29
24
  }
@@ -1,9 +1,20 @@
1
+ /**
2
+ * @summary A control that opens a menu of actions.
3
+ *
4
+ * @slot — The default slot.
5
+ * @slot label
6
+ */
1
7
  export declare class MenuView extends HTMLElement {
2
8
  #private;
3
9
  static get observedAttributes(): string[];
4
10
  static get template(): DocumentFragment;
5
11
  constructor();
12
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
6
13
  disconnectedCallback(): void;
7
14
  connectedCallback(): void;
8
- attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
15
+ }
16
+ declare global {
17
+ interface HTMLElementTagNameMap {
18
+ 'menu-view': MenuView;
19
+ }
9
20
  }
@@ -1,23 +1,30 @@
1
1
  var _a;
2
2
  import { CleanupRegistry } from '../internal/class/cleanup-registry';
3
- import { $, onoff, touchGlass } from '../internal/utils';
3
+ import { $, debug, onoff, touchGlass } from '../internal/utils';
4
+ import { queryMorph } from '../morphdom';
5
+ import { html } from '../tpl';
6
+ /**
7
+ * @summary A control that opens a menu of actions.
8
+ *
9
+ * @slot — The default slot.
10
+ * @slot label
11
+ */
4
12
  export class MenuView extends HTMLElement {
5
13
  static get observedAttributes() {
6
14
  return ['open', 'closing', 'label'];
7
15
  }
8
16
  static #template;
9
17
  static get template() {
10
- return (this.#template ??= $(String.raw `
11
- <button type="button" part="root button menu-summary">
12
- <slot name="label"></slot>
13
- </button>
14
- <dialog part="root menu-dialog" autofocus inert>
15
- <form part="root menu-form" method="dialog" novalidate>
16
- <div part="root menu-scrollable">
17
- <slot></slot>
18
- </div>
19
- </form>
20
- </dialog>`, ''));
18
+ return (this.#template ??= $(html `<button type="button" part="root button menu-summary">
19
+ <slot name="label"></slot>
20
+ </button>
21
+ <dialog part="root menu-dialog" autofocus inert>
22
+ <form part="root menu-form" method="dialog" novalidate>
23
+ <div part="root menu-scrollable">
24
+ <slot></slot>
25
+ </div>
26
+ </form>
27
+ </dialog>`));
21
28
  }
22
29
  #shadowRoot;
23
30
  #dialog;
@@ -26,50 +33,15 @@ export class MenuView extends HTMLElement {
26
33
  this.#shadowRoot = this.attachShadow({ mode: 'closed' });
27
34
  this.#shadowRoot.appendChild(document.importNode(this.constructor.template, true));
28
35
  }
29
- disconnectedCallback() {
30
- console.debug(`${_a.name} ⚡️ disconnect`);
31
- // const dialog = this.#shadowRoot.querySelector('dialog'),
32
- // trigger = this.#shadowRoot.querySelector('button')
33
- // trigger?.removeEventListener('click', this.#handleTriggerClick)
34
- // dialog?.removeEventListener('click', this.#handleDialogClick)
35
- // dialog?.removeEventListener('close', this.#handleDialogClose)
36
- // dialog?.removeEventListener('cancel', this.#handleDialogCancel)
37
- const summaryPart = this.#shadowRoot.querySelector('[part*=menu-summary]'), dialogPart = this.#shadowRoot.querySelector('[part*=menu-dialog]');
38
- summaryPart?.style.removeProperty('anchor-name'); //$.prop('anchor-name', null, summaryPart)
39
- dialogPart?.style.removeProperty('position-anchor'); //$.prop('position-anchor', null, dialogPart)
40
- CleanupRegistry.unregister(this);
41
- }
42
- connectedCallback() {
43
- console.debug(`${_a.name} ⚡️ connect`);
44
- this.#dialog = this.#shadowRoot.querySelector('dialog') ?? undefined;
45
- const trigger = this.#shadowRoot.querySelector('button') ?? undefined;
46
- CleanupRegistry.register(this, onoff('click', this.#handleTriggerClick, trigger).on());
47
- CleanupRegistry.register(this, onoff([
48
- { types: 'click', listener: this.#handleDialogClick },
49
- { types: 'close', listener: this.#handleDialogClose },
50
- { types: 'cancel', listener: this.#handleDialogCancel },
51
- ], this.#dialog).on());
52
- CleanupRegistry.register(this, onoff(touchGlass(this, (t) => t, (evt) => {
53
- if (evt.target.matches('menu-view'))
54
- return false;
55
- if (!evt.target.closest('menu-view[open]'))
56
- return false;
57
- return true;
58
- }), this).on());
59
- const newAnchorName = `--menu-view-${self.crypto.randomUUID()}`;
60
- const summaryPart = this.#shadowRoot.querySelector('[part*=menu-summary]'), dialogPart = this.#shadowRoot.querySelector('[part*=menu-dialog]');
61
- summaryPart?.style.setProperty('anchor-name', newAnchorName, 'important'); // override unset:all // $.prop('anchor-name', newAnchorName, summaryPart, 'important') //
62
- dialogPart?.style.setProperty('position-anchor', newAnchorName); // $.prop('position-anchor', newAnchorName, dialogPart) //
63
- }
64
36
  attributeChangedCallback(name, oldValue, newValue) {
65
- console.debug(`${_a.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
37
+ debug(`${_a.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
66
38
  switch (name) {
67
39
  case 'open':
68
40
  if (!this.#dialog)
69
41
  break;
70
42
  this.#dialog.inert = null === newValue;
71
43
  if (null === newValue && this.#dialog.open) {
72
- console.debug(`${_a.name} ⚡️ will-close`);
44
+ debug(`${_a.name} ⚡️ will-close`);
73
45
  this.setAttribute('closing', '');
74
46
  Promise.allSettled(this.#dialog.getAnimations().map(({ finished }) => finished)).then(() => {
75
47
  if (!this.hasAttribute('closing'))
@@ -79,7 +51,7 @@ export class MenuView extends HTMLElement {
79
51
  });
80
52
  }
81
53
  if ('' === newValue && !this.#dialog.open) {
82
- console.debug(`${_a.name} ⚡️ will-open`);
54
+ debug(`${_a.name} ⚡️ will-open`);
83
55
  this.removeAttribute('closing');
84
56
  const form = this.#shadowRoot.querySelector('form');
85
57
  form.scrollTop = 0;
@@ -87,46 +59,72 @@ export class MenuView extends HTMLElement {
87
59
  }
88
60
  break;
89
61
  case 'label':
90
- let label = this.querySelector(':scope>[slot=label]');
91
- if (newValue) {
92
- label ??= this.appendChild($(`<label-view slot="label"></label-view>`));
93
- label.setAttribute('title', newValue);
94
- }
95
- else
96
- label?.remove();
62
+ queryMorph('[slot=label]', html `<label-view slot="label">${newValue ? html `<span>${newValue}</span>` : null}</label-view>`, this);
97
63
  break;
98
64
  }
99
65
  }
100
- #handleDialogClick = (evt) => {
101
- console.debug(`${_a.name} ⚡️ ${evt?.type}`);
102
- if (evt.target.matches('dialog'))
66
+ disconnectedCallback() {
67
+ debug(`${_a.name} ⚡️ disconnect`);
68
+ const summaryPart = this.#shadowRoot.querySelector('[part*=menu-summary]'), dialogPart = this.#shadowRoot.querySelector('[part*=menu-dialog]');
69
+ summaryPart?.style.removeProperty('anchor-name'); //$.prop('anchor-name', null, summaryPart)
70
+ dialogPart?.style.removeProperty('position-anchor'); //$.prop('position-anchor', null, dialogPart)
71
+ CleanupRegistry.unregister(this);
72
+ }
73
+ connectedCallback() {
74
+ debug(`${_a.name} ⚡️ connect`);
75
+ this.#dialog = this.#shadowRoot.querySelector('dialog') ?? undefined;
76
+ const trigger = this.#shadowRoot.querySelector('button') ?? undefined;
77
+ CleanupRegistry.register(this, onoff('click', this.#handleTriggerClick, trigger).on());
78
+ CleanupRegistry.register(this, onoff([
79
+ { types: 'click', listener: this.#handleDialogClick },
80
+ { types: 'close', listener: this.#handleDialogClose },
81
+ { types: 'cancel', listener: this.#handleDialogCancel },
82
+ ], this.#dialog).on());
83
+ CleanupRegistry.register(this, onoff(touchGlass(this, (t) => t, ({ target }) => {
84
+ if (!(target instanceof HTMLElement))
85
+ return true;
86
+ if (target.matches('menu-view'))
87
+ return false;
88
+ if (!target.closest('menu-view[open]'))
89
+ return false;
90
+ return true;
91
+ }), this).on());
92
+ const newAnchorName = `--menu-view-${self.crypto.randomUUID()}`;
93
+ const summaryPart = this.#shadowRoot.querySelector('[part*=menu-summary]'), dialogPart = this.#shadowRoot.querySelector('[part*=menu-dialog]');
94
+ summaryPart?.style.setProperty('anchor-name', newAnchorName, 'important'); // override unset:all // $.prop('anchor-name', newAnchorName, summaryPart, 'important') //
95
+ dialogPart?.style.setProperty('position-anchor', newAnchorName); // $.prop('position-anchor', newAnchorName, dialogPart) //
96
+ }
97
+ #handleDialogClick = ({ type, target }) => {
98
+ debug(`${_a.name} ⚡️ ${type}`);
99
+ if (!(target instanceof HTMLElement))
100
+ return;
101
+ if (target.matches('dialog'))
103
102
  return this.toggleAttribute('open', false); // click outside
104
- const target = evt.target;
105
103
  target.scrollIntoView({
106
104
  behavior: self.matchMedia('(prefers-reduced-motion: no-preference)').matches ? 'smooth' : 'instant',
107
105
  block: 'nearest',
108
106
  inline: 'nearest',
109
107
  });
110
- if (!evt.target.closest('button'))
108
+ if (!target.closest('button'))
111
109
  return;
112
110
  // TODO: Handle btns this.toggleAttribute('open', false)
113
111
  this.toggleAttribute('open', false);
114
112
  // event.stopPropagation() //NOTE: add this only if not nested, disposes all nicely if ommited
115
113
  };
116
114
  #handleTriggerClick = (evt) => {
117
- console.debug(`${_a.name} ⚡️ ${evt?.type}`);
115
+ debug(`${_a.name} ⚡️ ${evt?.type}`);
118
116
  this.toggleAttribute('open', true);
119
117
  };
120
118
  // intercept to modify open attr
121
119
  #handleDialogCancel = (evt) => {
122
- console.debug(`${_a.name} ⚡️ ${evt?.type}`);
120
+ debug(`${_a.name} ⚡️ ${evt?.type}`);
123
121
  if (!evt.cancelable)
124
122
  return;
125
123
  evt.preventDefault();
126
124
  this.toggleAttribute('open', false);
127
125
  };
128
126
  #handleDialogClose = (evt) => {
129
- console.debug(`${_a.name} ⚡️ ${evt?.type}`);
127
+ debug(`${_a.name} ⚡️ ${evt?.type}`);
130
128
  this.toggleAttribute('open', this.#shadowRoot.querySelector('dialog')?.open ?? false);
131
129
  };
132
130
  }
@@ -1,6 +1,17 @@
1
+ /**
2
+ *
3
+ * @attr {boolean} padding
4
+ * @attr {boolean} navigation-bar-auto-hide
5
+ *
6
+ */
1
7
  export declare class NavigationLargeTitle extends HTMLElement {
2
8
  #private;
3
9
  constructor();
4
10
  disconnectedCallback(): void;
5
11
  connectedCallback(): void;
6
12
  }
13
+ declare global {
14
+ interface HTMLElementTagNameMap {
15
+ 'navigation-large-title': NavigationLargeTitle;
16
+ }
17
+ }