@exmg/exm-collapsed 1.0.0
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 +65 -0
- package/index.d.ts +3 -0
- package/index.js +4 -0
- package/package.json +43 -0
- package/src/exm-collapsed-base.d.ts +53 -0
- package/src/exm-collapsed-base.js +164 -0
- package/src/exm-collapsed.d.ts +15 -0
- package/src/exm-collapsed.js +18 -0
- package/src/styles/exm-collapsed-styles-css.d.ts +2 -0
- package/src/styles/exm-collapsed-styles-css.js +4 -0
- package/src/styles/exm-collapsed-styles.scss +12 -0
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# `<exm-collapsed>` [](https://www.npmjs.com/package/@exmg/exm-collapsed)
|
|
2
|
+
|
|
3
|
+
Collapsed element contains a slot that can be expanded or collapsed to reveal additional content or information.
|
|
4
|
+
|
|
5
|
+
[Demo](https://exmg.github.io/exmachina-web-components/demo/?el=exm-collapsed)
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @exmg/exm-collapsed
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Example Usage
|
|
14
|
+
|
|
15
|
+
### Standard
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
@property({type: Boolean})
|
|
19
|
+
opened = false;
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<exm-button @click="${()" =""> (this.opened = !this.opened)}>Open</exm-button>
|
|
24
|
+
|
|
25
|
+
<exm-collapsed ?opened="${this.opened}">
|
|
26
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
|
|
27
|
+
aliqua.
|
|
28
|
+
</exm-collapsed>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## API
|
|
32
|
+
|
|
33
|
+
### Slots
|
|
34
|
+
|
|
35
|
+
| Name | Description |
|
|
36
|
+
| --------- | --------------------------------------------------------- |
|
|
37
|
+
| _default_ | Default content to display within the collapsible element |
|
|
38
|
+
|
|
39
|
+
### Properties/Attributes
|
|
40
|
+
|
|
41
|
+
| Name | Type | Default | Description |
|
|
42
|
+
| -------- | --------- | ------- | --------------------------------- |
|
|
43
|
+
| `opened` | `boolean` | `false` | The opened state of the component |
|
|
44
|
+
|
|
45
|
+
### Methods
|
|
46
|
+
|
|
47
|
+
| Name | Description |
|
|
48
|
+
| -------- | ------------------------------------------------- |
|
|
49
|
+
| `toggle` | Toggles the opened state of the component |
|
|
50
|
+
| `show` | Sets the opened state of the component to _true_ |
|
|
51
|
+
| `hide` | Sets the opened state of the component to _false_ |
|
|
52
|
+
|
|
53
|
+
### Events
|
|
54
|
+
|
|
55
|
+
_None_
|
|
56
|
+
|
|
57
|
+
### CSS Custom Properties
|
|
58
|
+
|
|
59
|
+
_None_
|
|
60
|
+
|
|
61
|
+
## Additional references
|
|
62
|
+
|
|
63
|
+
- [Additional Documentation](https://exmg.github.io/exmachina-web-components/ExmgCollapsed.html)
|
|
64
|
+
|
|
65
|
+
- [Demo](https://exmg.github.io/exmachina-web-components/demo/?el=exm-collapsed)
|
package/index.d.ts
ADDED
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@exmg/exm-collapsed",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"module": "index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.js",
|
|
9
|
+
"./exm-collapsed.js": "./src/exm-collapsed.js"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@exmg/lit-base": "^2.0.1",
|
|
13
|
+
"lit": "^3.0.0",
|
|
14
|
+
"tslib": "^2.6.2"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@exmg/lit-cli": "1.1.13"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"web-components",
|
|
21
|
+
"lit",
|
|
22
|
+
"collapsed"
|
|
23
|
+
],
|
|
24
|
+
"files": [
|
|
25
|
+
"**/*.scss",
|
|
26
|
+
"**/*.js",
|
|
27
|
+
"**/*.d.ts"
|
|
28
|
+
],
|
|
29
|
+
"homepage": "https://github.com/exmg/exmachina-web-components",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git@github.com:exmg/exm-web-components.git",
|
|
33
|
+
"directory": "packages/exm-collapsed"
|
|
34
|
+
},
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build:styles": "exmg-lit-cli sass -f \"./**/*.scss\""
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"gitHead": "0907b55c89325d59902b98a64c352bf6e1fc81ff"
|
|
43
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ExmgElement } from '@exmg/lit-base/index.js';
|
|
2
|
+
export declare class ExmgCollapsedBase extends ExmgElement {
|
|
3
|
+
/**
|
|
4
|
+
* Whether or not the element is opened or not
|
|
5
|
+
* @type {Boolean}
|
|
6
|
+
*/
|
|
7
|
+
opened: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Whether the element is transitioning or not
|
|
10
|
+
* @type {Boolean}
|
|
11
|
+
*/
|
|
12
|
+
transitioning: boolean;
|
|
13
|
+
_desiredSize: string;
|
|
14
|
+
_initialized: boolean;
|
|
15
|
+
constructor();
|
|
16
|
+
/**
|
|
17
|
+
* Toggle the current(opened/closed) state.
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
toggle(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Set the opened state
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
show(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Set the closed state
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
hide(): void;
|
|
31
|
+
/**
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
_calcSize(): string;
|
|
35
|
+
/**
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
_updateTransition(enabled: boolean): void;
|
|
39
|
+
updateSize(size: string, animated: boolean): void;
|
|
40
|
+
/**
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
43
|
+
_openedChanged(): void;
|
|
44
|
+
/**
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
_onTransitionEnd(event: TransitionEvent): void;
|
|
48
|
+
/**
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
_transitionEnd(): void;
|
|
52
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
53
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { html } from 'lit';
|
|
3
|
+
import { property, state } from 'lit/decorators.js';
|
|
4
|
+
import { observer, ExmgElement } from '@exmg/lit-base/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* Helper function to toggle element
|
|
7
|
+
* @param className
|
|
8
|
+
* @param el
|
|
9
|
+
* @param val
|
|
10
|
+
*/
|
|
11
|
+
const toggleClass = (className, el, val) => {
|
|
12
|
+
if (val !== undefined) {
|
|
13
|
+
if (val) {
|
|
14
|
+
if (!el.classList.contains(className)) {
|
|
15
|
+
el.classList.add(className);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
el.classList.remove(className);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
el.classList.toggle(className);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export class ExmgCollapsedBase extends ExmgElement {
|
|
27
|
+
constructor() {
|
|
28
|
+
super();
|
|
29
|
+
/**
|
|
30
|
+
* Whether or not the element is opened or not
|
|
31
|
+
* @type {Boolean}
|
|
32
|
+
*/
|
|
33
|
+
this.opened = false;
|
|
34
|
+
/**
|
|
35
|
+
* Whether the element is transitioning or not
|
|
36
|
+
* @type {Boolean}
|
|
37
|
+
*/
|
|
38
|
+
this.transitioning = false;
|
|
39
|
+
this._desiredSize = '';
|
|
40
|
+
this._initialized = false;
|
|
41
|
+
this.addEventListener('transitionend', this._onTransitionEnd.bind(this));
|
|
42
|
+
this.setAttribute('role', 'group');
|
|
43
|
+
this.setAttribute('aria-hidden', 'true');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Toggle the current(opened/closed) state.
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
toggle() {
|
|
50
|
+
this.opened = !this.opened;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Set the opened state
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
show() {
|
|
57
|
+
this.opened = true;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Set the closed state
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
hide() {
|
|
64
|
+
this.opened = false;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
69
|
+
_calcSize() {
|
|
70
|
+
return this.getBoundingClientRect()['height'] + 'px';
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
_updateTransition(enabled) {
|
|
76
|
+
this.style.transitionDuration = enabled ? '' : '0s';
|
|
77
|
+
}
|
|
78
|
+
updateSize(size, animated) {
|
|
79
|
+
// Consider 'auto' as '', to take full size.
|
|
80
|
+
size = size === 'auto' ? '' : size;
|
|
81
|
+
let willAnimate = animated && this._desiredSize !== size;
|
|
82
|
+
this._desiredSize = size;
|
|
83
|
+
this._updateTransition(false);
|
|
84
|
+
// If we can animate, must do some prep work.
|
|
85
|
+
if (willAnimate) {
|
|
86
|
+
// Animation will start at the current size.
|
|
87
|
+
const startSize = this._calcSize();
|
|
88
|
+
// For `auto` we must calculate what is the final size for the animation.
|
|
89
|
+
// After the transition is done, _transitionEnd will set the size back to
|
|
90
|
+
// `auto`.
|
|
91
|
+
if (size === '') {
|
|
92
|
+
this.style['maxHeight'] = '';
|
|
93
|
+
size = this._calcSize();
|
|
94
|
+
}
|
|
95
|
+
// Go to startSize without animation.
|
|
96
|
+
this.style['maxHeight'] = startSize;
|
|
97
|
+
// Force layout to ensure transition will go. Set scrollTop to itself
|
|
98
|
+
// so that compilers won't remove it.
|
|
99
|
+
// eslint-disable-next-line no-self-assign
|
|
100
|
+
this.scrollTop = this.scrollTop;
|
|
101
|
+
// Enable animation.
|
|
102
|
+
this._updateTransition(true);
|
|
103
|
+
// If final size is the same as startSize it will not animate.
|
|
104
|
+
willAnimate = size !== startSize;
|
|
105
|
+
}
|
|
106
|
+
// Set the final size.
|
|
107
|
+
this.style['maxHeight'] = size;
|
|
108
|
+
// If it won't animate, call transitionEnd to set correct classes.
|
|
109
|
+
if (!willAnimate) {
|
|
110
|
+
this._transitionEnd();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
_openedChanged() {
|
|
117
|
+
this.setAttribute('aria-hidden', String(!this.opened));
|
|
118
|
+
if (this._initialized) {
|
|
119
|
+
this.transitioning = true;
|
|
120
|
+
}
|
|
121
|
+
toggleClass('collapse-closed', this, false);
|
|
122
|
+
toggleClass('collapse-opened', this, false);
|
|
123
|
+
this.updateSize(this.opened ? 'auto' : '0px', this._initialized);
|
|
124
|
+
// Focus the current collapse.
|
|
125
|
+
if (this.opened) {
|
|
126
|
+
this.focus();
|
|
127
|
+
}
|
|
128
|
+
this._initialized = true;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* @private
|
|
132
|
+
*/
|
|
133
|
+
_onTransitionEnd(event) {
|
|
134
|
+
if (event.target === this) {
|
|
135
|
+
this._transitionEnd();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* @private
|
|
140
|
+
*/
|
|
141
|
+
_transitionEnd() {
|
|
142
|
+
this.style['maxHeight'] = String(this._desiredSize);
|
|
143
|
+
toggleClass('collapse-closed', this, !this.opened);
|
|
144
|
+
toggleClass('collapse-opened', this, this.opened);
|
|
145
|
+
this._updateTransition(false);
|
|
146
|
+
this.transitioning = false;
|
|
147
|
+
}
|
|
148
|
+
render() {
|
|
149
|
+
return html ` <slot></slot> `;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
__decorate([
|
|
153
|
+
property({ type: Boolean, reflect: true }),
|
|
154
|
+
observer(function () {
|
|
155
|
+
this._openedChanged();
|
|
156
|
+
})
|
|
157
|
+
], ExmgCollapsedBase.prototype, "opened", void 0);
|
|
158
|
+
__decorate([
|
|
159
|
+
property({ type: Boolean, reflect: true })
|
|
160
|
+
], ExmgCollapsedBase.prototype, "transitioning", void 0);
|
|
161
|
+
__decorate([
|
|
162
|
+
state()
|
|
163
|
+
], ExmgCollapsedBase.prototype, "_desiredSize", void 0);
|
|
164
|
+
//# sourceMappingURL=exm-collapsed-base.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ExmgCollapsedBase } from './exm-collapsed-base.js';
|
|
2
|
+
/**
|
|
3
|
+
* 'exm-collapsed' element contains a slot that can be expanded or collapsed to reveal additional content or information.
|
|
4
|
+
*
|
|
5
|
+
* @customElement exm-collapsed
|
|
6
|
+
* @extends ExmgCollapsedBase
|
|
7
|
+
*/
|
|
8
|
+
export declare class ExmgCollapsed extends ExmgCollapsedBase {
|
|
9
|
+
static styles: import("lit").CSSResult[];
|
|
10
|
+
}
|
|
11
|
+
declare global {
|
|
12
|
+
interface HTMLElementTagNameMap {
|
|
13
|
+
'exm-collapsed': ExmgCollapsed;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { customElement } from 'lit/decorators.js';
|
|
3
|
+
import { ExmgCollapsedBase } from './exm-collapsed-base.js';
|
|
4
|
+
import { style } from './styles/exm-collapsed-styles-css.js';
|
|
5
|
+
/**
|
|
6
|
+
* 'exm-collapsed' element contains a slot that can be expanded or collapsed to reveal additional content or information.
|
|
7
|
+
*
|
|
8
|
+
* @customElement exm-collapsed
|
|
9
|
+
* @extends ExmgCollapsedBase
|
|
10
|
+
*/
|
|
11
|
+
let ExmgCollapsed = class ExmgCollapsed extends ExmgCollapsedBase {
|
|
12
|
+
};
|
|
13
|
+
ExmgCollapsed.styles = [style];
|
|
14
|
+
ExmgCollapsed = __decorate([
|
|
15
|
+
customElement('exm-collapsed')
|
|
16
|
+
], ExmgCollapsed);
|
|
17
|
+
export { ExmgCollapsed };
|
|
18
|
+
//# sourceMappingURL=exm-collapsed.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const style = css `:host{display:block;transition-duration:300ms;-webkit-transition-duration:300ms;overflow:visible}:host(.collapse-closed){display:none}:host(:not(.collapse-closed)){overflow:hidden}`;
|
|
3
|
+
export default style;
|
|
4
|
+
//# sourceMappingURL=exm-collapsed-styles-css.js.map
|