@vollowx/seele 0.12.2 → 0.12.4

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 CHANGED
@@ -1,38 +1,29 @@
1
1
  # Standard Extensible Elements
2
2
 
3
- **SEELE** is a modern, lightweight [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) library. It provides a set of highly customizable UI components that follow the [Material Design 3](https://m3.material.io/) guidelines out of the box, while being designed for easy extension and restyling.
3
+ **SEELE** is a modern, lightweight and accessible
4
+ [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
5
+ library. It provides a set of highly customizable UI components that follow the
6
+ [Material Design 3](https://m3.material.io/) guidelines out of the box, while
7
+ being designed for easy extension and restyling.
4
8
 
5
9
  Visit the [website of SEELE](https://seele.v9.nz/) for documentation and demos.
6
10
 
7
- ## Features
8
-
9
- - **Material Design 3**: Ready-to-use components following the latest Material guidelines.
10
- - **Web Components**: Framework-agnostic. Works with vanilla HTML or any framework.
11
- - **Extensible**: Built to be extended. Create your own design system on top of SEELE's logic.
12
- - **Lightweight**: Built on [Lit](https://lit.dev/) and [floating-ui](https://floating-ui.com/) only, ensuring fast performance and small bundle sizes.
13
- - **Accessible**: Designed with accessibility in mind (using `ElementInternals` and standard ARIA patterns).
14
-
15
11
  ## Installation
16
12
 
17
- Install SEELE using your preferred package manager:
13
+ SEELE is published on [npm](https://www.npmjs.com/package/@vollowx/seele),
14
+ install with your preferred package manager:
18
15
 
19
16
  ```bash
20
- # npm
21
17
  npm install @vollowx/seele
22
18
 
23
- # pnpm
24
- pnpm add @vollowx/seele
25
-
26
- # yarn
27
19
  yarn add @vollowx/seele
28
20
 
29
- # bun
30
21
  bun add @vollowx/seele
31
22
  ```
32
23
 
33
24
  ## Usage
34
25
 
35
- ### Importing Components
26
+ ### Importing
36
27
 
37
28
  You can import the entire library or individual components to keep your bundle size small.
38
29
 
@@ -40,14 +31,15 @@ You can import the entire library or individual components to keep your bundle s
40
31
  // Import all components
41
32
  import '@vollowx/seele';
42
33
 
43
- // OR Import specific components (Recommended)
34
+ // Or import specific components (recommended)
35
+ // They all follow such path :@/catagory/group/component.js
44
36
  import '@vollowx/seele/m3/button/common-button.js';
45
37
  import '@vollowx/seele/m3/checkbox/checkbox.js';
46
38
  ```
47
39
 
48
- ### Using Components
40
+ ### Using
49
41
 
50
- Once imported, use the components just like standard HTML tags.
42
+ Once imported, the components can be used just like standard HTML elements.
51
43
 
52
44
  ```html
53
45
  <md-button variant="filled">Filled Button</md-button>
@@ -61,9 +53,15 @@ Once imported, use the components just like standard HTML tags.
61
53
 
62
54
  ### Theming
63
55
 
64
- SEELE components use CSS variables for styling. Currently, the global Material Design 3 token variables are not included in the JavaScript bundle.
56
+ SEELE components use CSS variables for styling.
57
+
58
+ Currently, Material Design 3 token variables are not yet included in the source
59
+ code.
65
60
 
66
- To style the components correctly, you need to define the necessary CSS variables in your project. You can find reference implementations in [vollowx/seele-docs](https://github.com/vollowx/seele-docs/) or the `dev` folder of this repository.
61
+ To style the components correctly, you need to define the necessary CSS
62
+ variables in your project. You can find reference implementations in
63
+ [vollowx/seele-docs](https://github.com/vollowx/seele-docs/) or the `dev` folder
64
+ of this repository.
67
65
 
68
66
  ## Browser Supporty
69
67
 
@@ -75,5 +73,5 @@ SEELE relies on modern web standards like `ElementInternals`.
75
73
  ## Resources
76
74
 
77
75
  - [Roadmap](./ROADMAP.md)
78
- - [Contributing Guide](./CONTRIBUTING.md)
76
+ - [Contributing](./CONTRIBUTING.md)
79
77
  - [License](./LICENSE)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vollowx/seele",
3
- "version": "0.12.2",
3
+ "version": "0.12.4",
4
4
  "description": "Standard Extensible Elements. A web components library that can be styled and extended freely, pre-providing components in Material Design 3.",
5
5
  "author": "vollowx",
6
6
  "license": "Apache-2.0",
@@ -9,8 +9,8 @@
9
9
  "module": "./src/all.js",
10
10
  "exports": {
11
11
  ".": "./src/all.js",
12
- "./m3/*": "./src/m3/*.js",
13
- "./base/*": "./src/base/*.js"
12
+ "./base/*": "./src/base/*",
13
+ "./m3/*": "./src/m3/*"
14
14
  },
15
15
  "files": [
16
16
  "src/**/*.js",
package/src/base/list.js CHANGED
@@ -1,13 +1,11 @@
1
1
  import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
2
- import { LitElement, html } from 'lit';
3
- import { property, query, queryAssignedElements } from 'lit/decorators.js';
2
+ import { LitElement, html, isServer } from 'lit';
3
+ import { property, queryAssignedElements } from 'lit/decorators.js';
4
4
  import { setFocusVisible } from '../core/focus-visible.js';
5
- import { InternalsAttached } from './mixins/internals-attached.js';
6
- import { FocusDelegated } from './mixins/focus-delegated.js';
5
+ import { InternalsAttached, internals } from './mixins/internals-attached.js';
7
6
  import { ListController } from './controllers/list-controller.js';
8
- const Base = FocusDelegated(InternalsAttached(LitElement));
7
+ const Base = InternalsAttached(LitElement);
9
8
  /**
10
- * @csspart list
11
9
  * @csspart items
12
10
  *
13
11
  * @fires {Event} open - Fires when the menu is opened.
@@ -18,20 +16,44 @@ const Base = FocusDelegated(InternalsAttached(LitElement));
18
16
  get $items() {
19
17
  return this.listController.items || [];
20
18
  }
19
+ constructor(){
20
+ super(), this._possibleItemTags = [], this._scrollPadding = 0, this.noFocusControl = false, this.listController = new ListController(this, {
21
+ isItem: (item)=>this._possibleItemTags.includes(item.tagName.toLowerCase()) && !item.hasAttribute('disabled') && !item.hidden,
22
+ getPossibleItems: ()=>this.slotItems,
23
+ blurItem: (item)=>{
24
+ item.focused = false;
25
+ },
26
+ focusItem: (item)=>{
27
+ item.focused = true;
28
+ if (!this.noFocusControl) {
29
+ this[internals].ariaActiveDescendantElement = item;
30
+ }
31
+ scrollItemIntoView(this, item, this._scrollPadding);
32
+ this.dispatchEvent(new CustomEvent('item-focus', {
33
+ detail: {
34
+ item: item
35
+ },
36
+ bubbles: true,
37
+ composed: true
38
+ }));
39
+ },
40
+ wrapNavigation: ()=>false
41
+ });
42
+ if (!isServer) {
43
+ this[internals].role = 'listbox';
44
+ if (!this.hasAttribute('tabindex')) {
45
+ this.setAttribute('tabindex', '0');
46
+ }
47
+ this.addEventListener('keydown', (e)=>this.#handleKeyDown(e));
48
+ this.addEventListener('focusin', ()=>this.#handleFocusIn());
49
+ this.addEventListener('focusout', ()=>this.#handleFocusOut());
50
+ this.addEventListener('pointerdown', (e)=>this.#handlePointerDown(e));
51
+ this.addEventListener('click', (e)=>this.#handleClick(e));
52
+ this.addEventListener('mouseover', (e)=>this.#handleMouseOver(e));
53
+ }
54
+ }
21
55
  render() {
22
- return html`<div
23
- part="list"
24
- role="listbox"
25
- tabindex="0"
26
- @keydown=${this.#handleKeyDown}
27
- @focusin=${this.#handleFocusIn}
28
- @focusout=${this.#handleFocusOut}
29
- @pointerdown=${this.#handlePointerDown}
30
- @click=${this.#handleClick}
31
- @mouseover=${this.#handleMouseOver}
32
- >
33
- ${this.renderItemSlot()}
34
- </div>`;
56
+ return html` ${this.renderItemSlot()} `;
35
57
  }
36
58
  renderItemSlot() {
37
59
  return html`<slot part="items"></slot>`;
@@ -92,13 +114,13 @@ const Base = FocusDelegated(InternalsAttached(LitElement));
92
114
  }
93
115
  #handlePointerDown(event) {
94
116
  event.preventDefault(); // This makes sure that the container is focused
95
- this.$list.focus();
117
+ this.focus();
96
118
  const item = this.#getEventItem(event);
97
119
  if (!item || !this.listController.items.includes(item)) return;
98
120
  this.listController._focusItem(item);
99
121
  }
100
122
  #handleClick(event) {
101
- this.$list.focus();
123
+ this.focus();
102
124
  const item = this.#getEventItem(event);
103
125
  if (!item || !this.listController.items.includes(item)) return;
104
126
  this.dispatchEvent(new CustomEvent('select', {
@@ -126,30 +148,6 @@ const Base = FocusDelegated(InternalsAttached(LitElement));
126
148
  focusItem(item) {
127
149
  this.listController._focusItem(item);
128
150
  }
129
- constructor(...args){
130
- super(...args), this._possibleItemTags = [], this._scrollPadding = 0, this.noFocusControl = false, this.listController = new ListController(this, {
131
- isItem: (item)=>this._possibleItemTags.includes(item.tagName.toLowerCase()) && !item.hasAttribute('disabled') && !item.hidden,
132
- getPossibleItems: ()=>this.slotItems,
133
- blurItem: (item)=>{
134
- item.focused = false;
135
- },
136
- focusItem: (item)=>{
137
- item.focused = true;
138
- if (!this.noFocusControl) {
139
- this.$list.ariaActiveDescendantElement = item;
140
- }
141
- scrollItemIntoView(this.$list, item, this._scrollPadding);
142
- this.dispatchEvent(new CustomEvent('item-focus', {
143
- detail: {
144
- item: item
145
- },
146
- bubbles: true,
147
- composed: true
148
- }));
149
- },
150
- wrapNavigation: ()=>false
151
- });
152
- }
153
151
  }
154
152
  _ts_decorate([
155
153
  property({
@@ -157,9 +155,6 @@ _ts_decorate([
157
155
  attribute: 'no-focus-control'
158
156
  })
159
157
  ], List.prototype, "noFocusControl", void 0);
160
- _ts_decorate([
161
- query('[part="list"]')
162
- ], List.prototype, "$list", void 0);
163
158
  _ts_decorate([
164
159
  queryAssignedElements({
165
160
  flatten: true
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const listStyles = css`:host{min-width:112px;display:contents}[part=list]{box-sizing:border-box;height:inherit;max-height:inherit;max-width:inherit;min-width:inherit;-webkit-user-select:none;user-select:none;width:inherit;outline:0;flex-direction:column;gap:2px;padding:4px;display:flex;position:absolute;inset:auto;overflow-y:auto}`;
2
+ export const listStyles = css`:host{box-sizing:border-box;-webkit-user-select:none;user-select:none;outline:0;flex-direction:column;gap:2px;min-width:112px;height:max-content;padding:4px;display:flex;position:relative;overflow-y:auto}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const menuStyles = css`:host{min-width:112px;display:contents}[part=menu]{background:var(--md-sys-color-surface-container);box-shadow:var(--md-sys-elevation-shadow-2);box-sizing:border-box;color:var(--md-sys-color-on-surface);height:inherit;max-height:var(--md-menu-max-height,inherit);max-width:inherit;min-width:inherit;opacity:0;-webkit-user-select:none;user-select:none;z-index:1000;border-radius:16px;outline:0;padding:4px;position:absolute;inset:auto;overflow-y:auto;transform:scaleY(.4)}:host([color=vibrant]){& [part=menu]{--md-divider-color:var(--md-sys-color-tertiary);--md-item-supporting-text-color:var(--md-sys-color-on-tertiary-container);background-color:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container)}& ::slotted([selected]){--md-item-supporting-text-color:var(--md-sys-color-on-tertiary);background-color:var(--md-sys-color-tertiary);color:var(--md-sys-color-on-tertiary)}}:host([alignstrategy=fixed]) [part=menu]{position:fixed}[part=items]{opacity:0;flex-direction:column;gap:2px;display:flex}:host(:state(closed)) [part=menu]{display:none}:host(:state(opening)){& [part=menu]{opacity:1;transition:opacity 67ms, transform var(--md-sys-motion-exp-spatial-default-duration) var(--md-sys-motion-exp-spatial-default);display:block;transform:scaleY(1)}& [part=items]{opacity:1;transition:opacity 67ms linear 67ms}}:host(:state(opened)){& [part=menu]{opacity:1;display:block;transform:scaleY(1)}& [part=items]{opacity:1}}:host(:state(closing)){& [part=menu]{opacity:0;transition:opacity var(--md-sys-motion-exp-effects-fast-duration), transform var(--md-sys-motion-exp-effects-slow-duration) var(--md-sys-motion-exp-effects-slow);transform:scaleY(.4)}& [part=items]{opacity:0;transition:opacity 67ms}}::slotted(md-divider){margin-block:6px}`;
2
+ export const menuStyles = css`:host{min-width:112px;display:contents}[part=menu]{background:var(--md-sys-color-surface-container);box-shadow:var(--md-sys-elevation-shadow-2);box-sizing:border-box;color:var(--md-sys-color-on-surface);height:inherit;max-height:var(--md-menu-max-height,inherit);max-width:inherit;min-width:inherit;opacity:0;-webkit-user-select:none;user-select:none;z-index:1000;border-radius:16px;outline:0;padding:4px;position:absolute;inset:auto;overflow-y:auto;transform:scaleY(.35)}:host([color=vibrant]){& [part=menu]{--md-divider-color:var(--md-sys-color-tertiary);--md-item-supporting-text-color:var(--md-sys-color-on-tertiary-container);background-color:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container)}& ::slotted([selected]){--md-item-supporting-text-color:var(--md-sys-color-on-tertiary);background-color:var(--md-sys-color-tertiary);color:var(--md-sys-color-on-tertiary)}}:host([alignstrategy=fixed]) [part=menu]{position:fixed}[part=items]{opacity:0;flex-direction:column;gap:2px;display:flex}:host(:state(closed)) [part=menu]{display:none}:host(:state(opening)){& [part=menu]{opacity:1;transition:opacity 67ms, transform var(--md-sys-motion-exp-spatial-default-duration) var(--md-sys-motion-exp-spatial-default);display:block;transform:scaleY(1)}& [part=items]{opacity:1;transition:opacity 67ms linear 67ms}}:host(:state(opened)){& [part=menu]{opacity:1;display:block;transform:scaleY(1)}& [part=items]{opacity:1}}:host(:state(closing)){& [part=menu]{opacity:0;transition:opacity var(--md-sys-motion-exp-effects-fast-duration), transform var(--md-sys-motion-exp-effects-slow-duration) var(--md-sys-motion-exp-effects-slow);transform:scaleY(.35)}& [part=items]{opacity:0;transition:opacity 67ms}}::slotted(md-divider){margin-block:6px}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const textFieldStyles = css`:host{-webkit-user-select:none;user-select:none;min-width:210px;display:inline-block}md-filled-field,md-outlined-field{width:100%}[part=input]{color:inherit;font:inherit;background:0 0;border:none;outline:none;width:100%;height:100%;margin:0;padding:0}`;
2
+ export const textFieldStyles = css`:host{-webkit-user-select:none;user-select:none;min-width:210px;display:inline-block}md-filled-field,md-outlined-field{width:100%}[part=input]{color:inherit;font:inherit;-webkit-tap-highlight-color:transparent;background:0 0;border:none;outline:none;width:100%;height:100%;margin:0;padding:0}`;
@@ -1,2 +1,2 @@
1
1
  import { css } from 'lit';
2
- export const tooltipStyles = css`:host{background-color:var(--md-sys-color-inverse-surface);box-sizing:border-box;color:#0000;font:var(--md-sys-typography-body-small);max-width:var(--_max-width,300px);opacity:0;pointer-events:none;z-index:800;border-radius:4px;align-items:center;width:max-content;min-height:24px;padding:4px 8px;display:flex;position:absolute;top:0;left:0;transform:scaleY(.4)}:host(:state(closed)){display:none}:host(:state(opening):not([forceinvisible])){color:var(--md-sys-color-inverse-on-surface);opacity:1;pointer-events:auto;transition:color linear 67ms 67ms, opacity var(--md-sys-motion-exp-effects-fast-duration) var(--md-sys-motion-exp-effects-fast), transform var(--md-sys-motion-exp-effects-fast-duration) var(--md-sys-motion-exp-effects-fast);transform:scaleY(1)}:host(:state(opened):not([forceinvisible])){color:var(--md-sys-color-inverse-on-surface);opacity:1;pointer-events:auto;transform:scaleY(1)}:host(:state(closing):not([forceinvisible])){color:#0000;opacity:0;transition:color linear 67ms, opacity var(--md-sys-motion-exp-effects-fast-duration) var(--md-sys-motion-exp-effects-fast), transform var(--md-sys-motion-exp-effects-fast-duration) var(--md-sys-motion-exp-effects-fast);transform:scaleY(.4)}`;
2
+ export const tooltipStyles = css`:host{background-color:var(--md-sys-color-inverse-surface);box-sizing:border-box;color:#0000;font:var(--md-sys-typography-body-small);max-width:var(--_max-width,300px);opacity:0;pointer-events:none;z-index:800;border-radius:4px;align-items:center;width:max-content;min-height:24px;padding:4px 8px;display:flex;position:absolute;top:0;left:0;transform:scaleY(.35)}:host(:state(closed)){display:none}:host(:state(opening):not([forceinvisible])){color:var(--md-sys-color-inverse-on-surface);opacity:1;pointer-events:auto;transition:color linear 67ms 67ms, opacity var(--md-sys-motion-exp-effects-fast-duration) var(--md-sys-motion-exp-effects-fast), transform var(--md-sys-motion-exp-effects-fast-duration) var(--md-sys-motion-exp-effects-fast);transform:scaleY(1)}:host(:state(opened):not([forceinvisible])){color:var(--md-sys-color-inverse-on-surface);opacity:1;pointer-events:auto;transform:scaleY(1)}:host(:state(closing):not([forceinvisible])){color:#0000;opacity:0;transition:color linear 67ms, opacity var(--md-sys-motion-exp-effects-fast-duration) var(--md-sys-motion-exp-effects-fast), transform var(--md-sys-motion-exp-effects-fast-duration) var(--md-sys-motion-exp-effects-fast);transform:scaleY(.35)}`;