@nectary/components 1.1.1 → 1.1.2
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/date-picker/index.js +3 -3
- package/dialog/index.js +3 -4
- package/package.json +1 -1
- package/pagination/index.js +4 -4
- package/pop/index.js +15 -4
- package/utils/event-target.d.ts +3 -0
- package/utils/event-target.js +17 -0
- package/utils/index.d.ts +1 -0
- package/utils/index.js +2 -1
package/date-picker/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import '../icon-button';
|
|
2
2
|
import '../icon';
|
|
3
3
|
import '../text';
|
|
4
|
-
import { defineCustomElement, getAttribute, getBooleanAttribute, getCssVars, getReactEventHandler, getRect, isAttrTrue, NectaryElement, packCsv, setClass, unpackCsv, updateAttribute, updateBooleanAttribute } from '../utils';
|
|
4
|
+
import { defineCustomElement, getAttribute, getBooleanAttribute, getCssVars, getReactEventHandler, getRect, getTargetAttribute, isAttrTrue, NectaryElement, packCsv, setClass, unpackCsv, updateAttribute, updateBooleanAttribute } from '../utils';
|
|
5
5
|
const templateHTML = '<style>:host{display:block;outline:0}#content{width:fit-content;box-sizing:border-box;padding:16px;display:flex;flex-direction:column;gap:8px}#month{display:flex;flex-direction:column;row-gap:8px}.week{display:flex;flex-direction:row;column-gap:8px}.week.empty{display:none}.day{all:initial;font:var(--sinch-font-text-xs);color:var(--sinch-color-text-default);text-align:center;border-radius:var(--sinch-shape-radius-s);width:24px;height:24px;line-height:22px;cursor:pointer;border:1px solid transparent;background-color:transparent;box-sizing:border-box;user-select:none}.day.today{border:1px solid var(--sinch-color-tropical-500)}.day:disabled{cursor:initial;color:var(--sinch-color-snow-700)}.day:focus-visible{outline:1px solid var(--sinch-color-border-focus);outline-offset:1px}.day.range{background-color:var(--sinch-color-tropical-100)}.day.selected{background-color:var(--sinch-color-tropical-500);color:var(--sinch-color-snow-100)}.day:hover:enabled:not(.selected){background-color:var(--sinch-color-tropical-200)}#week-day-names{display:flex;flex-direction:row;gap:8px;height:24px}.week-day-name{font:var(--sinch-font-text-xs);font-weight:var(--sinch-font-weight-emphasized);color:var(--sinch-color-text-default);text-align:center;width:24px;height:24px;line-height:24px;user-select:none;text-transform:uppercase}#content-header{display:flex;flex-direction:row;height:32px;align-items:center}#date{flex:1;text-align:center;text-transform:capitalize}#prev-year{margin-left:-4px}#next-year{margin-right:-4px}</style><div id="content"><div id="content-header"><sinch-icon-button id="prev-year" size="s"><sinch-icon id="icon-prev-year" slot="icon"></sinch-icon></sinch-icon-button><sinch-icon-button id="prev-month" size="s"><sinch-icon id="icon-prev-month" slot="icon"></sinch-icon></sinch-icon-button><sinch-text id="date" type="m" emphasized aria-live="polite"></sinch-text><sinch-icon-button id="next-month" size="s"><sinch-icon id="icon-next-month" slot="icon"></sinch-icon></sinch-icon-button><sinch-icon-button id="next-year" size="s"><sinch-icon id="icon-next-year" slot="icon"></sinch-icon></sinch-icon-button></div><div id="week-day-names"><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div><div class="week-day-name"></div></div><div id="month"><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div><div class="week"><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button><button class="day"></button></div></div></div>';
|
|
6
6
|
import { areDatesEqual, assertDate, assertLocale, assertMinMax, assertValue, canGoNextMonth, canGoNextYear, canGoPrevMonth, canGoPrevYear, clampMaxDate, clampMinDate, cloneDate, dateToIso, decMonth, decYear, getCalendarMonth, getDayNames, getMonthNames, incMonth, incYear, isDateBetween, isoToDate, isValidDate, sortDates, today } from './utils';
|
|
7
7
|
const template = document.createElement('template');
|
|
@@ -257,7 +257,7 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
|
|
|
257
257
|
};
|
|
258
258
|
#onDateMouseEnter = e => {
|
|
259
259
|
if (this.#date1 !== null && this.#date2 === null) {
|
|
260
|
-
const hoverDateIso = e
|
|
260
|
+
const hoverDateIso = getTargetAttribute(e, 'data-date');
|
|
261
261
|
if (hoverDateIso === null) {
|
|
262
262
|
return;
|
|
263
263
|
}
|
|
@@ -276,7 +276,7 @@ defineCustomElement('sinch-date-picker', class extends NectaryElement {
|
|
|
276
276
|
};
|
|
277
277
|
#onDateClick = e => {
|
|
278
278
|
e.stopPropagation();
|
|
279
|
-
const dateIso = e
|
|
279
|
+
const dateIso = getTargetAttribute(e, 'data-date');
|
|
280
280
|
if (dateIso === null || dateIso.length === 0) {
|
|
281
281
|
return;
|
|
282
282
|
}
|
package/dialog/index.js
CHANGED
|
@@ -3,8 +3,8 @@ import '../icon';
|
|
|
3
3
|
import '../stop-events';
|
|
4
4
|
import '../title';
|
|
5
5
|
import { disableScroll, enableScroll } from '../pop/utils';
|
|
6
|
-
import { defineCustomElement, getAttribute, getBooleanAttribute, getRect, isAttrTrue, updateAttribute, getReactEventHandler, NectaryElement, updateBooleanAttribute, getCssVar, setClass } from '../utils';
|
|
7
|
-
const templateHTML = '<style>:host{display:contents}#dialog{position:fixed;left:0;right:0;margin:auto;display:flex;flex-direction:column;padding:24px 0;max-width:var(--sinch-dialog-max-width,512px);max-height:unset;border-radius:var(--sinch-shape-radius-l);box-sizing:border-box;contain:content;background-color:var(--sinch-color-snow-100);color:var(--sinch-color-text-default);font:var(--sinch-font-text-m);border:none;box-shadow:var(--sinch-elevation-level-3)}#dialog:not([open]){display:none}dialog::backdrop{background-color:#000;opacity:.55}
|
|
6
|
+
import { defineCustomElement, getAttribute, getBooleanAttribute, getRect, isAttrTrue, updateAttribute, getReactEventHandler, NectaryElement, updateBooleanAttribute, getCssVar, setClass, isTargetEqual } from '../utils';
|
|
7
|
+
const templateHTML = '<style>:host{display:contents}#dialog{position:fixed;left:0;right:0;margin:auto;display:flex;flex-direction:column;padding:24px 0;max-width:var(--sinch-dialog-max-width,512px);max-height:unset;border-radius:var(--sinch-shape-radius-l);box-sizing:border-box;contain:content;background-color:var(--sinch-color-snow-100);color:var(--sinch-color-text-default);font:var(--sinch-font-text-m);border:none;box-shadow:var(--sinch-elevation-level-3)}#dialog:not([open]){display:none}dialog::backdrop{background-color:#000;opacity:.55}#header{display:flex;flex-direction:row;justify-content:space-between;align-items:flex-start;margin-bottom:12px;padding:0 24px}#caption{color:var(--sinch-color-text-default)}#content{min-height:0;overflow:auto;max-height:var(--sinch-dialog-max-height,50vh);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{transform:translate(4px,-4px)}</style><dialog id="dialog"><div id="header"><sinch-title id="caption" type="m" level="3" ellipsis></sinch-title><sinch-icon-button id="close" size="s" tabindex="0"><sinch-icon id="icon-close" slot="icon"></sinch-icon></sinch-icon-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>';
|
|
8
8
|
const template = document.createElement('template');
|
|
9
9
|
template.innerHTML = templateHTML;
|
|
10
10
|
defineCustomElement('sinch-dialog', class extends NectaryElement {
|
|
@@ -100,8 +100,7 @@ defineCustomElement('sinch-dialog', class extends NectaryElement {
|
|
|
100
100
|
this.#dispatchCloseEvent('close');
|
|
101
101
|
};
|
|
102
102
|
#onBackdropMouseDown = e => {
|
|
103
|
-
|
|
104
|
-
if (tgt === this.#$dialog) {
|
|
103
|
+
if (isTargetEqual(e, this.#$dialog)) {
|
|
105
104
|
const rect = this.dialogRect;
|
|
106
105
|
const isInside = e.x >= rect.x && e.x < rect.x + rect.width && e.y >= rect.y && e.y < rect.y + rect.height;
|
|
107
106
|
if (!isInside) {
|
package/package.json
CHANGED
package/pagination/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '../icon';
|
|
2
|
-
import { defineCustomElement, updateAttribute, getIntegerAttribute, setClass, NectaryElement, getRect, getReactEventHandler, getCssVars } from '../utils';
|
|
2
|
+
import { defineCustomElement, updateAttribute, getIntegerAttribute, setClass, NectaryElement, getRect, getReactEventHandler, getCssVars, isTargetEqual, getTargetIndexInParent } from '../utils';
|
|
3
3
|
const templateHTML = '<style>:host{display:inline-block;vertical-align:middle;outline:0}#wrapper{display:flex;justify-content:center;gap:8px;width:100%;box-sizing:border-box}button{all:initial;width:28px;height:28px;box-sizing:border-box;cursor:pointer;text-align:center;contain:strict;--sinch-color-icon:var(--sinch-color-stormy-500)}button:disabled{--sinch-color-icon:var(--sinch-color-stormy-100);cursor:initial}button>*{pointer-events:none}.page{border-radius:50%;font:var(--sinch-font-text-m);color:var(--sinch-color-stormy-500)}.page.dots>span{display:none}.page.dots::after{content:"..."}.page.active{font-weight:var(--sinch-font-weight-emphasized);background-color:var(--sinch-color-snow-600);pointer-events:none;cursor:initial}.page.hidden{display:none}#left,#right{display:flex;padding:2px;--sinch-icon-size:24px}</style><div id="wrapper"><button id="left"><sinch-icon id="icon-left"></sinch-icon></button><button class="page"><span>1</span></button><button class="page active"><span>2</span></button><button class="page"><span>3</span></button><button class="page"><span>4</span></button><button class="page"><span>5</span></button><button class="page dots"><span>6</span></button><button class="page"><span>20</span></button><button id="right"><sinch-icon id="icon-right"></sinch-icon></button></div>';
|
|
4
4
|
const NUM_BUTTONS = 7;
|
|
5
5
|
const MIDDLE_BTN_INDEX = Math.floor(NUM_BUTTONS / 2);
|
|
@@ -99,13 +99,13 @@ defineCustomElement('sinch-pagination', class extends NectaryElement {
|
|
|
99
99
|
e.stopPropagation();
|
|
100
100
|
const value = getIntegerAttribute(this, 'value', 0) - 1;
|
|
101
101
|
const max = Math.max(0, getIntegerAttribute(this, 'max', 0));
|
|
102
|
-
if (e
|
|
102
|
+
if (isTargetEqual(e, this.#$left)) {
|
|
103
103
|
return this.#dispatchChangeEvent(value - 1);
|
|
104
104
|
}
|
|
105
|
-
if (e
|
|
105
|
+
if (isTargetEqual(e, this.#$right)) {
|
|
106
106
|
return this.#dispatchChangeEvent(value + 1);
|
|
107
107
|
}
|
|
108
|
-
const btnIndex =
|
|
108
|
+
const btnIndex = getTargetIndexInParent(e, this.#$wrapper) - 1;
|
|
109
109
|
if (btnIndex >= 0 && btnIndex < this.#$buttons.length) {
|
|
110
110
|
if (btnIndex === FIRST_BTN_INDEX) {
|
|
111
111
|
return this.#dispatchChangeEvent(0);
|
package/pop/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineCustomElement, getBooleanAttribute, getLiteralAttribute, getRect, isAttrTrue, updateLiteralAttribute, getReactEventHandler, updateBooleanAttribute, NectaryElement, throttleAnimationFrame, isElementFocused, updateIntegerAttribute, getIntegerAttribute, getFirstFocusableElement, getFirstSlotElement, Context, subscribeContext } from '../utils';
|
|
2
|
-
const templateHTML = '<style>:host{display:contents;position:relative}dialog{position:fixed;left:0;top:0;margin:0;outline:0;padding:0;border:none;box-sizing:border-box;max-width:unset;max-height:unset;z-index:1;background:0 0;overflow:visible}dialog:not([open]){display:none}dialog::backdrop{background-color:transparent}
|
|
1
|
+
import { defineCustomElement, getBooleanAttribute, getLiteralAttribute, getRect, isAttrTrue, updateLiteralAttribute, getReactEventHandler, updateBooleanAttribute, NectaryElement, throttleAnimationFrame, isElementFocused, updateIntegerAttribute, getIntegerAttribute, getFirstFocusableElement, getFirstSlotElement, Context, subscribeContext, isTargetEqual } from '../utils';
|
|
2
|
+
const templateHTML = '<style>:host{display:contents;position:relative}dialog{position:fixed;left:0;top:0;margin:0;outline:0;padding:0;border:none;box-sizing:border-box;max-width:unset;max-height:unset;z-index:1;background:0 0;overflow:visible}dialog:not([open]){display:none}dialog::backdrop{background-color:transparent}#content{position:relative;z-index:1}#target-open{display:flex;flex-direction:column;position:absolute;left:0;top:0}#focus{display:none;position:absolute;width:0;height:0}</style><slot id="target" name="target" aria-haspopup="dialog" aria-expanded="false"></slot><div id="focus" tabindex="-1"></div><dialog id="dialog"><div id="content"><slot name="content"></slot></div><div id="target-open"><slot name="target-open"></slot></div></dialog>';
|
|
3
3
|
import { assertOrientation, disableScroll, enableScroll, orientationValues } from './utils';
|
|
4
4
|
const template = document.createElement('template');
|
|
5
5
|
template.innerHTML = templateHTML;
|
|
@@ -195,6 +195,11 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
|
|
|
195
195
|
}
|
|
196
196
|
disableScroll();
|
|
197
197
|
window.addEventListener('resize', this.#onResize);
|
|
198
|
+
requestAnimationFrame(() => {
|
|
199
|
+
if (this.#isOpen()) {
|
|
200
|
+
this.#$contentSlot.addEventListener('slotchange', this.#onContentSlotChange);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
198
203
|
this.#dispatchContentVisibility(true);
|
|
199
204
|
}
|
|
200
205
|
#onCollapse() {
|
|
@@ -244,6 +249,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
|
|
|
244
249
|
enableScroll();
|
|
245
250
|
this.#resizeThrottle.cancel();
|
|
246
251
|
window.removeEventListener('resize', this.#onResize);
|
|
252
|
+
this.#$contentSlot.removeEventListener('slotchange', this.#onContentSlotChange);
|
|
247
253
|
}
|
|
248
254
|
#isOpen() {
|
|
249
255
|
return getBooleanAttribute(this.#$dialog, 'open');
|
|
@@ -299,8 +305,7 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
|
|
|
299
305
|
}
|
|
300
306
|
};
|
|
301
307
|
#onBackdropMouseDown = e => {
|
|
302
|
-
|
|
303
|
-
if (tgt === this.#$dialog) {
|
|
308
|
+
if (isTargetEqual(e, this.#$dialog)) {
|
|
304
309
|
const rect = this.popoverRect;
|
|
305
310
|
const isInside = e.x >= rect.x && e.x < rect.x + rect.width && e.y >= rect.y && e.y < rect.y + rect.height;
|
|
306
311
|
if (!isInside) {
|
|
@@ -347,4 +352,10 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
|
|
|
347
352
|
this.#dispatchCloseEvent();
|
|
348
353
|
}
|
|
349
354
|
};
|
|
355
|
+
#onContentSlotChange = e => {
|
|
356
|
+
e.stopPropagation();
|
|
357
|
+
if (this.#isOpen()) {
|
|
358
|
+
this.#updateOrientation();
|
|
359
|
+
}
|
|
360
|
+
};
|
|
350
361
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const isTargetEqual = (e, $elem) => {
|
|
2
|
+
return e.target === $elem || e.originalTarget === $elem;
|
|
3
|
+
};
|
|
4
|
+
export const getTargetAttribute = (e, attr) => {
|
|
5
|
+
return e.target.getAttribute(attr) ?? e.originalTarget?.getAttribute(attr) ?? null;
|
|
6
|
+
};
|
|
7
|
+
export const getTargetIndexInParent = (e, parent) => {
|
|
8
|
+
const indexOf = Array.prototype.indexOf.call(parent.children, e.target);
|
|
9
|
+
if (indexOf >= 0) {
|
|
10
|
+
return indexOf;
|
|
11
|
+
}
|
|
12
|
+
const origTgt = e.originalTarget;
|
|
13
|
+
if (origTgt != null) {
|
|
14
|
+
return Array.prototype.indexOf.call(parent.children, origTgt);
|
|
15
|
+
}
|
|
16
|
+
return -1;
|
|
17
|
+
};
|
package/utils/index.d.ts
CHANGED
package/utils/index.js
CHANGED