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

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 (262) hide show
  1. package/README.md +15 -0
  2. package/generated/client/index.d.ts +16 -2
  3. package/generated/client/index.js +293 -8
  4. package/generated/components/body-view.d.ts +5 -0
  5. package/generated/components/body-view.js +11 -0
  6. package/generated/components/bordered-button.d.ts +7 -0
  7. package/generated/components/bordered-button.js +20 -0
  8. package/generated/components/bordered-prominent-button.d.ts +7 -0
  9. package/generated/components/bordered-prominent-button.js +20 -0
  10. package/generated/components/borderless-button.d.ts +9 -0
  11. package/generated/components/borderless-button.js +35 -0
  12. package/generated/components/confirmation-dialog.d.ts +9 -0
  13. package/generated/components/confirmation-dialog.js +102 -0
  14. package/generated/components/date-picker.d.ts +46 -0
  15. package/generated/components/date-picker.js +430 -0
  16. package/generated/components/disclosure-group.d.ts +9 -0
  17. package/generated/components/disclosure-group.js +51 -0
  18. package/generated/components/form-view.d.ts +6 -0
  19. package/generated/components/form-view.js +58 -0
  20. package/generated/components/glass-button.d.ts +6 -0
  21. package/generated/components/glass-button.js +17 -0
  22. package/generated/components/glass-prominent-button.d.ts +6 -0
  23. package/generated/components/glass-prominent-button.js +17 -0
  24. package/generated/components/index.d.ts +39 -1
  25. package/generated/components/index.js +38 -5
  26. package/generated/components/label-view.d.ts +9 -0
  27. package/generated/components/label-view.js +83 -0
  28. package/generated/components/list-view.d.ts +5 -0
  29. package/generated/components/list-view.js +29 -0
  30. package/generated/components/menu-view.d.ts +9 -0
  31. package/generated/components/menu-view.js +133 -0
  32. package/generated/components/navigation-large-title.d.ts +6 -0
  33. package/generated/components/navigation-large-title.js +177 -0
  34. package/generated/components/navigation-split-view.d.ts +7 -0
  35. package/generated/components/navigation-split-view.js +18 -0
  36. package/generated/components/navigation-stack.d.ts +7 -0
  37. package/generated/components/navigation-stack.js +24 -0
  38. package/generated/components/navigation-title.d.ts +8 -0
  39. package/generated/components/navigation-title.js +66 -0
  40. package/generated/components/picker-view.d.ts +27 -0
  41. package/generated/components/picker-view.js +442 -0
  42. package/generated/components/plain-button.d.ts +7 -0
  43. package/generated/components/plain-button.js +20 -0
  44. package/generated/components/screen-view.d.ts +5 -0
  45. package/generated/components/screen-view.js +9 -0
  46. package/generated/components/scroll-view.d.ts +10 -0
  47. package/generated/components/scroll-view.js +187 -0
  48. package/generated/components/section-view.d.ts +9 -0
  49. package/generated/components/section-view.js +81 -0
  50. package/generated/components/sheet-view.d.ts +9 -0
  51. package/generated/components/sheet-view.js +69 -0
  52. package/generated/components/sidebar-toggle.d.ts +7 -0
  53. package/generated/components/sidebar-toggle.js +107 -0
  54. package/generated/components/sidebar-view.d.ts +7 -0
  55. package/generated/components/sidebar-view.js +29 -0
  56. package/generated/components/sticky-container.d.ts +6 -0
  57. package/generated/components/sticky-container.js +22 -0
  58. package/generated/components/tab-bar.d.ts +7 -0
  59. package/generated/components/tab-bar.js +33 -0
  60. package/generated/components/tab-item.d.ts +7 -0
  61. package/generated/components/tab-item.js +120 -0
  62. package/generated/components/tab-view.d.ts +22 -0
  63. package/generated/components/tab-view.js +256 -0
  64. package/generated/components/table-view.d.ts +7 -0
  65. package/generated/components/table-view.js +175 -0
  66. package/generated/components/text-field.d.ts +29 -0
  67. package/generated/components/text-field.js +489 -0
  68. package/generated/components/tool-bar-item-group.d.ts +5 -0
  69. package/generated/components/tool-bar-item-group.js +11 -0
  70. package/generated/components/tool-bar-item.d.ts +5 -0
  71. package/generated/components/tool-bar-item.js +19 -0
  72. package/generated/components/tool-bar.d.ts +7 -0
  73. package/generated/components/tool-bar.js +77 -0
  74. package/generated/components/v-keyboard.d.ts +11 -0
  75. package/generated/components/v-keyboard.js +81 -0
  76. package/generated/components/v-stack.d.ts +5 -0
  77. package/generated/components/v-stack.js +11 -0
  78. package/generated/confirmation-dialog/index.d.ts +1 -0
  79. package/generated/confirmation-dialog/index.js +1 -0
  80. package/generated/css/index.css +7463 -0
  81. package/generated/events/confirmation-dialog.d.ts +9 -0
  82. package/generated/events/confirmation-dialog.js +1 -0
  83. package/generated/events/date-picker.d.ts +8 -0
  84. package/generated/events/date-picker.js +1 -0
  85. package/generated/events/index.d.ts +7 -0
  86. package/generated/events/index.js +7 -0
  87. package/generated/events/lifecycle-observer.d.ts +10 -0
  88. package/generated/events/lifecycle-observer.js +1 -0
  89. package/generated/events/picker-view.d.ts +8 -0
  90. package/generated/events/picker-view.js +1 -0
  91. package/generated/events/scroll-view.d.ts +10 -0
  92. package/generated/events/scroll-view.js +1 -0
  93. package/generated/events/tab-view.d.ts +24 -0
  94. package/generated/events/tab-view.js +1 -0
  95. package/generated/events/text-field.d.ts +8 -0
  96. package/generated/events/text-field.js +1 -0
  97. package/generated/i18n/index.d.ts +24 -0
  98. package/generated/i18n/index.js +139 -0
  99. package/generated/index.js +1 -1
  100. package/generated/internal/class/cleanup-registry.d.ts +5 -0
  101. package/generated/internal/class/cleanup-registry.js +38 -0
  102. package/generated/internal/class/css-style-observer.d.ts +8 -0
  103. package/generated/internal/class/css-style-observer.js +25 -0
  104. package/generated/internal/class/form-associated-base.d.ts +20 -0
  105. package/generated/internal/class/form-associated-base.js +93 -0
  106. package/generated/internal/class/mutation-observer-singleton.d.ts +10 -0
  107. package/generated/internal/class/mutation-observer-singleton.js +46 -0
  108. package/generated/internal/class/navigation-path.d.ts +15 -0
  109. package/generated/internal/class/navigation-path.js +84 -0
  110. package/generated/internal/class/navigation-view.d.ts +8 -0
  111. package/generated/internal/class/navigation-view.js +77 -0
  112. package/generated/internal/class/resize-observer-singleton.d.ts +7 -0
  113. package/generated/internal/class/resize-observer-singleton.js +22 -0
  114. package/generated/internal/decorators/custom-element.d.ts +5 -0
  115. package/generated/internal/decorators/custom-element.js +4 -0
  116. package/generated/internal/privateNamespace.d.ts +4 -0
  117. package/generated/internal/privateNamespace.js +1 -0
  118. package/generated/internal/utils/add.d.ts +1 -0
  119. package/generated/internal/utils/add.js +7 -0
  120. package/generated/internal/utils/cash/ancestors.d.ts +1 -0
  121. package/generated/internal/utils/cash/ancestors.js +27 -0
  122. package/generated/internal/utils/cash/index.d.ts +22 -0
  123. package/generated/internal/utils/cash/index.js +23 -0
  124. package/generated/internal/utils/cash/next-all.d.ts +1 -0
  125. package/generated/internal/utils/cash/next-all.js +10 -0
  126. package/generated/internal/utils/cash/next.d.ts +1 -0
  127. package/generated/internal/utils/cash/next.js +9 -0
  128. package/generated/internal/utils/cash/prev-all.d.ts +1 -0
  129. package/generated/internal/utils/cash/prev-all.js +10 -0
  130. package/generated/internal/utils/cash/prev.d.ts +1 -0
  131. package/generated/internal/utils/cash/prev.js +9 -0
  132. package/generated/internal/utils/cash/prop.d.ts +18 -0
  133. package/generated/internal/utils/cash/prop.js +30 -0
  134. package/generated/internal/utils/cash/siblings.d.ts +1 -0
  135. package/generated/internal/utils/cash/siblings.js +10 -0
  136. package/generated/internal/utils/clamp.d.ts +1 -0
  137. package/generated/internal/utils/clamp.js +4 -0
  138. package/generated/internal/utils/compare-big-decimals.d.ts +1 -0
  139. package/generated/internal/utils/compare-big-decimals.js +90 -0
  140. package/generated/internal/utils/css-time.d.ts +1 -0
  141. package/generated/internal/utils/css-time.js +3 -0
  142. package/generated/internal/utils/debounce.d.ts +1 -0
  143. package/generated/internal/utils/debounce.js +13 -0
  144. package/generated/internal/utils/frame.d.ts +1 -0
  145. package/generated/internal/utils/frame.js +6 -0
  146. package/generated/internal/utils/index.d.ts +17 -1
  147. package/generated/internal/utils/index.js +18 -1
  148. package/generated/internal/utils/kebab-case.d.ts +1 -1
  149. package/generated/internal/utils/kebab-case.js +3 -3
  150. package/generated/internal/utils/list-active.d.ts +7 -0
  151. package/generated/internal/utils/list-active.js +28 -0
  152. package/generated/internal/utils/microtask.d.ts +1 -0
  153. package/generated/internal/utils/microtask.js +3 -0
  154. package/generated/internal/utils/onoff.d.ts +45 -0
  155. package/generated/internal/utils/onoff.js +31 -0
  156. package/generated/internal/utils/set.d.ts +1 -0
  157. package/generated/internal/utils/set.js +7 -0
  158. package/generated/internal/utils/sleep.d.ts +1 -0
  159. package/generated/internal/utils/sleep.js +3 -0
  160. package/generated/internal/utils/slow-hide-show.d.ts +1 -0
  161. package/generated/internal/utils/slow-hide-show.js +16 -0
  162. package/generated/internal/utils/timeout.d.ts +5 -0
  163. package/generated/internal/utils/timeout.js +16 -0
  164. package/generated/internal/utils/touch-glass.d.ts +7 -0
  165. package/generated/internal/utils/touch-glass.js +19 -0
  166. package/generated/lifecycle-observer/index.d.ts +1 -0
  167. package/generated/lifecycle-observer/index.js +1 -0
  168. package/generated/namespace-browser/base.d.ts +36 -0
  169. package/generated/namespace-browser/base.js +92 -0
  170. package/generated/namespace-browser/index.d.ts +7 -0
  171. package/generated/namespace-browser/index.js +1 -0
  172. package/generated/snapshot/index.d.ts +7 -0
  173. package/generated/snapshot/index.js +37 -0
  174. package/package.json +32 -7
  175. package/scss/_base.scss +5 -0
  176. package/scss/_components.scss +75 -0
  177. package/scss/_final.scss +1 -0
  178. package/scss/_functions.scss +21 -0
  179. package/scss/_mixins.scss +3 -0
  180. package/scss/_placeholders.scss +3 -0
  181. package/scss/_transitions.scss +27 -0
  182. package/scss/_utils.scss +9 -0
  183. package/scss/_vars.scss +174 -0
  184. package/scss/base/_layout.scss +56 -0
  185. package/scss/base/_reboot.scss +158 -0
  186. package/scss/base/_root.scss +399 -0
  187. package/scss/colors/_index.scss +653 -0
  188. package/scss/components/_body-view.scss +17 -0
  189. package/scss/components/_bordered-button.scss +22 -0
  190. package/scss/components/_bordered-prominent-button.scss +19 -0
  191. package/scss/components/_borderless-button.scss +19 -0
  192. package/scss/components/_confirmation-dialog.scss +110 -0
  193. package/scss/components/_date-picker.scss +30 -0
  194. package/scss/components/_detail-placeholder.scss +155 -0
  195. package/scss/components/_disclosure-group.scss +128 -0
  196. package/scss/components/_form-view.scss +195 -0
  197. package/scss/components/_full-screen.scss +15 -0
  198. package/scss/components/_glass-button.scss +24 -0
  199. package/scss/components/_glass-prominent-button.scss +24 -0
  200. package/scss/components/_h-divider.scss +13 -0
  201. package/scss/components/_h-stack.scss +39 -0
  202. package/scss/components/_index.scss +241 -0
  203. package/scss/components/_label-view.scss +386 -0
  204. package/scss/components/_labeled-content.scss +9 -0
  205. package/scss/components/_list-view.scss +229 -0
  206. package/scss/components/_menu-view.scss +188 -0
  207. package/scss/components/_navigation-large-title.scss +27 -0
  208. package/scss/components/_navigation-split-view.scss +424 -0
  209. package/scss/components/_navigation-stack.scss +11 -0
  210. package/scss/components/_navigation-title.scss +10 -0
  211. package/scss/components/_picker-view.scss +122 -0
  212. package/scss/components/_plain-button.scss +11 -0
  213. package/scss/components/_scroll-view-proxy.scss +79 -0
  214. package/scss/components/_scroll-view-toolbars.scss +126 -0
  215. package/scss/components/_scroll-view.scss +130 -0
  216. package/scss/components/_section-view.scss +119 -0
  217. package/scss/components/_sheet-view.scss +93 -0
  218. package/scss/components/_sidebar-toggle.scss +124 -0
  219. package/scss/components/_sidebar-view.scss +53 -0
  220. package/scss/components/_sticky-container.scss +42 -0
  221. package/scss/components/_tab-bar.scss +254 -0
  222. package/scss/components/_tab-item.scss +25 -0
  223. package/scss/components/_tab-view.scss +310 -0
  224. package/scss/components/_table-column.scss +52 -0
  225. package/scss/components/_table-row.scss +172 -0
  226. package/scss/components/_table-view.scss +223 -0
  227. package/scss/components/_text-field.scss +37 -0
  228. package/scss/components/_tool-bar-item-group.scss +48 -0
  229. package/scss/components/_tool-bar-item.scss +145 -0
  230. package/scss/components/_tool-bar.scss +133 -0
  231. package/scss/components/_v-divider.scss +13 -0
  232. package/scss/components/_v-flex-stack.scss +29 -0
  233. package/scss/components/_v-keyboard.scss +14 -0
  234. package/scss/components/_v-stack.scss +18 -0
  235. package/scss/final/_touch-glass.scss +67 -0
  236. package/scss/index.scss +18 -1
  237. package/scss/mixins/_dialog.scss +88 -0
  238. package/scss/mixins/_index.scss +405 -0
  239. package/scss/placeholders/_buttons.scss +83 -0
  240. package/scss/placeholders/_lists.scss +589 -0
  241. package/scss/transitions/_bwd.navbar.scss +19 -0
  242. package/scss/transitions/_bwd.scss +39 -0
  243. package/scss/transitions/_confirmation-dialog.scss +19 -0
  244. package/scss/transitions/_dialog.scss +28 -0
  245. package/scss/transitions/_disclosure-group.scss +35 -0
  246. package/scss/transitions/_fwd.navbar.scss +41 -0
  247. package/scss/transitions/_fwd.scss +24 -0
  248. package/scss/transitions/_glass-button.scss +12 -0
  249. package/scss/transitions/_glass-prominent-button.scss +12 -0
  250. package/scss/transitions/_index.scss +74 -0
  251. package/scss/transitions/_menu-view.scss +26 -0
  252. package/scss/transitions/_navigation-split-view.scss +23 -0
  253. package/scss/transitions/_sidebar-view.scss +36 -0
  254. package/scss/transitions/_tab-bar.scss +19 -0
  255. package/scss/utils/_frame.scss +84 -0
  256. package/scss/utils/_index.scss +68 -0
  257. package/scss/utils/_scroll-view.scss +14 -0
  258. package/scss/utils/_spacing.scss +25 -0
  259. package/scss/utils/_stacks.scss +242 -0
  260. package/web-components.html-data/en.json +330 -0
  261. package/generated/internal/snapshot.d.ts +0 -5
  262. package/generated/internal/snapshot.js +0 -23
@@ -0,0 +1,187 @@
1
+ var _a;
2
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
3
+ import { ResizeObserverSingleton } from '../internal/class/resize-observer-singleton';
4
+ import { $, frame, onoff, slowHideShow } from '../internal/utils';
5
+ import { LifecycleObserver } from '../lifecycle-observer';
6
+ const observers = new ResizeObserverSingleton();
7
+ export class ScrollView extends HTMLElement {
8
+ static get observedAttributes() {
9
+ return ['navigation-title', 'navigation-inline-title', 'navigation-inline-subtitle', 'navigation-bar-title-display-mode'];
10
+ }
11
+ static #template;
12
+ static get template() {
13
+ return (this.#template ??= $(String.raw `
14
+ <slot></slot>
15
+ <div part="root scroll-view-navbar">
16
+ <div part="root scroll-view-navbar-stack">
17
+ <slot name="top-bar-principal"></slot>
18
+ </div>
19
+ </div>
20
+ <div part="root scroll-view-toolbar">
21
+ <div part="root scroll-view-toolbar-stack">
22
+ <slot name="bottom-bar-principal"></slot>
23
+ </div>
24
+ </div>`, ''));
25
+ }
26
+ #shadowRoot;
27
+ #navbarPrincipalSlot;
28
+ #isMidScroll;
29
+ #lastScrollTop = 0;
30
+ // #stopRecordingScrollTop?: boolean = false
31
+ #beforeTabSwapLastScrolltop;
32
+ constructor() {
33
+ super();
34
+ this.#shadowRoot = this.attachShadow({ mode: 'closed' });
35
+ this.#shadowRoot.appendChild(document.importNode(this.constructor.template, true));
36
+ this.#navbarPrincipalSlot = this.#shadowRoot.querySelector('slot[name=top-bar-principal]') ?? undefined;
37
+ }
38
+ disconnectedCallback() {
39
+ console.debug(`${_a.name} ⚡️ disconnect`);
40
+ CleanupRegistry.unregister(this);
41
+ observers.unobserve(this);
42
+ frame().then(() => LifecycleObserver.dispatchEvent(new CustomEvent('pagehide', { detail: { page: this }, bubbles: true, composed: true })));
43
+ }
44
+ connectedCallback() {
45
+ console.debug(`${_a.name} ⚡️ connect`);
46
+ CleanupRegistry.register(this, onoff([
47
+ // { types: 'tabreveal', listener: this.#handleTabReveal as EventListener },
48
+ { types: 'beforetabswap', listener: this.#handleTabBeforeswap },
49
+ ], this.closest('tab-view') ?? undefined).on());
50
+ CleanupRegistry.register(this, onoff([
51
+ { types: 'scroll', listener: this.#handleScroll, addOptions: { passive: true } },
52
+ { types: 'scrollend', listener: this.#handleScrollend, addOptions: { passive: true } },
53
+ ], this).on());
54
+ frame().then(() => LifecycleObserver.dispatchEvent(new CustomEvent('pageshow', { detail: { page: this }, bubbles: true, composed: true })));
55
+ observers.observe(this, this.#handleMeasure.bind(this));
56
+ // frame(this).then((r) => {
57
+ // if (!r) return
58
+ // let first = true
59
+ // observeResizeEnd(this, () => {
60
+ // if (first) {
61
+ // first = false
62
+ // return
63
+ // }
64
+ // this.dispatchEvent(new CustomEvent('resizeend', { bubbles: true, composed: true }))
65
+ // })
66
+ // })
67
+ }
68
+ attributeChangedCallback(name, oldValue, newValue) {
69
+ console.debug(`${_a.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
70
+ switch (name) {
71
+ case 'navigation-inline-title':
72
+ this.#renderNavTitle(newValue, this.getAttribute('navigation-inline-subtitle'));
73
+ break;
74
+ case 'navigation-inline-subtitle':
75
+ this.#renderNavTitle(this.getAttribute('navigation-inline-title'), newValue);
76
+ break;
77
+ case 'navigation-title':
78
+ //
79
+ break;
80
+ case 'navigation-bar-title-display-mode':
81
+ if (oldValue === newValue)
82
+ break;
83
+ if (this.closest('[hidden]'))
84
+ break; // iREPAINT ALERT! if (0 === this.offsetHeight + this.offsetWidth) break
85
+ if (!this.#isMidScroll)
86
+ break;
87
+ const title = this.#navbarPrincipalSlot?.assignedElements({ flatten: true })?.at(0);
88
+ slowHideShow('largeinline' === `${oldValue}${newValue}` ? 'show' : 'hide', title);
89
+ break;
90
+ }
91
+ }
92
+ #handleScroll = (evt) => {
93
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
94
+ if (!this.#isMidScroll)
95
+ this.#isMidScroll = true;
96
+ // if (this.#stopRecordingScrollTop) return
97
+ this.#lastScrollTop = evt.target.scrollTop;
98
+ };
99
+ #handleScrollend = (evt) => {
100
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
101
+ if (this.#isMidScroll)
102
+ this.#isMidScroll = false;
103
+ };
104
+ #handleMeasure = (entry) => {
105
+ console.debug(`${_a.name} ⚡️ measure`);
106
+ if (0 === entry.contentRect.width + entry.contentRect.height)
107
+ return;
108
+ if (undefined === this.#beforeTabSwapLastScrolltop)
109
+ return;
110
+ if (this.#beforeTabSwapLastScrolltop === this.#lastScrollTop)
111
+ return;
112
+ // this.#stopRecordingScrollTop = true
113
+ entry.target.scrollTop = this.#beforeTabSwapLastScrolltop;
114
+ // entry.target.scrollTo({
115
+ // top: this.#beforeTabSwapLastScrolltop,
116
+ // behavior: 'smooth',
117
+ // }) //
118
+ // this.#stopRecordingScrollTop = false
119
+ this.#beforeTabSwapLastScrolltop = undefined;
120
+ };
121
+ #handleTabReveal = (evt) => {
122
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
123
+ if (!evt.target?.contains(this))
124
+ return;
125
+ if (this.closest('[hidden]'))
126
+ return;
127
+ // console.log(888, this.#beforeTabSwapLastScrolltop, this.#lastScrollTop)
128
+ // this.style.setProperty('clip-path', 'inset(50%)')
129
+ // this.style.setProperty('opacity', '0.001')
130
+ // this.style.opacity = '0.001'
131
+ // console.log(99, this.style.opacity)
132
+ // self.requestAnimationFrame(() => {
133
+ // if (undefined === this.#beforeTabSwapLastScrolltop) return
134
+ // if (this.#beforeTabSwapLastScrolltop === this.#lastScrollTop) return
135
+ // this.#stopRecordingScrollTop = true
136
+ // // console.log(999, this.#beforeTabSwapLastScrolltop)
137
+ // // console.log(999, this, this.#beforeTabSwapLastScrolltop, this.#lastScrollTop)
138
+ // this.scrollTop = this.#beforeTabSwapLastScrolltop
139
+ // // this.scrollTo({
140
+ // // top: this.#beforeTabSwapLastScrolltop,
141
+ // // behavior: 'instant',
142
+ // // }) //
143
+ // this.#stopRecordingScrollTop = false
144
+ // this.#beforeTabSwapLastScrolltop = undefined
145
+ // // self.requestAnimationFrame(() => {
146
+ // // // this.style.removeProperty('opacity')
147
+ // // })
148
+ // })
149
+ };
150
+ #handleTabBeforeswap = (evt) => {
151
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
152
+ if (!evt.target?.contains(this))
153
+ return;
154
+ if (this.closest('[hidden]'))
155
+ return;
156
+ this.#beforeTabSwapLastScrolltop = this.scrollTop; //#lastScrollTop
157
+ };
158
+ centerScrollToElement(child) {
159
+ // scrollTop needed to center child
160
+ const parentRect = this.getBoundingClientRect(), childRect = child.getBoundingClientRect();
161
+ // current scroll + offset of child relative to parent
162
+ const top = this.scrollTop + childRect.top - parentRect.top - parentRect.height / 2 + childRect.height / 2;
163
+ this.scrollTo({
164
+ top,
165
+ behavior: self.matchMedia('(prefers-reduced-motion: no-preference)').matches ? 'smooth' : 'instant', // optional: smooth scroll
166
+ });
167
+ }
168
+ #renderNavTitle = (title, subtitle) => {
169
+ const vStack = this.querySelector(':scope>[slot=top-bar-principal]') ??
170
+ this.appendChild($(`<v-stack spacing="0" alignment="fill" slot="top-bar-principal"><label-view line-limit="1" truncation-mode="tail" font="headline"></label-view><label-view line-limit="1" truncation-mode="tail" font="callout"></label-view></v-stack>`));
171
+ let titleLabel = vStack.querySelector(':scope>label-view:nth-child(1)');
172
+ if (title) {
173
+ titleLabel ??= vStack.appendChild($(`<label-view line-limit="1" truncation-mode="tail" font="headline"></label-view>`));
174
+ titleLabel.setAttribute('title', title);
175
+ }
176
+ else
177
+ titleLabel?.remove();
178
+ let subtitleLabel = vStack.querySelector(':scope>label-view:nth-child(2)');
179
+ if (subtitle) {
180
+ subtitleLabel ??= vStack.appendChild($(`<label-view line-limit="1" truncation-mode="tail" font="callout"></label-view>`));
181
+ subtitleLabel.setAttribute('title', subtitle);
182
+ }
183
+ else
184
+ subtitleLabel?.remove();
185
+ };
186
+ }
187
+ _a = ScrollView;
@@ -0,0 +1,9 @@
1
+ export declare class SectionView extends HTMLElement {
2
+ #private;
3
+ static get observedAttributes(): string[];
4
+ static get template(): DocumentFragment;
5
+ constructor();
6
+ disconnectedCallback(): void;
7
+ connectedCallback(): void;
8
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
9
+ }
@@ -0,0 +1,81 @@
1
+ import { $ } from '../internal/utils';
2
+ export class SectionView extends HTMLElement {
3
+ static get observedAttributes() {
4
+ return ['header', 'footer'];
5
+ }
6
+ static #template;
7
+ static get template() {
8
+ return (this.#template ??= $(String.raw `
9
+ <div part="root section-main-stack">
10
+ <slot></slot>
11
+ </div>
12
+ <div part="root section-header-stack">
13
+ <slot name="header"></slot>
14
+ </div>
15
+ <div part="root section-footer-stack">
16
+ <slot name="footer"></slot>
17
+ </div>`, ''));
18
+ // <div class="sticky-sentinel" style="grid-area:sentinel;inline-size:100%;block-size:0.1px;pointer-events:none;"></div>
19
+ }
20
+ #shadowRoot;
21
+ // #observer?: IntersectionObserver
22
+ // #sibling?: HTMLElement
23
+ // #sentinel?: HTMLElement
24
+ // #sentinelIsIntersecting: boolean = false
25
+ // #isIntersecting: boolean = false
26
+ constructor() {
27
+ super();
28
+ this.#shadowRoot = this.attachShadow({ mode: 'closed' });
29
+ // Snapshot.waitReady.then(() => {
30
+ this.#shadowRoot.appendChild(document.importNode(this.constructor.template, true));
31
+ // this.#sentinel = this.#shadowRoot.querySelector('.sticky-sentinel') ?? undefined
32
+ // })
33
+ }
34
+ disconnectedCallback() {
35
+ console.debug(`${SectionView.name} ⚡️ disconnect`);
36
+ // if (this.#sentinel) this.#observer?.unobserve(this.#sentinel)
37
+ // this.#observer?.unobserve(this)
38
+ }
39
+ connectedCallback() {
40
+ console.debug(`${SectionView.name} ⚡️ connect`);
41
+ // this.#sibling = this.closest('scroll-view') ?? undefined
42
+ // Snapshot.waitReady.then(() => {
43
+ // if (!(await frame(this))) return // NOTE: Required or BREAKS transitions // self.requestAnimationFrame(() => {
44
+ // if (!this.isConnected) return
45
+ // const blockSizeProp = getComputedStyle(this).getPropertyValue('--navigation-bar-block-size') || '0', //`${document.documentElement.computedStyleMap().get(`--navigation-bar-block-size`) ?? '0'}`, //
46
+ // blockSize = parseFloat(blockSizeProp) * (blockSizeProp.endsWith('rem') ? parseFloat(getComputedStyle(document.documentElement).fontSize) : 1)
47
+ // this.#observer = new IntersectionObserver(this.#handleIntersect, {
48
+ // root: this.#sibling,
49
+ // rootMargin: `-${blockSize}px 0px 0px 0px`,
50
+ // threshold: [0, 1],
51
+ // })
52
+ // if (this.#sentinel) this.#observer.observe(this.#sentinel)
53
+ // this.#observer.observe(this)
54
+ // })
55
+ }
56
+ attributeChangedCallback(name, oldValue, newValue) {
57
+ console.debug(`${SectionView.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
58
+ // Snapshot.waitReady.then(() => {
59
+ switch (name) {
60
+ case 'header':
61
+ let header = this.querySelector(':scope>[slot=header]');
62
+ if (newValue) {
63
+ header ??= this.appendChild($(`<header slot="header"><label-view line-limit="1" truncation-mode="tail" font="callout"></label-view></header>`));
64
+ header.querySelector('label-view')?.setAttribute('title', newValue);
65
+ }
66
+ else
67
+ header?.remove();
68
+ break;
69
+ case 'footer':
70
+ let footer = this.querySelector(':scope>[slot=footer]');
71
+ if (newValue) {
72
+ footer ??= this.appendChild($(`<footer slot="footer"><label-view line-limit="1" truncation-mode="tail" font="callout"></label-view></footer>`));
73
+ footer.querySelector('label-view')?.setAttribute('title', newValue);
74
+ }
75
+ else
76
+ footer?.remove();
77
+ break;
78
+ }
79
+ // })
80
+ }
81
+ }
@@ -0,0 +1,9 @@
1
+ import { DialogBase } from '../namespace-browser/base';
2
+ export declare class SheetView extends DialogBase {
3
+ #private;
4
+ static get observedAttributes(): string[];
5
+ constructor();
6
+ static polyfillDisconnectedCallback(el: SheetView): void;
7
+ static polyfillConnectedCallback(el: SheetView): void;
8
+ static polyfillAttributeChangedCallback([{ attributeName, target, oldValue }]: Pick<MutationRecord, 'attributeName' | 'oldValue' | 'target'>[]): Promise<void>;
9
+ }
@@ -0,0 +1,69 @@
1
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
2
+ import { onoff } from '../internal/utils';
3
+ import { DialogBase } from '../namespace-browser/base';
4
+ import { Snapshot } from '../snapshot';
5
+ export class SheetView extends DialogBase {
6
+ static get observedAttributes() {
7
+ return ['fine-presentation-large-adaptation'];
8
+ }
9
+ constructor() {
10
+ super();
11
+ }
12
+ static polyfillDisconnectedCallback(el) {
13
+ console.debug(`${SheetView.name} ⚡️ disconnect`);
14
+ CleanupRegistry.unregister(el);
15
+ }
16
+ static polyfillConnectedCallback(el) {
17
+ console.debug(`${SheetView.name} ⚡️ connect`);
18
+ CleanupRegistry.register(el, onoff([
19
+ { types: 'cancel', listener: this.#handleCancel },
20
+ { types: 'keydown', listener: SheetView.#handleKeydown },
21
+ ], el).on());
22
+ el.autofocus = true;
23
+ }
24
+ static async polyfillAttributeChangedCallback([{ attributeName, target, oldValue }]) {
25
+ console.debug(`${SheetView.name} ⚡️ attr-change [${attributeName}] ("${oldValue}" → "${target.getAttribute(attributeName ?? '')}")`);
26
+ await Snapshot.waitReady; // NOTE: wait for config
27
+ switch (attributeName) {
28
+ case 'fine-presentation-large-adaptation':
29
+ const node = target;
30
+ CleanupRegistry.unregister(node, 'mediaquery');
31
+ if ('bottom-bar' !== target.getAttribute(attributeName ?? ''))
32
+ break;
33
+ const mediaQueryList = self.matchMedia(`(pointer: fine) and (min-width: ${Snapshot.config['ipad-sheet-view-inline-size']}) and (min-height: ${Snapshot.config['ipad-sheet-view-height']})`);
34
+ SheetView.#handleMediaChange(node, new MediaQueryListEvent(`media-change`, {
35
+ matches: mediaQueryList.matches,
36
+ })); // Initial check
37
+ const handler1 = SheetView.#handleMediaChange.bind(null, node);
38
+ CleanupRegistry.register(node, onoff('change', handler1, mediaQueryList).on(), 'mediaquery');
39
+ break;
40
+ }
41
+ }
42
+ static #handleKeydown = (evt) => {
43
+ console.debug(`${SheetView.name} ⚡️ ${evt?.type} (${evt.key})`);
44
+ if ('Escape' !== evt.key)
45
+ return;
46
+ evt.preventDefault();
47
+ evt.stopImmediatePropagation();
48
+ evt.stopPropagation();
49
+ };
50
+ static #handleCancel = (evt) => {
51
+ console.debug(`${SheetView.name} ⚡️ ${evt?.type} (${evt.cancelable})`);
52
+ if (!evt.cancelable)
53
+ return;
54
+ evt.preventDefault();
55
+ };
56
+ static #handleMediaChange = (el, evt) => {
57
+ console.debug(`${SheetView.name} ⚡️ ${evt?.type}`);
58
+ if (evt.matches)
59
+ for (const item of el.querySelectorAll(':scope>tool-bar>[slot^="top-bar-"]')) {
60
+ item.dataset.previousSlot = item.getAttribute('slot') ?? '';
61
+ item.slot = 'bottom-bar-trailing';
62
+ }
63
+ else
64
+ for (const item of el.querySelectorAll(':scope>tool-bar>[data-previous-slot]')) {
65
+ item.slot = item.dataset.previousSlot ?? '';
66
+ delete item.dataset.previousSlot;
67
+ }
68
+ };
69
+ }
@@ -0,0 +1,7 @@
1
+ export declare class SidebarToggle extends HTMLElement {
2
+ #private;
3
+ constructor();
4
+ connectedCallback(): void;
5
+ disconnectedCallback(): void;
6
+ private static query;
7
+ }
@@ -0,0 +1,107 @@
1
+ var _a;
2
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
3
+ import { ResizeObserverSingleton } from '../internal/class/resize-observer-singleton';
4
+ import { $, debounce, onoff } from '../internal/utils';
5
+ const observers = new ResizeObserverSingleton();
6
+ export class SidebarToggle extends HTMLElement {
7
+ // #ro
8
+ // #io
9
+ constructor() {
10
+ super();
11
+ // this.#ro = new ResizeObserver(
12
+ // debounce(this.#handleMeasure.bind(this), 100, true)
13
+ // )
14
+ // this.#io = new IntersectionObserver((entries) => {
15
+ // this._checkVisibility2(entries)
16
+ // })
17
+ }
18
+ connectedCallback() {
19
+ console.debug(`${_a.name} ⚡️ connect`);
20
+ CleanupRegistry.register(this, onoff('click', this.#handleClick, this).on());
21
+ const entry = {
22
+ target: this,
23
+ };
24
+ // NOTE: wait for config
25
+ // Snapshot.waitReady.then(() => {
26
+ observers.observe(this, debounce(_a.#handleMeasure, 100, true)); //this.#ro?.observe(this)
27
+ // this.#io.observe(this)
28
+ // @ts-expect-error
29
+ _a.#handleMeasure([entry]);
30
+ // })
31
+ }
32
+ disconnectedCallback() {
33
+ console.debug(`${_a.name} ⚡️ disconnect`);
34
+ observers.unobserve(this); //this.#ro?.disconnect()
35
+ // this.#io.disconnect()
36
+ CleanupRegistry.unregister(this);
37
+ }
38
+ static query(target) {
39
+ const container = target?.closest('navigation-split-view,tab-view'), sideBar = container?.querySelector(':scope > [is=sidebar-view]');
40
+ return { container, sideBar };
41
+ }
42
+ // This triggers on show/hide of any of sidebar-toggle elements
43
+ static #handleMeasure(entry) {
44
+ console.debug(`${_a.name} ⚡️ measure`);
45
+ const target = entry?.target;
46
+ // set/remove css var/prop to parent based on shown/hidden
47
+ // for (const { target } of entries) {
48
+ const tv = target?.parentElement, width = target?.offsetWidth ?? 0;
49
+ // const gapProp =
50
+ // getComputedStyle(tg).getPropertyValue('--toolbar-col-gap') || '0',
51
+ // gap = parseFloat(gapProp) * 1 //(gapProp.endsWith('rem')? parseFloat(getComputedStyle(document.documentElement).fontSize): 1)
52
+ if (0 < width)
53
+ $.prop('--sidebar-toggle-padding-inline-start', `${width}px`, tv); //tv?.style?.setProperty?.(Snapshot.config!['sidebar-toggle-padding-inline-start-css-prop'], `${width}px`)
54
+ else
55
+ $.prop('--sidebar-toggle-padding-inline-start', null, tv); //tv?.style?.removeProperty?.(Snapshot.config!['sidebar-toggle-padding-inline-start-css-prop'])
56
+ // }
57
+ // auto close IF open
58
+ // for (const { target } of entries) {
59
+ const { container, sideBar } = _a.query(target); //target?.closest('navigation-split-view,tab-view')
60
+ // const sideBar = container?.querySelector<HTMLDialogElement>(':scope > dialog[is=sidebar-view]')
61
+ if (!sideBar?.open)
62
+ return;
63
+ switch (container?.tagName) {
64
+ case 'NAVIGATION-SPLIT-VIEW':
65
+ // const sideBar = target?.parentElement?.querySelector<HTMLDialogElement>(':scope > dialog[is=sidebar-view]')
66
+ // if (!sideBar?.open) return
67
+ if (0 < target.offsetWidth && 0 < target.offsetHeight)
68
+ return;
69
+ // sideBar?.close?.()
70
+ break;
71
+ case 'TAB-VIEW':
72
+ // const tabBar = container.querySelector<HTMLDialogElement>(':scope > dialog[is=tab-bar]')
73
+ // if (!tabBar?.open) return
74
+ // scan all toggles for anyone that is visible, sign that sidebar should stay open
75
+ if ([
76
+ ...container.querySelectorAll(":scope > sidebar-toggle,:scope > [is=tab-bar] > sidebar-toggle,:scope > [is='sidebar-view'] > tool-bar > sidebar-toggle"),
77
+ ].some(({ offsetWidth, offsetHeight }) => 0 < offsetWidth && 0 < offsetHeight))
78
+ return;
79
+ //tabBar?.close?.()
80
+ break;
81
+ }
82
+ sideBar?.close?.();
83
+ // }
84
+ }
85
+ // _checkVisibility2(entries) {
86
+ // entries.forEach((entry) => {
87
+ // console.log('Visible in viewport?', entry.isIntersecting)
88
+ // })
89
+ // }
90
+ #handleClick(evt) {
91
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
92
+ const target = evt.target;
93
+ if (!target?.closest('button'))
94
+ return;
95
+ const { sideBar } = _a.query(target);
96
+ // const container = target?.closest('tab-view,navigation-split-view')
97
+ // const dialog =
98
+ // 'TAB-VIEW' === container?.tagName
99
+ // ? container.querySelector<TabBar>('dialog[is="tab-bar"]')
100
+ // : container?.querySelector<SidebarView>('dialog[is="sidebar-view"]')
101
+ if (!sideBar?.open)
102
+ sideBar?.showModal();
103
+ else
104
+ sideBar.close();
105
+ }
106
+ }
107
+ _a = SidebarToggle;
@@ -0,0 +1,7 @@
1
+ import { DialogBase } from '../namespace-browser/base';
2
+ export declare class SidebarView extends DialogBase {
3
+ #private;
4
+ constructor();
5
+ static polyfillDisconnectedCallback(el: HTMLDialogElement): void;
6
+ static polyfillConnectedCallback(el: HTMLDialogElement): void;
7
+ }
@@ -0,0 +1,29 @@
1
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
2
+ import { onoff, touchGlass } from '../internal/utils';
3
+ import { DialogBase } from '../namespace-browser/base';
4
+ export class SidebarView extends DialogBase {
5
+ constructor() {
6
+ super();
7
+ }
8
+ static polyfillDisconnectedCallback(el) {
9
+ el.removeEventListener('click', SidebarView.#handleClick);
10
+ CleanupRegistry.unregister(el);
11
+ }
12
+ static polyfillConnectedCallback(el) {
13
+ CleanupRegistry.register(el, onoff('click', SidebarView.#handleClick, el).on());
14
+ CleanupRegistry.register(el, onoff(touchGlass(el, (t) => t, (evt) => {
15
+ if (evt.target.matches('[is=sidebar-view]'))
16
+ return false;
17
+ if (evt.target.closest('tool-bar-item'))
18
+ return false;
19
+ return true;
20
+ }), el).on());
21
+ el.autofocus = true;
22
+ }
23
+ /** Autoclose on click outside. */
24
+ static #handleClick = async (evt) => {
25
+ console.debug(`${SidebarView.name} ⚡️ ${evt?.type}`);
26
+ if ('DIALOG' === evt.target.tagName && 'sidebar-view' === evt.target.getAttribute('is'))
27
+ evt?.target?.close?.();
28
+ };
29
+ }
@@ -0,0 +1,6 @@
1
+ export declare class StickyContainer extends HTMLElement {
2
+ #private;
3
+ constructor();
4
+ connectedCallback(): void;
5
+ disconnectedCallback(): void;
6
+ }
@@ -0,0 +1,22 @@
1
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
2
+ import { onoff } from '../internal/utils';
3
+ export class StickyContainer extends HTMLElement {
4
+ constructor() {
5
+ super();
6
+ }
7
+ connectedCallback() {
8
+ console.debug(`${StickyContainer.name} ⚡️ connect`);
9
+ // CleanupRegistry.register(this, onoff('transitionend transitionstart transitioncancel', this.#handleTransitionrun as unknown as EventListener, this).on())
10
+ CleanupRegistry.register(this, onoff('transitionrun', this.#handleTransitionrun, this).on());
11
+ }
12
+ disconnectedCallback() {
13
+ console.debug(`${StickyContainer.name} ⚡️ disconnect`);
14
+ CleanupRegistry.unregister(this);
15
+ }
16
+ #handleTransitionrun = ({ target, propertyName, pseudoElement }) => {
17
+ if ('--stuck' !== propertyName || '::before' !== pseudoElement || !target?.matches('sticky-container'))
18
+ return;
19
+ const stuck = self.getComputedStyle(this, 'before').getPropertyValue('--stuck');
20
+ this.toggleAttribute('stuck', '1' === stuck);
21
+ };
22
+ }
@@ -0,0 +1,7 @@
1
+ import { DialogBase } from '../namespace-browser/base';
2
+ export declare class TabBar extends DialogBase {
3
+ #private;
4
+ constructor();
5
+ static polyfillDisconnectedCallback(el: HTMLDialogElement): void;
6
+ static polyfillConnectedCallback(el: HTMLDialogElement): void;
7
+ }
@@ -0,0 +1,33 @@
1
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
2
+ import { onoff, touchGlass } from '../internal/utils';
3
+ import { DialogBase } from '../namespace-browser/base';
4
+ export class TabBar extends DialogBase {
5
+ constructor() {
6
+ super();
7
+ }
8
+ static polyfillDisconnectedCallback(el) {
9
+ console.debug(`${TabBar.name} ⚡️ disconnect`);
10
+ el.removeEventListener('click', TabBar.#handleClick);
11
+ CleanupRegistry.unregister(el);
12
+ }
13
+ static polyfillConnectedCallback(el) {
14
+ console.debug(`${TabBar.name} ⚡️ connect`);
15
+ el.autofocus = true;
16
+ // Snapshot.waitReadyFor(el).then((r) => {
17
+ // if (!r) return
18
+ CleanupRegistry.register(el, onoff('click', TabBar.#handleClick, el).on());
19
+ CleanupRegistry.register(el, onoff(touchGlass(el, (t) => t, (evt) => {
20
+ if (evt.target.matches('[is=tab-bar]'))
21
+ return false;
22
+ if (evt.target.closest('tool-bar-item'))
23
+ return false;
24
+ return true;
25
+ }), el).on());
26
+ // })
27
+ }
28
+ static #handleClick = async (event) => {
29
+ console.debug(`${TabBar.name} ⚡️ ${event?.type}`);
30
+ if ('DIALOG' === event.target.tagName && 'tab-bar' === event.target.getAttribute('is'))
31
+ event?.target?.close?.();
32
+ };
33
+ }
@@ -0,0 +1,7 @@
1
+ import { ButtonBase } from '../namespace-browser/base';
2
+ export declare class TabItem extends ButtonBase {
3
+ #private;
4
+ constructor();
5
+ static polyfillDisconnectedCallback(btn: HTMLButtonElement): void;
6
+ static polyfillConnectedCallback(btn: TabItem): void;
7
+ }