@swiftwc/ui 0.0.0-dev.8 → 0.0.0-dev.80

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 (243) hide show
  1. package/generated/buses/alert-dialog.d.ts +2 -0
  2. package/generated/buses/alert-dialog.js +1 -0
  3. package/generated/buses/confirmation-dialog.d.ts +2 -0
  4. package/generated/buses/confirmation-dialog.js +1 -0
  5. package/generated/buses/index.d.ts +6 -0
  6. package/generated/buses/index.js +6 -0
  7. package/generated/buses/lifecycle-observer.d.ts +2 -0
  8. package/generated/buses/lifecycle-observer.js +1 -0
  9. package/generated/client/index.d.ts +21 -10
  10. package/generated/client/index.js +177 -194
  11. package/generated/components/alert-dialog.d.ts +8 -0
  12. package/generated/components/alert-dialog.js +99 -0
  13. package/generated/components/body-view.js +5 -2
  14. package/generated/components/bordered-button.d.ts +10 -0
  15. package/generated/components/bordered-button.js +39 -3
  16. package/generated/components/bordered-prominent-button.d.ts +10 -0
  17. package/generated/components/bordered-prominent-button.js +39 -3
  18. package/generated/components/borderless-button.d.ts +9 -1
  19. package/generated/components/borderless-button.js +32 -11
  20. package/generated/components/color-scheme.d.ts +7 -0
  21. package/generated/components/color-scheme.js +54 -0
  22. package/generated/components/confirmation-dialog.d.ts +1 -1
  23. package/generated/components/confirmation-dialog.js +43 -32
  24. package/generated/components/content-unavailable-view.d.ts +24 -0
  25. package/generated/components/content-unavailable-view.js +81 -0
  26. package/generated/components/date-picker.d.ts +2 -12
  27. package/generated/components/date-picker.js +96 -65
  28. package/generated/components/disclosure-group.d.ts +5 -0
  29. package/generated/components/disclosure-group.js +18 -7
  30. package/generated/components/fine-tooltip.d.ts +7 -0
  31. package/generated/components/fine-tooltip.js +107 -0
  32. package/generated/components/form-view.d.ts +3 -0
  33. package/generated/components/form-view.js +8 -3
  34. package/generated/components/glass-button.d.ts +10 -0
  35. package/generated/components/glass-button.js +39 -3
  36. package/generated/components/glass-prominent-button.d.ts +10 -0
  37. package/generated/components/glass-prominent-button.js +39 -3
  38. package/generated/components/h-stack.d.ts +14 -0
  39. package/generated/components/h-stack.js +23 -0
  40. package/generated/components/image-view.d.ts +9 -0
  41. package/generated/components/image-view.js +64 -0
  42. package/generated/components/index.d.ts +11 -3
  43. package/generated/components/index.js +11 -3
  44. package/generated/components/label-view.d.ts +6 -1
  45. package/generated/components/label-view.js +32 -59
  46. package/generated/components/labeled-content.d.ts +9 -0
  47. package/generated/components/labeled-content.js +116 -0
  48. package/generated/components/list-view.d.ts +3 -0
  49. package/generated/components/list-view.js +20 -17
  50. package/generated/components/menu-view.d.ts +4 -1
  51. package/generated/components/menu-view.js +60 -51
  52. package/generated/components/navigation-large-title.js +9 -5
  53. package/generated/components/navigation-split-view.d.ts +4 -1
  54. package/generated/components/navigation-split-view.js +13 -6
  55. package/generated/components/navigation-stack.d.ts +4 -1
  56. package/generated/components/navigation-stack.js +16 -9
  57. package/generated/components/navigation-title.d.ts +1 -1
  58. package/generated/components/navigation-title.js +58 -55
  59. package/generated/components/picker-view.d.ts +32 -4
  60. package/generated/components/picker-view.js +924 -234
  61. package/generated/components/plain-button.js +5 -3
  62. package/generated/components/progress-view.d.ts +13 -0
  63. package/generated/components/progress-view.js +120 -0
  64. package/generated/components/screen-view.js +3 -1
  65. package/generated/components/scroll-view-proxy.d.ts +8 -0
  66. package/generated/components/scroll-view-proxy.js +17 -0
  67. package/generated/components/scroll-view.d.ts +1 -1
  68. package/generated/components/scroll-view.js +101 -85
  69. package/generated/components/search-view.d.ts +7 -0
  70. package/generated/components/search-view.js +30 -0
  71. package/generated/components/section-view.d.ts +1 -1
  72. package/generated/components/section-view.js +35 -30
  73. package/generated/components/sheet-view.d.ts +1 -2
  74. package/generated/components/sheet-view.js +32 -39
  75. package/generated/components/sidebar-toggle.js +44 -66
  76. package/generated/components/sidebar-view.js +13 -8
  77. package/generated/components/sticky-container.js +8 -4
  78. package/generated/components/tab-bar.d.ts +3 -0
  79. package/generated/components/tab-bar.js +20 -10
  80. package/generated/components/tab-item.js +24 -13
  81. package/generated/components/tab-view.js +25 -17
  82. package/generated/components/table-view.d.ts +5 -0
  83. package/generated/components/table-view.js +55 -77
  84. package/generated/components/text-field.d.ts +2 -2
  85. package/generated/components/text-field.js +95 -88
  86. package/generated/components/toggle-view.d.ts +28 -0
  87. package/generated/components/toggle-view.js +224 -0
  88. package/generated/components/tool-bar-item-group.js +21 -4
  89. package/generated/components/tool-bar-item.d.ts +4 -1
  90. package/generated/components/tool-bar-item.js +57 -10
  91. package/generated/components/tool-bar.d.ts +12 -0
  92. package/generated/components/tool-bar.js +27 -11
  93. package/generated/components/v-keyboard.d.ts +3 -1
  94. package/generated/components/v-keyboard.js +12 -6
  95. package/generated/components/v-stack.d.ts +12 -0
  96. package/generated/components/v-stack.js +17 -2
  97. package/generated/css/index.css +2533 -941
  98. package/generated/events/alert-dialog.d.ts +8 -0
  99. package/generated/events/alert-dialog.js +1 -0
  100. package/generated/events/confirmation-dialog.d.ts +2 -2
  101. package/generated/events/index.d.ts +2 -0
  102. package/generated/events/index.js +2 -0
  103. package/generated/events/picker-view.d.ts +7 -0
  104. package/generated/events/scroll-view.js +4 -0
  105. package/generated/events/tab-view.d.ts +6 -2
  106. package/generated/events/text-field.js +3 -0
  107. package/generated/events/toggle-view.d.ts +9 -0
  108. package/generated/events/toggle-view.js +4 -0
  109. package/generated/i18n/index.d.ts +20 -10
  110. package/generated/i18n/index.js +82 -54
  111. package/generated/i18n/locales/el.d.ts +16 -0
  112. package/generated/i18n/locales/el.js +16 -0
  113. package/generated/i18n/locales/en.d.ts +16 -0
  114. package/generated/i18n/locales/en.js +16 -0
  115. package/generated/i18n/locales/index.d.ts +4 -0
  116. package/generated/i18n/locales/index.js +4 -0
  117. package/generated/internal/class/css-style-observer.js +3 -2
  118. package/generated/internal/class/form-associated-base.d.ts +0 -4
  119. package/generated/internal/class/form-associated-base.js +23 -38
  120. package/generated/internal/class/mutation-observer-set.d.ts +9 -0
  121. package/generated/internal/class/mutation-observer-set.js +42 -0
  122. package/generated/internal/class/mutation-observer-singleton.js +18 -0
  123. package/generated/internal/class/navigation-view.d.ts +1 -1
  124. package/generated/internal/class/navigation-view.js +38 -43
  125. package/generated/internal/decorators/adaptive-slot.d.ts +1 -0
  126. package/generated/internal/decorators/adaptive-slot.js +50 -0
  127. package/generated/internal/decorators/custom-element.d.ts +1 -1
  128. package/generated/internal/decorators/custom-element.js +2 -1
  129. package/generated/internal/decorators/index.d.ts +6 -0
  130. package/generated/internal/decorators/index.js +6 -0
  131. package/generated/internal/decorators/microtask-on-connected.d.ts +39 -0
  132. package/generated/internal/decorators/microtask-on-connected.js +67 -0
  133. package/generated/internal/privateNamespace.d.ts +10 -0
  134. package/generated/internal/privateNamespace.js +168 -1
  135. package/generated/internal/utils/cash/index.d.ts +4 -3
  136. package/generated/internal/utils/cash/index.js +6 -4
  137. package/generated/internal/utils/dev-flags.d.ts +3 -0
  138. package/generated/internal/utils/dev-flags.js +5 -0
  139. package/generated/internal/utils/ensure-placeholder.d.ts +1 -0
  140. package/generated/internal/utils/ensure-placeholder.js +55 -0
  141. package/generated/internal/utils/index.d.ts +7 -2
  142. package/generated/internal/utils/index.js +9 -2
  143. package/generated/internal/utils/is-inside.d.ts +1 -0
  144. package/generated/internal/utils/is-inside.js +4 -0
  145. package/generated/internal/utils/list-active.js +67 -12
  146. package/generated/internal/utils/render-label-icon.d.ts +2 -0
  147. package/generated/internal/utils/render-label-icon.js +19 -0
  148. package/generated/internal/utils/render-label-title.d.ts +2 -0
  149. package/generated/internal/utils/render-label-title.js +16 -0
  150. package/generated/internal/utils/render-label.d.ts +1 -0
  151. package/generated/internal/utils/render-label.js +19 -0
  152. package/generated/internal/utils/touch-glass.js +5 -5
  153. package/generated/namespace-browser/base.d.ts +12 -3
  154. package/generated/namespace-browser/base.js +41 -18
  155. package/generated/namespace-browser/event.d.ts +10 -0
  156. package/generated/namespace-browser/event.js +1 -0
  157. package/generated/snapshot/index.d.ts +3 -1
  158. package/generated/snapshot/index.js +25 -2
  159. package/generated/tpl/html.d.ts +5 -0
  160. package/generated/tpl/html.js +3 -0
  161. package/generated/tpl/index.d.ts +4 -0
  162. package/generated/tpl/index.js +4 -0
  163. package/generated/tpl/render.d.ts +2 -0
  164. package/generated/tpl/render.js +132 -0
  165. package/package.json +18 -4
  166. package/scss/_components.scss +14 -0
  167. package/scss/_functions.scss +10 -0
  168. package/scss/_mixins.scss +4 -0
  169. package/scss/_transitions.scss +6 -1
  170. package/scss/_vars.scss +9 -2
  171. package/scss/base/_layout.scss +17 -7
  172. package/scss/base/_reboot.scss +34 -1
  173. package/scss/base/_root.scss +117 -114
  174. package/scss/colors/_index.scss +304 -85
  175. package/scss/components/_alert-dialog.scss +111 -0
  176. package/scss/components/_bordered-button.scss +35 -0
  177. package/scss/components/_bordered-prominent-button.scss +45 -0
  178. package/scss/components/_borderless-button.scss +25 -0
  179. package/scss/components/_confirmation-dialog.scss +41 -49
  180. package/scss/components/_content-unavailable-view.scss +56 -0
  181. package/scss/components/_date-picker.scss +15 -15
  182. package/scss/components/_detail-placeholder.scss +1 -3
  183. package/scss/components/_disclosure-group.scss +84 -33
  184. package/scss/components/_fine-tooltip.scss +84 -0
  185. package/scss/components/_form-view.scss +58 -20
  186. package/scss/components/_glass-button.scss +35 -0
  187. package/scss/components/_glass-prominent-button.scss +46 -0
  188. package/scss/components/_group-box.scss +27 -0
  189. package/scss/components/_h-flex-stack.scss +23 -0
  190. package/scss/components/_h-stack.scss +21 -15
  191. package/scss/components/_image-view.scss +20 -0
  192. package/scss/components/_index.scss +40 -20
  193. package/scss/components/_label-view copy.scss.txt +420 -0
  194. package/scss/components/_label-view.scss +94 -110
  195. package/scss/components/_label-view.scss.txt +536 -0
  196. package/scss/components/_labeled-content.scss +59 -1
  197. package/scss/components/_list-view.scss +65 -25
  198. package/scss/components/_menu-view.scss +95 -60
  199. package/scss/components/_navigation-large-title.scss +17 -0
  200. package/scss/components/_navigation-split-view.scss +3 -3
  201. package/scss/components/_picker-view.scss +259 -59
  202. package/scss/components/_plain-button.scss +7 -0
  203. package/scss/components/_progress-view.scss +98 -0
  204. package/scss/components/_scroll-view-proxy.scss +22 -20
  205. package/scss/components/_scroll-view.scss +4 -0
  206. package/scss/components/_search-view.scss +22 -0
  207. package/scss/components/_section-view.scss +23 -22
  208. package/scss/components/_sheet-view.scss +16 -6
  209. package/scss/components/_sidebar-toggle.scss +1 -4
  210. package/scss/components/_sticky-container.scss +1 -1
  211. package/scss/components/_tab-bar.scss +17 -3
  212. package/scss/components/_tab-view.scss +4 -2
  213. package/scss/components/_table-column.scss +2 -0
  214. package/scss/components/_table-row.scss +69 -1
  215. package/scss/components/_table-view.scss +22 -14
  216. package/scss/components/_text-field.scss +37 -17
  217. package/scss/components/_toggle-view.scss +112 -0
  218. package/scss/components/_tool-bar-item.scss +34 -82
  219. package/scss/components/_tool-bar.scss +77 -57
  220. package/scss/components/_v-stack.scss +9 -2
  221. package/scss/final/_touch-glass.scss +24 -0
  222. package/scss/mixins/_button.scss +44 -0
  223. package/scss/mixins/_color.scss +16 -0
  224. package/scss/mixins/_dialog.scss +1 -0
  225. package/scss/mixins/_index.scss +64 -2
  226. package/scss/placeholders/_buttons.scss +44 -10
  227. package/scss/placeholders/_lists.scss +133 -126
  228. package/scss/transitions/_alert-dialog.scss +18 -0
  229. package/scss/transitions/_confirmation-dialog.scss +8 -0
  230. package/scss/transitions/_fine-tooltip.scss +21 -0
  231. package/scss/transitions/_menu-view.scss +17 -15
  232. package/scss/transitions/_progress-view.scss +23 -0
  233. package/scss/transitions/_sheet-view.scss +30 -0
  234. package/scss/transitions/_tab-bar.scss +6 -5
  235. package/scss/utils/_frame.scss +42 -0
  236. package/scss/utils/_index.scss +67 -52
  237. package/scss/utils/_stacks.scss +56 -73
  238. package/web-components.html-data/en.json +623 -24
  239. package/generated/confirmation-dialog/index.d.ts +0 -1
  240. package/generated/confirmation-dialog/index.js +0 -1
  241. package/generated/lifecycle-observer/index.d.ts +0 -1
  242. package/generated/lifecycle-observer/index.js +0 -1
  243. package/scss/transitions/_dialog.scss +0 -28
@@ -1,14 +1,17 @@
1
1
  var _a;
2
2
  import { CleanupRegistry } from '../internal/class/cleanup-registry';
3
3
  import { CSSStyleObserver } from '../internal/class/css-style-observer';
4
- import { MutationObserverSingleton } from '../internal/class/mutation-observer-singleton';
5
- import { $, listActive, onoff } from '../internal/utils';
4
+ import { MutationObserverSet } from '../internal/class/mutation-observer-set';
5
+ import { $, devFlags, listActive, onoff, renderLabelTitle } from '../internal/utils';
6
6
  import { Snapshot } from '../snapshot';
7
- const observers = new MutationObserverSingleton();
7
+ /**
8
+ * @summary Display selectable, sortable data arranged in rows and columns.
9
+ *
10
+ * @attr {title:trailing:subtitle|trailing:title:subtitle|title:subtitle:trailing|*} preferred-compact-template - Sets the template areas when the table is in compact mode
11
+ */
8
12
  export class TableView extends HTMLElement {
9
13
  #styleObserver;
10
14
  #compactToolbarItem;
11
- #trackedElements = new Set();
12
15
  static #template;
13
16
  static get template() {
14
17
  return (this.#template ??= $(String.raw `
@@ -39,59 +42,33 @@ export class TableView extends HTMLElement {
39
42
  <slot name="footer-trailing"></slot>
40
43
  </div>
41
44
  </div>
42
- </div>`, ''));
45
+ </div>`));
43
46
  }
44
47
  #shadowRoot;
45
- #colSlot;
46
- // #slot?: HTMLSlotElement
48
+ #slots = new Map();
47
49
  constructor() {
48
50
  super();
49
51
  this.#shadowRoot = this.attachShadow({ mode: 'closed' });
50
52
  this.#shadowRoot.appendChild(document.importNode(this.constructor.template, true));
51
- this.#colSlot = this.#shadowRoot.querySelector('slot[name=column]') ?? undefined;
52
- // this.#slot = this.#shadowRoot.querySelector<HTMLSlotElement>('slot:not([name])') ?? undefined
53
- this.#colSlot?.addEventListener('slotchange', this.#handleSlotchange);
54
- // this.append(
55
- // document.createRange().createContextualFragment(`<menu-view slot="header-trailing">
56
- // <label-view slot="label" title="Delete"></label-view>
57
- // <button type="button" tabindex="0">
58
- // <label-view system-image="dots-three" title="Scan Documents"></label-view>
59
- // </button>
60
- // <button type="button" tabindex="0">
61
- // <label-view system-image="dots-three" title="Connect to Server"></label-view>
62
- // </button>
63
- // <button type="button" tabindex="0">
64
- // <label-view title="Edit Sidebar"></label-view>
65
- // </button>
66
- // </menu-view>
67
- // `)
68
- // $(`<menu-view slot="header-trailing">
69
- // <label-view slot="label" title="Delete"></label-view>
70
- // <button type="button" tabindex="0">
71
- // <label-view system-image="dots-three" title="Scan Documents"></label-view>
72
- // </button>
73
- // <button type="button" tabindex="0">
74
- // <label-view system-image="dots-three" title="Connect to Server"></label-view>
75
- // </button>
76
- // <button type="button" tabindex="0">
77
- // <label-view title="Edit Sidebar"></label-view>
78
- // </button>
79
- // </menu-view>
80
- // <div slot="footer-leading">22</div>
81
- // <div slot="footer-trailing"><button>&lt;</button> <button>&gt;</button></div>`)
82
- // )
53
+ for (const slot of this.#shadowRoot.querySelectorAll('slot'))
54
+ this.#slots?.set(slot.name, slot);
55
+ CleanupRegistry.register(this, () => {
56
+ this.#slots = new Map();
57
+ });
58
+ this.#slots?.get('column')?.addEventListener('slotchange', this.#handleColumnSlotchange);
83
59
  }
84
60
  disconnectedCallback() {
85
- console.debug(`${_a.name} ⚡️ disconnect`);
61
+ if (devFlags.debug)
62
+ console.debug(`${_a.name} ⚡️ disconnect`);
86
63
  CleanupRegistry.unregister(this);
87
64
  this.#styleObserver?.disconnect();
88
- observers.clearObservationsSet(this.#trackedElements);
65
+ this.#observers.unobserveAll();
89
66
  this.#compactToolbarItem = undefined;
90
67
  }
91
68
  connectedCallback() {
92
- console.debug(`${_a.name} ⚡️ connect`);
69
+ if (devFlags.debug)
70
+ console.debug(`${_a.name} ⚡️ connect`);
93
71
  CleanupRegistry.register(this, onoff(listActive(this), this).on());
94
- // console.log(999, this.#shadowRoot.querySelector('[part*=table-column-stack]'))
95
72
  this.#styleObserver = new CSSStyleObserver({
96
73
  properties: ['--adaptable-table-style-index'],
97
74
  });
@@ -101,27 +78,26 @@ export class TableView extends HTMLElement {
101
78
  this.#styleObserver.observe(target, this.#handleStyleChange);
102
79
  Snapshot.waitReady.then(() => self.requestAnimationFrame(this.#handleStyleChange));
103
80
  }
104
- #handleSlotchange = (evt) => {
105
- console.debug(`${_a.name} ⚡️ ${evt?.type}`);
106
- const slot = evt.target, assigned = slot.assignedElements({ flatten: true });
107
- observers.syncObservations(this.#trackedElements, assigned, this.#handleTagMutation);
108
- if (0 < assigned.length)
109
- this.#handleTagMutation();
81
+ #handleColumnSlotchange = ({ type, target: slot }) => {
82
+ if (devFlags.debug)
83
+ console.debug(`${_a.name} ⚡️ ${type}`);
84
+ if (!(slot instanceof HTMLSlotElement))
85
+ return;
86
+ const assigned = slot.assignedElements();
87
+ this.#observers.syncObservations(assigned);
88
+ // if (0 < assigned.length)
89
+ this.#renderColumns([]);
110
90
  };
111
- #handleTagMutation = (entry) => {
112
- console.debug(`${_a.name} ⚡️ mutation`);
113
- // const sourceSlot = 0 < (this.#colSlot?.assignedElements({ flatten: true }) ?? []).length ? this.#colSlot : this.#colSlot
114
- // const menu = this.querySelector(':scope>menu-view:not([slot])') ?? this.appendChild($(`<menu-view></menu-view>`))
115
- // menu.innerHTML = `<label-view slot="label" system-image="dots-three" title="rtyty"></label-view>`
116
- // for (const el of sourceSlot?.assignedElements({ flatten: true }) ?? []) menu.insertAdjacentElement('beforeend', TableView.wrapTag(el, sourceSlot?.name))
117
- //
91
+ #renderColumns = (entries) => {
92
+ if (devFlags.debug)
93
+ console.debug(`${_a.name} ⚡️ mutation`);
118
94
  if (!this.#compactToolbarItem) {
119
- this.#compactToolbarItem = $(`<menu-view tabindex="0" slot="header-trailing"></menu-view>`);
95
+ this.#compactToolbarItem = $(`<menu-view tabindex="0" slot="header-trailing"></menu-view>`, '>1');
120
96
  CleanupRegistry.unregister(this, 'compact_toolbar');
121
97
  CleanupRegistry.register(this, onoff('click', this.#handleMenuClick, this.#compactToolbarItem).on(), 'compact_toolbar');
122
98
  }
123
99
  this.#compactToolbarItem.innerHTML = `<label-view slot="label" system-image="dots-three"></label-view>`;
124
- for (const node of this.#colSlot?.assignedElements({ flatten: true }) ?? []) {
100
+ for (const node of this.#slots?.get('column')?.assignedElements({ flatten: true }) ?? []) {
125
101
  if (!node.matches('[is=table-column]'))
126
102
  continue;
127
103
  const btn = $(`<button type="button" tabindex="0">
@@ -129,20 +105,18 @@ export class TableView extends HTMLElement {
129
105
  <label-view></label-view>
130
106
  <label-view font="callout" foreground="secondary"></label-view>
131
107
  </v-stack>
132
- </button>`), title = btn.querySelector('label-view:first-child'), subTitle = btn.querySelector('label-view:last-child');
133
- title?.setAttribute('title', node.textContent.trim());
134
- subTitle?.setAttribute('title', node.ariaSort ?? '');
108
+ </button>`, '>1'), title = btn.querySelector('label-view:first-child'), subTitle = btn.querySelector('label-view:last-child');
109
+ if (title)
110
+ renderLabelTitle(title, node.textContent.trim()); //title?.setAttribute('title', node.textContent.trim())
111
+ if (subTitle)
112
+ renderLabelTitle(subTitle, node.ariaSort ?? ''); //subTitle?.setAttribute('title', node.ariaSort ?? '')
135
113
  this.#compactToolbarItem.appendChild(btn);
136
114
  }
137
- // const wasConnected = this.#compactToolbarItem?.isConnected
138
- // this.#compactToolbarItem?.removeEventListener('click', this.#handleMenuClick)
139
- // this.#compactToolbarItem?.remove()
140
- // this.#compactToolbarItem = menu
141
- // this.#compactToolbarItem?.addEventListener('click', this.#handleMenuClick)
142
- // if (wasConnected) this.insertAdjacentElement('beforeend', this.#compactToolbarItem)
143
115
  };
116
+ #observers = new MutationObserverSet(this.#renderColumns);
144
117
  #handleStyleChange = () => {
145
- console.debug(`${_a.name} ⚡️ style`);
118
+ if (devFlags.debug)
119
+ console.debug(`${_a.name} ⚡️ style`);
146
120
  const target = this.#shadowRoot.querySelector('[part*=table-container]') ?? undefined;
147
121
  if (!target)
148
122
  return;
@@ -150,25 +124,29 @@ export class TableView extends HTMLElement {
150
124
  const adaptableTableStyle = style.getPropertyValue('--adaptable-table-style') || 'compact';
151
125
  switch (adaptableTableStyle) {
152
126
  case 'expanded':
153
- if (!this.#compactToolbarItem?.isConnected)
154
- break;
155
- this.#compactToolbarItem?.remove();
127
+ if (this.#compactToolbarItem?.isConnected)
128
+ this.#compactToolbarItem?.remove();
156
129
  break;
157
130
  default:
158
131
  if (!this.#compactToolbarItem)
159
132
  break;
160
- if (this.#compactToolbarItem?.isConnected)
133
+ if (!this.#slots
134
+ ?.get('column')
135
+ ?.assignedElements()
136
+ .filter((el) => el.matches(':is(button[is=table-column])')).length)
161
137
  break;
162
- this.insertAdjacentElement('beforeend', this.#compactToolbarItem);
138
+ if (!this.#compactToolbarItem?.isConnected)
139
+ this.insertAdjacentElement('beforeend', this.#compactToolbarItem);
163
140
  break;
164
141
  }
165
142
  };
166
- #handleMenuClick = (evt) => {
167
- const btn = evt.target.closest('button');
143
+ #handleMenuClick = ({ target }) => {
144
+ if (!(target instanceof HTMLElement))
145
+ return;
146
+ const btn = target.closest('button');
168
147
  if (!btn)
169
148
  return;
170
- const siblings = [...(btn.parentNode?.querySelectorAll(':scope>button') ?? [])];
171
- const index = siblings.indexOf(btn);
149
+ const siblings = [...(btn.parentNode?.querySelectorAll(':scope>button') ?? [])], index = siblings.indexOf(btn);
172
150
  this.querySelector(`:scope>[slot=column]:nth-of-type(${index + 1})`)?.click();
173
151
  };
174
152
  }
@@ -10,9 +10,9 @@ export declare class TextField extends FormAssociatedBase {
10
10
  static get observedAttributes(): string[];
11
11
  static get template(): DocumentFragment;
12
12
  constructor();
13
- connectedCallback(): void;
14
- disconnectedCallback(): void;
15
13
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
14
+ disconnectedCallback(): void;
15
+ connectedCallback(): void;
16
16
  get keyboardType(): KeyboardType;
17
17
  get text(): string;
18
18
  set text(v: string);
@@ -1,8 +1,9 @@
1
1
  var _a;
2
2
  import { I18n } from '../i18n';
3
3
  import { CleanupRegistry } from '../internal/class/cleanup-registry';
4
- import { FormAssociatedBase, getInternals, makeSlotchangeHandler } from '../internal/class/form-associated-base';
5
- import { $, compareBigDecimals, kebabCase, onoff, set } from '../internal/utils';
4
+ import { FormAssociatedBase, getInternals } from '../internal/class/form-associated-base';
5
+ import { MutationObserverSet } from '../internal/class/mutation-observer-set';
6
+ import { $, compareBigDecimals, devFlags, kebabCase, onoff, renderLabel, set } from '../internal/utils';
6
7
  const keyboardTypes = ['decimal-pad', 'number-pad', 'default'];
7
8
  /**
8
9
  * @slot label
@@ -10,21 +11,7 @@ const keyboardTypes = ['decimal-pad', 'number-pad', 'default'];
10
11
  */
11
12
  export class TextField extends FormAssociatedBase {
12
13
  static get observedAttributes() {
13
- return [
14
- 'prompt',
15
- 'minimum',
16
- 'maximum',
17
- 'min-length',
18
- 'max-length',
19
- 'label',
20
- 'name',
21
- 'text',
22
- 'text-input-autocapitalization',
23
- 'disable-autocorrection',
24
- 'keyboard-type',
25
- 'required',
26
- 'disabled',
27
- ];
14
+ return ['prompt', 'minimum', 'maximum', 'min-length', 'max-length', 'label', 'name', 'text', 'text-input-autocapitalization', 'disable-autocorrection', 'keyboard-type', 'required', 'disabled'];
28
15
  }
29
16
  static #template;
30
17
  static get template() {
@@ -37,12 +24,19 @@ export class TextField extends FormAssociatedBase {
37
24
  <input type="text" part="root input text-field-form-input">
38
25
  </div>
39
26
  <slot name="validity-options" hidden></slot>
40
- </label>`, ''));
27
+ </label>`));
41
28
  }
29
+ #renderValidityMsgs = (entries) => {
30
+ if (devFlags.debug)
31
+ console.debug(`${_a.name} ⚡️ mutation`);
32
+ this.setValidity(this.validity, this.validationMessage);
33
+ };
42
34
  #shadowRoot;
43
35
  // #internals: ElementInternals
44
36
  #customValidity = '';
45
- #validitiesSlot;
37
+ // #validitiesSlot?: HTMLSlotElement
38
+ #slots = new Map();
39
+ #validityObservers = new MutationObserverSet(this.#renderValidityMsgs);
46
40
  #input;
47
41
  get #internals() {
48
42
  return getInternals(this);
@@ -51,9 +45,13 @@ export class TextField extends FormAssociatedBase {
51
45
  super();
52
46
  this.#shadowRoot = this.attachShadow({ mode: 'closed' });
53
47
  this.#shadowRoot.appendChild(document.importNode(this.constructor.template, true));
54
- this.#validitiesSlot = this.#shadowRoot.querySelector('slot[name=validity-options]') ?? undefined;
48
+ for (const slot of this.#shadowRoot.querySelectorAll('slot'))
49
+ this.#slots?.set(slot.name, slot);
50
+ CleanupRegistry.register(this, () => {
51
+ this.#slots = new Map();
52
+ });
55
53
  CleanupRegistry.unregister(this, 'validities');
56
- CleanupRegistry.register(this, onoff(makeSlotchangeHandler(this), this.#validitiesSlot).on(), 'validities');
54
+ CleanupRegistry.register(this, onoff('slotchange', this.#handleValiditiesSlotchange, this.#slots?.get('validity-options')).on(), 'validities');
57
55
  this.#input = this.#shadowRoot.querySelector('input') ?? undefined;
58
56
  CleanupRegistry.register(this, onoff([{ types: 'focusin', listener: this.#handleFocusin }], this).on());
59
57
  CleanupRegistry.register(this, onoff([
@@ -62,23 +60,13 @@ export class TextField extends FormAssociatedBase {
62
60
  { types: 'beforeinput', listener: this.#handleInputBeforeinput },
63
61
  { types: 'paste', listener: this.#handleInputPaste },
64
62
  ], this.#input).on());
65
- CleanupRegistry.register(this, onoff('change', () => {
63
+ CleanupRegistry.register(this, onoff('localechange', () => {
66
64
  this.text = this.text;
67
65
  }, I18n.on).on());
68
66
  }
69
- connectedCallback() {
70
- super.connectedCallback();
71
- // finally
72
- if (!this.hasAttribute('text'))
73
- return;
74
- this.text = this.getAttribute('text') ?? ''; // this.#input.value = this.getAttribute('text') ?? ''
75
- this.#sendValueToForm(false);
76
- }
77
- disconnectedCallback() {
78
- super.disconnectedCallback();
79
- }
80
67
  attributeChangedCallback(name, oldValue, newValue) {
81
- console.debug(`${_a.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
68
+ if (devFlags.debug)
69
+ console.debug(`${_a.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
82
70
  switch (name) {
83
71
  case 'keyboard-type':
84
72
  switch (newValue) {
@@ -126,7 +114,7 @@ export class TextField extends FormAssociatedBase {
126
114
  break;
127
115
  case 'text':
128
116
  // if (this.#input) this.#input.value = newValue ?? ''
129
- this.text = newValue ?? '';
117
+ // nothing happens //this.text = newValue ?? ''
130
118
  break;
131
119
  case 'required':
132
120
  this.#input?.setAttribute(name, newValue ?? ''); // else this.#input?.removeAttribute(name)
@@ -149,14 +137,8 @@ export class TextField extends FormAssociatedBase {
149
137
  this.#sendValueToForm();
150
138
  break;
151
139
  case 'label':
152
- let label = this.querySelector(':scope>[slot=label]');
153
- if (newValue) {
154
- label ??= this.appendChild($(`<span slot="label" foreground="secondary"></span>`));
155
- label.textContent = newValue;
156
- }
157
- else
158
- label?.remove();
159
- this.#sendValueToForm();
140
+ renderLabel(':scope>label-view[slot=label]', `<label-view slot="label" foreground="secondary"><span></span></label-view>`, this, newValue);
141
+ // this.#sendValueToForm()
160
142
  break;
161
143
  case 'disabled':
162
144
  for (const el of this.#shadowRoot.querySelectorAll('input'))
@@ -180,10 +162,20 @@ export class TextField extends FormAssociatedBase {
180
162
  break;
181
163
  }
182
164
  }
165
+ disconnectedCallback() {
166
+ super.disconnectedCallback();
167
+ this.#validityObservers.unobserveAll();
168
+ }
169
+ connectedCallback() {
170
+ super.connectedCallback();
171
+ // finally
172
+ if (!this.hasAttribute('text'))
173
+ return;
174
+ this.text = this.getAttribute('text') ?? ''; // this.#input.value = this.getAttribute('text') ?? ''
175
+ this.#sendValueToForm(false);
176
+ }
183
177
  get keyboardType() {
184
- return keyboardTypes.includes(this.getAttribute('keyboard-type') ?? '')
185
- ? this.getAttribute('keyboard-type')
186
- : 'default';
178
+ return keyboardTypes.includes(this.getAttribute('keyboard-type') ?? '') ? this.getAttribute('keyboard-type') : 'default';
187
179
  }
188
180
  get text() {
189
181
  return this.#input?.value ?? '';
@@ -200,8 +192,19 @@ export class TextField extends FormAssociatedBase {
200
192
  set(this.#input, 'value', finalText); // if (this.text !== finalText) this.#input.value = finalText
201
193
  }
202
194
  }
195
+ #handleValiditiesSlotchange = ({ type, target: slot }) => {
196
+ if (devFlags.debug)
197
+ console.debug(`${_a.name} ⚡️ ${type}`);
198
+ if (!(slot instanceof HTMLSlotElement))
199
+ return;
200
+ const assigned = slot.assignedElements();
201
+ this.#validityObservers.syncObservations(assigned, ['value', 'label']);
202
+ // if (0 < assigned.length)
203
+ this.#renderValidityMsgs([]);
204
+ };
203
205
  #handleFocusin = (evt) => {
204
- console.debug(`${_a.name} ⚡️ ${evt?.type}`);
206
+ if (devFlags.debug)
207
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
205
208
  if (evt.target === this)
206
209
  this.#input?.focus();
207
210
  };
@@ -232,9 +235,10 @@ export class TextField extends FormAssociatedBase {
232
235
  this.dispatchEvent(new CustomEvent('commit', { detail: { text: this.text }, bubbles: true, composed: true }));
233
236
  };
234
237
  #handleInputPaste = (evt) => {
235
- console.debug(`${_a.name} ⚡️ ${evt?.type}`);
236
- const input = evt.target;
237
- if (!input)
238
+ if (devFlags.debug)
239
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
240
+ const { target: input } = evt;
241
+ if (!(input instanceof HTMLInputElement))
238
242
  return;
239
243
  evt.preventDefault();
240
244
  const data = this.#identity(evt.clipboardData?.getData('text') ?? ''); // number is now sanitized but contains edge cases like '+' and also global one separator that could be wither dot or decimal.
@@ -303,41 +307,42 @@ export class TextField extends FormAssociatedBase {
303
307
  const allowedSignsRegex2 = /^[+-]?$|^[+-]?(\d+([.,]\d*)?|[.,]\d*)$/, // allow single '+' or '-', then allow only one ',' or '.' and finally only digits
304
308
  digitsDecimalsOnlyRegex = /^(\d+([.,]\d*)?|[.,]\d*)?$/; // allow only one ',' or '.' and finally only digits
305
309
  return (this.negativeNumbersAllowed ? allowedSignsRegex2 : digitsDecimalsOnlyRegex).test(str);
306
- // // console.log(isValidDecimal("")); // true
307
- // // console.log(isValidDecimal("+")); // true
308
- // // console.log(isValidDecimal("-")); // true
309
- // // console.log(isValidDecimal("123")); // true
310
- // // console.log(isValidDecimal("+123")); // true
311
- // // console.log(isValidDecimal("-456")); // true
312
- // // console.log(isValidDecimal("12.34")); // true
313
- // // console.log(isValidDecimal("-0,56")); // true
314
- // // console.log(isValidDecimal(".78")); // true
315
- // // console.log(isValidDecimal(",9")); // true
316
- // // console.log(isValidDecimal("12.3.4")); // false
317
- // // console.log(isValidDecimal("12,3,4")); // false
318
- // // console.log(isValidDecimal("12-3")); // false
319
- // // console.log(isValidDecimal("12a")); // false
310
+ // // isValidDecimal(""); // true
311
+ // // isValidDecimal("+"); // true
312
+ // // isValidDecimal("-"); // true
313
+ // // isValidDecimal("123"); // true
314
+ // // isValidDecimal("+123"); // true
315
+ // // isValidDecimal("-456"); // true
316
+ // // isValidDecimal("12.34"); // true
317
+ // // isValidDecimal("-0,56"); // true
318
+ // // isValidDecimal(".78"); // true
319
+ // // isValidDecimal(",9"); // true
320
+ // // isValidDecimal("12.3.4"); // false
321
+ // // isValidDecimal("12,3,4"); // false
322
+ // // isValidDecimal("12-3"); // false
323
+ // // isValidDecimal("12a"); // false
320
324
  case 'number-pad':
321
325
  const allowedSignsRegex = /^([+-]|\d+|[+-]\d+)?$/, // allow single '+' or '-', then allow only digits
322
326
  digitsOnlyRegex = /^(\d+)?$/; // allow only digits
323
327
  return (this.negativeNumbersAllowed ? allowedSignsRegex : digitsOnlyRegex).test(str);
324
- // // console.log(isValidInteger("")); // true
325
- // // console.log(isValidInteger("+")); // true
326
- // // console.log(isValidInteger("-")); // true
327
- // // console.log(isValidInteger("123")); // true
328
- // // console.log(isValidInteger("+123")); // true
329
- // // console.log(isValidInteger("-456")); // true
330
- // // console.log(isValidInteger("12-3")); // false
331
- // // console.log(isValidInteger("++123")); // false
332
- // // console.log(isValidInteger("123a")); // false
328
+ // // isValidInteger(""); // true
329
+ // // isValidInteger("+"); // true
330
+ // // isValidInteger("-"); // true
331
+ // // isValidInteger("123"); // true
332
+ // // isValidInteger("+123"); // true
333
+ // // isValidInteger("-456"); // true
334
+ // // isValidInteger("12-3"); // false
335
+ // // isValidInteger("++123"); // false
336
+ // // isValidInteger("123a"); // false
333
337
  default:
334
338
  return true;
335
339
  }
336
340
  };
337
341
  #handleInputBeforeinput = (evt) => {
338
- console.debug(`${_a.name} ⚡️ ${evt?.type}`);
339
- const input = evt.target;
340
- if (!input)
342
+ if (devFlags.debug)
343
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
344
+ const { target: input } = evt;
345
+ if (!(input instanceof HTMLInputElement))
341
346
  return;
342
347
  if ('insertText' !== evt.inputType)
343
348
  return;
@@ -369,10 +374,10 @@ export class TextField extends FormAssociatedBase {
369
374
  // this.setValidity(prevValidity, prevValiditationMessage) // restore
370
375
  }
371
376
  };
372
- #handleInputBlur = (evt) => {
373
- console.debug(`${_a.name} ⚡️ ${evt?.type}`);
374
- const input = evt.target;
375
- if (!input)
377
+ #handleInputBlur = ({ type, target: input }) => {
378
+ if (devFlags.debug)
379
+ console.debug(`${_a.name} ⚡️ ${type}`);
380
+ if (!(input instanceof HTMLInputElement))
376
381
  return;
377
382
  if (0 === input.value.length)
378
383
  return;
@@ -382,7 +387,8 @@ export class TextField extends FormAssociatedBase {
382
387
  this.#sendValueToForm();
383
388
  };
384
389
  #handleInputInput = (evt) => {
385
- console.debug(`${_a.name} ⚡️ ${evt?.type}`);
390
+ if (devFlags.debug)
391
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
386
392
  this.#sendValueToForm();
387
393
  };
388
394
  // Optional: form participation properties
@@ -442,16 +448,16 @@ export class TextField extends FormAssociatedBase {
442
448
  const key = k; // ✅ type-safe cast
443
449
  if (true !== flags[key])
444
450
  continue;
445
- for (const el of this.#validitiesSlot?.assignedElements({ flatten: true }) ?? []) {
451
+ for (const el of this.#slots?.get('validity-options')?.assignedElements({ flatten: true }) ?? []) {
446
452
  if (!el.matches('option'))
447
453
  continue;
448
- const option = el;
449
- if (`${kebabCase(key)}` === option.value) {
450
- message = option.label;
454
+ const { label, value } = el;
455
+ if (`${kebabCase(key)}` === value) {
456
+ message = label;
451
457
  break;
452
458
  }
453
- else if (`${kebabCase(key)}:${message}` === option.value) {
454
- message = option.label;
459
+ else if (`${kebabCase(key)}:${message}` === value) {
460
+ message = label;
455
461
  break;
456
462
  }
457
463
  }
@@ -464,7 +470,8 @@ export class TextField extends FormAssociatedBase {
464
470
  message = kebabCase(key);
465
471
  break;
466
472
  }
467
- console.debug(`${_a.name} ⚡️ validity-change`);
473
+ if (devFlags.debug)
474
+ console.debug(`${_a.name} ⚡️ validity-change`);
468
475
  return this.#internals.setValidity(flags, this.#customValidity || message, anchor ?? this.#input);
469
476
  };
470
477
  setCustomValidity = (message) => {
@@ -0,0 +1,28 @@
1
+ import { FormAssociatedBase } from '../internal/class/form-associated-base';
2
+ declare const toggleStyles: readonly ["switch", "button"];
3
+ export type ToggleStyle = (typeof toggleStyles)[number];
4
+ /**
5
+ * @slot label
6
+ * @slot validity-options
7
+ */
8
+ export declare class ToggleView extends FormAssociatedBase {
9
+ #private;
10
+ static get observedAttributes(): string[];
11
+ static get template(): DocumentFragment;
12
+ constructor();
13
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
14
+ disconnectedCallback(): void;
15
+ connectedCallback(): void;
16
+ get toggleStyle(): ToggleStyle;
17
+ get isOn(): boolean;
18
+ set isOn(v: boolean);
19
+ get name(): string;
20
+ get value(): string | null;
21
+ set value(v: string | null);
22
+ setValidity: (flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement) => void;
23
+ setCustomValidity: (message: string) => void;
24
+ formAssociatedCallback: (form: HTMLFormElement) => void;
25
+ formDisabledCallback: (disabled: boolean) => void;
26
+ formResetCallback: () => void;
27
+ }
28
+ export {};