@swiftwc/ui 0.0.0-dev.1 → 0.0.0-dev.13

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 (263) hide show
  1. package/README.md +15 -0
  2. package/generated/client/index.d.ts +16 -2
  3. package/generated/client/index.js +298 -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 +7466 -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 +28 -8
  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 +257 -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
  263. package/generated/styles.css +0 -1
@@ -0,0 +1,430 @@
1
+ var _a;
2
+ import { I18n } from '../i18n';
3
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
4
+ import { FormAssociatedBase, getInternals, makeSlotchangeHandler } from '../internal/class/form-associated-base';
5
+ import { $, clamp, kebabCase, onoff, set } from '../internal/utils';
6
+ const datePickerStyles = ['graphical', 'field', 'automatic'];
7
+ export class DatePicker extends FormAssociatedBase {
8
+ static get observedAttributes() {
9
+ return [
10
+ /**
11
+ * The style of this element
12
+ * @type {"graphical"|"field"|"automatic"}
13
+ */
14
+ 'date-picker-style',
15
+ 'required',
16
+ 'prompt',
17
+ 'label',
18
+ 'name',
19
+ 'selection',
20
+ 'disabled',
21
+ 'minimum',
22
+ 'maximum',
23
+ ];
24
+ }
25
+ static #templates = new Map();
26
+ // #lastRenderedStyle?: DatePickerStyle //string | null
27
+ #shadowRoot;
28
+ #customValidity = '';
29
+ #validitiesSlot;
30
+ #inputs = [];
31
+ get #internals() {
32
+ return getInternals(this);
33
+ }
34
+ get template() {
35
+ if (!_a.#templates.has(this.datePickerStyle))
36
+ switch (this.datePickerStyle) {
37
+ default:
38
+ _a.#templates.set(this.datePickerStyle, $(String.raw `
39
+ <label part="root date-picker-stack">
40
+ <div part="root date-picker-label-stack">
41
+ <slot name="label"></slot>
42
+ </div>
43
+ <div part="root date-picker-input-stack">
44
+ <input type="text" name="month" inputmode="numeric" pattern="\d*" minlength="1" maxlength="2" min="1" max="12" part="root input date-picker-form-input">
45
+ <span part="root date-picker-separator"></span>
46
+ <input type="text" name="day" inputmode="numeric" pattern="\d*" minlength="1" maxlength="2" min="1" max="31" part="root input date-picker-form-input">
47
+ <span part="root date-picker-separator"></span>
48
+ <input type="text" name="year" inputmode="numeric" pattern="\d*" minlength="4" maxlength="4" min="0" max="9999" part="root input date-picker-form-input">
49
+ </div>
50
+ <slot name="validity-options" hidden></slot>
51
+ </label>`, ''));
52
+ break;
53
+ }
54
+ return _a.#templates.get(this.datePickerStyle);
55
+ }
56
+ constructor() {
57
+ super();
58
+ this.#shadowRoot = this.attachShadow({ mode: 'closed' });
59
+ }
60
+ connectedCallback() {
61
+ super.connectedCallback();
62
+ CleanupRegistry.register(this, onoff('click', this.#handleClick, this).on());
63
+ this.#render();
64
+ CleanupRegistry.register(this, onoff('change', () => {
65
+ this.#render();
66
+ }, I18n.on).on());
67
+ // finally
68
+ if (!this.hasAttribute('selection'))
69
+ return;
70
+ const [y = '', m = '', d = ''] = (this.getAttribute('selection') ?? '').split(/\D+/);
71
+ this.selection = { year: y, month: m, day: d };
72
+ this.#sendValueToForm(false);
73
+ }
74
+ disconnectedCallback() {
75
+ super.disconnectedCallback();
76
+ }
77
+ attributeChangedCallback(name, oldValue, newValue) {
78
+ console.debug(`${_a.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
79
+ switch (name) {
80
+ case 'selection':
81
+ const [y = '', m = '', d = ''] = (newValue ?? '').split(/\D+/);
82
+ this.selection = { year: y, month: m, day: d };
83
+ break;
84
+ case 'required':
85
+ for (const input of this.#inputs)
86
+ input.setAttribute(name, newValue ?? ''); // else this.#input?.removeAttribute(name)
87
+ this.#sendValueToForm();
88
+ break;
89
+ case 'name':
90
+ case 'minimum':
91
+ case 'maximum':
92
+ this.#sendValueToForm();
93
+ break;
94
+ case 'prompt':
95
+ const [py = '', pm = '', pd = ''] = (newValue ?? '').split(/\D+/), map = { year: py, month: pm, day: pd };
96
+ for (const input of this.#inputs)
97
+ input.setAttribute('placeholder', map[input.name] ?? '');
98
+ break;
99
+ case 'label':
100
+ let label = this.querySelector(':scope>[slot=label]');
101
+ if (newValue) {
102
+ label ??= this.appendChild($(`<span slot="label"></span>`));
103
+ label.textContent = newValue;
104
+ }
105
+ else
106
+ label?.remove();
107
+ this.#sendValueToForm();
108
+ break;
109
+ case 'disabled':
110
+ for (const input of this.#inputs)
111
+ input.toggleAttribute('disabled', !newValue);
112
+ break;
113
+ }
114
+ }
115
+ get datePickerStyle() {
116
+ return datePickerStyles.includes(this.getAttribute('date-picker-style') ?? '')
117
+ ? this.getAttribute('date-picker-style')
118
+ : 'automatic';
119
+ }
120
+ #render() {
121
+ console.debug(`${_a.name} ⚡️ render (${this.datePickerStyle})`);
122
+ if (!this.isConnected)
123
+ return;
124
+ // if (this.#lastRenderedStyle === this.datePickerStyle) return // skip if already applied
125
+ // this.#lastRenderedStyle = this.datePickerStyle
126
+ // clear shadow DOM
127
+ this.#shadowRoot.replaceChildren(document.importNode(this.template, true));
128
+ this.#validitiesSlot = this.#shadowRoot.querySelector('slot[name=validity-options]') ?? undefined;
129
+ CleanupRegistry.unregister(this, 'validities');
130
+ CleanupRegistry.register(this, onoff(makeSlotchangeHandler(this), this.#validitiesSlot).on(), 'validities');
131
+ switch (this.datePickerStyle) {
132
+ default:
133
+ const [yyyy = '', mm = '', dd = ''] = new Date().toISOString().split('T').shift()?.split('-') ?? [], map = { year: yyyy, month: mm, day: dd };
134
+ this.#inputs = [...this.#shadowRoot.querySelectorAll('input')]
135
+ .sort((a, b) => I18n.dateOrder.indexOf(a.name) - I18n.dateOrder.indexOf(b.name))
136
+ .map((input, i) => {
137
+ input.style.order = `${i * 2}`;
138
+ input.tabIndex = i + 1;
139
+ input.setAttribute('placeholder', map[input.name]);
140
+ return input;
141
+ });
142
+ for (const span of this.#shadowRoot.querySelectorAll('input~span')) {
143
+ const prevOrder = Number(span.previousElementSibling?.style.getPropertyValue('order'));
144
+ span.style.setProperty('order', `${prevOrder + 1}`);
145
+ span.textContent = I18n.dateSeparator;
146
+ }
147
+ CleanupRegistry.unregister(this, 'inputs:*');
148
+ for (const input of this.#inputs) {
149
+ CleanupRegistry.register(this, onoff([
150
+ { types: 'focus', listener: this.#handleInputFocus },
151
+ { types: 'blur', listener: this.#handleInputBlur },
152
+ { types: 'input', listener: this.#handleInputInput },
153
+ { types: 'beforeinput', listener: this.#handleInputBeforeinput },
154
+ { types: 'paste', listener: this.#handleInputPaste },
155
+ { types: 'keydown', listener: this.#handleInputKeydown },
156
+ ], input).on(), `inputs:${input.name}`);
157
+ }
158
+ break;
159
+ }
160
+ }
161
+ get selection() {
162
+ const map = Object.fromEntries(this.#inputs.map(({ name, value }) => [name, value]));
163
+ return {
164
+ year: map.year ?? '',
165
+ month: map.month ?? '',
166
+ day: map.day ?? '',
167
+ };
168
+ }
169
+ set selection(v) {
170
+ for (const input of this.#inputs) {
171
+ const nv = v[input.name] ?? '', pattern = /^(\d+)?$/;
172
+ let finalValue = pattern.test(nv) ? nv : '', parsedValue = parseInt(finalValue);
173
+ if (_a.#min(input) > parsedValue)
174
+ finalValue = '';
175
+ else if (_a.#max(input) < parsedValue)
176
+ finalValue = '';
177
+ input.value = finalValue;
178
+ }
179
+ }
180
+ #handleClick = (evt) => {
181
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
182
+ const input = evt.target?.closest('input');
183
+ if (input)
184
+ return;
185
+ this.#shadowRoot.querySelector('input.focus')?.focus?.();
186
+ evt.stopImmediatePropagation();
187
+ evt.preventDefault();
188
+ evt.stopPropagation();
189
+ };
190
+ #sendValueToForm = (dispatchEvent = true) => {
191
+ // input.value has already been updated/synced !!
192
+ if (this.matches(':disabled'))
193
+ return this.setValidity({});
194
+ if (this.#inputs.some((el) => el.matches(':invalid'))) {
195
+ for (const input of this.#inputs) {
196
+ if (input.matches(':invalid'))
197
+ this.setValidity(input.validity, input.validationMessage, input);
198
+ }
199
+ }
200
+ else if (null === this.valueAsDate) {
201
+ this.setValidity({ badInput: true }, 'invalid-date');
202
+ }
203
+ else {
204
+ const parts = ['year', 'month', 'day'], input = (name) => this.#inputs.find((el) => el.name === name);
205
+ const underflow = this.minimum && parts.find((p) => parseInt(this.minimum[p]) > parseInt(this.value[p])), overflow = this.maximum && parts.find((p) => parseInt(this.maximum[p]) < parseInt(this.value[p]));
206
+ if (underflow)
207
+ this.setValidity({ rangeUnderflow: true }, `${underflow}-underflow`, input(underflow));
208
+ else if (overflow)
209
+ this.setValidity({ rangeOverflow: true }, `${overflow}-overflow`, input(overflow));
210
+ else
211
+ this.setValidity({});
212
+ }
213
+ const selection = `${this.selection.year}-${this.selection.month}-${this.selection.day}`;
214
+ const entries = new FormData();
215
+ entries.append(this.name, selection);
216
+ this.#internals.setFormValue(entries);
217
+ if (dispatchEvent)
218
+ this.dispatchEvent(new CustomEvent('selection', { detail: { selection }, bubbles: true, composed: true }));
219
+ };
220
+ #handleInputPaste = (evt) => {
221
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
222
+ const input = evt.target;
223
+ if (!input)
224
+ return;
225
+ evt.preventDefault();
226
+ const data = [...`${(evt.clipboardData?.getData('text') ?? '').trim()}`].reduce((acc, ch, i) => {
227
+ if (/\d/.test(ch))
228
+ return `${acc}${ch}`;
229
+ else
230
+ return acc; // skip everything else
231
+ }, ''); // number is now sanitized but contains edge cases like '+' and also global one separator that could be wither dot or decimal.
232
+ if (0 === data.length)
233
+ return this.shake(); //.then(this.reportValidity) // nothing to paste
234
+ const start = input.selectionStart ?? 0, end = input.selectionEnd ?? 0, before = input.value.slice(0, start), after = input.value.slice(end), newText = `${before}${data}${after}`;
235
+ if (-1 < input.maxLength && input.maxLength < newText.length)
236
+ return this.shake(); //.then(this.reportValidity) // exceeding maxlength
237
+ input.value = newText;
238
+ const newCaret = start + data.length;
239
+ input.setSelectionRange(newCaret, newCaret); // move caret after inserted char
240
+ this.#sendValueToForm();
241
+ };
242
+ #handleInputBeforeinput = (evt) => {
243
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
244
+ const input = evt.target;
245
+ if (!input)
246
+ return;
247
+ if ('insertText' !== evt.inputType)
248
+ return;
249
+ const data = evt.data ?? '';
250
+ if (-1 < input.maxLength && 0 === data.length) {
251
+ evt.preventDefault();
252
+ return this.shake(); //.then(this.reportValidity)
253
+ } // nothing to add
254
+ const start = input.selectionStart ?? 0, end = input.selectionEnd ?? 0, before = input.value.slice(0, start), after = input.value.slice(end), newText = `${before}${data}${after}`;
255
+ if (0 === newText.length)
256
+ return;
257
+ switch (input.getAttribute('inputmode')) {
258
+ case 'numeric':
259
+ if (/^(\d+)?$/.test(newText))
260
+ break; // allow only digits
261
+ evt.preventDefault();
262
+ return this.shake(); //.then(this.reportValidity)
263
+ }
264
+ };
265
+ #handleInputKeydown = ({ type, target, key }) => {
266
+ console.debug(`${_a.name} ⚡️ ${type}`);
267
+ const input = target;
268
+ if (!input)
269
+ return;
270
+ const currentIndex = this.#inputs.indexOf(input);
271
+ let index = currentIndex;
272
+ if (key === 'ArrowRight' && input.value.length === input.selectionStart) {
273
+ if (-1 < currentIndex && currentIndex < this.#inputs.length - 1)
274
+ index++;
275
+ }
276
+ else if (key === 'ArrowLeft' && 0 === input.selectionStart) {
277
+ if (0 < currentIndex)
278
+ index -= 1;
279
+ }
280
+ this.#inputs[index]?.focus();
281
+ };
282
+ #handleInputFocus = (evt) => {
283
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
284
+ for (const input of this.#inputs)
285
+ input.classList.toggle('focus', input === evt.target);
286
+ };
287
+ #handleInputBlur = (evt) => {
288
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
289
+ const input = evt.target;
290
+ if (0 === input.value.length)
291
+ return;
292
+ const finalText = `${clamp(this.value[input.name] ?? '0', _a.#min(input), _a.#max(input))}`.padStart(parseInt(input.getAttribute('maxlength') ?? '0'), '0');
293
+ if (!set(input, 'value', finalText))
294
+ return;
295
+ // this.selection = this.selection
296
+ this.#sendValueToForm();
297
+ };
298
+ #handleInputInput = (evt) => {
299
+ console.debug(`${_a.name} ⚡️ ${evt?.type}`);
300
+ this.#sendValueToForm();
301
+ };
302
+ // Optional: form participation properties
303
+ get name() {
304
+ return this.getAttribute('name') ?? this.getAttribute('label') ?? this.querySelector(':scope>[slot=label]')?.textContent ?? '';
305
+ }
306
+ get value() {
307
+ // text allows special edge cases, like '0' for day and generally might be invalid day/month/year.
308
+ // here we make sure it is date-like, to be used in date operations.
309
+ const map = Object.fromEntries(this.#inputs.map(({ name, value }) => [name, value]));
310
+ return {
311
+ year: (map.year ?? '').padStart(4, '0'),
312
+ month: (map.month ?? '').padStart(2, '0'),
313
+ day: (map.day ?? '').padStart(2, '0'),
314
+ };
315
+ }
316
+ get valueAsDate() {
317
+ try {
318
+ const d = new Date(`${this.value.year}-${this.value.month}-${this.value.day}`);
319
+ if (!(d instanceof Date) || isNaN(d.getTime()))
320
+ return null;
321
+ return d;
322
+ }
323
+ catch {
324
+ return null;
325
+ }
326
+ }
327
+ static #min(input) {
328
+ if (!input?.hasAttribute('min'))
329
+ return -Infinity;
330
+ const number = Number(input.getAttribute('min'));
331
+ if (Number.isNaN(number))
332
+ return -Infinity;
333
+ return number;
334
+ }
335
+ static #max(input) {
336
+ if (!input?.hasAttribute('max'))
337
+ return Infinity;
338
+ const number = Number(input.getAttribute('max'));
339
+ if (Number.isNaN(number))
340
+ return Infinity;
341
+ return number;
342
+ }
343
+ get minimum() {
344
+ if (!this.hasAttribute('minimum'))
345
+ return null;
346
+ try {
347
+ new Date(this.getAttribute('minimum') ?? '');
348
+ const [y = '', m = '', d = ''] = (this.getAttribute('minimum') ?? '').split(/\D+/);
349
+ return {
350
+ year: y.padStart(4, '0'),
351
+ month: m.padStart(2, '0'),
352
+ day: d.padStart(2, '0'),
353
+ };
354
+ }
355
+ catch {
356
+ return null;
357
+ }
358
+ }
359
+ get maximum() {
360
+ if (!this.hasAttribute('maximum'))
361
+ return null;
362
+ try {
363
+ new Date(this.getAttribute('maximum') ?? '');
364
+ const [y = '', m = '', d = ''] = (this.getAttribute('maximum') ?? '').split(/\D+/);
365
+ return {
366
+ year: y.padStart(4, '0'),
367
+ month: m.padStart(2, '0'),
368
+ day: d.padStart(2, '0'),
369
+ };
370
+ }
371
+ catch {
372
+ return null;
373
+ }
374
+ }
375
+ setValidity = (flags, message, anchor) => {
376
+ // let msg
377
+ // if (message)
378
+ for (const k in flags) {
379
+ const key = k; // ✅ type-safe cast
380
+ if (true !== flags[key])
381
+ continue;
382
+ for (const el of this.#validitiesSlot?.assignedElements({ flatten: true }) ?? []) {
383
+ if (!el.matches('option'))
384
+ continue;
385
+ const option = el;
386
+ if (`${kebabCase(key)}` === option.value) {
387
+ message = option.label;
388
+ break;
389
+ }
390
+ else if (`${kebabCase(key)}:${message}` === option.value) {
391
+ message = option.label;
392
+ break;
393
+ }
394
+ }
395
+ }
396
+ if (!message)
397
+ for (const k in flags) {
398
+ const key = k; // ✅ type-safe cast
399
+ if (true !== flags[key])
400
+ continue;
401
+ message = kebabCase(key);
402
+ break;
403
+ }
404
+ console.debug(`${_a.name} ⚡️ validity-change`);
405
+ return this.#internals.setValidity(flags, this.#customValidity || message, anchor ?? this.#inputs.at(0));
406
+ };
407
+ setCustomValidity = (message) => {
408
+ this.#customValidity = message;
409
+ if (this.#customValidity)
410
+ this.#internals.setValidity({ ...this.#internals.validity, customError: true }, message);
411
+ else
412
+ this.#sendValueToForm(false);
413
+ };
414
+ formAssociatedCallback = (form) => {
415
+ this.#sendValueToForm();
416
+ };
417
+ formDisabledCallback = (disabled) => {
418
+ for (const input of this.#inputs)
419
+ input.toggleAttribute('disabled', !disabled);
420
+ };
421
+ formResetCallback = () => {
422
+ this.selection = {
423
+ year: '',
424
+ month: '',
425
+ day: '',
426
+ };
427
+ this.#sendValueToForm();
428
+ };
429
+ }
430
+ _a = DatePicker;
@@ -0,0 +1,9 @@
1
+ import { DetailsBase } from '../namespace-browser/base';
2
+ export declare class DisclosureGroup extends DetailsBase {
3
+ #private;
4
+ static get observedAttributes(): string[];
5
+ constructor();
6
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
7
+ static polyfillDisconnectedCallback(el: DisclosureGroup): void;
8
+ static polyfillConnectedCallback(el: DisclosureGroup): void;
9
+ }
@@ -0,0 +1,51 @@
1
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
2
+ import { cssTime, onoff, timeout } from '../internal/utils';
3
+ import { DetailsBase } from '../namespace-browser/base';
4
+ const toggleTimers = new WeakMap();
5
+ export class DisclosureGroup extends DetailsBase {
6
+ static get observedAttributes() {
7
+ return [
8
+ /**
9
+ * The status of this element
10
+ */
11
+ 'open',
12
+ ];
13
+ }
14
+ constructor() {
15
+ super();
16
+ }
17
+ attributeChangedCallback(name, oldValue, newValue) {
18
+ console.debug(`${DisclosureGroup.name} ⚡️ attr-change [${name}]`);
19
+ // if (CSS.supports('interpolate-size', 'allow-keywords')) return
20
+ }
21
+ static polyfillDisconnectedCallback(el) {
22
+ console.debug(`${DisclosureGroup.name} ⚡️ disconnect`);
23
+ CleanupRegistry.unregister(el);
24
+ }
25
+ static polyfillConnectedCallback(el) {
26
+ console.debug(`${DisclosureGroup.name} ⚡️ connect`);
27
+ const newValue = el.open ? 'open' : 'closed';
28
+ if (newValue !== el.dataset.state)
29
+ el.dataset.state = newValue;
30
+ CleanupRegistry.register(el, onoff('toggle', DisclosureGroup.#handleToggle, el).on());
31
+ CleanupRegistry.register(el, () => {
32
+ toggleTimers.get(el)?.cancel();
33
+ toggleTimers.delete(el);
34
+ });
35
+ }
36
+ static #handleToggle = async (evt) => {
37
+ console.debug(`${DisclosureGroup.name} ⚡️ ${evt?.type}`);
38
+ const details = evt.currentTarget, newValue = details.open ? 'opening' : 'closing';
39
+ if (newValue !== details.dataset.state)
40
+ details.dataset.state = newValue;
41
+ if (!toggleTimers.has(details))
42
+ toggleTimers.set(details, timeout()); //if (!toggleTimeouts.has(details)) toggleTimeouts.set(details, null)
43
+ // Cancel previous timeout for this instance
44
+ //if (toggleTimeouts.has(details) && toggleTimeouts.get(details)) self.clearTimeout(toggleTimeouts.get(details))
45
+ // Schedule a new hook
46
+ toggleTimers.get(details).next(() => {
47
+ details.dataset.state = details.open ? 'open' : 'closed';
48
+ details?.dispatchEvent(new CustomEvent(`is-${details.open ? 'expanded' : 'collapsed'}`, { bubbles: true, composed: true }));
49
+ }, cssTime(`${details.computedStyleMap().get('--disclosure-group-animation-duration')}`));
50
+ };
51
+ }
@@ -0,0 +1,6 @@
1
+ import { FormBase } from '../namespace-browser/base';
2
+ export declare class FormView extends FormBase {
3
+ constructor();
4
+ static polyfillDisconnectedCallback(el: HTMLFormElement): void;
5
+ static polyfillConnectedCallback(el: HTMLFormElement): void;
6
+ }
@@ -0,0 +1,58 @@
1
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
2
+ import { listActive, onoff } from '../internal/utils';
3
+ import { FormBase } from '../namespace-browser/base';
4
+ export class FormView extends FormBase {
5
+ constructor() {
6
+ super();
7
+ }
8
+ static polyfillDisconnectedCallback(el) {
9
+ console.debug(`${FormView.name} ⚡️ disconnect`);
10
+ // finally
11
+ CleanupRegistry.unregister(el);
12
+ }
13
+ static polyfillConnectedCallback(el) {
14
+ console.debug(`${FormView.name} ⚡️ connect`);
15
+ if (el.closest('[is=sidebar-view],[is=tab-bar]')) {
16
+ el.method = 'dialog';
17
+ el.noValidate = true;
18
+ }
19
+ CleanupRegistry.register(el, onoff(listActive(el), el).on());
20
+ if (el.matches(':empty'))
21
+ el.insertAdjacentHTML('beforeend', `<button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
22
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
23
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
24
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
25
+ <details is="disclosure-group">
26
+ <summary><button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></summary>
27
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
28
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
29
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
30
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
31
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
32
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
33
+ </details>
34
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
35
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
36
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
37
+ <details is="disclosure-group">
38
+ <summary><label-view system-image="smiley" title="Item 1"></label-view></summary>
39
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
40
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
41
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
42
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
43
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
44
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
45
+ </details>
46
+ <details is="disclosure-group">
47
+ <summary><label-view system-image="smiley" title="Item 1"></label-view></summary>
48
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
49
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
50
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
51
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
52
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
53
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
54
+ </details>
55
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>
56
+ <button type="button" tabindex="0"><label-view system-image="smiley" title="Item 1"></label-view></button>`);
57
+ }
58
+ }
@@ -0,0 +1,6 @@
1
+ import { ButtonBase } from '../namespace-browser/base';
2
+ export declare class GlassButton extends ButtonBase {
3
+ constructor();
4
+ static polyfillDisconnectedCallback(el: ButtonBase): void;
5
+ static polyfillConnectedCallback(el: ButtonBase): void;
6
+ }
@@ -0,0 +1,17 @@
1
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
2
+ import { onoff, touchGlass } from '../internal/utils';
3
+ import { ButtonBase } from '../namespace-browser/base';
4
+ export class GlassButton extends ButtonBase {
5
+ constructor() {
6
+ super();
7
+ }
8
+ static polyfillDisconnectedCallback(el) {
9
+ console.debug(`${GlassButton.name} ⚡️ disconnect`);
10
+ CleanupRegistry.unregister(el);
11
+ }
12
+ static polyfillConnectedCallback(el) {
13
+ console.debug(`${GlassButton.name} ⚡️ connect`);
14
+ CleanupRegistry.register(el, onoff(touchGlass(el, (t) => t, () => true), el).on());
15
+ el.tabIndex = 0;
16
+ }
17
+ }
@@ -0,0 +1,6 @@
1
+ import { ButtonBase } from '../namespace-browser/base';
2
+ export declare class GlassProminentButton extends ButtonBase {
3
+ constructor();
4
+ static polyfillDisconnectedCallback(el: ButtonBase): void;
5
+ static polyfillConnectedCallback(el: ButtonBase): void;
6
+ }
@@ -0,0 +1,17 @@
1
+ import { CleanupRegistry } from '../internal/class/cleanup-registry';
2
+ import { onoff, touchGlass } from '../internal/utils';
3
+ import { ButtonBase } from '../namespace-browser/base';
4
+ export class GlassProminentButton extends ButtonBase {
5
+ constructor() {
6
+ super();
7
+ }
8
+ static polyfillDisconnectedCallback(el) {
9
+ console.debug(`${GlassProminentButton.name} ⚡️ disconnect`);
10
+ CleanupRegistry.unregister(el);
11
+ }
12
+ static polyfillConnectedCallback(el) {
13
+ console.debug(`${GlassProminentButton.name} ⚡️ connect`);
14
+ CleanupRegistry.register(el, onoff(touchGlass(el, (t) => t, () => true), el).on());
15
+ el.tabIndex = 0;
16
+ }
17
+ }
@@ -1 +1,39 @@
1
- export * from "./v-keyboard";
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
4
+ export * from './body-view';
5
+ export * from './bordered-button';
6
+ export * from './bordered-prominent-button';
7
+ export * from './borderless-button';
8
+ export * from './confirmation-dialog';
9
+ export * from './date-picker';
10
+ export * from './disclosure-group';
11
+ export * from './form-view';
12
+ export * from './glass-button';
13
+ export * from './glass-prominent-button';
14
+ export * from './label-view';
15
+ export * from './list-view';
16
+ export * from './menu-view';
17
+ export * from './navigation-large-title';
18
+ export * from './navigation-split-view';
19
+ export * from './navigation-stack';
20
+ export * from './navigation-title';
21
+ export * from './picker-view';
22
+ export * from './plain-button';
23
+ export * from './screen-view';
24
+ export * from './scroll-view';
25
+ export * from './section-view';
26
+ export * from './sheet-view';
27
+ export * from './sidebar-toggle';
28
+ export * from './sidebar-view';
29
+ export * from './sticky-container';
30
+ export * from './tab-bar';
31
+ export * from './tab-item';
32
+ export * from './tab-view';
33
+ export * from './table-view';
34
+ export * from './text-field';
35
+ export * from './tool-bar-item-group';
36
+ export * from './tool-bar-item';
37
+ export * from './tool-bar';
38
+ export * from './v-keyboard';
39
+ export * from './v-stack';