@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 ADDED
@@ -0,0 +1,65 @@
1
+ # `<exm-collapsed>` [![Published on npm](https://img.shields.io/npm/v/@exmg/exm-collapsed.svg)](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
@@ -0,0 +1,3 @@
1
+ export { ExmgCollapsed } from './src/exm-collapsed.js';
2
+ export { ExmgCollapsedBase } from './src/exm-collapsed-base.js';
3
+ export { style as collapsedStyles } from './src/styles/exm-collapsed-styles-css.js';
package/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { ExmgCollapsed } from './src/exm-collapsed.js';
2
+ export { ExmgCollapsedBase } from './src/exm-collapsed-base.js';
3
+ export { style as collapsedStyles } from './src/styles/exm-collapsed-styles-css.js';
4
+ //# sourceMappingURL=index.js.map
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,2 @@
1
+ export declare const style: import("lit").CSSResult;
2
+ export default style;
@@ -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
@@ -0,0 +1,12 @@
1
+ :host {
2
+ display: block;
3
+ transition-duration: 300ms;
4
+ -webkit-transition-duration: 300ms;
5
+ overflow: visible;
6
+ }
7
+ :host(.collapse-closed) {
8
+ display: none;
9
+ }
10
+ :host(:not(.collapse-closed)) {
11
+ overflow: hidden;
12
+ }