@exmg/exm-collapsed 0.0.2-alpha.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/dist/exm-collapsed-base.d.ts +53 -0
- package/dist/exm-collapsed-base.js +164 -0
- package/dist/exm-collapsed.d.ts +15 -0
- package/dist/exm-collapsed.js +18 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/styles/exm-collapsed-styles-css.d.ts +1 -0
- package/dist/styles/exm-collapsed-styles-css.js +18 -0
- package/package.json +39 -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/ExmCollapsed.html)
|
|
64
|
+
|
|
65
|
+
- [Demo](https://exmg.github.io/exmachina-web-components/demo/?el=exm-collapsed)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ExmgElement } from '@exmg/lit-base/index.js';
|
|
2
|
+
export declare class ExmCollapsedBase 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 ExmCollapsedBase 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
|
+
], ExmCollapsedBase.prototype, "opened", void 0);
|
|
158
|
+
__decorate([
|
|
159
|
+
property({ type: Boolean, reflect: true })
|
|
160
|
+
], ExmCollapsedBase.prototype, "transitioning", void 0);
|
|
161
|
+
__decorate([
|
|
162
|
+
state()
|
|
163
|
+
], ExmCollapsedBase.prototype, "_desiredSize", void 0);
|
|
164
|
+
//# sourceMappingURL=exm-collapsed-base.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ExmCollapsedBase } 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 ExmCollapsedBase
|
|
7
|
+
*/
|
|
8
|
+
export declare class ExmCollapsed extends ExmCollapsedBase {
|
|
9
|
+
static styles: import("lit").CSSResult[];
|
|
10
|
+
}
|
|
11
|
+
declare global {
|
|
12
|
+
interface HTMLElementTagNameMap {
|
|
13
|
+
'exm-collapsed': ExmCollapsed;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { customElement } from 'lit/decorators.js';
|
|
3
|
+
import { ExmCollapsedBase } 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 ExmCollapsedBase
|
|
10
|
+
*/
|
|
11
|
+
let ExmCollapsed = class ExmCollapsed extends ExmCollapsedBase {
|
|
12
|
+
};
|
|
13
|
+
ExmCollapsed.styles = [style];
|
|
14
|
+
ExmCollapsed = __decorate([
|
|
15
|
+
customElement('exm-collapsed')
|
|
16
|
+
], ExmCollapsed);
|
|
17
|
+
export { ExmCollapsed };
|
|
18
|
+
//# sourceMappingURL=exm-collapsed.js.map
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const style: import("lit").CSSResult;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const style = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
transition-duration: 300ms;
|
|
6
|
+
-webkit-transition-duration: 300ms;
|
|
7
|
+
overflow: visible;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
:host(.collapse-closed) {
|
|
11
|
+
display: none;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:host(:not(.collapse-closed)) {
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
}
|
|
17
|
+
`;
|
|
18
|
+
//# sourceMappingURL=exm-collapsed-styles-css.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@exmg/exm-collapsed",
|
|
3
|
+
"version": "0.0.2-alpha.0+df24e0c",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js",
|
|
10
|
+
"./exm-collapsed.js": "./dist/exm-collapsed.js"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@exmg/lit-base": "^3.0.3",
|
|
14
|
+
"lit": "^3.2.1",
|
|
15
|
+
"tslib": "^2.6.2"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"web-components",
|
|
19
|
+
"lit",
|
|
20
|
+
"collapsed"
|
|
21
|
+
],
|
|
22
|
+
"files": [
|
|
23
|
+
"**/*.scss",
|
|
24
|
+
"**/*.js",
|
|
25
|
+
"**/*.d.ts"
|
|
26
|
+
],
|
|
27
|
+
"homepage": "https://bitbucket.org/exmachina/exm-web-components",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git@bitbucket.org:exmachina/exm-web-components.git",
|
|
31
|
+
"directory": "packages/exm-collapsed"
|
|
32
|
+
},
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"scripts": {},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"gitHead": "df24e0c74a76a7e1c258f69386036e24e7860256"
|
|
39
|
+
}
|