@nectary/components 5.17.0 → 5.18.1
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/dialog/index.js +1 -1
- package/package.json +3 -3
- package/sheet/global/index.d.ts +1 -0
- package/sheet/global/index.js +2 -0
- package/sheet/index.d.ts +18 -0
- package/sheet/index.js +230 -0
- package/sheet/types.d.ts +71 -0
- package/sheet/types.js +1 -0
- package/sheet-title/global/index.d.ts +1 -0
- package/sheet-title/global/index.js +2 -0
- package/sheet-title/index.d.ts +17 -0
- package/sheet-title/index.js +79 -0
- package/sheet-title/types.d.ts +53 -0
- package/sheet-title/types.js +1 -0
- package/utils/component-names.d.ts +2 -2
- package/utils/component-names.js +2 -0
- package/utils/element.d.ts +2 -0
- /package/{dialog/utils.d.ts → utils/scroll-lock.d.ts} +0 -0
- /package/{dialog/utils.js → utils/scroll-lock.js} +0 -0
package/dialog/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { defineCustomElement, NectaryElement } from "../utils/element.js";
|
|
|
6
6
|
import { getRect } from "../utils/rect.js";
|
|
7
7
|
import { getReactEventHandler } from "../utils/get-react-event-handler.js";
|
|
8
8
|
import { isTargetEqual } from "../utils/event-target.js";
|
|
9
|
-
import { disableScroll, enableScroll } from "
|
|
9
|
+
import { disableScroll, enableScroll } from "../utils/scroll-lock.js";
|
|
10
10
|
const templateHTML = '<style>:host{display:contents;--sinch-comp-dialog-max-width:512px;--sinch-comp-dialog-max-height:90vh;--sinch-comp-dialog-width:fit-content;--sinch-dialog-close-button-display:unset}#dialog{position:fixed;left:0;right:0;margin:auto;display:flex;flex-direction:column;padding:24px 0;width:var(--sinch-comp-dialog-width);max-width:var(--sinch-comp-dialog-max-width);max-height:var(--sinch-comp-dialog-max-height);border-radius:var(--sinch-comp-dialog-shape-radius);box-sizing:border-box;contain:content;background-color:var(--sinch-comp-dialog-color-default-background-initial);border:none;box-shadow:var(--sinch-comp-dialog-shadow);outline:0}#dialog:not([open]){display:none}dialog::backdrop{background-color:#000;opacity:.55}#header{display:flex;flex-direction:row;align-items:flex-start;margin-bottom:12px;padding:0 24px;gap:8px;--sinch-global-size-icon:24px;--sinch-global-color-icon:var(--sinch-comp-dialog-color-default-icon-initial)}#caption{--sinch-global-color-text:var(--sinch-comp-dialog-color-default-title-initial);--sinch-comp-title-font:var(--sinch-comp-dialog-font-title)}#content{min-height:0;overflow:auto;padding:4px 24px}#action{display:flex;flex-direction:row;justify-content:flex-end;gap:16px;margin-top:20px;padding:0 24px}#action.empty{display:none}#close{display:var(--sinch-dialog-close-button-display,initial);position:relative;left:4px;top:-4px;margin-left:auto}</style><dialog id="dialog"><div id="header"><slot id="icon" name="icon"></slot><sinch-title id="caption" type="m" level="3"></sinch-title><sinch-button id="close" size="s"><sinch-icon icons-version="2" name="fa-xmark" id="icon-close" slot="icon"></sinch-icon></sinch-button></div><div id="content"><sinch-stop-events events="close"><slot name="content"></slot></sinch-stop-events></div><div id="action"><sinch-stop-events events="close"><slot name="buttons"></slot></sinch-stop-events></div></dialog>';
|
|
11
11
|
const template = document.createElement("template");
|
|
12
12
|
template.innerHTML = templateHTML;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nectary/components",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.18.1",
|
|
4
4
|
"files": [
|
|
5
5
|
"**/*/*.css",
|
|
6
6
|
"**/*/*.json",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@babel/runtime": "^7.22.15",
|
|
27
|
-
"@nectary/assets": "3.4.
|
|
27
|
+
"@nectary/assets": "3.4.3"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@babel/cli": "^7.22.15",
|
|
@@ -40,6 +40,6 @@
|
|
|
40
40
|
"vite": "^7.0.6"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@nectary/theme-base": "1.
|
|
43
|
+
"@nectary/theme-base": "1.9.0"
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../types';
|
package/sheet/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import '../stop-events';
|
|
2
|
+
import { NectaryElement } from '../utils';
|
|
3
|
+
export * from './types';
|
|
4
|
+
export declare class Sheet extends NectaryElement {
|
|
5
|
+
#private;
|
|
6
|
+
constructor();
|
|
7
|
+
connectedCallback(): void;
|
|
8
|
+
disconnectedCallback(): void;
|
|
9
|
+
static get observedAttributes(): string[];
|
|
10
|
+
attributeChangedCallback(name: string, oldVal: string | null, newVal: string | null): void;
|
|
11
|
+
set open(isOpen: boolean);
|
|
12
|
+
get open(): boolean;
|
|
13
|
+
set placement(placement: string);
|
|
14
|
+
get placement(): string;
|
|
15
|
+
set overlay(overlayMode: string);
|
|
16
|
+
get overlay(): string;
|
|
17
|
+
get dialogRect(): import("../types").TRect;
|
|
18
|
+
}
|
package/sheet/index.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import "../stop-events/index.js";
|
|
2
|
+
import { isAttrEqual, updateBooleanAttribute, getBooleanAttribute, updateAttribute, getAttribute, getCssVar, setClass, isAttrTrue } from "../utils/dom.js";
|
|
3
|
+
import { defineCustomElement, NectaryElement } from "../utils/element.js";
|
|
4
|
+
import { getRect } from "../utils/rect.js";
|
|
5
|
+
import { getReactEventHandler } from "../utils/get-react-event-handler.js";
|
|
6
|
+
import { isTargetEqual } from "../utils/event-target.js";
|
|
7
|
+
import { disableScroll, enableScroll } from "../utils/scroll-lock.js";
|
|
8
|
+
const templateHTML = '<style>:host{display:contents}#dialog{position:fixed;margin:0;display:grid;grid-template-rows:auto 1fr auto;padding:var(--sinch-comp-sheet-size-padding);gap:var(--sinch-comp-sheet-size-gap);max-width:unset;max-height:unset;box-sizing:border-box;contain:content;background-color:var(--sinch-comp-sheet-color-background);border:none;outline:0;opacity:0;transition-property:transform,opacity;transition-duration:var(--sinch-comp-sheet-animation-duration),calc(var(--sinch-comp-sheet-animation-duration) / 2.5);transition-timing-function:var(--sinch-comp-sheet-animation-easing)}#dialog.overlay-push{opacity:.5}#dialog[open],#dialog[open].placement-bottom,#dialog[open].placement-left,#dialog[open].placement-right,#dialog[open].placement-top{transform:translateX(0) translateY(0);opacity:1}#dialog.placement-right{top:0;right:0;margin-left:auto;height:100dvh;transform:translateX(100%);max-width:var(--sinch-comp-sheet-size-max-horizontal)}#dialog.placement-left{top:0;left:0;margin-right:auto;height:100dvh;transform:translateX(-100%);max-width:var(--sinch-comp-sheet-size-max-horizontal)}#dialog.placement-top{top:0;left:0;right:0;width:100%;transform:translateY(-100%);max-height:var(--sinch-comp-sheet-size-max-vertical)}#dialog.placement-bottom{bottom:0;left:0;right:0;width:100%;margin-top:auto;transform:translateY(100%);max-height:var(--sinch-comp-sheet-size-max-vertical)}#dialog::backdrop{display:block;background:linear-gradient(var(--sinch-comp-sheet-color-backdrop-from),var(--sinch-comp-sheet-color-backdrop-to));backdrop-filter:blur(var(--sinch-comp-sheet-size-backdrop-blur))}#content{min-height:0;overflow:auto;overscroll-behavior:contain}#action{display:flex;flex-direction:row;justify-content:flex-end;gap:16px}#action.empty{display:none}@media screen and (max-width:576px){#dialog.placement-left,#dialog.placement-right{max-width:100dvw}}@media (prefers-reduced-motion:reduce){#dialog{transition-duration:0s}}</style><dialog id="dialog" aria-labelledby="title" aria-describedby="content"><slot id="title" name="title"></slot><div id="content"><sinch-stop-events events="close"><slot name="content"></slot></sinch-stop-events></div><div id="action"><sinch-stop-events events="close"><slot name="footer"></slot></sinch-stop-events></div></dialog>';
|
|
9
|
+
const template = document.createElement("template");
|
|
10
|
+
template.innerHTML = templateHTML;
|
|
11
|
+
class Sheet extends NectaryElement {
|
|
12
|
+
#$dialog;
|
|
13
|
+
#$actionWrapper;
|
|
14
|
+
#$actionSlot;
|
|
15
|
+
#controller = null;
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
const shadowRoot = this.attachShadow();
|
|
19
|
+
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
20
|
+
this.#$dialog = shadowRoot.querySelector("#dialog");
|
|
21
|
+
this.#$actionWrapper = shadowRoot.querySelector("#action");
|
|
22
|
+
this.#$actionSlot = shadowRoot.querySelector('slot[name="footer"]');
|
|
23
|
+
}
|
|
24
|
+
connectedCallback() {
|
|
25
|
+
super.connectedCallback();
|
|
26
|
+
this.#controller = new AbortController();
|
|
27
|
+
const options = {
|
|
28
|
+
signal: this.#controller.signal
|
|
29
|
+
};
|
|
30
|
+
this.#$dialog.classList.add(`placement-${this.placement}`);
|
|
31
|
+
this.#$dialog.classList.add(`overlay-${this.overlay}`);
|
|
32
|
+
this.#$dialog.addEventListener(
|
|
33
|
+
"mousedown",
|
|
34
|
+
this.#onBackdropMouseDown,
|
|
35
|
+
options
|
|
36
|
+
);
|
|
37
|
+
this.#$dialog.addEventListener("cancel", this.#onCancel, options);
|
|
38
|
+
this.#$dialog.addEventListener(
|
|
39
|
+
"transitionstart",
|
|
40
|
+
this.#onAnimationStart,
|
|
41
|
+
options
|
|
42
|
+
);
|
|
43
|
+
this.#$dialog.addEventListener(
|
|
44
|
+
"transitionend",
|
|
45
|
+
this.#onAnimationEnd,
|
|
46
|
+
options
|
|
47
|
+
);
|
|
48
|
+
this.#$actionSlot.addEventListener(
|
|
49
|
+
"slotchange",
|
|
50
|
+
this.#onActionSlotChange,
|
|
51
|
+
options
|
|
52
|
+
);
|
|
53
|
+
this.addEventListener("-close", this.#onCloseReactHandler, options);
|
|
54
|
+
this.addEventListener(
|
|
55
|
+
"-animation-start",
|
|
56
|
+
this.#onAnimationStartReactHandler,
|
|
57
|
+
options
|
|
58
|
+
);
|
|
59
|
+
this.addEventListener(
|
|
60
|
+
"-animation-end",
|
|
61
|
+
this.#onAnimationEndReactHandler,
|
|
62
|
+
options
|
|
63
|
+
);
|
|
64
|
+
this.#onActionSlotChange();
|
|
65
|
+
if (this.open) {
|
|
66
|
+
requestAnimationFrame(() => {
|
|
67
|
+
this.#onExpand();
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
disconnectedCallback() {
|
|
72
|
+
super.disconnectedCallback();
|
|
73
|
+
this.#onCollapse();
|
|
74
|
+
this.#controller.abort();
|
|
75
|
+
this.#controller = null;
|
|
76
|
+
document.body.style.removeProperty("--sinch-sheet-export-current-width");
|
|
77
|
+
document.body.style.removeProperty("--sinch-sheet-export-current-height");
|
|
78
|
+
}
|
|
79
|
+
// overlay attribute is not observed because it is expected to be set once on initialization
|
|
80
|
+
// there is no practical use case for changing it dynamically
|
|
81
|
+
static get observedAttributes() {
|
|
82
|
+
return ["open", "placement"];
|
|
83
|
+
}
|
|
84
|
+
attributeChangedCallback(name, oldVal, newVal) {
|
|
85
|
+
if (isAttrEqual(oldVal, newVal)) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
switch (name) {
|
|
89
|
+
case "open": {
|
|
90
|
+
const shouldOpen = isAttrTrue(newVal);
|
|
91
|
+
if (shouldOpen) {
|
|
92
|
+
requestAnimationFrame(() => {
|
|
93
|
+
this.#onExpand();
|
|
94
|
+
});
|
|
95
|
+
} else {
|
|
96
|
+
this.#onCollapse();
|
|
97
|
+
}
|
|
98
|
+
updateBooleanAttribute(this, "open", shouldOpen);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
case "placement": {
|
|
102
|
+
this.#$dialog.classList.remove(...Array.from(this.#$dialog.classList).filter((cls) => cls.startsWith("placement-")));
|
|
103
|
+
this.#$dialog.classList.add(`placement-${newVal ?? "right"}`);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
set open(isOpen) {
|
|
109
|
+
updateBooleanAttribute(this, "open", isOpen);
|
|
110
|
+
}
|
|
111
|
+
get open() {
|
|
112
|
+
return getBooleanAttribute(this, "open");
|
|
113
|
+
}
|
|
114
|
+
set placement(placement) {
|
|
115
|
+
updateAttribute(this, "placement", placement);
|
|
116
|
+
}
|
|
117
|
+
get placement() {
|
|
118
|
+
return getAttribute(this, "placement", "right");
|
|
119
|
+
}
|
|
120
|
+
set overlay(overlayMode) {
|
|
121
|
+
updateAttribute(this, "overlay", overlayMode);
|
|
122
|
+
}
|
|
123
|
+
get overlay() {
|
|
124
|
+
return getAttribute(this, "overlay", "modal");
|
|
125
|
+
}
|
|
126
|
+
get dialogRect() {
|
|
127
|
+
return getRect(this.#$dialog);
|
|
128
|
+
}
|
|
129
|
+
#onAnimationStart = (e) => {
|
|
130
|
+
if (e.propertyName !== "transform") {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
this.#dispatchAnimationEvent("start");
|
|
134
|
+
};
|
|
135
|
+
#onAnimationEnd = (e) => {
|
|
136
|
+
if (e.propertyName !== "transform") {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this.#dispatchAnimationEvent("end");
|
|
140
|
+
};
|
|
141
|
+
#onCancel = (e) => {
|
|
142
|
+
if (e.cancelable) {
|
|
143
|
+
e.preventDefault();
|
|
144
|
+
} else {
|
|
145
|
+
this.#onCollapse();
|
|
146
|
+
}
|
|
147
|
+
e.stopPropagation();
|
|
148
|
+
this.#dispatchCloseEvent("escape", e.cancelable);
|
|
149
|
+
};
|
|
150
|
+
#onBackdropMouseDown = (e) => {
|
|
151
|
+
if (isTargetEqual(e, this.#$dialog)) {
|
|
152
|
+
const rect = this.dialogRect;
|
|
153
|
+
const isInside = e.x >= rect.x && e.x < rect.x + rect.width && e.y >= rect.y && e.y < rect.y + rect.height;
|
|
154
|
+
if (!isInside) {
|
|
155
|
+
e.stopPropagation();
|
|
156
|
+
this.#dispatchCloseEvent("backdrop", e.cancelable);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
#onCloseReactHandler = (e) => {
|
|
161
|
+
getReactEventHandler(this, "on-close")?.(e);
|
|
162
|
+
getReactEventHandler(this, "onClose")?.(e);
|
|
163
|
+
};
|
|
164
|
+
#onAnimationStartReactHandler = (e) => {
|
|
165
|
+
getReactEventHandler(this, "on-animation-start")?.(e);
|
|
166
|
+
getReactEventHandler(this, "onAnimationStart")?.(e);
|
|
167
|
+
};
|
|
168
|
+
#onAnimationEndReactHandler = (e) => {
|
|
169
|
+
getReactEventHandler(this, "on-animation-end")?.(e);
|
|
170
|
+
getReactEventHandler(this, "onAnimationEnd")?.(e);
|
|
171
|
+
};
|
|
172
|
+
#dispatchCloseEvent(detail, cancelable) {
|
|
173
|
+
this.dispatchEvent(new CustomEvent("-close", { detail, cancelable }));
|
|
174
|
+
}
|
|
175
|
+
#dispatchAnimationEvent(type) {
|
|
176
|
+
const eventName = type === "start" ? "-animation-start" : "-animation-end";
|
|
177
|
+
const action = this.#$dialog.open ? "expand" : "collapse";
|
|
178
|
+
const width = this.#$dialog.offsetWidth;
|
|
179
|
+
const height = this.#$dialog.offsetHeight;
|
|
180
|
+
const duration = getCssVar(this, "--sinch-comp-sheet-animation-duration") ?? "750ms";
|
|
181
|
+
const easing = getCssVar(this, "--sinch-comp-sheet-animation-easing") ?? "cubic-bezier(0.25, 1, 0.5, 1)";
|
|
182
|
+
const detail = {
|
|
183
|
+
action,
|
|
184
|
+
width,
|
|
185
|
+
height,
|
|
186
|
+
duration,
|
|
187
|
+
easing
|
|
188
|
+
};
|
|
189
|
+
document.body.style.setProperty(
|
|
190
|
+
"--sinch-sheet-export-current-width",
|
|
191
|
+
`${width}px`
|
|
192
|
+
);
|
|
193
|
+
document.body.style.setProperty(
|
|
194
|
+
"--sinch-sheet-export-current-height",
|
|
195
|
+
`${height}px`
|
|
196
|
+
);
|
|
197
|
+
this.dispatchEvent(new CustomEvent(eventName, { detail }));
|
|
198
|
+
}
|
|
199
|
+
#onExpand() {
|
|
200
|
+
if (!this.isDomConnected || this.#$dialog.open || !this.open) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (this.overlay === "modal") {
|
|
204
|
+
this.#$dialog.showModal();
|
|
205
|
+
disableScroll();
|
|
206
|
+
} else {
|
|
207
|
+
this.#$dialog.show();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
#onCollapse() {
|
|
211
|
+
if (!this.#$dialog.open) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
this.#$dialog.close?.();
|
|
215
|
+
if (this.overlay === "modal") {
|
|
216
|
+
enableScroll();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
#onActionSlotChange = () => {
|
|
220
|
+
setClass(
|
|
221
|
+
this.#$actionWrapper,
|
|
222
|
+
"empty",
|
|
223
|
+
this.#$actionSlot.assignedElements().length === 0
|
|
224
|
+
);
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
defineCustomElement("sinch-sheet", Sheet);
|
|
228
|
+
export {
|
|
229
|
+
Sheet
|
|
230
|
+
};
|
package/sheet/types.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { NectaryComponentReact, NectaryComponentReactByType, NectaryComponentVanilla, NectaryComponentVanillaByType, TRect } from '../types';
|
|
2
|
+
export type TSinchSheetCloseDetail = 'close' | 'escape' | 'backdrop';
|
|
3
|
+
export type TSinchSheetAnimationDetail = {
|
|
4
|
+
action: 'expand' | 'collapse';
|
|
5
|
+
/** Dialog width, useful for push overlay */
|
|
6
|
+
width: number;
|
|
7
|
+
/** Dialog height, useful for push overlay */
|
|
8
|
+
height: number;
|
|
9
|
+
/** Animation duration, read from CSS var */
|
|
10
|
+
duration: string;
|
|
11
|
+
/** Animation easing, read from CSS var */
|
|
12
|
+
easing: string;
|
|
13
|
+
};
|
|
14
|
+
export type TSinchSheetPlacement = 'left' | 'right' | 'top' | 'bottom';
|
|
15
|
+
export type TSinchSheetOverlayMode = 'modal' | 'push';
|
|
16
|
+
export type TSinchSheetProps = {
|
|
17
|
+
/** Controls whether the sheet should be open */
|
|
18
|
+
open: boolean;
|
|
19
|
+
/** Sheet placement */
|
|
20
|
+
placement?: TSinchSheetPlacement;
|
|
21
|
+
/** Sheet overlay, set once when connecting the component */
|
|
22
|
+
overlay?: TSinchSheetOverlayMode;
|
|
23
|
+
readonly dialogRect?: TRect;
|
|
24
|
+
};
|
|
25
|
+
export type TSinchSheetEvents = {
|
|
26
|
+
/** close event handler */
|
|
27
|
+
'-close'?: (e: CustomEvent<TSinchSheetCloseDetail>) => void;
|
|
28
|
+
/** animation start event handler */
|
|
29
|
+
'-animation-start'?: (e: CustomEvent<TSinchSheetAnimationDetail>) => void;
|
|
30
|
+
/** animation end event handler */
|
|
31
|
+
'-animation-end'?: (e: CustomEvent<TSinchSheetAnimationDetail>) => void;
|
|
32
|
+
};
|
|
33
|
+
export type TSinchSheetStyle = {
|
|
34
|
+
'--sinch-comp-sheet-size-gap'?: string;
|
|
35
|
+
'--sinch-comp-sheet-size-max-horizontal'?: string;
|
|
36
|
+
'--sinch-comp-sheet-size-max-vertical'?: string;
|
|
37
|
+
'--sinch-comp-sheet-size-padding'?: string;
|
|
38
|
+
'--sinch-comp-sheet-animation-duration'?: string;
|
|
39
|
+
'--sinch-comp-sheet-animation-easing'?: string;
|
|
40
|
+
'--sinch-comp-sheet-size-backdrop-blur'?: string;
|
|
41
|
+
'--sinch-comp-sheet-color-backdrop-from'?: string;
|
|
42
|
+
'--sinch-comp-sheet-color-backdrop-to'?: string;
|
|
43
|
+
'--sinch-comp-sheet-color-background'?: string;
|
|
44
|
+
};
|
|
45
|
+
export type TSinchSheet = {
|
|
46
|
+
props: TSinchSheetProps;
|
|
47
|
+
events: TSinchSheetEvents;
|
|
48
|
+
style: TSinchSheetStyle;
|
|
49
|
+
};
|
|
50
|
+
export type TSinchSheetElement = NectaryComponentVanillaByType<TSinchSheet>;
|
|
51
|
+
export type TSinchSheetReact = NectaryComponentReactByType<TSinchSheet>;
|
|
52
|
+
declare global {
|
|
53
|
+
interface NectaryComponentMap {
|
|
54
|
+
'sinch-sheet': TSinchSheet;
|
|
55
|
+
}
|
|
56
|
+
interface HTMLElementTagNameMap {
|
|
57
|
+
'sinch-sheet': NectaryComponentVanilla<'sinch-sheet'>;
|
|
58
|
+
}
|
|
59
|
+
namespace JSX {
|
|
60
|
+
interface IntrinsicElements {
|
|
61
|
+
'sinch-sheet': NectaryComponentReact<'sinch-sheet'>;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
declare module 'react' {
|
|
66
|
+
namespace JSX {
|
|
67
|
+
interface IntrinsicElements extends globalThis.JSX.IntrinsicElements {
|
|
68
|
+
'sinch-sheet': NectaryComponentReact<'sinch-sheet'>;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
package/sheet/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../types';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import '../icon';
|
|
2
|
+
import '../title';
|
|
3
|
+
import { NectaryElement } from '../utils';
|
|
4
|
+
export * from './types';
|
|
5
|
+
export declare class SheetTitle extends NectaryElement {
|
|
6
|
+
#private;
|
|
7
|
+
constructor();
|
|
8
|
+
connectedCallback(): void;
|
|
9
|
+
disconnectedCallback(): void;
|
|
10
|
+
static get observedAttributes(): string[];
|
|
11
|
+
attributeChangedCallback(name: string, oldVal: string | null, newVal: string | null): void;
|
|
12
|
+
set title(caption: string);
|
|
13
|
+
get title(): string;
|
|
14
|
+
set description(description: string);
|
|
15
|
+
get description(): string;
|
|
16
|
+
get closeButtonRect(): import("../types").TRect;
|
|
17
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import "../icon/index.js";
|
|
2
|
+
import "../title/index.js";
|
|
3
|
+
import { isAttrEqual, updateAttribute, getAttribute } from "../utils/dom.js";
|
|
4
|
+
import { defineCustomElement, NectaryElement } from "../utils/element.js";
|
|
5
|
+
import { getRect } from "../utils/rect.js";
|
|
6
|
+
const templateHTML = '<style>:host{display:contents;--sinch-sheet-close-button-display:unset}#top{display:flex;flex-direction:row;align-items:center;margin-top:8px;gap:8px}#text{--sinch-global-color-text:var(--sinch-comp-sheet-color-title);--sinch-comp-title-font:var(--sinch-comp-sheet-font-title)}#description{--sinch-global-color-text:var(--sinch-comp-sheet-color-description);--sinch-comp-text-font:var(--sinch-comp-sheet-font-description)}#close{display:var(--sinch-sheet-close-button-display,initial);margin-left:auto}</style><div id="title"><div id="top"><slot id="icon" name="icon"></slot><sinch-title id="text" type="m" level="3"></sinch-title><sinch-button id="close" size="s" aria-label="Close"><sinch-icon icons-version="2" name="fa-xmark" id="icon-close" slot="icon"></sinch-icon></sinch-button></div><sinch-text id="description" type="m"></sinch-text></div>';
|
|
7
|
+
const template = document.createElement("template");
|
|
8
|
+
template.innerHTML = templateHTML;
|
|
9
|
+
class SheetTitle extends NectaryElement {
|
|
10
|
+
#$closeButton;
|
|
11
|
+
#$text;
|
|
12
|
+
#$description;
|
|
13
|
+
#controller = null;
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
const shadowRoot = this.attachShadow();
|
|
17
|
+
shadowRoot.appendChild(template.content.cloneNode(true));
|
|
18
|
+
this.#$closeButton = shadowRoot.querySelector("#close");
|
|
19
|
+
this.#$text = shadowRoot.querySelector("#text");
|
|
20
|
+
this.#$description = shadowRoot.querySelector("#description");
|
|
21
|
+
}
|
|
22
|
+
connectedCallback() {
|
|
23
|
+
super.connectedCallback();
|
|
24
|
+
this.#controller = new AbortController();
|
|
25
|
+
const options = {
|
|
26
|
+
signal: this.#controller.signal
|
|
27
|
+
};
|
|
28
|
+
this.#$closeButton.addEventListener("click", this.#onCloseClick, options);
|
|
29
|
+
}
|
|
30
|
+
disconnectedCallback() {
|
|
31
|
+
super.disconnectedCallback();
|
|
32
|
+
this.#controller.abort();
|
|
33
|
+
this.#controller = null;
|
|
34
|
+
}
|
|
35
|
+
static get observedAttributes() {
|
|
36
|
+
return ["title", "description", "close-aria-label"];
|
|
37
|
+
}
|
|
38
|
+
attributeChangedCallback(name, oldVal, newVal) {
|
|
39
|
+
if (isAttrEqual(oldVal, newVal)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
switch (name) {
|
|
43
|
+
case "title": {
|
|
44
|
+
updateAttribute(this.#$text, "text", newVal);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case "description": {
|
|
48
|
+
this.#$description.textContent = newVal;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
case "close-aria-label": {
|
|
52
|
+
updateAttribute(this.#$closeButton, "aria-label", newVal);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
set title(caption) {
|
|
58
|
+
updateAttribute(this, "title", caption);
|
|
59
|
+
}
|
|
60
|
+
get title() {
|
|
61
|
+
return getAttribute(this, "title", "");
|
|
62
|
+
}
|
|
63
|
+
set description(description) {
|
|
64
|
+
updateAttribute(this, "description", description);
|
|
65
|
+
}
|
|
66
|
+
get description() {
|
|
67
|
+
return getAttribute(this, "description", "");
|
|
68
|
+
}
|
|
69
|
+
get closeButtonRect() {
|
|
70
|
+
return getRect(this.#$closeButton);
|
|
71
|
+
}
|
|
72
|
+
#onCloseClick = () => {
|
|
73
|
+
this.dispatchEvent(new CustomEvent("-close", { cancelable: true, bubbles: true, detail: "close" }));
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
defineCustomElement("sinch-sheet-title", SheetTitle);
|
|
77
|
+
export {
|
|
78
|
+
SheetTitle
|
|
79
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { NectaryComponentReact, NectaryComponentReactByType, NectaryComponentVanilla, NectaryComponentVanillaByType, TRect } from '../types';
|
|
2
|
+
export type TSinchSheetTitleProps = {
|
|
3
|
+
/** The title of the sheet. */
|
|
4
|
+
title: string;
|
|
5
|
+
/** The description of the sheet. */
|
|
6
|
+
description?: string;
|
|
7
|
+
/** Close button label that is used for a11y */
|
|
8
|
+
'close-aria-label'?: string;
|
|
9
|
+
readonly closeButtonRect?: TRect;
|
|
10
|
+
};
|
|
11
|
+
export type TSinchSheetTitleEvents = {
|
|
12
|
+
/** close event handler */
|
|
13
|
+
'-close'?: (e: CustomEvent<'close'>) => void;
|
|
14
|
+
};
|
|
15
|
+
export type TSinchSheetTitleStyle = {
|
|
16
|
+
'--sinch-sheet-close-button-display'?: string;
|
|
17
|
+
'--sinch-comp-sheet-font-description'?: string;
|
|
18
|
+
'--sinch-comp-sheet-font-title'?: string;
|
|
19
|
+
'--sinch-comp-sheet-color-description'?: string;
|
|
20
|
+
'--sinch-comp-sheet-color-title'?: string;
|
|
21
|
+
'--sinch-global-size-icon'?: string;
|
|
22
|
+
'--sinch-global-color-icon'?: string;
|
|
23
|
+
'--sinch-global-color-text'?: string;
|
|
24
|
+
'--sinch-comp-title-font'?: string;
|
|
25
|
+
'--sinch-comp-text-font'?: string;
|
|
26
|
+
};
|
|
27
|
+
export type TSinchSheetTitle = {
|
|
28
|
+
props: TSinchSheetTitleProps;
|
|
29
|
+
events: TSinchSheetTitleEvents;
|
|
30
|
+
style: TSinchSheetTitleStyle;
|
|
31
|
+
};
|
|
32
|
+
export type TSinchSheetTitleElement = NectaryComponentVanillaByType<TSinchSheetTitle>;
|
|
33
|
+
export type TSinchSheetTitleReact = NectaryComponentReactByType<TSinchSheetTitle>;
|
|
34
|
+
declare global {
|
|
35
|
+
interface NectaryComponentMap {
|
|
36
|
+
'sinch-sheet-title': TSinchSheetTitle;
|
|
37
|
+
}
|
|
38
|
+
interface HTMLElementTagNameMap {
|
|
39
|
+
'sinch-sheet-title': NectaryComponentVanilla<'sinch-sheet-title'>;
|
|
40
|
+
}
|
|
41
|
+
namespace JSX {
|
|
42
|
+
interface IntrinsicElements {
|
|
43
|
+
'sinch-sheet-title': NectaryComponentReact<'sinch-sheet-title'>;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
declare module 'react' {
|
|
48
|
+
namespace JSX {
|
|
49
|
+
interface IntrinsicElements extends globalThis.JSX.IntrinsicElements {
|
|
50
|
+
'sinch-sheet-title': NectaryComponentReact<'sinch-sheet-title'>;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const BASE_COMPONENT_NAMES_LIST: readonly ["accordion-item", "accordion", "action-menu-option", "action-menu", "alert", "avatar", "badge", "button-group-item", "button-group", "button", "card-container", "card-v2-title", "card-v2", "checkbox", "chip", "code-tag", "color-menu-option", "color-menu", "color-swatch", "date-picker", "dialog", "emoji-picker", "emoji", "field", "file-drop", "file-picker", "file-status", "flag", "grid-item", "grid", "help-tooltip", "icon", "inline-alert", "input", "link", "list-item", "list", "pagination", "persistent-overlay", "pop", "popover", "progress-stepper-item", "progress-stepper", "progress", "radio-option", "radio", "rich-text", "rich-textarea", "rich-textarea-chip", "segment-collapse", "segmented-control-option", "segmented-control", "segmented-icon-control-option", "segmented-icon-control", "select-button", "select-menu-option", "select-menu", "skeleton-item", "skeleton", "spinner", "stop-events", "table-body", "table-cell", "table-head-cell", "table-head", "table-row", "table", "tabs-icon-option", "tabs-option", "tabs", "tag", "text", "textarea", "time-picker", "title", "toast-manager", "toast", "toggle", "tooltip"];
|
|
2
|
-
export declare const BASE_COMPONENT_NAMES: Set<"pop" | "button" | "dialog" | "input" | "link" | "progress" | "table" | "textarea" | "title" | "accordion-item" | "accordion" | "action-menu-option" | "action-menu" | "alert" | "avatar" | "badge" | "button-group-item" | "button-group" | "card-container" | "card-v2-title" | "card-v2" | "checkbox" | "chip" | "code-tag" | "color-menu-option" | "color-menu" | "color-swatch" | "date-picker" | "emoji-picker" | "emoji" | "field" | "file-drop" | "file-picker" | "file-status" | "flag" | "grid-item" | "grid" | "help-tooltip" | "icon" | "inline-alert" | "list-item" | "list" | "pagination" | "persistent-overlay" | "popover" | "progress-stepper-item" | "progress-stepper" | "radio-option" | "radio" | "rich-text" | "rich-textarea" | "rich-textarea-chip" | "segment-collapse" | "segmented-control-option" | "segmented-control" | "segmented-icon-control-option" | "segmented-icon-control" | "select-button" | "select-menu-option" | "select-menu" | "skeleton-item" | "skeleton" | "spinner" | "stop-events" | "table-body" | "table-cell" | "table-head-cell" | "table-head" | "table-row" | "tabs-icon-option" | "tabs-option" | "tabs" | "tag" | "text" | "time-picker" | "toast-manager" | "toast" | "toggle" | "tooltip">;
|
|
1
|
+
export declare const BASE_COMPONENT_NAMES_LIST: readonly ["accordion-item", "accordion", "action-menu-option", "action-menu", "alert", "avatar", "badge", "button-group-item", "button-group", "button", "card-container", "card-v2-title", "card-v2", "checkbox", "chip", "code-tag", "color-menu-option", "color-menu", "color-swatch", "date-picker", "dialog", "emoji-picker", "emoji", "field", "file-drop", "file-picker", "file-status", "flag", "grid-item", "grid", "help-tooltip", "icon", "inline-alert", "input", "link", "list-item", "list", "pagination", "persistent-overlay", "pop", "popover", "progress-stepper-item", "progress-stepper", "progress", "radio-option", "radio", "rich-text", "rich-textarea", "rich-textarea-chip", "segment-collapse", "segmented-control-option", "segmented-control", "segmented-icon-control-option", "segmented-icon-control", "select-button", "select-menu-option", "select-menu", "sheet", "sheet-title", "skeleton-item", "skeleton", "spinner", "stop-events", "table-body", "table-cell", "table-head-cell", "table-head", "table-row", "table", "tabs-icon-option", "tabs-option", "tabs", "tag", "text", "textarea", "time-picker", "title", "toast-manager", "toast", "toggle", "tooltip"];
|
|
2
|
+
export declare const BASE_COMPONENT_NAMES: Set<"pop" | "button" | "dialog" | "input" | "link" | "progress" | "table" | "textarea" | "title" | "accordion-item" | "accordion" | "action-menu-option" | "action-menu" | "alert" | "avatar" | "badge" | "button-group-item" | "button-group" | "card-container" | "card-v2-title" | "card-v2" | "checkbox" | "chip" | "code-tag" | "color-menu-option" | "color-menu" | "color-swatch" | "date-picker" | "emoji-picker" | "emoji" | "field" | "file-drop" | "file-picker" | "file-status" | "flag" | "grid-item" | "grid" | "help-tooltip" | "icon" | "inline-alert" | "list-item" | "list" | "pagination" | "persistent-overlay" | "popover" | "progress-stepper-item" | "progress-stepper" | "radio-option" | "radio" | "rich-text" | "rich-textarea" | "rich-textarea-chip" | "segment-collapse" | "segmented-control-option" | "segmented-control" | "segmented-icon-control-option" | "segmented-icon-control" | "select-button" | "select-menu-option" | "select-menu" | "sheet" | "sheet-title" | "skeleton-item" | "skeleton" | "spinner" | "stop-events" | "table-body" | "table-cell" | "table-head-cell" | "table-head" | "table-row" | "tabs-icon-option" | "tabs-option" | "tabs" | "tag" | "text" | "time-picker" | "toast-manager" | "toast" | "toggle" | "tooltip">;
|
|
3
3
|
export type ComponentName = `sinch-${typeof BASE_COMPONENT_NAMES_LIST[number]}`;
|
package/utils/component-names.js
CHANGED
package/utils/element.d.ts
CHANGED
|
File without changes
|
|
File without changes
|