luxen-ui 0.2.1 → 0.4.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/cdn/chunks/decorate.js +1 -1
- package/cdn/chunks/decorate.js.map +1 -1
- package/cdn/custom-elements.json +185 -112
- package/cdn/elements/avatar/avatar.js +1 -1
- package/cdn/elements/avatar/avatar.js.map +1 -1
- package/cdn/elements/badge/badge.js +1 -1
- package/cdn/elements/carousel/carousel.d.ts +9 -1
- package/cdn/elements/carousel/carousel.d.ts.map +1 -1
- package/cdn/elements/carousel/carousel.js +21 -20
- package/cdn/elements/carousel/carousel.js.map +1 -1
- package/cdn/elements/dialog/dialog.js +1 -1
- package/cdn/elements/dialog/dialog.styles.js +1 -1
- package/cdn/elements/dialog/dialog.styles.js.map +1 -1
- package/cdn/elements/divider/divider.js +1 -1
- package/cdn/elements/drawer/drawer.js +1 -1
- package/cdn/elements/dropdown/dropdown.d.ts +5 -2
- package/cdn/elements/dropdown/dropdown.d.ts.map +1 -1
- package/cdn/elements/dropdown/dropdown.js +6 -3
- package/cdn/elements/dropdown/dropdown.js.map +1 -1
- package/cdn/elements/dropdown-item/dropdown-item.js +1 -1
- package/cdn/elements/dropdown-item/dropdown-item.js.map +1 -1
- package/cdn/elements/icon/icon.js +1 -1
- package/cdn/elements/input-otp/input-otp.d.ts +8 -2
- package/cdn/elements/input-otp/input-otp.d.ts.map +1 -1
- package/cdn/elements/input-otp/input-otp.js +1 -1
- package/cdn/elements/input-otp/input-otp.js.map +1 -1
- package/cdn/elements/input-stepper/input-stepper.js +1 -1
- package/cdn/elements/popover/popover.js +1 -1
- package/cdn/elements/popover/popover.js.map +1 -1
- package/cdn/elements/rating/rating.js +1 -1
- package/cdn/elements/tabs/tabs.js +1 -1
- package/cdn/elements/toast/toast.js +1 -1
- package/cdn/elements/toast/toast.js.map +1 -1
- package/cdn/elements/tooltip/tooltip.d.ts +3 -3
- package/cdn/elements/tooltip/tooltip.js +1 -1
- package/cdn/elements/tooltip/tooltip.js.map +1 -1
- package/cdn/elements/tree/tree.js +1 -1
- package/cdn/elements/tree/tree.js.map +1 -1
- package/cdn/elements/tree-item/tree-item.js +1 -1
- package/cdn/elements/tree-item/tree-item.js.map +1 -1
- package/cdn/shared/luxen-form-associated-element.js +1 -1
- package/cdn/styles/elements/divider.css +7 -0
- package/cdn/styles/elements/input-otp.css +63 -29
- package/cdn/styles/elements/select.css +3 -3
- package/cdn/styles/index.css +10 -0
- package/dist/css/elements/divider.css +7 -0
- package/dist/css/elements/input-otp.css +63 -29
- package/dist/css/elements/select.css +3 -3
- package/dist/css/index.css +10 -0
- package/dist/custom-elements.json +185 -112
- package/dist/elements/avatar/avatar.css +13 -7
- package/dist/elements/carousel/carousel.css +7 -0
- package/dist/elements/carousel/carousel.d.ts +9 -1
- package/dist/elements/carousel/carousel.d.ts.map +1 -1
- package/dist/elements/carousel/carousel.js +71 -37
- package/dist/elements/dialog/dialog.css +10 -0
- package/dist/elements/dropdown/dropdown.css +14 -3
- package/dist/elements/dropdown/dropdown.d.ts +5 -2
- package/dist/elements/dropdown/dropdown.d.ts.map +1 -1
- package/dist/elements/dropdown/dropdown.js +19 -7
- package/dist/elements/input-otp/input-otp.d.ts +8 -2
- package/dist/elements/input-otp/input-otp.d.ts.map +1 -1
- package/dist/elements/input-otp/input-otp.js +14 -5
- package/dist/elements/tooltip/tooltip.css +15 -7
- package/dist/elements/tooltip/tooltip.d.ts +3 -3
- package/dist/elements/tooltip/tooltip.js +3 -3
- package/dist/skills/luxen-ui/references/dialog.md +76 -0
- package/dist/skills/luxen-ui/references/drawer.md +8 -0
- package/dist/skills/luxen-ui/references/select.md +1 -1
- package/package.json +1 -1
|
@@ -93,7 +93,9 @@ img {
|
|
|
93
93
|
border: none;
|
|
94
94
|
border-radius: calc(var(--_size) * 0.2);
|
|
95
95
|
background-color: var(--color, var(--l-color-bg-fill-neutral-soft));
|
|
96
|
-
color: oklch(
|
|
96
|
+
color: oklch(
|
|
97
|
+
from var(--color) calc(0.65 - 0.2 * sign(l - 0.5)) calc(c * (1.75 + 0.25 * sign(l - 0.5))) h
|
|
98
|
+
);
|
|
97
99
|
font-size: var(--_font-size);
|
|
98
100
|
font-weight: 500;
|
|
99
101
|
line-height: 1;
|
|
@@ -102,6 +104,16 @@ img {
|
|
|
102
104
|
cursor: inherit;
|
|
103
105
|
}
|
|
104
106
|
|
|
107
|
+
@supports (color: contrast-color(red vs black, white)) {
|
|
108
|
+
.base {
|
|
109
|
+
color: contrast-color(
|
|
110
|
+
var(--color, var(--l-color-bg-fill-neutral-soft)) vs
|
|
111
|
+
oklch(from var(--color) 0.45 calc(c * 2) h),
|
|
112
|
+
oklch(from var(--color) 0.85 calc(c * 1.5) h) to AA
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
105
117
|
button.base {
|
|
106
118
|
cursor: pointer;
|
|
107
119
|
}
|
|
@@ -115,12 +127,6 @@ button.base:hover {
|
|
|
115
127
|
box-shadow: inset 0 0 0 1.5px var(--l-color-border-interactive);
|
|
116
128
|
}
|
|
117
129
|
|
|
118
|
-
@media (prefers-color-scheme: dark) {
|
|
119
|
-
.base {
|
|
120
|
-
color: oklch(from var(--color) 0.85 calc(c * 1.5) h);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
130
|
@container style(--appearance: circle) {
|
|
125
131
|
.base {
|
|
126
132
|
border-radius: 50%;
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
--dot-color: #9ca3af;
|
|
17
17
|
--dot-color-active: #111827;
|
|
18
18
|
--dot-margin: 0.5rem 0;
|
|
19
|
+
--dot-edge-scale: 0.5;
|
|
19
20
|
|
|
20
21
|
--scrollbar-color: #d1d5db transparent;
|
|
21
22
|
|
|
@@ -180,6 +181,12 @@
|
|
|
180
181
|
padding-block: 0.5rem;
|
|
181
182
|
border: 0;
|
|
182
183
|
cursor: pointer;
|
|
184
|
+
transition: transform 180ms ease;
|
|
185
|
+
transform-origin: center;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.dot[data-edge] {
|
|
189
|
+
transform: scale(var(--dot-edge-scale));
|
|
183
190
|
}
|
|
184
191
|
|
|
185
192
|
.dot--bar i {
|
|
@@ -33,6 +33,7 @@ import { LuxenElement } from '../../shared/luxen-element';
|
|
|
33
33
|
* @cssproperty --dot-color - Color of inactive dots.
|
|
34
34
|
* @cssproperty --dot-color-active - Color of active dot.
|
|
35
35
|
* @cssproperty --dot-margin - Margin around dots container.
|
|
36
|
+
* @cssproperty --dot-edge-scale - Scale factor applied to edge dots that signal more dots exist beyond the visible window (default `0.5`).
|
|
36
37
|
*/
|
|
37
38
|
export declare class LuxenCarousel extends LuxenElement {
|
|
38
39
|
static styles: CSSResultGroup;
|
|
@@ -110,12 +111,18 @@ export declare class LuxenCarousel extends LuxenElement {
|
|
|
110
111
|
accessor withScrollbar: boolean;
|
|
111
112
|
accessor withFullscreen: boolean;
|
|
112
113
|
accessor dotAppearance: 'circle' | 'bar';
|
|
114
|
+
/**
|
|
115
|
+
* Maximum number of dots rendered at once. When the snap count exceeds this,
|
|
116
|
+
* a sliding window keeps the active dot in view and shrinks the edge dot(s)
|
|
117
|
+
* on the side where dots are hidden. `0` (default) renders all dots.
|
|
118
|
+
*/
|
|
119
|
+
accessor maxVisibleDots: number;
|
|
113
120
|
accessor scrollButtonsPosition: 'inside' | 'outside';
|
|
121
|
+
private accessor _selectedSnap;
|
|
114
122
|
scrollButtons: HTMLElement;
|
|
115
123
|
previousBtn: HTMLButtonElement;
|
|
116
124
|
nextBtn: HTMLButtonElement;
|
|
117
125
|
container: HTMLSlotElement;
|
|
118
|
-
dotNodes: HTMLButtonElement[];
|
|
119
126
|
constructor();
|
|
120
127
|
connectedCallback(): void;
|
|
121
128
|
disconnectedCallback(): void;
|
|
@@ -142,6 +149,7 @@ export declare class LuxenCarousel extends LuxenElement {
|
|
|
142
149
|
isActive(): boolean;
|
|
143
150
|
renderFullscreenButton(): import("lit").TemplateResult<1>;
|
|
144
151
|
renderNextPreviousButtons(): import("lit").TemplateResult<1>;
|
|
152
|
+
private renderDots;
|
|
145
153
|
render(): import("lit").TemplateResult<1>;
|
|
146
154
|
}
|
|
147
155
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["../../../src/html/elements/carousel/carousel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAG1E,KAAK,cAAc,GAAG,GAAG,GAAG,GAAG,CAAC;AAChC,KAAK,mBAAmB,GACpB,OAAO,GACP,QAAQ,GACR,KAAK,GACL,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;AACpE,KAAK,wBAAwB,GAAG,MAAM,GAAG,MAAM,CAAC;AAChD,KAAK,uBAAuB,GAAG,WAAW,GAAG,WAAW,GAAG,KAAK,CAAC;AAEjE,OAAO,
|
|
1
|
+
{"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["../../../src/html/elements/carousel/carousel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAG1E,KAAK,cAAc,GAAG,GAAG,GAAG,GAAG,CAAC;AAChC,KAAK,mBAAmB,GACpB,OAAO,GACP,QAAQ,GACR,KAAK,GACL,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;AACpE,KAAK,wBAAwB,GAAG,MAAM,GAAG,MAAM,CAAC;AAChD,KAAK,uBAAuB,GAAG,WAAW,GAAG,WAAW,GAAG,KAAK,CAAC;AAEjE,OAAO,EAA4B,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAGzF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAM1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAgB,MAAM,EAAE,cAAc,CAAwB;IAE9D,KAAK,EAAG,iBAAiB,CAAC;IAE1B;;OAEG;IAEH,QAAQ,CAAC,QAAQ,SAAK;IAEtB;;;;OAIG;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC;IAE9B;;;;OAIG;IAEH,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAO;IAEpC;;;;OAIG;IAEH,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAW;IAE9C;;OAEG;IAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAM;IAE/B;;;;OAIG;IAEH,QAAQ,CAAC,IAAI,UAAS;IAEtB;;;;OAIG;IAEH,QAAQ,CAAC,QAAQ,UAAS;IAE1B;;;;OAIG;IAEH,QAAQ,CAAC,QAAQ,SAAM;IAEvB;;;;OAIG;IAEH,QAAQ,CAAC,SAAS,UAAS;IAE3B;;;;OAIG;IAEH,QAAQ,CAAC,cAAc,EAAE,wBAAwB,CAAK;IAEtD;;;;OAIG;IAEH,QAAQ,CAAC,UAAU,SAAK;IAExB;;;;OAIG;IAEH,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAe;IAG9D,QAAQ,CAAC,MAAM,UAAS;IAGxB,QAAQ,CAAC,QAAQ,UAAS;IAG1B,QAAQ,CAAC,aAAa,UAAS;IAG/B,QAAQ,CAAC,cAAc,UAAS;IAGhC,QAAQ,CAAC,aAAa,EAAE,QAAQ,GAAG,KAAK,CAAS;IAEjD;;;;OAIG;IAEH,QAAQ,CAAC,cAAc,SAAK;IAG5B,QAAQ,CAAC,qBAAqB,EAAE,QAAQ,GAAG,SAAS,CAAY;IAEvD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAK;IAElB,aAAa,EAAG,WAAW,CAAC;IAC3B,WAAW,EAAG,iBAAiB,CAAC;IACpC,OAAO,EAAG,iBAAiB,CAAC;IAC9B,SAAS,EAAG,eAAe,CAAC;;IAcxC,iBAAiB,IAAI,IAAI;IAKzB,oBAAoB;cAOV,YAAY,IAAI,IAAI;IAIvC,SAAS,CAAC,WAAW;IAWrB,SAAS,CAAC,cAAc;IAMxB,SAAS,CAAC,MAAM;IAIhB,SAAS,CAAC,QAAQ;IAKlB,SAAS,CAAC,QAAQ;IAOlB,SAAS,CAAC,QAAQ;IAIlB,SAAS,CAAC,oBAAoB;IAK9B,SAAS,CAAC,oBAAoB;IAK9B,SAAS,CAAC,gBAAgB;IAUX,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,IAAI,CAAC;IAM9D,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,cAAc;IAKtB,OAAO,IAAI,gBAAgB;IA0B3B,IAAI;IAIJ,QAAQ;IAIR,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAIvC,UAAU;IAIV,YAAY;IAIZ,QAAQ;IAIR,sBAAsB;IAoBtB,yBAAyB;IAyCzB,OAAO,CAAC,UAAU;IAgDT,MAAM;CAkBhB"}
|
|
@@ -15,11 +15,11 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
15
15
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
16
16
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
17
17
|
};
|
|
18
|
-
var _LuxenCarousel_autoplay_accessor_storage, _LuxenCarousel_autoplayOptions_accessor_storage, _LuxenCarousel_axis_accessor_storage, _LuxenCarousel_align_accessor_storage, _LuxenCarousel_breakpoints_accessor_storage, _LuxenCarousel_loop_accessor_storage, _LuxenCarousel_dragFree_accessor_storage, _LuxenCarousel_duration_accessor_storage, _LuxenCarousel_skipSnaps_accessor_storage, _LuxenCarousel_slidesToScroll_accessor_storage, _LuxenCarousel_startIndex_accessor_storage, _LuxenCarousel_containScroll_accessor_storage, _LuxenCarousel_single_accessor_storage, _LuxenCarousel_withDots_accessor_storage, _LuxenCarousel_withScrollbar_accessor_storage, _LuxenCarousel_withFullscreen_accessor_storage, _LuxenCarousel_dotAppearance_accessor_storage, _LuxenCarousel_scrollButtonsPosition_accessor_storage;
|
|
18
|
+
var _LuxenCarousel_autoplay_accessor_storage, _LuxenCarousel_autoplayOptions_accessor_storage, _LuxenCarousel_axis_accessor_storage, _LuxenCarousel_align_accessor_storage, _LuxenCarousel_breakpoints_accessor_storage, _LuxenCarousel_loop_accessor_storage, _LuxenCarousel_dragFree_accessor_storage, _LuxenCarousel_duration_accessor_storage, _LuxenCarousel_skipSnaps_accessor_storage, _LuxenCarousel_slidesToScroll_accessor_storage, _LuxenCarousel_startIndex_accessor_storage, _LuxenCarousel_containScroll_accessor_storage, _LuxenCarousel_single_accessor_storage, _LuxenCarousel_withDots_accessor_storage, _LuxenCarousel_withScrollbar_accessor_storage, _LuxenCarousel_withFullscreen_accessor_storage, _LuxenCarousel_dotAppearance_accessor_storage, _LuxenCarousel_maxVisibleDots_accessor_storage, _LuxenCarousel_scrollButtonsPosition_accessor_storage, _LuxenCarousel__selectedSnap_accessor_storage;
|
|
19
19
|
import EmblaCarousel from 'embla-carousel';
|
|
20
20
|
import Autoplay from 'embla-carousel-autoplay';
|
|
21
|
-
import { html, unsafeCSS } from 'lit';
|
|
22
|
-
import { property, query,
|
|
21
|
+
import { html, nothing, unsafeCSS } from 'lit';
|
|
22
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
23
23
|
import { map } from 'lit/directives/map.js';
|
|
24
24
|
import { LuxenElement } from '../../shared/luxen-element';
|
|
25
25
|
import hostStyles from '../../shared/styles/host.styles';
|
|
@@ -53,6 +53,7 @@ const styles = unsafeCSS(rawStyles);
|
|
|
53
53
|
* @cssproperty --dot-color - Color of inactive dots.
|
|
54
54
|
* @cssproperty --dot-color-active - Color of active dot.
|
|
55
55
|
* @cssproperty --dot-margin - Margin around dots container.
|
|
56
|
+
* @cssproperty --dot-edge-scale - Scale factor applied to edge dots that signal more dots exist beyond the visible window (default `0.5`).
|
|
56
57
|
*/
|
|
57
58
|
export class LuxenCarousel extends LuxenElement {
|
|
58
59
|
/**
|
|
@@ -145,8 +146,17 @@ export class LuxenCarousel extends LuxenElement {
|
|
|
145
146
|
set withFullscreen(value) { __classPrivateFieldSet(this, _LuxenCarousel_withFullscreen_accessor_storage, value, "f"); }
|
|
146
147
|
get dotAppearance() { return __classPrivateFieldGet(this, _LuxenCarousel_dotAppearance_accessor_storage, "f"); }
|
|
147
148
|
set dotAppearance(value) { __classPrivateFieldSet(this, _LuxenCarousel_dotAppearance_accessor_storage, value, "f"); }
|
|
149
|
+
/**
|
|
150
|
+
* Maximum number of dots rendered at once. When the snap count exceeds this,
|
|
151
|
+
* a sliding window keeps the active dot in view and shrinks the edge dot(s)
|
|
152
|
+
* on the side where dots are hidden. `0` (default) renders all dots.
|
|
153
|
+
*/
|
|
154
|
+
get maxVisibleDots() { return __classPrivateFieldGet(this, _LuxenCarousel_maxVisibleDots_accessor_storage, "f"); }
|
|
155
|
+
set maxVisibleDots(value) { __classPrivateFieldSet(this, _LuxenCarousel_maxVisibleDots_accessor_storage, value, "f"); }
|
|
148
156
|
get scrollButtonsPosition() { return __classPrivateFieldGet(this, _LuxenCarousel_scrollButtonsPosition_accessor_storage, "f"); }
|
|
149
157
|
set scrollButtonsPosition(value) { __classPrivateFieldSet(this, _LuxenCarousel_scrollButtonsPosition_accessor_storage, value, "f"); }
|
|
158
|
+
get _selectedSnap() { return __classPrivateFieldGet(this, _LuxenCarousel__selectedSnap_accessor_storage, "f"); }
|
|
159
|
+
set _selectedSnap(value) { __classPrivateFieldSet(this, _LuxenCarousel__selectedSnap_accessor_storage, value, "f"); }
|
|
150
160
|
constructor() {
|
|
151
161
|
super();
|
|
152
162
|
_LuxenCarousel_autoplay_accessor_storage.set(this, 0);
|
|
@@ -166,7 +176,9 @@ export class LuxenCarousel extends LuxenElement {
|
|
|
166
176
|
_LuxenCarousel_withScrollbar_accessor_storage.set(this, false);
|
|
167
177
|
_LuxenCarousel_withFullscreen_accessor_storage.set(this, false);
|
|
168
178
|
_LuxenCarousel_dotAppearance_accessor_storage.set(this, 'bar');
|
|
179
|
+
_LuxenCarousel_maxVisibleDots_accessor_storage.set(this, 0);
|
|
169
180
|
_LuxenCarousel_scrollButtonsPosition_accessor_storage.set(this, 'inside');
|
|
181
|
+
_LuxenCarousel__selectedSnap_accessor_storage.set(this, 0);
|
|
170
182
|
this.next = this.next.bind(this);
|
|
171
183
|
this.previous = this.previous.bind(this);
|
|
172
184
|
this.onInit = this.onInit.bind(this);
|
|
@@ -233,14 +245,7 @@ export class LuxenCarousel extends LuxenElement {
|
|
|
233
245
|
this.previousBtn.toggleAttribute('disabled', !this.embla.canScrollPrev());
|
|
234
246
|
this.nextBtn.toggleAttribute('disabled', !this.embla.canScrollNext());
|
|
235
247
|
this.scrollButtons.classList.toggle('scroll-buttons--disabled', !canScroll);
|
|
236
|
-
|
|
237
|
-
const previous = this.embla.previousScrollSnap();
|
|
238
|
-
const selected = this.embla.selectedScrollSnap();
|
|
239
|
-
this.dotNodes[previous]?.classList.remove('dot--selected');
|
|
240
|
-
this.dotNodes[previous]?.removeAttribute('aria-selected');
|
|
241
|
-
this.dotNodes[selected]?.classList.add('dot--selected');
|
|
242
|
-
this.dotNodes[selected]?.setAttribute('aria-selected', 'true');
|
|
243
|
-
}
|
|
248
|
+
this._selectedSnap = this.embla.selectedScrollSnap();
|
|
244
249
|
}
|
|
245
250
|
async updated(changedProperties) {
|
|
246
251
|
if (changedProperties.has('autoplay') && this.autoplay) {
|
|
@@ -360,6 +365,53 @@ export class LuxenCarousel extends LuxenElement {
|
|
|
360
365
|
</button>
|
|
361
366
|
</div>`;
|
|
362
367
|
}
|
|
368
|
+
renderDots() {
|
|
369
|
+
if (!this.embla)
|
|
370
|
+
return nothing;
|
|
371
|
+
const snaps = this.embla.scrollSnapList();
|
|
372
|
+
const total = snaps.length;
|
|
373
|
+
if (total === 0)
|
|
374
|
+
return nothing;
|
|
375
|
+
const selected = this._selectedSnap;
|
|
376
|
+
const max = this.maxVisibleDots;
|
|
377
|
+
let start = 0;
|
|
378
|
+
let end = total;
|
|
379
|
+
if (max > 0 && max < total) {
|
|
380
|
+
const half = Math.floor((max - 1) / 2);
|
|
381
|
+
start = Math.max(0, selected - half);
|
|
382
|
+
end = Math.min(total, start + max);
|
|
383
|
+
if (end - start < max)
|
|
384
|
+
start = Math.max(0, end - max);
|
|
385
|
+
}
|
|
386
|
+
const edgeStart = start > 0;
|
|
387
|
+
const edgeEnd = end < total;
|
|
388
|
+
return html `<div
|
|
389
|
+
class="dots"
|
|
390
|
+
part="dots"
|
|
391
|
+
role="tablist"
|
|
392
|
+
>
|
|
393
|
+
${map(snaps.slice(start, end), (_, i) => {
|
|
394
|
+
const index = start + i;
|
|
395
|
+
const isFirst = i === 0;
|
|
396
|
+
const isLast = i === end - start - 1;
|
|
397
|
+
const isSelected = index === selected;
|
|
398
|
+
const isEdge = !isSelected && ((isFirst && edgeStart) || (isLast && edgeEnd));
|
|
399
|
+
return html `<button
|
|
400
|
+
part="button-dot"
|
|
401
|
+
type="button"
|
|
402
|
+
role="tab"
|
|
403
|
+
class="dot dot--${this.dotAppearance} ${isSelected ? 'dot--selected' : ''}"
|
|
404
|
+
aria-label="Go to slide ${index + 1}"
|
|
405
|
+
aria-selected=${isSelected ? 'true' : nothing}
|
|
406
|
+
data-index="${index}"
|
|
407
|
+
data-edge=${isEdge ? '' : nothing}
|
|
408
|
+
@click=${this.handleDotClick}
|
|
409
|
+
>
|
|
410
|
+
<i></i>
|
|
411
|
+
</button>`;
|
|
412
|
+
})}
|
|
413
|
+
</div>`;
|
|
414
|
+
}
|
|
363
415
|
render() {
|
|
364
416
|
return html `
|
|
365
417
|
<div class="wrapper ${this.isActive() ? '' : 'inactive'}">
|
|
@@ -374,33 +426,12 @@ export class LuxenCarousel extends LuxenElement {
|
|
|
374
426
|
></slot>
|
|
375
427
|
</div>
|
|
376
428
|
${this.withFullscreen ? this.renderFullscreenButton() : ''}
|
|
377
|
-
${this.renderNextPreviousButtons()}
|
|
378
|
-
${this.withDots
|
|
379
|
-
? html `<div
|
|
380
|
-
class="dots"
|
|
381
|
-
part="dots"
|
|
382
|
-
role="tablist"
|
|
383
|
-
>
|
|
384
|
-
${map(this.embla.scrollSnapList(), (_, index) => {
|
|
385
|
-
return html `<button
|
|
386
|
-
part="button-dot"
|
|
387
|
-
type="button"
|
|
388
|
-
role="tab"
|
|
389
|
-
class="dot dot--${this.dotAppearance}"
|
|
390
|
-
aria-label="Go to slide ${index + 1}"
|
|
391
|
-
data-index="${index}"
|
|
392
|
-
@click=${this.handleDotClick}
|
|
393
|
-
>
|
|
394
|
-
<i></i>
|
|
395
|
-
</button>`;
|
|
396
|
-
})}
|
|
397
|
-
</div> `
|
|
398
|
-
: ''}
|
|
429
|
+
${this.renderNextPreviousButtons()} ${this.withDots ? this.renderDots() : ''}
|
|
399
430
|
</div>
|
|
400
431
|
`;
|
|
401
432
|
}
|
|
402
433
|
}
|
|
403
|
-
_LuxenCarousel_autoplay_accessor_storage = new WeakMap(), _LuxenCarousel_autoplayOptions_accessor_storage = new WeakMap(), _LuxenCarousel_axis_accessor_storage = new WeakMap(), _LuxenCarousel_align_accessor_storage = new WeakMap(), _LuxenCarousel_breakpoints_accessor_storage = new WeakMap(), _LuxenCarousel_loop_accessor_storage = new WeakMap(), _LuxenCarousel_dragFree_accessor_storage = new WeakMap(), _LuxenCarousel_duration_accessor_storage = new WeakMap(), _LuxenCarousel_skipSnaps_accessor_storage = new WeakMap(), _LuxenCarousel_slidesToScroll_accessor_storage = new WeakMap(), _LuxenCarousel_startIndex_accessor_storage = new WeakMap(), _LuxenCarousel_containScroll_accessor_storage = new WeakMap(), _LuxenCarousel_single_accessor_storage = new WeakMap(), _LuxenCarousel_withDots_accessor_storage = new WeakMap(), _LuxenCarousel_withScrollbar_accessor_storage = new WeakMap(), _LuxenCarousel_withFullscreen_accessor_storage = new WeakMap(), _LuxenCarousel_dotAppearance_accessor_storage = new WeakMap(), _LuxenCarousel_scrollButtonsPosition_accessor_storage = new WeakMap();
|
|
434
|
+
_LuxenCarousel_autoplay_accessor_storage = new WeakMap(), _LuxenCarousel_autoplayOptions_accessor_storage = new WeakMap(), _LuxenCarousel_axis_accessor_storage = new WeakMap(), _LuxenCarousel_align_accessor_storage = new WeakMap(), _LuxenCarousel_breakpoints_accessor_storage = new WeakMap(), _LuxenCarousel_loop_accessor_storage = new WeakMap(), _LuxenCarousel_dragFree_accessor_storage = new WeakMap(), _LuxenCarousel_duration_accessor_storage = new WeakMap(), _LuxenCarousel_skipSnaps_accessor_storage = new WeakMap(), _LuxenCarousel_slidesToScroll_accessor_storage = new WeakMap(), _LuxenCarousel_startIndex_accessor_storage = new WeakMap(), _LuxenCarousel_containScroll_accessor_storage = new WeakMap(), _LuxenCarousel_single_accessor_storage = new WeakMap(), _LuxenCarousel_withDots_accessor_storage = new WeakMap(), _LuxenCarousel_withScrollbar_accessor_storage = new WeakMap(), _LuxenCarousel_withFullscreen_accessor_storage = new WeakMap(), _LuxenCarousel_dotAppearance_accessor_storage = new WeakMap(), _LuxenCarousel_maxVisibleDots_accessor_storage = new WeakMap(), _LuxenCarousel_scrollButtonsPosition_accessor_storage = new WeakMap(), _LuxenCarousel__selectedSnap_accessor_storage = new WeakMap();
|
|
404
435
|
LuxenCarousel.styles = [hostStyles, styles];
|
|
405
436
|
__decorate([
|
|
406
437
|
property({ type: Number, reflect: true })
|
|
@@ -453,9 +484,15 @@ __decorate([
|
|
|
453
484
|
__decorate([
|
|
454
485
|
property({ type: String, attribute: 'dot-appearance' })
|
|
455
486
|
], LuxenCarousel.prototype, "dotAppearance", null);
|
|
487
|
+
__decorate([
|
|
488
|
+
property({ type: Number, attribute: 'max-visible-dots' })
|
|
489
|
+
], LuxenCarousel.prototype, "maxVisibleDots", null);
|
|
456
490
|
__decorate([
|
|
457
491
|
property({ type: String, attribute: 'scroll-buttons-position' })
|
|
458
492
|
], LuxenCarousel.prototype, "scrollButtonsPosition", null);
|
|
493
|
+
__decorate([
|
|
494
|
+
state()
|
|
495
|
+
], LuxenCarousel.prototype, "_selectedSnap", null);
|
|
459
496
|
__decorate([
|
|
460
497
|
query('.scroll-buttons')
|
|
461
498
|
], LuxenCarousel.prototype, "scrollButtons", void 0);
|
|
@@ -468,6 +505,3 @@ __decorate([
|
|
|
468
505
|
__decorate([
|
|
469
506
|
query('.container')
|
|
470
507
|
], LuxenCarousel.prototype, "container", void 0);
|
|
471
|
-
__decorate([
|
|
472
|
-
queryAll('.dot')
|
|
473
|
-
], LuxenCarousel.prototype, "dotNodes", void 0);
|
|
@@ -69,18 +69,28 @@ dialog {
|
|
|
69
69
|
line-height: 1.4;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/* Pin body and footer so the layout stays correct when [without-header]
|
|
73
|
+
removes the header and only two children auto-place into the grid. */
|
|
72
74
|
[part='body'] {
|
|
75
|
+
grid-row: 2;
|
|
73
76
|
padding-inline: var(--padding);
|
|
74
77
|
overflow-y: auto;
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
[part='footer'] {
|
|
81
|
+
grid-row: 3;
|
|
78
82
|
display: flex;
|
|
79
83
|
place-content: end;
|
|
80
84
|
gap: 0.5rem;
|
|
81
85
|
padding: var(--padding);
|
|
82
86
|
}
|
|
83
87
|
|
|
88
|
+
/* Without a header, the body has to provide its own block-start padding
|
|
89
|
+
(normally inherited visually from the header padding above it). */
|
|
90
|
+
:host([without-header]) [part='body'] {
|
|
91
|
+
padding-block-start: var(--padding);
|
|
92
|
+
}
|
|
93
|
+
|
|
84
94
|
::slotted(menu[slot='footer']) {
|
|
85
95
|
display: contents;
|
|
86
96
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
:host {
|
|
2
|
+
--padding: 0.25rem;
|
|
3
|
+
|
|
2
4
|
--background: var(--l-color-bg-surface, Canvas);
|
|
3
|
-
--radius: 6px;
|
|
5
|
+
--border-radius: 6px;
|
|
4
6
|
--shadow: 0 4px 6px -1px rgb(0 0 0 / 8%), 0 2px 4px -2px rgb(0 0 0 / 6%);
|
|
5
7
|
--show-duration: 150;
|
|
6
8
|
--hide-duration: 150;
|
|
@@ -19,13 +21,22 @@
|
|
|
19
21
|
box-sizing: border-box;
|
|
20
22
|
width: max-content;
|
|
21
23
|
min-width: anchor-size(width);
|
|
22
|
-
padding:
|
|
24
|
+
padding: var(--padding);
|
|
23
25
|
margin: 0;
|
|
24
26
|
border: 1px solid var(--l-color-border-overlay, light-dark(#e5e7eb, #374151));
|
|
25
|
-
border-radius: var(--radius);
|
|
27
|
+
border-radius: var(--border-radius);
|
|
26
28
|
background: var(--background);
|
|
27
29
|
color: var(--l-color-text-primary, CanvasText);
|
|
28
30
|
box-shadow: var(--shadow);
|
|
29
31
|
font-size: 0.875rem;
|
|
30
32
|
line-height: 1.5;
|
|
31
33
|
}
|
|
34
|
+
|
|
35
|
+
/* Lightweight separator alternative to <l-divider> — same dimensions, no extra import. */
|
|
36
|
+
::slotted(hr) {
|
|
37
|
+
height: 1px;
|
|
38
|
+
margin-block: var(--padding);
|
|
39
|
+
margin-inline: calc(var(--padding) * -1);
|
|
40
|
+
border: 0;
|
|
41
|
+
background: var(--l-color-divider);
|
|
42
|
+
}
|
|
@@ -5,12 +5,15 @@ import type { Placement } from '@floating-ui/dom';
|
|
|
5
5
|
* A dropdown menu anchored to a trigger element.
|
|
6
6
|
*
|
|
7
7
|
* @slot trigger - The element that triggers the dropdown.
|
|
8
|
-
* @slot -
|
|
8
|
+
* @slot header - Optional content rendered above the menu items (e.g. a user profile row). Use an `<l-divider>` (or `<hr>`) after it to separate from items.
|
|
9
|
+
* @slot - Menu content (`l-dropdown-item` elements). Drop an `<l-divider>` (or `<hr>`) between items to render a section separator.
|
|
10
|
+
* @slot footer - Optional content rendered below the menu items (e.g. a version label or shortcut row). Use an `<l-divider>` (or `<hr>`) before it to separate from items.
|
|
9
11
|
*
|
|
10
12
|
* @csspart panel - The floating menu container.
|
|
11
13
|
*
|
|
12
14
|
* @cssproperty --background - Panel background color.
|
|
13
|
-
* @cssproperty --radius - Panel border radius. Default `8px`.
|
|
15
|
+
* @cssproperty --border-radius - Panel border radius. Default `8px`.
|
|
16
|
+
* @cssproperty --padding - Panel inner padding. Default `0.25rem`. Slotted `<l-divider>` elements bleed by this amount on each side to span the panel edges.
|
|
14
17
|
* @cssproperty --shadow - Panel box shadow.
|
|
15
18
|
* @cssproperty --show-duration - Show animation duration in ms. Default `150`.
|
|
16
19
|
* @cssproperty --hide-duration - Hide animation duration in ms. Default `150`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.d.ts","sourceRoot":"","sources":["../../../src/html/elements/dropdown/dropdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AASlD
|
|
1
|
+
{"version":3,"file":"dropdown.d.ts","sourceRoot":"","sources":["../../../src/html/elements/dropdown/dropdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AASlD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAgB,MAAM,4BAAwB;IAE9C,OAAO,CAAC,SAAS,CAId;IAEH,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,iBAAiB,CAAK;IAE9B,oCAAoC;IAEpC,QAAQ,CAAC,IAAI,UAAS;IAEtB,wCAAwC;IAExC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAkB;IAE/C,2CAA2C;IAE3C,QAAQ,CAAC,QAAQ,SAAK;IAEtB,qCAAqC;IAErC,QAAQ,CAAC,QAAQ,UAAS;IAE1B,OAAO,KAAK,UAAU,GAGrB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,YAAY;IAOpB,IAAI;IAKJ,IAAI;IAKJ,MAAM;IAOG,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;YAQhC,iBAAiB;IAyB/B,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,eAAe,CAQrB;IAEF,OAAO,CAAC,iBAAiB,CAYvB;IAEF,OAAO,CAAC,eAAe,CAiCrB;IAEF,OAAO,CAAC,YAAY,CAKlB;IAEF,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,WAAW;IAWnB,2DAA2D;IAC3D,OAAO,CAAC,SAAS,CAMf;IAEO,MAAM;CAwBhB"}
|
|
@@ -28,12 +28,15 @@ const styles = unsafeCSS(rawStyles);
|
|
|
28
28
|
* A dropdown menu anchored to a trigger element.
|
|
29
29
|
*
|
|
30
30
|
* @slot trigger - The element that triggers the dropdown.
|
|
31
|
-
* @slot -
|
|
31
|
+
* @slot header - Optional content rendered above the menu items (e.g. a user profile row). Use an `<l-divider>` (or `<hr>`) after it to separate from items.
|
|
32
|
+
* @slot - Menu content (`l-dropdown-item` elements). Drop an `<l-divider>` (or `<hr>`) between items to render a section separator.
|
|
33
|
+
* @slot footer - Optional content rendered below the menu items (e.g. a version label or shortcut row). Use an `<l-divider>` (or `<hr>`) before it to separate from items.
|
|
32
34
|
*
|
|
33
35
|
* @csspart panel - The floating menu container.
|
|
34
36
|
*
|
|
35
37
|
* @cssproperty --background - Panel background color.
|
|
36
|
-
* @cssproperty --radius - Panel border radius. Default `8px`.
|
|
38
|
+
* @cssproperty --border-radius - Panel border radius. Default `8px`.
|
|
39
|
+
* @cssproperty --padding - Panel inner padding. Default `0.25rem`. Slotted `<l-divider>` elements bleed by this amount on each side to span the panel edges.
|
|
37
40
|
* @cssproperty --shadow - Panel box shadow.
|
|
38
41
|
* @cssproperty --show-duration - Show animation duration in ms. Default `150`.
|
|
39
42
|
* @cssproperty --hide-duration - Hide animation duration in ms. Default `150`.
|
|
@@ -59,9 +62,15 @@ export class LuxenDropdown extends LuxenElement {
|
|
|
59
62
|
_LuxenDropdown_distance_accessor_storage.set(this, 4);
|
|
60
63
|
_LuxenDropdown_disabled_accessor_storage.set(this, false);
|
|
61
64
|
// --- Event handlers ---
|
|
62
|
-
this._onTriggerClick = () => {
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
+
this._onTriggerClick = (e) => {
|
|
66
|
+
if (this.disabled)
|
|
67
|
+
return;
|
|
68
|
+
this.toggle();
|
|
69
|
+
// Space/Enter on a native button dispatches click with detail=0; focus the
|
|
70
|
+
// first item so the menu is keyboard-navigable immediately on open.
|
|
71
|
+
if (this.open && e.detail === 0) {
|
|
72
|
+
requestAnimationFrame(() => this._focusFirstItem());
|
|
73
|
+
}
|
|
65
74
|
};
|
|
66
75
|
this._onTriggerKeyDown = (e) => {
|
|
67
76
|
if (this.disabled)
|
|
@@ -296,12 +305,15 @@ export class LuxenDropdown extends LuxenElement {
|
|
|
296
305
|
<div
|
|
297
306
|
popover="auto"
|
|
298
307
|
part="panel"
|
|
299
|
-
role="menu"
|
|
300
308
|
@keydown=${this._onPanelKeyDown}
|
|
301
309
|
@click=${this._onItemClick}
|
|
302
310
|
@toggle=${this._onToggle}
|
|
303
311
|
>
|
|
304
|
-
<slot></slot>
|
|
312
|
+
<slot name="header"></slot>
|
|
313
|
+
<div role="menu">
|
|
314
|
+
<slot></slot>
|
|
315
|
+
</div>
|
|
316
|
+
<slot name="footer"></slot>
|
|
305
317
|
</div>
|
|
306
318
|
`;
|
|
307
319
|
}
|
|
@@ -9,8 +9,13 @@ import { LuxenElement } from '../../shared/luxen-element';
|
|
|
9
9
|
* @customElement l-input-otp
|
|
10
10
|
*
|
|
11
11
|
* @cssproperty --digits - Number of digit boxes (default: 6). Must match input's maxlength.
|
|
12
|
-
* @cssproperty --size - Cell width and height (default: 2.75rem). Font size scales automatically.
|
|
13
|
-
* @cssproperty --gap - Space between cells (default: 0.5rem).
|
|
12
|
+
* @cssproperty --cell-size - Cell width and height (default: 2.75rem). Font size scales automatically.
|
|
13
|
+
* @cssproperty --cell-gap - Space between cells (default: 0.5rem).
|
|
14
|
+
* @cssproperty --cell-bg-color - Cell background color.
|
|
15
|
+
* @cssproperty --cell-border-color - Cell border color.
|
|
16
|
+
* @cssproperty --cell-border-radius - Cell border-radius.
|
|
17
|
+
* @cssproperty --cell-focus-color - Border + ring color of the active (focused) cell.
|
|
18
|
+
* @cssproperty --cell-focus-ring - `box-shadow` of the active cell ring (defaults to a 1px solid ring; set to `none` to disable).
|
|
14
19
|
*/
|
|
15
20
|
export declare class LuxenInputOtp extends LuxenElement {
|
|
16
21
|
createRenderRoot(): this;
|
|
@@ -27,5 +32,6 @@ export declare class LuxenInputOtp extends LuxenElement {
|
|
|
27
32
|
private _teardown;
|
|
28
33
|
private _updateCells;
|
|
29
34
|
private _clearCells;
|
|
35
|
+
private _scheduleUpdateCells;
|
|
30
36
|
}
|
|
31
37
|
//# sourceMappingURL=input-otp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-otp.d.ts","sourceRoot":"","sources":["../../../src/html/elements/input-otp/input-otp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D
|
|
1
|
+
{"version":3,"file":"input-otp.d.ts","sourceRoot":"","sources":["../../../src/html/elements/input-otp/input-otp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,aAAc,SAAQ,YAAY;IACpC,gBAAgB;IAIzB,sFAAsF;IAEtF,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,YAAY,CAAS;IAEpB,iBAAiB;IAKjB,oBAAoB;IAO7B,OAAO,CAAC,MAAM;IA4Dd,OAAO,CAAC,SAAS;IAoBjB,OAAO,CAAC,YAAY,CAyBlB;IAEF,OAAO,CAAC,WAAW,CAIjB;IAEF,OAAO,CAAC,oBAAoB,CAE1B;CACH"}
|
|
@@ -16,8 +16,13 @@ import { LuxenElement } from '../../shared/luxen-element';
|
|
|
16
16
|
* @customElement l-input-otp
|
|
17
17
|
*
|
|
18
18
|
* @cssproperty --digits - Number of digit boxes (default: 6). Must match input's maxlength.
|
|
19
|
-
* @cssproperty --size - Cell width and height (default: 2.75rem). Font size scales automatically.
|
|
20
|
-
* @cssproperty --gap - Space between cells (default: 0.5rem).
|
|
19
|
+
* @cssproperty --cell-size - Cell width and height (default: 2.75rem). Font size scales automatically.
|
|
20
|
+
* @cssproperty --cell-gap - Space between cells (default: 0.5rem).
|
|
21
|
+
* @cssproperty --cell-bg-color - Cell background color.
|
|
22
|
+
* @cssproperty --cell-border-color - Cell border color.
|
|
23
|
+
* @cssproperty --cell-border-radius - Cell border-radius.
|
|
24
|
+
* @cssproperty --cell-focus-color - Border + ring color of the active (focused) cell.
|
|
25
|
+
* @cssproperty --cell-focus-ring - `box-shadow` of the active cell ring (defaults to a 1px solid ring; set to `none` to disable).
|
|
21
26
|
*/
|
|
22
27
|
export class LuxenInputOtp extends LuxenElement {
|
|
23
28
|
constructor() {
|
|
@@ -55,6 +60,9 @@ export class LuxenInputOtp extends LuxenElement {
|
|
|
55
60
|
cell.removeAttribute('data-active');
|
|
56
61
|
}
|
|
57
62
|
};
|
|
63
|
+
this._scheduleUpdateCells = () => {
|
|
64
|
+
requestAnimationFrame(this._updateCells);
|
|
65
|
+
};
|
|
58
66
|
}
|
|
59
67
|
createRenderRoot() {
|
|
60
68
|
return this;
|
|
@@ -111,11 +119,12 @@ export class LuxenInputOtp extends LuxenElement {
|
|
|
111
119
|
this._initialized = true;
|
|
112
120
|
// Populate cells if input already has a value (e.g. disabled with prefilled value)
|
|
113
121
|
this._updateCells();
|
|
114
|
-
// Events
|
|
122
|
+
// Events — focus is deferred so it runs after the click that triggered it
|
|
123
|
+
// (otherwise selectionStart is stale and the active cell flickers).
|
|
115
124
|
this._input.addEventListener('input', this._updateCells);
|
|
116
125
|
this._input.addEventListener('click', this._updateCells);
|
|
117
126
|
this._input.addEventListener('keyup', this._updateCells);
|
|
118
|
-
this._input.addEventListener('focus', this.
|
|
127
|
+
this._input.addEventListener('focus', this._scheduleUpdateCells);
|
|
119
128
|
this._input.addEventListener('blur', this._clearCells);
|
|
120
129
|
}
|
|
121
130
|
_teardown() {
|
|
@@ -124,7 +133,7 @@ export class LuxenInputOtp extends LuxenElement {
|
|
|
124
133
|
this._input.removeEventListener('input', this._updateCells);
|
|
125
134
|
this._input.removeEventListener('click', this._updateCells);
|
|
126
135
|
this._input.removeEventListener('keyup', this._updateCells);
|
|
127
|
-
this._input.removeEventListener('focus', this.
|
|
136
|
+
this._input.removeEventListener('focus', this._scheduleUpdateCells);
|
|
128
137
|
this._input.removeEventListener('blur', this._clearCells);
|
|
129
138
|
// Restore input to direct child
|
|
130
139
|
this._container.replaceWith(this._input);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
:host {
|
|
2
|
-
--background: var(--l-color-bg-fill-brand, light-dark(#1f2937, #f9fafb));
|
|
3
|
-
--
|
|
4
|
-
--radius: 4px;
|
|
2
|
+
--background-color: var(--l-color-bg-fill-brand, light-dark(#1f2937, #f9fafb));
|
|
3
|
+
--border-radius: 4px;
|
|
5
4
|
--max-width: 180px;
|
|
6
5
|
--arrow-size: 6px;
|
|
7
6
|
--show-duration: 150ms;
|
|
@@ -18,20 +17,29 @@
|
|
|
18
17
|
max-width: var(--max-width);
|
|
19
18
|
padding: 4px 8px;
|
|
20
19
|
border: 0;
|
|
21
|
-
border-radius: var(--radius);
|
|
22
|
-
background: var(--background);
|
|
23
|
-
color: var(
|
|
20
|
+
border-radius: var(--border-radius);
|
|
21
|
+
background: var(--background-color);
|
|
22
|
+
color: var(
|
|
23
|
+
--text-color,
|
|
24
|
+
oklch(from var(--background-color) calc(0.59 - 0.41 * sign(l - 0.5)) 0 0)
|
|
25
|
+
);
|
|
24
26
|
font-size: 0.8125rem;
|
|
25
27
|
line-height: 1.4;
|
|
26
28
|
filter: drop-shadow(0 1px 2px rgb(0 0 0 / 16%));
|
|
27
29
|
pointer-events: none;
|
|
28
30
|
}
|
|
29
31
|
|
|
32
|
+
@supports (color: contrast-color(red vs black, white)) {
|
|
33
|
+
[popover] {
|
|
34
|
+
color: var(--text-color, contrast-color(var(--background-color) vs #111827, #fff to AA));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
i {
|
|
31
39
|
position: absolute;
|
|
32
40
|
display: block;
|
|
33
41
|
width: var(--arrow-size);
|
|
34
42
|
height: var(--arrow-size);
|
|
35
|
-
background: var(--background);
|
|
43
|
+
background: var(--background-color);
|
|
36
44
|
transform: rotate(45deg);
|
|
37
45
|
}
|
|
@@ -10,9 +10,9 @@ import type { Placement } from '@floating-ui/dom';
|
|
|
10
10
|
* @csspart body - The tooltip popover container.
|
|
11
11
|
* @csspart arrow - The directional arrow element.
|
|
12
12
|
*
|
|
13
|
-
* @cssproperty --background - Background color. Default: dark in light mode, light in dark mode.
|
|
14
|
-
* @cssproperty --color - Text color.
|
|
15
|
-
* @cssproperty --radius - Border radius. Default `4px`.
|
|
13
|
+
* @cssproperty --background-color - Background color. Default: dark in light mode, light in dark mode.
|
|
14
|
+
* @cssproperty --text-color - Text color. If unset, auto-derived from `--background-color` luminance.
|
|
15
|
+
* @cssproperty --border-radius - Border radius. Default `4px`.
|
|
16
16
|
* @cssproperty --max-width - Maximum width. Default `180px`.
|
|
17
17
|
* @cssproperty --arrow-size - Arrow size. Default `6px`.
|
|
18
18
|
* @cssproperty --show-duration - Show animation duration. Default `150ms`.
|
|
@@ -33,9 +33,9 @@ const styles = unsafeCSS(rawStyles);
|
|
|
33
33
|
* @csspart body - The tooltip popover container.
|
|
34
34
|
* @csspart arrow - The directional arrow element.
|
|
35
35
|
*
|
|
36
|
-
* @cssproperty --background - Background color. Default: dark in light mode, light in dark mode.
|
|
37
|
-
* @cssproperty --color - Text color.
|
|
38
|
-
* @cssproperty --radius - Border radius. Default `4px`.
|
|
36
|
+
* @cssproperty --background-color - Background color. Default: dark in light mode, light in dark mode.
|
|
37
|
+
* @cssproperty --text-color - Text color. If unset, auto-derived from `--background-color` luminance.
|
|
38
|
+
* @cssproperty --border-radius - Border radius. Default `4px`.
|
|
39
39
|
* @cssproperty --max-width - Maximum width. Default `180px`.
|
|
40
40
|
* @cssproperty --arrow-size - Arrow size. Default `6px`.
|
|
41
41
|
* @cssproperty --show-duration - Show animation duration. Default `150ms`.
|