@swiftwc/ui 0.0.0-dev.65 → 0.0.0-dev.67
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.
- package/generated/client/index.js +0 -1
- package/generated/components/h-stack.d.ts +4 -0
- package/generated/components/h-stack.js +4 -0
- package/generated/components/index.d.ts +1 -0
- package/generated/components/index.js +1 -0
- package/generated/components/label-view.d.ts +5 -0
- package/generated/components/label-view.js +5 -0
- package/generated/components/toggle-view.d.ts +28 -0
- package/generated/components/toggle-view.js +222 -0
- package/generated/components/v-stack.d.ts +4 -0
- package/generated/components/v-stack.js +4 -0
- package/generated/css/index.css +135 -31
- package/generated/events/index.d.ts +1 -0
- package/generated/events/index.js +1 -0
- package/generated/events/toggle-view.d.ts +9 -0
- package/generated/events/toggle-view.js +1 -0
- package/package.json +1 -1
- package/scss/_components.scss +2 -0
- package/scss/components/_date-picker.scss +15 -15
- package/scss/components/_h-stack.scss +17 -1
- package/scss/components/_index.scss +4 -0
- package/scss/components/_menu-view.scss +53 -49
- package/scss/components/_picker-view.scss +38 -39
- package/scss/components/_scroll-view-proxy.scss +4 -2
- package/scss/components/_section-view.scss +23 -22
- package/scss/components/_table-view.scss +6 -6
- package/scss/components/_text-field.scss +26 -26
- package/scss/components/_toggle-view.scss +79 -0
- package/scss/components/_tool-bar.scss +52 -52
- package/scss/mixins/_index.scss +10 -2
- package/scss/placeholders/_lists.scss +14 -12
- package/scss/transitions/_menu-view.scss +17 -15
- package/scss/utils/_index.scss +6 -1
- package/web-components.html-data/en.json +175 -0
|
@@ -108,7 +108,6 @@ document.addEventListener('touchstart', () => { }, { passive: true });
|
|
|
108
108
|
//#endregion
|
|
109
109
|
// SECTION
|
|
110
110
|
const handleHelp = ({ target, relatedTarget }) => {
|
|
111
|
-
console.log(999, target);
|
|
112
111
|
if (!(target instanceof HTMLElement))
|
|
113
112
|
return;
|
|
114
113
|
const trigger = target.closest('[help]');
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
*
|
|
3
3
|
* @attr {@spacingSet} spacing - The gap between the primary axis
|
|
4
4
|
*
|
|
5
|
+
* @attr {@alignmentSet} alignment - The cross-axis alignment
|
|
6
|
+
* @attr {@distributionSet} distribution - The main-axis alignment
|
|
7
|
+
* @attr {@placementSet} placement - The main-axis alignment
|
|
8
|
+
*
|
|
5
9
|
*/
|
|
6
10
|
export declare class HStack extends HTMLElement {
|
|
7
11
|
constructor();
|
|
@@ -3,6 +3,10 @@ import { devFlags } from '../internal/utils';
|
|
|
3
3
|
*
|
|
4
4
|
* @attr {@spacingSet} spacing - The gap between the primary axis
|
|
5
5
|
*
|
|
6
|
+
* @attr {@alignmentSet} alignment - The cross-axis alignment
|
|
7
|
+
* @attr {@distributionSet} distribution - The main-axis alignment
|
|
8
|
+
* @attr {@placementSet} placement - The main-axis alignment
|
|
9
|
+
*
|
|
6
10
|
*/
|
|
7
11
|
export class HStack extends HTMLElement {
|
|
8
12
|
constructor() {
|
|
@@ -39,6 +39,7 @@ export * from './tab-item';
|
|
|
39
39
|
export * from './tab-view';
|
|
40
40
|
export * from './table-view';
|
|
41
41
|
export * from './text-field';
|
|
42
|
+
export * from './toggle-view';
|
|
42
43
|
export * from './tool-bar-item-group';
|
|
43
44
|
export * from './tool-bar-item';
|
|
44
45
|
export * from './tool-bar';
|
|
@@ -39,6 +39,7 @@ export * from './tab-item';
|
|
|
39
39
|
export * from './tab-view';
|
|
40
40
|
export * from './table-view';
|
|
41
41
|
export * from './text-field';
|
|
42
|
+
export * from './toggle-view';
|
|
42
43
|
export * from './tool-bar-item-group';
|
|
43
44
|
export * from './tool-bar-item';
|
|
44
45
|
export * from './tool-bar';
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { $, devFlags, renderLabelIcon, renderLabelTitle } from '../internal/utils';
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @attr {@fontSet} font - Sets the default font for text in this view.
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
2
7
|
export class LabelView extends HTMLElement {
|
|
3
8
|
static get observedAttributes() {
|
|
4
9
|
return ['system-image', 'title', 'line-limit', 'truncation-mode'];
|
|
@@ -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 {};
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
var _a;
|
|
2
|
+
import { CleanupRegistry } from '../internal/class/cleanup-registry';
|
|
3
|
+
import { FormAssociatedBase, getInternals } from '../internal/class/form-associated-base';
|
|
4
|
+
import { MutationObserverSet } from '../internal/class/mutation-observer-set';
|
|
5
|
+
import { $, devFlags, kebabCase, onoff, renderLabel } from '../internal/utils';
|
|
6
|
+
const toggleStyles = ['switch', 'button'];
|
|
7
|
+
/**
|
|
8
|
+
* @slot label
|
|
9
|
+
* @slot validity-options
|
|
10
|
+
*/
|
|
11
|
+
export class ToggleView extends FormAssociatedBase {
|
|
12
|
+
static get observedAttributes() {
|
|
13
|
+
return ['label', 'name', 'value', 'is-on', 'keyboard-type', 'required', 'disabled'];
|
|
14
|
+
}
|
|
15
|
+
static #template;
|
|
16
|
+
static get template() {
|
|
17
|
+
return (this.#template ??= $(String.raw `
|
|
18
|
+
<label part="root toggle-stack">
|
|
19
|
+
<div part="root toggle-label-stack">
|
|
20
|
+
<slot name="label"></slot>
|
|
21
|
+
</div>
|
|
22
|
+
<div part="root toggle-input-stack">
|
|
23
|
+
<!--<input type="checkbox" part="root input toggle-form-input">-->
|
|
24
|
+
<div part="root toggle-form-input" tabindex="0"></div>
|
|
25
|
+
</div>
|
|
26
|
+
<slot name="validity-options" hidden></slot>
|
|
27
|
+
</label>`));
|
|
28
|
+
}
|
|
29
|
+
#renderValidityMsgs = (entries) => {
|
|
30
|
+
if (devFlags.debug)
|
|
31
|
+
console.debug(`${_a.name} ⚡️ mutation`);
|
|
32
|
+
this.setValidity(this.validity, this.validationMessage);
|
|
33
|
+
};
|
|
34
|
+
#shadowRoot;
|
|
35
|
+
#customValidity = '';
|
|
36
|
+
#slots = new Map();
|
|
37
|
+
#validityObservers = new MutationObserverSet(this.#renderValidityMsgs);
|
|
38
|
+
#input;
|
|
39
|
+
#value = 'on';
|
|
40
|
+
#isOn = false;
|
|
41
|
+
#connected = false;
|
|
42
|
+
get #internals() {
|
|
43
|
+
return getInternals(this);
|
|
44
|
+
}
|
|
45
|
+
constructor() {
|
|
46
|
+
super();
|
|
47
|
+
this.#shadowRoot = this.attachShadow({ mode: 'closed' });
|
|
48
|
+
this.#shadowRoot.appendChild(document.importNode(this.constructor.template, true));
|
|
49
|
+
for (const slot of this.#shadowRoot.querySelectorAll('slot'))
|
|
50
|
+
this.#slots?.set(slot.name, slot);
|
|
51
|
+
CleanupRegistry.register(this, () => {
|
|
52
|
+
this.#slots = new Map();
|
|
53
|
+
});
|
|
54
|
+
CleanupRegistry.unregister(this, 'validities');
|
|
55
|
+
CleanupRegistry.register(this, onoff('slotchange', this.#handleValiditiesSlotchange, this.#slots?.get('validity-options')).on(), 'validities');
|
|
56
|
+
this.#input = this.#shadowRoot.querySelector('[part*=toggle-form-input]') ?? undefined;
|
|
57
|
+
this.#input?.addEventListener('click', () => {
|
|
58
|
+
this.isOn = !this.isOn;
|
|
59
|
+
this.#sendValueToForm(this.#connected);
|
|
60
|
+
});
|
|
61
|
+
CleanupRegistry.register(this, onoff([{ types: 'focusin', listener: this.#handleFocusin }], this).on());
|
|
62
|
+
CleanupRegistry.register(this, onoff([{ types: 'keydown', listener: this.#handleInputKeydown }], this.#input).on());
|
|
63
|
+
// CleanupRegistry.register(this, onoff([{ types: 'input', listener: this.#handleInputInput }], this.#input).on())
|
|
64
|
+
}
|
|
65
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
66
|
+
if (devFlags.debug)
|
|
67
|
+
console.debug(`${_a.name} ⚡️ attr-change [${name}] ("${oldValue}" → "${newValue}")`);
|
|
68
|
+
switch (name) {
|
|
69
|
+
case 'value':
|
|
70
|
+
this.value = String(newValue); // this.#input?.setAttribute('checked', newValue ?? '')
|
|
71
|
+
this.#sendValueToForm(this.#connected);
|
|
72
|
+
break;
|
|
73
|
+
case 'is-on':
|
|
74
|
+
this.isOn = newValue !== null; // this.#input?.setAttribute('checked', newValue ?? '')
|
|
75
|
+
this.#sendValueToForm(this.#connected);
|
|
76
|
+
break;
|
|
77
|
+
case 'required':
|
|
78
|
+
// this.#input?.setAttribute(name, newValue ?? '')
|
|
79
|
+
this.#sendValueToForm(this.#connected);
|
|
80
|
+
break;
|
|
81
|
+
case 'name':
|
|
82
|
+
this.#sendValueToForm(this.#connected);
|
|
83
|
+
break;
|
|
84
|
+
case 'label':
|
|
85
|
+
renderLabel(':scope>label-view[slot=label]', `<label-view slot="label" foreground="secondary"><span></span></label-view>`, this, newValue);
|
|
86
|
+
break;
|
|
87
|
+
case 'disabled':
|
|
88
|
+
for (const el of this.#shadowRoot.querySelectorAll('input'))
|
|
89
|
+
el.toggleAttribute('disabled', !newValue);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
disconnectedCallback() {
|
|
94
|
+
super.disconnectedCallback();
|
|
95
|
+
this.#validityObservers.unobserveAll();
|
|
96
|
+
}
|
|
97
|
+
connectedCallback() {
|
|
98
|
+
super.connectedCallback();
|
|
99
|
+
// finally
|
|
100
|
+
// if (this.hasAttribute('value')) this.value = this.getAttribute('value') ?? ''
|
|
101
|
+
if (this.hasAttribute('is-on'))
|
|
102
|
+
this.isOn = this.hasAttribute('is-on');
|
|
103
|
+
this.#sendValueToForm(false);
|
|
104
|
+
this.#connected = true;
|
|
105
|
+
}
|
|
106
|
+
get toggleStyle() {
|
|
107
|
+
return toggleStyles.includes(this.getAttribute('toggle-style') ?? '') ? this.getAttribute('toggle-style') : 'switch';
|
|
108
|
+
}
|
|
109
|
+
get isOn() {
|
|
110
|
+
return this.#isOn;
|
|
111
|
+
}
|
|
112
|
+
set isOn(v) {
|
|
113
|
+
this.#isOn = Boolean(v);
|
|
114
|
+
this.#value = this.#isOn ? (this.getAttribute('value') ?? 'on') : null;
|
|
115
|
+
this.ariaChecked = `${this.#isOn}`;
|
|
116
|
+
}
|
|
117
|
+
#handleValiditiesSlotchange = ({ type, target: slot }) => {
|
|
118
|
+
if (devFlags.debug)
|
|
119
|
+
console.debug(`${_a.name} ⚡️ ${type}`);
|
|
120
|
+
if (!(slot instanceof HTMLSlotElement))
|
|
121
|
+
return;
|
|
122
|
+
const assigned = slot.assignedElements();
|
|
123
|
+
this.#validityObservers.syncObservations(assigned, ['value', 'label']);
|
|
124
|
+
this.#renderValidityMsgs([]);
|
|
125
|
+
};
|
|
126
|
+
#handleFocusin = ({ type, target }) => {
|
|
127
|
+
if (devFlags.debug)
|
|
128
|
+
console.debug(`${_a.name} ⚡️ ${type}`);
|
|
129
|
+
if (target === this)
|
|
130
|
+
this.#input?.focus();
|
|
131
|
+
};
|
|
132
|
+
#sendValueToForm = (dispatchEvent = true) => {
|
|
133
|
+
// input.value has already been updated/synced !!
|
|
134
|
+
if (this.matches(':disabled'))
|
|
135
|
+
return this.setValidity({});
|
|
136
|
+
if (this.hasAttribute('required') && !this.isOn) {
|
|
137
|
+
this.setValidity({ valueMissing: true });
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.setValidity({});
|
|
141
|
+
}
|
|
142
|
+
const entries = new FormData();
|
|
143
|
+
if (this.value)
|
|
144
|
+
entries.append(this.name, this.value);
|
|
145
|
+
this.#internals.setFormValue(entries);
|
|
146
|
+
if (dispatchEvent)
|
|
147
|
+
this.dispatchEvent(new CustomEvent('commit', { detail: { value: this.value, isOn: this.isOn }, bubbles: true, composed: true }));
|
|
148
|
+
};
|
|
149
|
+
#handleInputKeydown = (evt) => {
|
|
150
|
+
if (devFlags.debug)
|
|
151
|
+
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
152
|
+
this.isOn = !this.isOn;
|
|
153
|
+
this.#sendValueToForm();
|
|
154
|
+
};
|
|
155
|
+
#handleInputInput = (evt) => {
|
|
156
|
+
if (devFlags.debug)
|
|
157
|
+
console.debug(`${_a.name} ⚡️ ${evt?.type}`);
|
|
158
|
+
this.#sendValueToForm();
|
|
159
|
+
};
|
|
160
|
+
// Optional: form participation properties
|
|
161
|
+
get name() {
|
|
162
|
+
return this.getAttribute('name') ?? this.getAttribute('label') ?? this.querySelector(':scope>[slot=label]')?.textContent ?? '';
|
|
163
|
+
}
|
|
164
|
+
get value() {
|
|
165
|
+
return this.#value;
|
|
166
|
+
}
|
|
167
|
+
set value(v) {
|
|
168
|
+
this.#value = this.isOn ? String(v) : null;
|
|
169
|
+
}
|
|
170
|
+
setValidity = (flags, message, anchor) => {
|
|
171
|
+
// let msg
|
|
172
|
+
// if (message)
|
|
173
|
+
for (const k in flags) {
|
|
174
|
+
const key = k; // ✅ type-safe cast
|
|
175
|
+
if (true !== flags[key])
|
|
176
|
+
continue;
|
|
177
|
+
for (const el of this.#slots?.get('validity-options')?.assignedElements({ flatten: true }) ?? []) {
|
|
178
|
+
if (!el.matches('option'))
|
|
179
|
+
continue;
|
|
180
|
+
const { label, value } = el;
|
|
181
|
+
if (`${kebabCase(key)}` === value) {
|
|
182
|
+
message = label;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
else if (`${kebabCase(key)}:${message}` === value) {
|
|
186
|
+
message = label;
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (!message)
|
|
192
|
+
for (const k in flags) {
|
|
193
|
+
const key = k; // ✅ type-safe cast
|
|
194
|
+
if (true !== flags[key])
|
|
195
|
+
continue;
|
|
196
|
+
message = kebabCase(key);
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
if (devFlags.debug)
|
|
200
|
+
console.debug(`${_a.name} ⚡️ validity-change`);
|
|
201
|
+
return this.#internals.setValidity(flags, this.#customValidity || message, anchor ?? this.#input);
|
|
202
|
+
};
|
|
203
|
+
setCustomValidity = (message) => {
|
|
204
|
+
this.#customValidity = message;
|
|
205
|
+
if (this.#customValidity)
|
|
206
|
+
this.#internals.setValidity({ ...this.#internals.validity, customError: true }, message);
|
|
207
|
+
else
|
|
208
|
+
this.#sendValueToForm(false);
|
|
209
|
+
};
|
|
210
|
+
formAssociatedCallback = (form) => {
|
|
211
|
+
this.#sendValueToForm();
|
|
212
|
+
};
|
|
213
|
+
formDisabledCallback = (disabled) => {
|
|
214
|
+
for (const el of this.#shadowRoot.querySelectorAll('input'))
|
|
215
|
+
el.toggleAttribute('disabled', !disabled);
|
|
216
|
+
};
|
|
217
|
+
formResetCallback = () => {
|
|
218
|
+
this.value = '';
|
|
219
|
+
this.#sendValueToForm();
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
_a = ToggleView;
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @attr {@spacingSet} spacing - The gap between the primary axis
|
|
7
7
|
*
|
|
8
|
+
* @attr {@alignmentSet} alignment - The cross-axis alignment
|
|
9
|
+
* @attr {@distributionSet} distribution - The main-axis alignment
|
|
10
|
+
* @attr {@placementSet} placement - The main-axis alignment
|
|
11
|
+
*
|
|
8
12
|
*/
|
|
9
13
|
export declare class VStack extends HTMLElement {
|
|
10
14
|
constructor();
|
|
@@ -6,6 +6,10 @@ import { devFlags } from '../internal/utils';
|
|
|
6
6
|
*
|
|
7
7
|
* @attr {@spacingSet} spacing - The gap between the primary axis
|
|
8
8
|
*
|
|
9
|
+
* @attr {@alignmentSet} alignment - The cross-axis alignment
|
|
10
|
+
* @attr {@distributionSet} distribution - The main-axis alignment
|
|
11
|
+
* @attr {@placementSet} placement - The main-axis alignment
|
|
12
|
+
*
|
|
9
13
|
*/
|
|
10
14
|
export class VStack extends HTMLElement {
|
|
11
15
|
constructor() {
|