@vollowx/seele 0.13.6 → 0.13.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vollowx/seele",
3
- "version": "0.13.6",
3
+ "version": "0.13.7",
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",
@@ -5,6 +5,7 @@ declare const Base: Constructor<import("./mixins/focus-delegated.js").FocusDeleg
5
5
  type AutocompleteMode = 'none' | 'list' | 'both';
6
6
  /**
7
7
  * TODO: Check if manually dispatching input/change events on input is necessary
8
+ * TODO: handle slotchange
8
9
  */
9
10
  export declare class Autocomplete extends Base {
10
11
  open: boolean;
@@ -1,11 +1,13 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { LitElement, html } from 'lit';
3
3
  import { property, query, queryAssignedElements } from 'lit/decorators.js';
4
+ import { ensureReady } from '../core/ensure-ready.js';
4
5
  import { InternalsAttached } from './mixins/internals-attached.js';
5
6
  import { FocusDelegated } from './mixins/focus-delegated.js';
6
7
  const Base = FocusDelegated(InternalsAttached(LitElement));
7
8
  /**
8
9
  * TODO: Check if manually dispatching input/change events on input is necessary
10
+ * TODO: handle slotchange
9
11
  */
10
12
  export class Autocomplete extends Base {
11
13
  constructor() {
@@ -52,12 +54,11 @@ export class Autocomplete extends Base {
52
54
  renderMenu() {
53
55
  return html ``;
54
56
  }
57
+ // TODO: handle multiple calls on this function, currently double-call
58
+ // disallowed
55
59
  handleInputSlotChange() {
56
- const input = this.$input;
57
- if (!input)
58
- return;
59
- const $realInput = this.$input.$inputOrTextarea;
60
- if ($realInput) {
60
+ ensureReady(this.$input).then((input) => {
61
+ const $realInput = input.$inputOrTextarea;
61
62
  $realInput.role = 'combobox';
62
63
  $realInput.ariaExpanded = String(this.open);
63
64
  $realInput.ariaHasPopup = 'listbox';
@@ -67,7 +68,7 @@ export class Autocomplete extends Base {
67
68
  input.addEventListener('keydown', this.handleInputKeydown.bind(this));
68
69
  input.addEventListener('click', () => (this.open = !this.open));
69
70
  this.$menu.attach($realInput);
70
- }
71
+ });
71
72
  }
72
73
  handleItemsSlotChange() {
73
74
  // Initial filter based on current input value (if any)
@@ -121,12 +122,6 @@ export class Autocomplete extends Base {
121
122
  }
122
123
  }
123
124
  handleMenuSelect(event) {
124
- // FIXME: pressing <Enter> in a 'both' mode autocomplete triggers this
125
- // function, which overrides the current value in the text field
126
- // since the selected value in the menu is not the same as the
127
- // one in autocomplete
128
- //
129
- // if (this.mode === 'list') {
130
125
  const selectedItem = event.detail.item;
131
126
  const newValue = selectedItem.getAttribute('value') ||
132
127
  selectedItem.textContent?.trim() ||
@@ -134,7 +129,6 @@ export class Autocomplete extends Base {
134
129
  if (this.$input) {
135
130
  this.$input.value = newValue;
136
131
  }
137
- // }
138
132
  if (!this.keepOpenSelect) {
139
133
  this.open = false;
140
134
  }
@@ -19,6 +19,8 @@ export type MenuItemFocusEvent = CustomEvent<ItemFocusDetail>;
19
19
  * @fires {Event} close - Fires when the menu is closed.
20
20
  * @fires {MenuSelectEvent} select - Fires when an item is selected.
21
21
  * @fires {MenuItemFocusEvent} item-focus - Fires when an item is focused
22
+ *
23
+ * TODO: handle slotchange
22
24
  */
23
25
  export declare class Menu extends Base {
24
26
  #private;
package/src/base/menu.js CHANGED
@@ -16,6 +16,8 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
16
16
  * @fires {Event} close - Fires when the menu is closed.
17
17
  * @fires {MenuSelectEvent} select - Fires when an item is selected.
18
18
  * @fires {MenuItemFocusEvent} item-focus - Fires when an item is focused
19
+ *
20
+ * TODO: handle slotchange
19
21
  */
20
22
  export class Menu extends Base {
21
23
  constructor() {
@@ -0,0 +1 @@
1
+ export declare function ensureReady(element: HTMLElement): Promise<HTMLElement>;
@@ -0,0 +1,15 @@
1
+ export async function ensureReady(element) {
2
+ if (!element)
3
+ return null;
4
+ if (element.matches(':not(:defined)'))
5
+ await customElements.whenDefined(element.tagName.toLowerCase());
6
+ // Handles Lit update
7
+ if ('updateComplete' in element) {
8
+ await element.updateComplete;
9
+ }
10
+ else {
11
+ // Yield to the next frame to allow initial render to finish
12
+ await new Promise((resolve) => requestAnimationFrame(resolve));
13
+ }
14
+ return element;
15
+ }
@@ -1,4 +1,5 @@
1
1
  import { Autocomplete } from '../../base/autocomplete.js';
2
+ import '../menu/menu.js';
2
3
  /**
3
4
  * TODO: Check if manually dispatching input/change events on input is necessary
4
5
  */
@@ -2,6 +2,7 @@ import { __decorate } from "tslib";
2
2
  import { html } from 'lit';
3
3
  import { customElement } from 'lit/decorators.js';
4
4
  import { Autocomplete } from '../../base/autocomplete.js';
5
+ import '../menu/menu.js';
5
6
  import { autocompleteStyles } from './autocomplete-styles.css.js';
6
7
  /**
7
8
  * TODO: Check if manually dispatching input/change events on input is necessary
@@ -4,6 +4,7 @@ export declare class M3Badge extends LitElement {
4
4
  value: number;
5
5
  max: number;
6
6
  showZero: boolean;
7
+ small: boolean;
7
8
  left: boolean;
8
9
  bottom: boolean;
9
10
  $badge: HTMLSpanElement;
@@ -7,6 +7,7 @@ let M3Badge = class M3Badge extends LitElement {
7
7
  constructor() {
8
8
  super(...arguments);
9
9
  this.showZero = false;
10
+ this.small = false;
10
11
  this.left = false;
11
12
  this.bottom = false;
12
13
  }
@@ -32,6 +33,9 @@ __decorate([
32
33
  __decorate([
33
34
  property({ type: Boolean, reflect: true, attribute: 'show-zero' })
34
35
  ], M3Badge.prototype, "showZero", void 0);
36
+ __decorate([
37
+ property({ type: Boolean, reflect: true })
38
+ ], M3Badge.prototype, "small", void 0);
35
39
  __decorate([
36
40
  property({ type: Boolean, reflect: true })
37
41
  ], M3Badge.prototype, "left", void 0);
@@ -1,7 +1,7 @@
1
1
  import { Checkbox } from '../../base/checkbox.js';
2
2
  import '../focus-ring/focus-ring.js';
3
3
  import '../ripple/ripple.js';
4
- import { M3Ripple } from '../ripple/ripple.js';
4
+ import type { M3Ripple } from '../ripple/ripple.js';
5
5
  /**
6
6
  * @tag md-checkbox
7
7
  *
@@ -1,7 +1,9 @@
1
1
  import { ListItem } from '../../base/list-item.js';
2
2
  import '../item/item.js';
3
- import { M3Ripple } from '../ripple/ripple.js';
4
- import { M3FocusRing } from '../focus-ring/focus-ring.js';
3
+ import '../ripple/ripple.js';
4
+ import '../focus-ring/focus-ring.js';
5
+ import type { M3Ripple } from '../ripple/ripple.js';
6
+ import type { M3FocusRing } from '../focus-ring/focus-ring.js';
5
7
  /**
6
8
  * @tag md-list-item
7
9
  *
@@ -3,6 +3,8 @@ import { html } from 'lit';
3
3
  import { customElement, query } from 'lit/decorators.js';
4
4
  import { ListItem } from '../../base/list-item.js';
5
5
  import '../item/item.js';
6
+ import '../ripple/ripple.js';
7
+ import '../focus-ring/focus-ring.js';
6
8
  import { listItemStyles } from './list-item-styles.css.js';
7
9
  /**
8
10
  * @tag md-list-item
@@ -1,3 +1,4 @@
1
+ import '../menu/menu.js';
1
2
  import { Select } from '../../base/select.js';
2
3
  import { M3Field } from '../field/field.js';
3
4
  /**
@@ -1,6 +1,7 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { html } from 'lit';
3
3
  import { property, query, state } from 'lit/decorators.js';
4
+ import '../menu/menu.js';
4
5
  import { Select } from '../../base/select.js';
5
6
  /**
6
7
  * @fires {Event} change - Fired when the selected value has changed.
@@ -1,45 +0,0 @@
1
- import { Dialog } from '../../base/dialog.js';
2
- /**
3
- * TODO: test if form actions `cancel` and other things related work - no,
4
- * event listener needed
5
- *
6
- * To get an approximation of the "not Expressive" version like:
7
- * https://m3.material.io/styles/motion/easing-and-duration/applying-easing-and-duration#e5b958f0-435d-4e84-aed4-8d1ea395fa5c
8
- *
9
- * ```css
10
- * --md-sys-motion-spatial-default: cubic-bezier(0, 0, 0, 1);
11
- * --md-sys-motion-spatial-default-duration: 500ms;
12
- * --md-sys-motion-spatial-fast: cubic-bezier(0.3, 0, 1, 1);
13
- * --md-sys-motion-spatial-fast-duration: 300ms;
14
- *
15
- * --md-sys-motion-effects-fast: linear;
16
- * --md-sys-motion-effects-fast-duration: 200ms;
17
- * --md-sys-motion-effects-default: linear;
18
- * --md-sys-motion-effects-default-duration: 300ms;
19
- * ```
20
- *
21
- * @tag md-dialog
22
- *
23
- * @csspart container
24
- * @csspart headline
25
- * @csspart content
26
- * @csspart actions
27
- *
28
- * @slot icon
29
- * @slot headline
30
- * @slot - content
31
- * @slot actions
32
- */
33
- export declare class M3Dialog extends Dialog {
34
- #private;
35
- private hasIcon;
36
- $container: HTMLDivElement;
37
- $body: HTMLDivElement;
38
- $actions: HTMLDivElement;
39
- $actionsPlaceholder: HTMLDivElement;
40
- $scrim: HTMLDivElement;
41
- static styles: any[];
42
- render(): import("lit-html").TemplateResult<1>;
43
- show(): void;
44
- close(): void;
45
- }
@@ -1,176 +0,0 @@
1
- import { __decorate } from "tslib";
2
- import { html } from 'lit';
3
- import { query, state, customElement } from 'lit/decorators.js';
4
- import { Dialog } from '../../base/dialog.js';
5
- import { getSpring } from '../system/motion.js';
6
- import { dialogStyles } from './dialog-styles.css.js';
7
- /**
8
- * TODO: test if form actions `cancel` and other things related work - no,
9
- * event listener needed
10
- *
11
- * To get an approximation of the "not Expressive" version like:
12
- * https://m3.material.io/styles/motion/easing-and-duration/applying-easing-and-duration#e5b958f0-435d-4e84-aed4-8d1ea395fa5c
13
- *
14
- * ```css
15
- * --md-sys-motion-spatial-default: cubic-bezier(0, 0, 0, 1);
16
- * --md-sys-motion-spatial-default-duration: 500ms;
17
- * --md-sys-motion-spatial-fast: cubic-bezier(0.3, 0, 1, 1);
18
- * --md-sys-motion-spatial-fast-duration: 300ms;
19
- *
20
- * --md-sys-motion-effects-fast: linear;
21
- * --md-sys-motion-effects-fast-duration: 200ms;
22
- * --md-sys-motion-effects-default: linear;
23
- * --md-sys-motion-effects-default-duration: 300ms;
24
- * ```
25
- *
26
- * @tag md-dialog
27
- *
28
- * @csspart container
29
- * @csspart headline
30
- * @csspart content
31
- * @csspart actions
32
- *
33
- * @slot icon
34
- * @slot headline
35
- * @slot - content
36
- * @slot actions
37
- */
38
- let M3Dialog = class M3Dialog extends Dialog {
39
- constructor() {
40
- super(...arguments);
41
- this.hasIcon = false;
42
- this.#activeAnimations = [];
43
- this.#handleClick = (e) => {
44
- const target = e.target;
45
- if (!this.$container.contains(target) && !this.contains(target))
46
- this.close();
47
- };
48
- this.#handleIconSlotChange = (e) => {
49
- const slot = e.target;
50
- this.hasIcon = slot.assignedElements({ flatten: true }).length > 0;
51
- };
52
- this.#opening = false;
53
- this.#closing = false;
54
- }
55
- static { this.styles = [dialogStyles]; }
56
- render() {
57
- return html `<dialog part="dialog" @click="${this.#handleClick}" @cancel="${this._handleCancel}"><div part="container"><div part="body"><div part="headline" class="${this.hasIcon ? 'has-icon' : ''}"><slot name="icon" @slotchange="${this.#handleIconSlotChange}"></slot><slot name="headline"></slot></div><div part="content"><slot></slot></div><div class="actions-placeholder"></div></div><div part="actions"><slot name="actions"></slot></div></div></dialog><div part="scrim"></div>`;
58
- }
59
- #activeAnimations;
60
- #clearAnimations() {
61
- this.#activeAnimations.forEach((anim) => anim.cancel());
62
- this.#activeAnimations = [];
63
- this.#opening = this.#closing = false;
64
- }
65
- #handleClick;
66
- #handleIconSlotChange;
67
- get #springs() {
68
- return {
69
- spatialDefault: getSpring(this, 'spatial', 'default'),
70
- spatialFast: getSpring(this, 'spatial', 'fast'),
71
- effectsDefault: getSpring(this, 'effects', 'default'),
72
- effectsFast: getSpring(this, 'effects', 'fast'),
73
- };
74
- }
75
- #opening;
76
- show() {
77
- if (this.#opening)
78
- return;
79
- this.#clearAnimations();
80
- this.#opening = true;
81
- // Reset margins to allow browser centering
82
- this.$dialog.style.marginTop = 'auto';
83
- this.$dialog.style.marginBottom = 'auto';
84
- super.show();
85
- const actionsHeight = this.$actions.offsetHeight;
86
- this.$actionsPlaceholder.style.height = `${actionsHeight}px`;
87
- this.$container.style.height = 'auto';
88
- const startHeight = 0;
89
- const endHeight = this.$container.offsetHeight;
90
- // Lock the position to prevent auto-centering during animation
91
- const rect = this.$container.getBoundingClientRect();
92
- this.$dialog.style.marginTop = `${rect.top}px`;
93
- this.$dialog.style.marginBottom = 'auto';
94
- this.$container.style.minHeight = '0px';
95
- const container = this.$container.animate([
96
- {
97
- height: `${startHeight}px`,
98
- transform: `translateY(-40px)`,
99
- },
100
- {
101
- height: `${endHeight}px`,
102
- transform: 'translateY(0px)',
103
- },
104
- ], this.#springs.spatialDefault);
105
- const scrim = this.$scrim.animate([{ opacity: 0 }, { opacity: 0.32 }], {
106
- ...this.#springs.effectsDefault,
107
- fill: 'forwards',
108
- });
109
- const body = this.$body.animate([{ opacity: 0.2 }, { opacity: 1 }], {
110
- ...this.#springs.effectsDefault,
111
- fill: 'forwards',
112
- });
113
- const actions = this.$actions.animate([{ opacity: 0.5 }, { opacity: 1 }], {
114
- ...this.#springs.effectsDefault,
115
- fill: 'forwards',
116
- });
117
- this.#activeAnimations.push(container, scrim, body, actions);
118
- container.onfinish = () => {
119
- this.$container.style.minHeight = '';
120
- this.#clearAnimations();
121
- };
122
- }
123
- #closing;
124
- close() {
125
- if (this.#closing)
126
- return;
127
- this.#clearAnimations();
128
- this.#closing = true;
129
- const startHeight = this.$container.offsetHeight;
130
- const endHeight = startHeight * 0.35;
131
- this.$container.style.minHeight = '0px';
132
- const containerSpatial = this.$container.animate([
133
- { height: `${startHeight}px`, transform: 'translateY(0px)' },
134
- {
135
- height: `${endHeight}px`,
136
- transform: `translateY(-40px)`,
137
- },
138
- ], this.#springs.spatialFast);
139
- const containerEffects = this.$container.animate([{ opacity: 1 }, { opacity: 0 }], {
140
- ...this.#springs.effectsFast,
141
- fill: 'forwards',
142
- });
143
- const scrim = this.$scrim.animate([{ opacity: 0.32 }, { opacity: 0 }], {
144
- ...this.#springs.effectsFast,
145
- fill: 'forwards',
146
- });
147
- this.#activeAnimations.push(containerSpatial, containerEffects, scrim);
148
- containerEffects.onfinish = () => {
149
- this.$container.style.minHeight = '';
150
- super.close();
151
- this.#clearAnimations();
152
- };
153
- }
154
- };
155
- __decorate([
156
- state()
157
- ], M3Dialog.prototype, "hasIcon", void 0);
158
- __decorate([
159
- query('[part=container]')
160
- ], M3Dialog.prototype, "$container", void 0);
161
- __decorate([
162
- query('[part=body]')
163
- ], M3Dialog.prototype, "$body", void 0);
164
- __decorate([
165
- query('[part=actions]')
166
- ], M3Dialog.prototype, "$actions", void 0);
167
- __decorate([
168
- query('.actions-placeholder')
169
- ], M3Dialog.prototype, "$actionsPlaceholder", void 0);
170
- __decorate([
171
- query('[part=scrim]')
172
- ], M3Dialog.prototype, "$scrim", void 0);
173
- M3Dialog = __decorate([
174
- customElement('md-dialog')
175
- ], M3Dialog);
176
- export { M3Dialog };
@@ -1,3 +0,0 @@
1
- import { Radio } from '../../base/radio.js';
2
- export declare class Win98Radio extends Radio {
3
- }
@@ -1,9 +0,0 @@
1
- import { __decorate } from "tslib";
2
- import { Radio } from '../../base/radio.js';
3
- import { customElement } from '../../core/decorators.js';
4
- let Win98Radio = class Win98Radio extends Radio {
5
- };
6
- Win98Radio = __decorate([
7
- customElement('win98-radio')
8
- ], Win98Radio);
9
- export { Win98Radio };
@@ -1,3 +0,0 @@
1
- import { Radio } from '../../base/radio.js';
2
- export declare class Win98Radio extends Radio {
3
- }
@@ -1,9 +0,0 @@
1
- import { __decorate } from "tslib";
2
- import { Radio } from '../../base/radio.js';
3
- import { customElement } from '../../core/decorators.js';
4
- let Win98Radio = class Win98Radio extends Radio {
5
- };
6
- Win98Radio = __decorate([
7
- customElement('win98-radio')
8
- ], Win98Radio);
9
- export { Win98Radio };