@vollowx/seele 0.13.8 → 0.13.9
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/README.md +3 -4
- package/package.json +2 -2
- package/src/all.d.ts +3 -0
- package/src/all.js +3 -0
- package/src/base/autocomplete.js +13 -13
- package/src/base/button.d.ts +1 -1
- package/src/base/button.js +1 -2
- package/src/base/experimental/popup.d.ts +3 -1
- package/src/base/experimental/popup.js +4 -2
- package/src/base/mixins/attachable.d.ts +5 -2
- package/src/base/mixins/attachable.js +63 -23
- package/src/base/mixins/button-toggle-mixin.js +1 -2
- package/src/base/mixins/internals-attached.d.ts +2 -0
- package/src/base/mixins/internals-attached.js +1 -0
- package/src/base/radio.d.ts +3 -0
- package/src/base/radio.js +28 -16
- package/src/base/tab-panel.d.ts +3 -3
- package/src/base/tab-panel.js +9 -11
- package/src/base/tab.d.ts +2 -8
- package/src/base/tab.js +16 -35
- package/src/base/tabs.d.ts +6 -6
- package/src/base/tabs.js +101 -99
- package/src/base/tooltip.d.ts +2 -1
- package/src/base/tooltip.js +2 -2
- package/src/core/ensure-ready.d.ts +2 -1
- package/src/core/ensure-ready.js +12 -7
- package/src/m3/button/shared-button-styles.css.js +1 -1
- package/src/m3/button-group/standard-button-group-styles.css.js +1 -1
- package/src/m3/button-group/standard-button-group.d.ts +2 -0
- package/src/m3/button-group/standard-button-group.js +44 -38
- package/src/m3/checkbox/checkbox.d.ts +1 -1
- package/src/m3/checkbox/checkbox.js +2 -5
- package/src/m3/dialog/dialog.d.ts +3 -1
- package/src/m3/dialog/dialog.js +6 -4
- package/src/m3/focus-ring/focus-ring.d.ts +2 -1
- package/src/m3/focus-ring/focus-ring.js +4 -7
- package/src/m3/nagivation/navigation-rail-item-styles.css.js +2 -0
- package/src/m3/nagivation/navigation-rail-item.d.ts +21 -0
- package/src/m3/nagivation/navigation-rail-item.js +44 -0
- package/src/m3/nagivation/navigation-rail-styles.css.js +2 -0
- package/src/m3/nagivation/navigation-rail.d.ts +12 -0
- package/src/m3/nagivation/navigation-rail.js +17 -0
- package/src/m3/radio/radio-styles.css.js +1 -1
- package/src/m3/radio/radio.d.ts +3 -0
- package/src/m3/radio/radio.js +12 -4
- package/src/m3/ripple/ripple.d.ts +2 -1
- package/src/m3/ripple/ripple.js +20 -22
- package/src/m3/{system → styles}/defaults.css +1 -1
- package/src/m3/styles/motion-expressive.css +15 -0
- package/src/m3/styles/motion-standard.css +15 -0
- package/src/m3/styles/typography.css +24 -0
- package/src/m3/switch/switch.d.ts +1 -0
- package/src/m3/switch/switch.js +4 -3
- package/src/m3/tab/secondary-tab-styles.css.js +2 -0
- package/src/m3/tab/secondary-tab.d.ts +5 -0
- package/src/m3/tab/secondary-tab.js +15 -0
- package/src/m3/tab/tab-panel-styles.css.js +1 -1
- package/src/m3/tab/tab-styles.css.js +1 -1
- package/src/m3/tab/tab.d.ts +3 -0
- package/src/m3/tab/tab.js +68 -3
- package/src/m3/tab/tabs-styles.css.js +1 -1
- package/src/m3/tab/tabs.d.ts +1 -7
- package/src/m3/tab/tabs.js +6 -39
- package/src/m3/system/typography.css +0 -34
- /package/src/m3/{system → styles}/base.css +0 -0
- /package/src/m3/{system → styles}/elevation.css +0 -0
- /package/src/m3/{system → styles}/motion.d.ts +0 -0
- /package/src/m3/{system → styles}/motion.js +0 -0
package/README.md
CHANGED
|
@@ -33,13 +33,12 @@ What's the differences comparing to other projects?
|
|
|
33
33
|
|
|
34
34
|
## Getting started
|
|
35
35
|
|
|
36
|
-
Check out [
|
|
36
|
+
Check out [Installation](https://tideover.cc/seele/docs/#installation).
|
|
37
37
|
|
|
38
38
|
## Documentations
|
|
39
39
|
|
|
40
|
-
- [Documentations](./docs/00-Overview.md)
|
|
41
|
-
|
|
42
|
-
- Previous [documentations and demos](https://tideover.cc/seele/docs/), being replaced
|
|
40
|
+
- [Documentations](https://tideover.cc/seele/docs/), ([source](./docs/00-Overview.md))
|
|
41
|
+
- [Backup site](https://lucaz.srht.site/)
|
|
43
42
|
|
|
44
43
|
## Download
|
|
45
44
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vollowx/seele",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.9",
|
|
4
4
|
"description": "A extensible Web Components library, with Material Design 3 components pre-provided.",
|
|
5
5
|
"author": "vollowx",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"files": [
|
|
21
21
|
"src/**/*.js",
|
|
22
22
|
"src/**/*.d.ts",
|
|
23
|
-
"src/m3/
|
|
23
|
+
"src/m3/styles/*.css",
|
|
24
24
|
"custom-elements.json",
|
|
25
25
|
"LICENSE",
|
|
26
26
|
"README.md"
|
package/src/all.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ import './m3/list/list-item.js';
|
|
|
17
17
|
import './m3/loading-indicator/loading-indicator.js';
|
|
18
18
|
import './m3/menu/menu.js';
|
|
19
19
|
import './m3/menu/menu-item.js';
|
|
20
|
+
import './m3/nagivation/navigation-rail.js';
|
|
21
|
+
import './m3/nagivation/navigation-rail-item.js';
|
|
20
22
|
import './m3/radio/radio.js';
|
|
21
23
|
import './m3/ripple/ripple.js';
|
|
22
24
|
import './m3/select/filled-select.js';
|
|
@@ -26,6 +28,7 @@ import './m3/slider/slider.js';
|
|
|
26
28
|
import './m3/switch/switch.js';
|
|
27
29
|
import './m3/tab/tabs.js';
|
|
28
30
|
import './m3/tab/tab.js';
|
|
31
|
+
import './m3/tab/secondary-tab.js';
|
|
29
32
|
import './m3/tab/tab-panel.js';
|
|
30
33
|
import './m3/text-field/filled-text-field.js';
|
|
31
34
|
import './m3/text-field/outlined-text-field.js';
|
package/src/all.js
CHANGED
|
@@ -17,6 +17,8 @@ import './m3/list/list-item.js';
|
|
|
17
17
|
import './m3/loading-indicator/loading-indicator.js';
|
|
18
18
|
import './m3/menu/menu.js';
|
|
19
19
|
import './m3/menu/menu-item.js';
|
|
20
|
+
import './m3/nagivation/navigation-rail.js';
|
|
21
|
+
import './m3/nagivation/navigation-rail-item.js';
|
|
20
22
|
import './m3/radio/radio.js';
|
|
21
23
|
import './m3/ripple/ripple.js';
|
|
22
24
|
import './m3/select/filled-select.js';
|
|
@@ -26,6 +28,7 @@ import './m3/slider/slider.js';
|
|
|
26
28
|
import './m3/switch/switch.js';
|
|
27
29
|
import './m3/tab/tabs.js';
|
|
28
30
|
import './m3/tab/tab.js';
|
|
31
|
+
import './m3/tab/secondary-tab.js';
|
|
29
32
|
import './m3/tab/tab-panel.js';
|
|
30
33
|
import './m3/text-field/filled-text-field.js';
|
|
31
34
|
import './m3/text-field/outlined-text-field.js';
|
package/src/base/autocomplete.js
CHANGED
|
@@ -56,19 +56,19 @@ export class Autocomplete extends Base {
|
|
|
56
56
|
}
|
|
57
57
|
// TODO: handle multiple calls on this function, currently double-call
|
|
58
58
|
// disallowed
|
|
59
|
-
handleInputSlotChange() {
|
|
60
|
-
ensureReady(this.$input)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
59
|
+
async handleInputSlotChange() {
|
|
60
|
+
await ensureReady(this.$input);
|
|
61
|
+
const input = this.$input;
|
|
62
|
+
const $realInput = input.$inputOrTextarea;
|
|
63
|
+
$realInput.role = 'combobox';
|
|
64
|
+
$realInput.ariaExpanded = String(this.open);
|
|
65
|
+
$realInput.ariaHasPopup = 'listbox';
|
|
66
|
+
$realInput.ariaAutoComplete = this.mode;
|
|
67
|
+
$realInput.ariaControlsElements = [this.$menu];
|
|
68
|
+
input.addEventListener('input', this.handleInput.bind(this));
|
|
69
|
+
input.addEventListener('keydown', this.handleInputKeydown.bind(this));
|
|
70
|
+
input.addEventListener('click', () => (this.open = !this.open));
|
|
71
|
+
this.$menu.attach($realInput);
|
|
72
72
|
}
|
|
73
73
|
handleItemsSlotChange() {
|
|
74
74
|
// Initial filter based on current input value (if any)
|
package/src/base/button.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
-
|
|
2
|
+
import { updateInternals } from './mixins/internals-attached.js';
|
|
3
3
|
declare const Base: Constructor<import("./mixins/form-associated.js").FormAssociatedInterface> & Constructor<import("./mixins/internals-attached.js").InternalsAttachedInterface> & typeof LitElement;
|
|
4
4
|
export declare class Button extends Base {
|
|
5
5
|
#private;
|
package/src/base/button.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { LitElement } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
|
-
import { InternalsAttached, internals } from './mixins/internals-attached.js';
|
|
4
|
+
import { InternalsAttached, internals, updateInternals, } from './mixins/internals-attached.js';
|
|
5
5
|
import { FormAssociated } from './mixins/form-associated.js';
|
|
6
6
|
import { hiddenStyles } from './hidden-styles.css.js';
|
|
7
|
-
export const updateInternals = Symbol('updateInternals');
|
|
8
7
|
const Base = FormAssociated(InternalsAttached(LitElement));
|
|
9
8
|
export class Button extends Base {
|
|
10
9
|
static { this.styles = [hiddenStyles]; }
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { LitElement, PropertyValues } from 'lit';
|
|
13
13
|
import { Placement, Strategy } from '@floating-ui/dom';
|
|
14
|
+
import { autoAttachToParent, handleControlChange } from '../mixins/attachable.js';
|
|
14
15
|
export declare function lookForTabbable(root: Node): HTMLElement | null;
|
|
15
16
|
declare const Popup_base: Constructor<import("../mixins/attachable.js").AttachableInterface> & Constructor<import("../mixins/internals-attached.js").InternalsAttachedInterface> & typeof LitElement;
|
|
16
17
|
export declare class Popup extends Popup_base {
|
|
@@ -27,7 +28,8 @@ export declare class Popup extends Popup_base {
|
|
|
27
28
|
connectedCallback(): void;
|
|
28
29
|
disconnectedCallback(): void;
|
|
29
30
|
protected updated(changedProperties: PropertyValues<this>): void;
|
|
30
|
-
|
|
31
|
+
[autoAttachToParent]: boolean;
|
|
32
|
+
[handleControlChange](prev: HTMLElement | null, next: HTMLElement | null): void;
|
|
31
33
|
toggle(): Promise<void>;
|
|
32
34
|
show(): Promise<void>;
|
|
33
35
|
hide(): Promise<void>;
|
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Design: TO BE ADDED
|
|
11
11
|
*/
|
|
12
|
+
var _a;
|
|
12
13
|
import { __decorate } from "tslib";
|
|
13
14
|
import { LitElement, html, isServer } from 'lit';
|
|
14
15
|
import { customElement, property } from 'lit/decorators.js';
|
|
15
16
|
import { autoUpdate, computePosition, arrow, flip, offset, shift, } from '@floating-ui/dom';
|
|
16
17
|
import { InternalsAttached } from '../mixins/internals-attached.js';
|
|
17
|
-
import { Attachable } from '../mixins/attachable.js';
|
|
18
|
+
import { Attachable, autoAttachToParent, handleControlChange, } from '../mixins/attachable.js';
|
|
18
19
|
import { transformOriginFromArrow } from '../controllers/popover-controller.js';
|
|
19
20
|
import { popupStyles } from './popup-styles.css.js';
|
|
20
21
|
// Returns the first tabbable element within an eleent
|
|
@@ -75,6 +76,7 @@ let Popup = class Popup extends Attachable(InternalsAttached(LitElement)) {
|
|
|
75
76
|
this.strategy = 'absolute';
|
|
76
77
|
this.offset = 0;
|
|
77
78
|
this.windowPadding = 8;
|
|
79
|
+
this[_a] = false;
|
|
78
80
|
this.#onRequestHide = () => {
|
|
79
81
|
this.hide();
|
|
80
82
|
};
|
|
@@ -142,7 +144,7 @@ let Popup = class Popup extends Attachable(InternalsAttached(LitElement)) {
|
|
|
142
144
|
this.#syncTriggerAria();
|
|
143
145
|
}
|
|
144
146
|
}
|
|
145
|
-
handleControlChange(prev, next) {
|
|
147
|
+
[(_a = autoAttachToParent, handleControlChange)](prev, next) {
|
|
146
148
|
if (prev) {
|
|
147
149
|
prev.removeEventListener('click', this.#onTriggerClick);
|
|
148
150
|
prev.removeEventListener('focusout', this.#onFocusOut);
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
+
export declare const autoAttachToParent: unique symbol;
|
|
3
|
+
export declare const handleControlChange: unique symbol;
|
|
2
4
|
export declare class AttachableInterface {
|
|
3
|
-
$control: HTMLElement;
|
|
5
|
+
$control: HTMLElement | null;
|
|
4
6
|
htmlFor: string | null;
|
|
5
7
|
attach(control: HTMLElement, force?: boolean): void;
|
|
6
8
|
detach(): void;
|
|
7
|
-
|
|
9
|
+
[autoAttachToParent]: boolean;
|
|
10
|
+
[handleControlChange](prev: HTMLElement | null, next: HTMLElement | null): void;
|
|
8
11
|
}
|
|
9
12
|
export declare const Attachable: <T extends Constructor<LitElement>>(superClass: T) => Constructor<AttachableInterface> & T;
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
|
+
export const autoAttachToParent = Symbol('autoAttachToParent');
|
|
4
|
+
export const handleControlChange = Symbol('handleControlChange');
|
|
3
5
|
export const Attachable = (superClass) => {
|
|
6
|
+
var _a;
|
|
4
7
|
class AttachableElement extends superClass {
|
|
5
8
|
constructor() {
|
|
6
9
|
super(...arguments);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The control element currently attached to
|
|
12
|
+
*/
|
|
13
|
+
this.#$control = null;
|
|
14
|
+
/**
|
|
15
|
+
* Whether `parentNode` is a candidate of `$control`.
|
|
16
|
+
*
|
|
17
|
+
* When false, only `id` is considered without manually setting `$control`
|
|
18
|
+
* or `attach()`
|
|
19
|
+
*/
|
|
20
|
+
this[_a] = true;
|
|
16
21
|
}
|
|
17
22
|
/**
|
|
18
23
|
* If has `for` attribute, use it to find the control element.
|
|
@@ -23,9 +28,19 @@ export const Attachable = (superClass) => {
|
|
|
23
28
|
if (!this.htmlFor || !this.isConnected) {
|
|
24
29
|
return null;
|
|
25
30
|
}
|
|
26
|
-
|
|
31
|
+
const root = this.getRootNode();
|
|
32
|
+
if (!root || !('querySelector' in root)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return root.querySelector(`#${CSS.escape(this.htmlFor)}`);
|
|
36
|
+
}
|
|
37
|
+
if (this.#$control) {
|
|
38
|
+
return this.#$control;
|
|
39
|
+
}
|
|
40
|
+
if (!this[autoAttachToParent]) {
|
|
41
|
+
return null;
|
|
27
42
|
}
|
|
28
|
-
return this.
|
|
43
|
+
return this.parentNode instanceof ShadowRoot
|
|
29
44
|
? this.parentNode.host
|
|
30
45
|
: this.parentElement;
|
|
31
46
|
}
|
|
@@ -37,32 +52,57 @@ export const Attachable = (superClass) => {
|
|
|
37
52
|
this.detach();
|
|
38
53
|
}
|
|
39
54
|
}
|
|
55
|
+
connectedCallback() {
|
|
56
|
+
super.connectedCallback();
|
|
57
|
+
this.#setControl(this.$control);
|
|
58
|
+
}
|
|
59
|
+
disconnectedCallback() {
|
|
60
|
+
this.#setControl(null);
|
|
61
|
+
super.disconnectedCallback();
|
|
62
|
+
}
|
|
63
|
+
firstUpdated(changed) {
|
|
64
|
+
super.firstUpdated(changed);
|
|
65
|
+
// When the control element is placed after `this` and wasn't parsed yet
|
|
66
|
+
// at `connectedCallback`.
|
|
67
|
+
if (!this.#$control && this.htmlFor) {
|
|
68
|
+
this.#setControl(this.$control);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
40
71
|
updated(changed) {
|
|
41
72
|
super.updated(changed);
|
|
42
73
|
if (changed.has('htmlFor')) {
|
|
43
74
|
// Will be triggered when first render using `for` attribute, will be
|
|
44
|
-
// prevented in
|
|
45
|
-
this
|
|
75
|
+
// prevented in #setControl since it's unnecessary.
|
|
76
|
+
this.#setControl(this.$control);
|
|
46
77
|
}
|
|
47
78
|
}
|
|
48
|
-
setCurrentControl(control, force = false) {
|
|
49
|
-
if (control === this.currentControl && !force)
|
|
50
|
-
return;
|
|
51
|
-
this.handleControlChange(this.currentControl, control);
|
|
52
|
-
this.currentControl = control;
|
|
53
|
-
}
|
|
54
79
|
attach(control, force = false) {
|
|
55
|
-
this
|
|
80
|
+
this.#setControl(control, force);
|
|
56
81
|
this.removeAttribute('for');
|
|
57
82
|
}
|
|
58
83
|
detach() {
|
|
59
|
-
this
|
|
60
|
-
this.
|
|
84
|
+
this.#setControl(null);
|
|
85
|
+
this.removeAttribute('for');
|
|
86
|
+
this[autoAttachToParent] = false;
|
|
87
|
+
// That is to prevent attaching automatically on a `$control` access.
|
|
88
|
+
// (yet, I don't even know who would call `detach()`) :/
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The control element currently attached to
|
|
92
|
+
*/
|
|
93
|
+
#$control;
|
|
94
|
+
#setControl(control, force = false) {
|
|
95
|
+
if (control === this.#$control && !force)
|
|
96
|
+
return;
|
|
97
|
+
this[handleControlChange](this.#$control, control);
|
|
98
|
+
this.#$control = control;
|
|
61
99
|
}
|
|
62
100
|
/**
|
|
63
101
|
* Handles the first attaching and actual control element changing
|
|
64
102
|
*/
|
|
65
|
-
handleControlChange(
|
|
103
|
+
[(_a = autoAttachToParent, handleControlChange)](_prev = null, _next = null) {
|
|
104
|
+
console.warn('[seele] You should implement [onControlChange] on any class that mixes Attachable');
|
|
105
|
+
}
|
|
66
106
|
}
|
|
67
107
|
__decorate([
|
|
68
108
|
property({ attribute: 'for', type: String })
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
|
-
import { internals, replaceStates } from './internals-attached.js';
|
|
4
|
-
import { updateInternals } from '../button.js';
|
|
3
|
+
import { internals, updateInternals, replaceStates, } from './internals-attached.js';
|
|
5
4
|
const PROPERTY_FROM_ARIA_PRESSED = {
|
|
6
5
|
true: 'checked',
|
|
7
6
|
false: 'unchecked',
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
export declare const internals: unique symbol;
|
|
3
|
+
export declare const updateInternals: unique symbol;
|
|
3
4
|
export declare const replaceStates: unique symbol;
|
|
4
5
|
export declare class InternalsAttachedInterface {
|
|
5
6
|
[internals]: ElementInternals;
|
|
7
|
+
[updateInternals]?(): void;
|
|
6
8
|
[replaceStates](del: Array<string>, add: Array<string>): void;
|
|
7
9
|
}
|
|
8
10
|
export declare const InternalsAttached: <T extends Constructor<LitElement>>(superClass: T) => Constructor<InternalsAttachedInterface> & T;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const internals = Symbol('internals');
|
|
2
2
|
const privateInternals = Symbol('privateInternals');
|
|
3
|
+
export const updateInternals = Symbol('updateInternals');
|
|
3
4
|
export const replaceStates = Symbol('replaceStates');
|
|
4
5
|
export const InternalsAttached = (superClass) => {
|
|
5
6
|
class InternalsAttachedElement extends superClass {
|
package/src/base/radio.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LitElement, PropertyValues } from 'lit';
|
|
2
|
+
import { updateInternals } from './mixins/internals-attached.js';
|
|
2
3
|
declare const Radio_base: Constructor<import("./mixins/form-associated.js").FormAssociatedInterface> & Constructor<import("./mixins/internals-attached.js").InternalsAttachedInterface> & typeof LitElement;
|
|
3
4
|
export declare class Radio extends Radio_base {
|
|
4
5
|
#private;
|
|
@@ -8,6 +9,8 @@ export declare class Radio extends Radio_base {
|
|
|
8
9
|
connectedCallback(): void;
|
|
9
10
|
disconnectedCallback(): void;
|
|
10
11
|
protected updated(changedProperties: PropertyValues<this>): void;
|
|
12
|
+
[updateInternals](): void;
|
|
11
13
|
formResetCallback(): void;
|
|
14
|
+
formStateRestoreCallback(state: string | null): void;
|
|
12
15
|
}
|
|
13
16
|
export {};
|
package/src/base/radio.js
CHANGED
|
@@ -3,7 +3,7 @@ import { __decorate } from "tslib";
|
|
|
3
3
|
import { LitElement } from 'lit';
|
|
4
4
|
import { property } from 'lit/decorators.js';
|
|
5
5
|
import { FormAssociated } from './mixins/form-associated.js';
|
|
6
|
-
import { InternalsAttached, internals } from './mixins/internals-attached.js';
|
|
6
|
+
import { InternalsAttached, internals, replaceStates, updateInternals, } from './mixins/internals-attached.js';
|
|
7
7
|
export class Radio extends FormAssociated(InternalsAttached(LitElement)) {
|
|
8
8
|
// Static hidden registry: Scope (Form or RootNode) -> Name -> Set<Radio>
|
|
9
9
|
static #registry = new Map();
|
|
@@ -19,7 +19,7 @@ export class Radio extends FormAssociated(InternalsAttached(LitElement)) {
|
|
|
19
19
|
connectedCallback() {
|
|
20
20
|
super.connectedCallback();
|
|
21
21
|
this.#registerToGroup();
|
|
22
|
-
this
|
|
22
|
+
this[updateInternals]();
|
|
23
23
|
this.addEventListener('click', this.#handleClick);
|
|
24
24
|
this.addEventListener('keydown', this.#handleKeyDown);
|
|
25
25
|
}
|
|
@@ -41,16 +41,16 @@ export class Radio extends FormAssociated(InternalsAttached(LitElement)) {
|
|
|
41
41
|
}
|
|
42
42
|
this[internals].setFormValue(this.checked ? this.value : null);
|
|
43
43
|
this.#updateGroupTabIndices();
|
|
44
|
-
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
45
44
|
}
|
|
46
45
|
if (changedProperties.has('disabled') || changedProperties.has('checked'))
|
|
47
|
-
this
|
|
46
|
+
this[updateInternals]();
|
|
48
47
|
}
|
|
49
48
|
#handleClick() {
|
|
50
49
|
if (this.disabled || this.checked)
|
|
51
50
|
return;
|
|
52
51
|
this.checked = true;
|
|
53
52
|
this.focus();
|
|
53
|
+
this.#dispatchEvents();
|
|
54
54
|
}
|
|
55
55
|
#handleKeyDown(event) {
|
|
56
56
|
if (this.disabled)
|
|
@@ -58,8 +58,10 @@ export class Radio extends FormAssociated(InternalsAttached(LitElement)) {
|
|
|
58
58
|
switch (event.key) {
|
|
59
59
|
case ' ':
|
|
60
60
|
event.preventDefault();
|
|
61
|
-
if (!this.checked)
|
|
61
|
+
if (!this.checked) {
|
|
62
62
|
this.checked = true;
|
|
63
|
+
this.#dispatchEvents();
|
|
64
|
+
}
|
|
63
65
|
break;
|
|
64
66
|
case 'ArrowDown':
|
|
65
67
|
case 'ArrowRight':
|
|
@@ -117,11 +119,9 @@ export class Radio extends FormAssociated(InternalsAttached(LitElement)) {
|
|
|
117
119
|
this.#currentName = '';
|
|
118
120
|
}
|
|
119
121
|
#getGroupRadios() {
|
|
120
|
-
if (!this
|
|
122
|
+
if (!this.#currentName || !this.#currentScope)
|
|
121
123
|
return [this];
|
|
122
|
-
|
|
123
|
-
const group = _a.#registry.get(scope)?.get(this.name);
|
|
124
|
-
return group ? Array.from(group) : [this];
|
|
124
|
+
return (_a.#registry.get(this.#currentScope)?.get(this.#currentName) ?? [this]);
|
|
125
125
|
}
|
|
126
126
|
#uncheckSiblings() {
|
|
127
127
|
const radios = this.#getGroupRadios();
|
|
@@ -130,10 +130,14 @@ export class Radio extends FormAssociated(InternalsAttached(LitElement)) {
|
|
|
130
130
|
radio.checked = false;
|
|
131
131
|
}
|
|
132
132
|
#updateGroupTabIndices(groupSet) {
|
|
133
|
-
const radios = groupSet
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
const radios = groupSet ?? this.#getGroupRadios();
|
|
134
|
+
let hasChecked = false;
|
|
135
|
+
for (const r of radios) {
|
|
136
|
+
if (r.checked && !r.disabled) {
|
|
137
|
+
hasChecked = true;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
137
141
|
let enabledFound = false;
|
|
138
142
|
for (const radio of radios) {
|
|
139
143
|
const active = !radio.disabled && (hasChecked ? radio.checked : !enabledFound);
|
|
@@ -143,7 +147,7 @@ export class Radio extends FormAssociated(InternalsAttached(LitElement)) {
|
|
|
143
147
|
}
|
|
144
148
|
}
|
|
145
149
|
#navigateGroup(direction) {
|
|
146
|
-
const radios = this.#getGroupRadios().filter((r) => !r.disabled);
|
|
150
|
+
const radios = Array.from(this.#getGroupRadios()).filter((r) => !r.disabled);
|
|
147
151
|
if (radios.length <= 1)
|
|
148
152
|
return;
|
|
149
153
|
const currentIndex = radios.indexOf(this);
|
|
@@ -152,18 +156,26 @@ export class Radio extends FormAssociated(InternalsAttached(LitElement)) {
|
|
|
152
156
|
targetRadio.checked = true;
|
|
153
157
|
targetRadio.focus();
|
|
154
158
|
}
|
|
155
|
-
|
|
159
|
+
[updateInternals]() {
|
|
156
160
|
this[internals].ariaChecked = String(this.checked);
|
|
157
161
|
this[internals].ariaDisabled = String(this.disabled);
|
|
162
|
+
this[replaceStates](['checked'], [this.checked ? 'checked' : null]);
|
|
163
|
+
}
|
|
164
|
+
#dispatchEvents() {
|
|
165
|
+
this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
|
166
|
+
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
158
167
|
}
|
|
159
168
|
formResetCallback() {
|
|
160
169
|
this.checked = this.hasAttribute('checked');
|
|
161
170
|
}
|
|
171
|
+
formStateRestoreCallback(state) {
|
|
172
|
+
this.checked = state === this.value;
|
|
173
|
+
}
|
|
162
174
|
}
|
|
163
175
|
_a = Radio;
|
|
164
176
|
__decorate([
|
|
165
177
|
property({ type: String })
|
|
166
178
|
], Radio.prototype, "value", void 0);
|
|
167
179
|
__decorate([
|
|
168
|
-
property({ type: Boolean
|
|
180
|
+
property({ type: Boolean })
|
|
169
181
|
], Radio.prototype, "checked", void 0);
|
package/src/base/tab-panel.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
declare const TabPanel_base: Constructor<import("./mixins/internals-attached.js").InternalsAttachedInterface> & typeof LitElement;
|
|
3
3
|
export declare class TabPanel extends TabPanel_base {
|
|
4
|
-
protected _role: string;
|
|
5
|
-
render(): import("lit-html").TemplateResult<1>;
|
|
6
4
|
value: string;
|
|
7
|
-
|
|
5
|
+
selected: boolean;
|
|
6
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
7
|
+
constructor();
|
|
8
8
|
}
|
|
9
9
|
export {};
|
package/src/base/tab-panel.js
CHANGED
|
@@ -2,24 +2,22 @@ import { __decorate } from "tslib";
|
|
|
2
2
|
import { LitElement, html } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
4
|
import { InternalsAttached, internals } from './mixins/internals-attached.js';
|
|
5
|
-
import { genUniqueId } from '../core/unique-id.js';
|
|
6
5
|
export class TabPanel extends InternalsAttached(LitElement) {
|
|
7
|
-
constructor() {
|
|
8
|
-
super(...arguments);
|
|
9
|
-
this._role = 'tabpanel';
|
|
10
|
-
this.value = '';
|
|
11
|
-
}
|
|
12
6
|
render() {
|
|
13
7
|
return html `<slot></slot>`;
|
|
14
8
|
}
|
|
15
|
-
|
|
16
|
-
super
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
this.value = '';
|
|
12
|
+
this.selected = false;
|
|
13
|
+
this[internals].role = 'tabpanel';
|
|
17
14
|
this.setAttribute('seele-base', 'tabpanel');
|
|
18
|
-
this
|
|
19
|
-
if (!this.id)
|
|
20
|
-
this.id = genUniqueId('tabpanel');
|
|
15
|
+
this.setAttribute('slot', 'panels');
|
|
21
16
|
}
|
|
22
17
|
}
|
|
23
18
|
__decorate([
|
|
24
19
|
property({ type: String, reflect: true })
|
|
25
20
|
], TabPanel.prototype, "value", void 0);
|
|
21
|
+
__decorate([
|
|
22
|
+
property({ type: Boolean, reflect: true })
|
|
23
|
+
], TabPanel.prototype, "selected", void 0);
|
package/src/base/tab.d.ts
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
declare const Tab_base: Constructor<import("./mixins/internals-attached.js").InternalsAttachedInterface> & typeof LitElement;
|
|
3
|
-
/**
|
|
4
|
-
* TODO: disabled
|
|
5
|
-
*/
|
|
6
3
|
export declare class Tab extends Tab_base {
|
|
7
4
|
#private;
|
|
8
|
-
|
|
5
|
+
disabled: boolean;
|
|
9
6
|
selected: boolean;
|
|
10
|
-
focused: boolean;
|
|
11
7
|
value: string;
|
|
12
8
|
render(): import("lit-html").TemplateResult<1>;
|
|
13
|
-
|
|
9
|
+
constructor();
|
|
14
10
|
protected updated(changed: Map<string, any>): void;
|
|
15
|
-
focus(): void;
|
|
16
|
-
blur(): void;
|
|
17
11
|
}
|
|
18
12
|
export {};
|
package/src/base/tab.js
CHANGED
|
@@ -1,60 +1,41 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { LitElement, html } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
|
-
import { InternalsAttached, internals } from './mixins/internals-attached.js';
|
|
5
|
-
import { genUniqueId } from '../core/unique-id.js';
|
|
6
|
-
/**
|
|
7
|
-
* TODO: disabled
|
|
8
|
-
*/
|
|
4
|
+
import { InternalsAttached, internals, replaceStates, } from './mixins/internals-attached.js';
|
|
9
5
|
export class Tab extends InternalsAttached(LitElement) {
|
|
10
|
-
constructor() {
|
|
11
|
-
super(...arguments);
|
|
12
|
-
this._role = 'tab';
|
|
13
|
-
this.selected = false;
|
|
14
|
-
this.focused = false;
|
|
15
|
-
this.value = '';
|
|
16
|
-
}
|
|
17
6
|
render() {
|
|
18
7
|
return html `<slot></slot>`;
|
|
19
8
|
}
|
|
20
|
-
|
|
21
|
-
super
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
this.disabled = false;
|
|
12
|
+
this.selected = false;
|
|
13
|
+
this.value = '';
|
|
22
14
|
this.setAttribute('seele-base', 'tab');
|
|
23
|
-
this[internals].role =
|
|
24
|
-
if (!this.id)
|
|
25
|
-
this.id = genUniqueId('tab');
|
|
15
|
+
this[internals].role = 'tab';
|
|
26
16
|
this.#updateInternals();
|
|
27
17
|
}
|
|
28
18
|
updated(changed) {
|
|
29
19
|
super.updated(changed);
|
|
30
|
-
if (changed.has('selected') ||
|
|
20
|
+
if (changed.has('selected') ||
|
|
21
|
+
changed.has('focused') ||
|
|
22
|
+
changed.has('disabled')) {
|
|
31
23
|
this.#updateInternals();
|
|
32
24
|
}
|
|
33
25
|
}
|
|
34
26
|
#updateInternals() {
|
|
35
|
-
this
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.selected
|
|
40
|
-
? this[internals].states.add('selected')
|
|
41
|
-
: this[internals].states.delete('selected');
|
|
42
|
-
}
|
|
43
|
-
focus() {
|
|
44
|
-
this.focused = true;
|
|
45
|
-
super.focus();
|
|
46
|
-
}
|
|
47
|
-
blur() {
|
|
48
|
-
this.focused = false;
|
|
49
|
-
super.blur();
|
|
27
|
+
this.tabIndex = this.disabled ? -1 : this.selected ? 0 : -1;
|
|
28
|
+
this[internals].ariaSelected = String(this.selected);
|
|
29
|
+
this[internals].ariaDisabled = String(this.disabled);
|
|
30
|
+
this[replaceStates](['selected', 'disabled'], [this.selected ? 'selected' : null, this.disabled ? 'disabled' : null]);
|
|
50
31
|
}
|
|
51
32
|
}
|
|
52
33
|
__decorate([
|
|
53
34
|
property({ type: Boolean, reflect: true })
|
|
54
|
-
], Tab.prototype, "
|
|
35
|
+
], Tab.prototype, "disabled", void 0);
|
|
55
36
|
__decorate([
|
|
56
37
|
property({ type: Boolean, reflect: true })
|
|
57
|
-
], Tab.prototype, "
|
|
38
|
+
], Tab.prototype, "selected", void 0);
|
|
58
39
|
__decorate([
|
|
59
40
|
property({ type: String, reflect: true })
|
|
60
41
|
], Tab.prototype, "value", void 0);
|
package/src/base/tabs.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
import type { Tab } from './tab.js';
|
|
3
|
+
import type { TabPanel } from './tab-panel.js';
|
|
3
4
|
/**
|
|
4
|
-
* @fires {CustomEvent}
|
|
5
|
+
* @fires {CustomEvent} select
|
|
5
6
|
*/
|
|
6
7
|
export declare class Tabs extends LitElement {
|
|
7
8
|
#private;
|
|
8
|
-
protected _role: string;
|
|
9
9
|
switch: 'auto' | 'manual';
|
|
10
10
|
selected: string;
|
|
11
|
-
$
|
|
12
|
-
get $
|
|
13
|
-
get $parent(): HTMLElement;
|
|
11
|
+
get $tabs(): Array<Tab>;
|
|
12
|
+
get $panels(): Array<TabPanel>;
|
|
14
13
|
render(): import("lit-html").TemplateResult<1>;
|
|
14
|
+
constructor();
|
|
15
15
|
connectedCallback(): void;
|
|
16
16
|
protected updated(changed: Map<string, any>): void;
|
|
17
17
|
focusTab(tab: Tab): void;
|
|
18
|
-
|
|
18
|
+
protected _selectTab(selectedTab: Tab, dispatchEvent?: boolean): void;
|
|
19
19
|
}
|