@eunomia/elements 1.0.0-beta.2 → 1.0.0-beta.3
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/dist/cdn/components/chunks/chunk-3LMI7KUA.js +48 -0
- package/dist/cdn/components/chunks/{chunk-74HHV4CX.js → chunk-53QH6MPM.js} +2 -2
- package/dist/cdn/components/chunks/{chunk-7WTSHE7M.js → chunk-EAGGN3ZI.js} +1 -1
- package/dist/cdn/components/chunks/chunk-GU6BVMFJ.js +1 -0
- package/dist/cdn/components/chunks/chunk-KNM5QHDK.js +38 -0
- package/dist/cdn/components/chunks/{chunk-AQQMW353.js → chunk-TBKKTJOX.js} +1 -1
- package/dist/cdn/components/chunks/chunk-YYCEPZUN.js +1 -0
- package/dist/cdn/components/chunks/{chunk-27Q2SLRY.js → chunk-Z6PJYSC3.js} +30 -11
- package/dist/cdn/components/eun-animate.js +178 -2
- package/dist/cdn/components/eun-button.js +1 -1
- package/dist/cdn/components/eun-card.js +15 -7
- package/dist/cdn/components/eun-carousel.js +1 -1
- package/dist/cdn/components/eun-check-card.js +1 -1
- package/dist/cdn/components/eun-checkbox-list.js +2 -2
- package/dist/cdn/components/eun-checkbox.js +1 -1
- package/dist/cdn/components/eun-chip.js +11 -14
- package/dist/cdn/components/eun-collapse.js +8 -15
- package/dist/cdn/components/eun-color-picker.js +19 -19
- package/dist/cdn/components/eun-counter.js +4 -4
- package/dist/cdn/components/eun-date-picker.js +2 -2
- package/dist/cdn/components/eun-icon.js +1 -1
- package/dist/cdn/components/eun-input-file.js +11 -11
- package/dist/cdn/components/eun-input-phone.js +3 -3
- package/dist/cdn/components/eun-input.js +1 -1
- package/dist/cdn/components/eun-radio-card.js +1 -1
- package/dist/cdn/components/eun-radio-list.js +3 -3
- package/dist/cdn/components/eun-radio.js +1 -1
- package/dist/cdn/components/eun-search.js +1 -1
- package/dist/cdn/components/eun-select.js +33 -12
- package/dist/cdn/components/eun-sidebar.js +1 -1
- package/dist/cdn/components/eun-slider.js +3 -3
- package/dist/cdn/components/eun-sliding-card.js +4 -8
- package/dist/cdn/components/eun-switch.js +1 -1
- package/dist/cdn/components/eun-table.js +1 -1
- package/dist/cdn/components/eun-tag.js +13 -9
- package/dist/cdn/components/eun-textarea.js +11 -11
- package/dist/cdn/components/eun-time-picker.js +2 -2
- package/dist/cdn/components/eun-toggle-group.js +2 -2
- package/dist/cdn/components/eun-toggle-item.js +1 -1
- package/dist/cdn/components/eun-toggle.js +2 -2
- package/dist/cdn/components/eun-toolbar.js +14 -12
- package/dist/cdn/components/eun-tooltip.js +2 -2
- package/dist/components/action/button/button.d.ts +5 -6
- package/dist/components/action/button/button.js +5 -6
- package/dist/components/action/button/button.styles.js +31 -9
- package/dist/components/action/toggle/toggle-group.js +1 -1
- package/dist/components/action/toggle/toggle-item.styles.js +1 -1
- package/dist/components/action/toggle/toggle.js +1 -1
- package/dist/components/content/card/card.d.ts +1 -1
- package/dist/components/content/card/card.js +1 -1
- package/dist/components/content/card/card.styles.js +13 -5
- package/dist/components/content/card/sliding-card.styles.js +0 -4
- package/dist/components/content/chip/chip.styles.js +6 -9
- package/dist/components/content/collapse/collapse.styles.js +0 -7
- package/dist/components/content/icon/icon.d.ts +48 -5
- package/dist/components/content/icon/icon.js +92 -20
- package/dist/components/content/tag/tag.styles.js +10 -6
- package/dist/components/content/tooltip/tooltip.styles.js +2 -2
- package/dist/components/form/checkbox/checkbox-list.js +1 -1
- package/dist/components/form/color-picker/color-picker.js +9 -7
- package/dist/components/form/counter/counter.js +3 -3
- package/dist/components/form/date-picker/date-picker.js +3 -3
- package/dist/components/form/input/input.js +2 -2
- package/dist/components/form/input-file/input-file.js +5 -5
- package/dist/components/form/input-phone/input-phone.js +3 -3
- package/dist/components/form/radio/radio-list.js +2 -2
- package/dist/components/form/select/select.d.ts +16 -0
- package/dist/components/form/select/select.js +28 -5
- package/dist/components/form/select/select.styles.js +11 -0
- package/dist/components/form/slider/slider.js +2 -2
- package/dist/components/form/textarea/textarea.js +4 -4
- package/dist/components/form/time-picker/time-picker.js +3 -3
- package/dist/components/layout/animate/animate.d.ts +40 -5
- package/dist/components/layout/animate/animate.js +30 -11
- package/dist/components/layout/animate/animate.styles.d.ts +1 -1
- package/dist/components/layout/animate/animate.styles.js +191 -1
- package/dist/components/navigation/carousel/carousel.styles.js +1 -1
- package/dist/components/navigation/toolbar/toolbar.d.ts +22 -0
- package/dist/components/navigation/toolbar/toolbar.js +28 -2
- package/dist/components/navigation/toolbar/toolbar.styles.js +4 -3
- package/dist/events/change.event.d.ts +13 -1
- package/dist/events/change.event.js +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mixins/check.mixin.js +6 -2
- package/dist/mixins/form.mixin.d.ts +4 -0
- package/dist/mixins/form.mixin.js +78 -2
- package/dist/mixins/radio.mixin.js +6 -2
- package/dist/ssr/animate-ssr.css +149 -0
- package/dist/ssr/overlay-ssr.css +57 -0
- package/dist/ssr/sidebar-ssr.css +57 -0
- package/dist/ssr/toolbar-ssr.css +41 -0
- package/package.json +9 -3
- package/dist/cdn/components/chunks/chunk-2IQUMAMI.js +0 -38
- package/dist/cdn/components/chunks/chunk-7Q6AHVI5.js +0 -1
- package/dist/cdn/components/chunks/chunk-DENMN3WH.js +0 -48
- package/dist/cdn/components/chunks/chunk-ONYUXQV2.js +0 -1
- package/dist/components/layout/animate/animate-ssr.css +0 -64
|
@@ -53,6 +53,7 @@ const EunomiaSelectMixinBase = AnchorPositionMixin(FieldVariantMixin(FormLabelMi
|
|
|
53
53
|
* @slot [icon] - Replaces the leading icon entirely with any content, not just an icon element. Falls back to icon when empty
|
|
54
54
|
* @slot [readonly-content] - Optional custom content displayed instead of the raw label in the static readonly display
|
|
55
55
|
* @slot [confirm] - Optional custom content for the confirm trigger, such as an icon, displayed as a link while editing in readonlyAvailable mode, or while multiple and the dropdown is open. Overrides confirmLabel when used. The button itself always shows in either of those states unless confirmLabel is set to an empty string
|
|
56
|
+
* @slot [actions] - Optional content rendered in a footer row below the options, for actions unrelated to picking a value, such as a link to manage the list elsewhere. Hidden entirely when empty. Ignored while native is set
|
|
56
57
|
* @prop {boolean} [searchable=false] - Whether the field filters its options as the user types. When false, the field is read only and driven by arrow keys, Enter, and type-ahead. Ignored while native is set
|
|
57
58
|
* @prop {boolean} [native=false] - Renders the field as a real select, using the browser's own dropdown instead of the listbox panel. Takes priority over searchable and multiple, neither of which a native dropdown can support
|
|
58
59
|
* @prop {boolean} [multiple=false] - Whether more than one option can be picked at once. Each option then renders a checkbox, and picking one toggles it without closing the dropdown, so value becomes an array of every picked option's value. Ignored while native is set
|
|
@@ -229,6 +230,15 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
|
|
|
229
230
|
this.handleIconSlotChange = () => {
|
|
230
231
|
this.requestUpdate();
|
|
231
232
|
};
|
|
233
|
+
/**
|
|
234
|
+
* Re-renders when the `actions` slot's assigned content changes, so the
|
|
235
|
+
* footer row correctly appears/disappears as content is slotted in or
|
|
236
|
+
* removed after the initial render.
|
|
237
|
+
* @private
|
|
238
|
+
*/
|
|
239
|
+
this.handleActionsSlotChange = () => {
|
|
240
|
+
this.requestUpdate();
|
|
241
|
+
};
|
|
232
242
|
/**
|
|
233
243
|
* Redirects focus to the native field whenever the host itself receives
|
|
234
244
|
* it. The host stays in the tab order (`DisabledMixin`) rather than
|
|
@@ -795,11 +805,11 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
|
|
|
795
805
|
this.value = current.includes(option.value)
|
|
796
806
|
? current.filter((value) => value !== option.value)
|
|
797
807
|
: [...current, option.value];
|
|
798
|
-
this.dispatchEvent(new ChangeEvent());
|
|
808
|
+
this.dispatchEvent(new ChangeEvent(this.value));
|
|
799
809
|
return;
|
|
800
810
|
}
|
|
801
811
|
this.value = option.value;
|
|
802
|
-
this.dispatchEvent(new ChangeEvent());
|
|
812
|
+
this.dispatchEvent(new ChangeEvent(this.value));
|
|
803
813
|
this.closeListbox();
|
|
804
814
|
if (this.readonlyAvailable) {
|
|
805
815
|
this.confirmEdit();
|
|
@@ -816,7 +826,7 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
|
|
|
816
826
|
*/
|
|
817
827
|
handleNativeChange(event) {
|
|
818
828
|
this.value = event.target.value;
|
|
819
|
-
this.dispatchEvent(new ChangeEvent());
|
|
829
|
+
this.dispatchEvent(new ChangeEvent(this.value));
|
|
820
830
|
if (this.readonlyAvailable) {
|
|
821
831
|
this.confirmEdit();
|
|
822
832
|
}
|
|
@@ -1166,7 +1176,7 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
|
|
|
1166
1176
|
aria-describedby=${hasDescription ? "description" : nothing}
|
|
1167
1177
|
?disabled=${this.disabled || this.readonly}
|
|
1168
1178
|
?required=${this.required}
|
|
1169
|
-
aria-invalid=${this.
|
|
1179
|
+
aria-invalid=${!this.hideError && !this.disabled && !this.valid}
|
|
1170
1180
|
@change=${this.handleNativeChange}
|
|
1171
1181
|
></select>
|
|
1172
1182
|
${this.showConfirmLink ? this.renderConfirmLink() : nothing}
|
|
@@ -1215,7 +1225,7 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
|
|
|
1215
1225
|
?disabled=${this.disabled}
|
|
1216
1226
|
?readonly=${this.readonly || !this.searchable}
|
|
1217
1227
|
aria-required=${this.required ? "true" : "false"}
|
|
1218
|
-
aria-invalid=${this.
|
|
1228
|
+
aria-invalid=${!this.hideError && !this.disabled && !this.valid}
|
|
1219
1229
|
@pointerdown=${this.handleFieldPointerDown}
|
|
1220
1230
|
@focus=${this.handleFieldActivate}
|
|
1221
1231
|
@click=${this.handleFieldActivate}
|
|
@@ -1234,6 +1244,16 @@ let EunomiaSelect = EunomiaSelect_1 = class EunomiaSelect extends EunomiaSelectM
|
|
|
1234
1244
|
@toggle=${this.handlePopoverToggle}
|
|
1235
1245
|
>
|
|
1236
1246
|
${this.renderListboxRows(options)}
|
|
1247
|
+
<li
|
|
1248
|
+
class="actions"
|
|
1249
|
+
role="presentation"
|
|
1250
|
+
?hidden=${!this.actionsSlotEls?.length}
|
|
1251
|
+
>
|
|
1252
|
+
<slot
|
|
1253
|
+
name="actions"
|
|
1254
|
+
@slotchange=${this.handleActionsSlotChange}
|
|
1255
|
+
></slot>
|
|
1256
|
+
</li>
|
|
1237
1257
|
</ul>
|
|
1238
1258
|
`;
|
|
1239
1259
|
}
|
|
@@ -1381,6 +1401,9 @@ __decorate([
|
|
|
1381
1401
|
__decorate([
|
|
1382
1402
|
queryAssignedElements({ slot: "icon" })
|
|
1383
1403
|
], EunomiaSelect.prototype, "iconSlotEls", void 0);
|
|
1404
|
+
__decorate([
|
|
1405
|
+
queryAssignedElements({ slot: "actions" })
|
|
1406
|
+
], EunomiaSelect.prototype, "actionsSlotEls", void 0);
|
|
1384
1407
|
EunomiaSelect = EunomiaSelect_1 = __decorate([
|
|
1385
1408
|
customElement(EunomiaSelectTagName)
|
|
1386
1409
|
], EunomiaSelect);
|
|
@@ -65,6 +65,17 @@ const select = css `
|
|
|
65
65
|
border-color: var(--eun-color-primary-500, #3d6fff);
|
|
66
66
|
--icon-color: var(--eun-color-on-primary-500, #ffffff);
|
|
67
67
|
}
|
|
68
|
+
#listbox .actions {
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
gap: var(--eun-space-s, 8px);
|
|
72
|
+
padding: var(--eun-space-s, 8px) var(--eun-space-m, 16px);
|
|
73
|
+
cursor: default;
|
|
74
|
+
border-block-start: var(--eun-borderWidth-s, 1px) solid var(--_borderColor);
|
|
75
|
+
}
|
|
76
|
+
#listbox .actions[hidden] {
|
|
77
|
+
display: none;
|
|
78
|
+
}
|
|
68
79
|
#confirm-link {
|
|
69
80
|
position: absolute;
|
|
70
81
|
right: calc(var(--eun-space-l, 32px) + var(--eun-space-xs, 4px));
|
|
@@ -150,7 +150,7 @@ let EunomiaSlider = class EunomiaSlider extends EunomiaSliderMixinBase {
|
|
|
150
150
|
*/
|
|
151
151
|
this.handleInput = (event) => {
|
|
152
152
|
this.value = Number(event.target.value);
|
|
153
|
-
this.dispatchEvent(new ChangeEvent());
|
|
153
|
+
this.dispatchEvent(new ChangeEvent(this.value));
|
|
154
154
|
};
|
|
155
155
|
/**
|
|
156
156
|
* Blocks every native keyboard interaction (arrow keys, Home/End, Page
|
|
@@ -431,7 +431,7 @@ let EunomiaSlider = class EunomiaSlider extends EunomiaSliderMixinBase {
|
|
|
431
431
|
step=${this.step}
|
|
432
432
|
.value=${String(value)}
|
|
433
433
|
?disabled=${this.disabled}
|
|
434
|
-
aria-invalid=${this.
|
|
434
|
+
aria-invalid=${!this.hideError && !this.disabled && !this.valid}
|
|
435
435
|
aria-label=${ifDefined(this.label)}
|
|
436
436
|
aria-describedby=${hasDescription ? "description" : nothing}
|
|
437
437
|
@input=${this.handleInput}
|
|
@@ -733,7 +733,7 @@ let EunomiaTextarea = class EunomiaTextarea extends EunomiaTextareaMixinBase {
|
|
|
733
733
|
this.lastSyncedValue = newValue;
|
|
734
734
|
this.value = newValue;
|
|
735
735
|
this.resizeEditableField();
|
|
736
|
-
this.dispatchEvent(new ChangeEvent());
|
|
736
|
+
this.dispatchEvent(new ChangeEvent(this.value));
|
|
737
737
|
this.syncToolbarToSelection();
|
|
738
738
|
};
|
|
739
739
|
/**
|
|
@@ -1076,7 +1076,7 @@ let EunomiaTextarea = class EunomiaTextarea extends EunomiaTextareaMixinBase {
|
|
|
1076
1076
|
handleInput(event) {
|
|
1077
1077
|
this.value = event.target.value;
|
|
1078
1078
|
this.resizeToContent();
|
|
1079
|
-
this.dispatchEvent(new ChangeEvent());
|
|
1079
|
+
this.dispatchEvent(new ChangeEvent(this.value));
|
|
1080
1080
|
}
|
|
1081
1081
|
/**
|
|
1082
1082
|
* @see handleSelectionChange
|
|
@@ -1539,7 +1539,7 @@ let EunomiaTextarea = class EunomiaTextarea extends EunomiaTextareaMixinBase {
|
|
|
1539
1539
|
?required=${this.required}
|
|
1540
1540
|
minlength=${ifDefined(this.minlength)}
|
|
1541
1541
|
maxlength=${ifDefined(this.maxlength)}
|
|
1542
|
-
aria-invalid=${this.
|
|
1542
|
+
aria-invalid=${!this.hideError && !this.disabled && !this.valid}
|
|
1543
1543
|
aria-label=${ifDefined(this.label)}
|
|
1544
1544
|
aria-describedby=${describedBy || nothing}
|
|
1545
1545
|
@input=${this.handleInput}
|
|
@@ -1570,7 +1570,7 @@ let EunomiaTextarea = class EunomiaTextarea extends EunomiaTextareaMixinBase {
|
|
|
1570
1570
|
role="textbox"
|
|
1571
1571
|
aria-multiline="true"
|
|
1572
1572
|
aria-required=${this.required ? "true" : nothing}
|
|
1573
|
-
aria-invalid=${this.
|
|
1573
|
+
aria-invalid=${!this.hideError && !this.disabled && !this.valid}
|
|
1574
1574
|
aria-label=${ifDefined(this.label)}
|
|
1575
1575
|
aria-describedby=${describedBy || nothing}
|
|
1576
1576
|
@beforeinput=${this.handleEditableBeforeInput}
|
|
@@ -535,7 +535,7 @@ let EunomiaTimePicker = class EunomiaTimePicker extends EunomiaTimePickerMixinBa
|
|
|
535
535
|
*/
|
|
536
536
|
commitStaged() {
|
|
537
537
|
this.value = this.stagingValue;
|
|
538
|
-
this.dispatchEvent(new ChangeEvent());
|
|
538
|
+
this.dispatchEvent(new ChangeEvent(this.value));
|
|
539
539
|
}
|
|
540
540
|
/**
|
|
541
541
|
* Applies a new hour/minute to {@link displaySource}'s calendar day (via
|
|
@@ -557,7 +557,7 @@ let EunomiaTimePicker = class EunomiaTimePicker extends EunomiaTimePickerMixinBa
|
|
|
557
557
|
return;
|
|
558
558
|
}
|
|
559
559
|
this.value = next;
|
|
560
|
-
this.dispatchEvent(new ChangeEvent());
|
|
560
|
+
this.dispatchEvent(new ChangeEvent(this.value));
|
|
561
561
|
}
|
|
562
562
|
/**
|
|
563
563
|
* Commits a directly-typed, complete hour/minute (bypassing staging
|
|
@@ -572,7 +572,7 @@ let EunomiaTimePicker = class EunomiaTimePicker extends EunomiaTimePickerMixinBa
|
|
|
572
572
|
*/
|
|
573
573
|
commitTypedTime(hour24, minute) {
|
|
574
574
|
this.value = setZonedTime(this.value ?? new Date(), this.timezone, hour24, minute);
|
|
575
|
-
this.dispatchEvent(new ChangeEvent());
|
|
575
|
+
this.dispatchEvent(new ChangeEvent(this.value));
|
|
576
576
|
if (this.isOpen || this.isModalOpen) {
|
|
577
577
|
this.resetStaging();
|
|
578
578
|
}
|
|
@@ -25,6 +25,8 @@ export type EunomiaAnimateAnimation = "none" | "fade" | "scroll-right" | "scroll
|
|
|
25
25
|
* @prop {boolean} [once=true] - Whether the animation plays only the first time it enters the viewport, or replays every time it re-enters
|
|
26
26
|
* @prop {number} [threshold=0.1] - The ratio of the element, from 0 to 1, that must be visible before the animation triggers
|
|
27
27
|
* @prop {string} [rootMargin='0px'] - The margin applied around the viewport before threshold is evaluated, accepting CSS-like values such as -50px 0px
|
|
28
|
+
* @prop {EunomiaAnimateAnimation} [tabletAnimation] - Overrides `animation` at tablet-width viewports and narrower (max-width: 768px). Left unset, the viewport keeps using `animation`
|
|
29
|
+
* @prop {EunomiaAnimateAnimation} [mobileAnimation] - Overrides `animation` (and `tabletAnimation`, if also set) at mobile-width viewports and narrower (max-width: 600px)
|
|
28
30
|
* @cssprop [--animate-distance] - Sets the travel distance for the scroll and faded-scroll animations
|
|
29
31
|
* @element eun-animate
|
|
30
32
|
*/
|
|
@@ -36,7 +38,7 @@ export declare class EunomiaAnimate extends LitElement {
|
|
|
36
38
|
* @internal
|
|
37
39
|
* @readonly
|
|
38
40
|
*/
|
|
39
|
-
static readonly styles: import("lit").CSSResult;
|
|
41
|
+
static readonly styles: import("lit").CSSResult[];
|
|
40
42
|
/**
|
|
41
43
|
* Which transition to apply. `none` renders the content immediately, with
|
|
42
44
|
* no transition, and skips setting up the `IntersectionObserver`
|
|
@@ -72,20 +74,53 @@ export declare class EunomiaAnimate extends LitElement {
|
|
|
72
74
|
* @default 0px
|
|
73
75
|
*/
|
|
74
76
|
rootMargin: string;
|
|
77
|
+
/**
|
|
78
|
+
* Overrides `animation` at tablet-width viewports and narrower
|
|
79
|
+
* (`max-width: 768px`, matching `EUNOMIA_BREAKPOINTS.tablet`). Purely a
|
|
80
|
+
* CSS `@media` switch (`animate.styles.ts`, mirrored in
|
|
81
|
+
* `animate-ssr.css` for the pre-hydration state) — never read from JS,
|
|
82
|
+
* so there's no `matchMedia` listener to keep in sync with the actual
|
|
83
|
+
* viewport, and no risk of the SSR/hydration mismatch that a JS-driven
|
|
84
|
+
* breakpoint switch would reintroduce. Left `undefined`, the viewport
|
|
85
|
+
* keeps using `animation`.
|
|
86
|
+
* @default undefined
|
|
87
|
+
*/
|
|
88
|
+
tabletAnimation?: EunomiaAnimateAnimation;
|
|
89
|
+
/**
|
|
90
|
+
* Overrides `animation` (and `tabletAnimation`, if also set) at
|
|
91
|
+
* mobile-width viewports and narrower (`max-width: 600px`, matching
|
|
92
|
+
* `EUNOMIA_BREAKPOINTS.mobile`). Same pure-CSS mechanism as
|
|
93
|
+
* {@link tabletAnimation}.
|
|
94
|
+
* @default undefined
|
|
95
|
+
*/
|
|
96
|
+
mobileAnimation?: EunomiaAnimateAnimation;
|
|
75
97
|
/**
|
|
76
98
|
* Observes the host's own viewport entry/exit. Left `undefined` while
|
|
77
|
-
*
|
|
99
|
+
* every breakpoint's effective animation is `"none"` — see
|
|
100
|
+
* {@link setupObserver} and {@link hasAnyAnimation}.
|
|
78
101
|
* @internal
|
|
79
102
|
*/
|
|
80
103
|
private observer?;
|
|
104
|
+
/**
|
|
105
|
+
* Whether at least one of `animation`, `tabletAnimation`, or
|
|
106
|
+
* `mobileAnimation` is set to something other than `"none"` — i.e.
|
|
107
|
+
* whether *some* viewport width could actually reveal an animation, and
|
|
108
|
+
* the observer is therefore worth setting up at all. Deliberately
|
|
109
|
+
* ignores the current viewport width itself: which of the three ends up
|
|
110
|
+
* active is a CSS `@media` decision, not something this component reads
|
|
111
|
+
* from JS (see {@link tabletAnimation}).
|
|
112
|
+
* @private
|
|
113
|
+
*/
|
|
114
|
+
private get hasAnyAnimation();
|
|
81
115
|
connectedCallback(): void;
|
|
82
116
|
disconnectedCallback(): void;
|
|
83
117
|
protected updated(changed: PropertyValues): void;
|
|
84
118
|
/**
|
|
85
119
|
* (Re)builds the `IntersectionObserver` for the current `threshold`/
|
|
86
|
-
* `rootMargin`, replacing any previous one — except while
|
|
87
|
-
* `
|
|
88
|
-
* unconditionally, so there'd
|
|
120
|
+
* `rootMargin`, replacing any previous one — except while
|
|
121
|
+
* {@link hasAnyAnimation} is `false`, where no observer is created at
|
|
122
|
+
* all : every viewport width renders unconditionally then, so there'd
|
|
123
|
+
* be nothing for it to drive.
|
|
89
124
|
* @private
|
|
90
125
|
*/
|
|
91
126
|
private setupObserver;
|
|
@@ -36,6 +36,8 @@ const IN_VIEW_ATTR = "in-view";
|
|
|
36
36
|
* @prop {boolean} [once=true] - Whether the animation plays only the first time it enters the viewport, or replays every time it re-enters
|
|
37
37
|
* @prop {number} [threshold=0.1] - The ratio of the element, from 0 to 1, that must be visible before the animation triggers
|
|
38
38
|
* @prop {string} [rootMargin='0px'] - The margin applied around the viewport before threshold is evaluated, accepting CSS-like values such as -50px 0px
|
|
39
|
+
* @prop {EunomiaAnimateAnimation} [tabletAnimation] - Overrides `animation` at tablet-width viewports and narrower (max-width: 768px). Left unset, the viewport keeps using `animation`
|
|
40
|
+
* @prop {EunomiaAnimateAnimation} [mobileAnimation] - Overrides `animation` (and `tabletAnimation`, if also set) at mobile-width viewports and narrower (max-width: 600px)
|
|
39
41
|
* @cssprop [--animate-distance] - Sets the travel distance for the scroll and faded-scroll animations
|
|
40
42
|
* @element eun-animate
|
|
41
43
|
*/
|
|
@@ -78,6 +80,21 @@ let EunomiaAnimate = class EunomiaAnimate extends LitElement {
|
|
|
78
80
|
*/
|
|
79
81
|
this.rootMargin = "0px";
|
|
80
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Whether at least one of `animation`, `tabletAnimation`, or
|
|
85
|
+
* `mobileAnimation` is set to something other than `"none"` — i.e.
|
|
86
|
+
* whether *some* viewport width could actually reveal an animation, and
|
|
87
|
+
* the observer is therefore worth setting up at all. Deliberately
|
|
88
|
+
* ignores the current viewport width itself: which of the three ends up
|
|
89
|
+
* active is a CSS `@media` decision, not something this component reads
|
|
90
|
+
* from JS (see {@link tabletAnimation}).
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
get hasAnyAnimation() {
|
|
94
|
+
return (this.animation !== "none" ||
|
|
95
|
+
(this.tabletAnimation !== undefined && this.tabletAnimation !== "none") ||
|
|
96
|
+
(this.mobileAnimation !== undefined && this.mobileAnimation !== "none"));
|
|
97
|
+
}
|
|
81
98
|
connectedCallback() {
|
|
82
99
|
super.connectedCallback?.();
|
|
83
100
|
this.setupObserver();
|
|
@@ -94,15 +111,10 @@ let EunomiaAnimate = class EunomiaAnimate extends LitElement {
|
|
|
94
111
|
if (changed.has("delay")) {
|
|
95
112
|
this.style.setProperty("--_delay", `${this.delay}ms`);
|
|
96
113
|
}
|
|
97
|
-
// Rebuilds the observer whenever anything its own setup depends on
|
|
98
|
-
// changes : `animation` (switching to/from "none" starts/stops
|
|
99
|
-
// observing entirely), `threshold`/`rootMargin` (the observer's own
|
|
100
|
-
// options, otherwise frozen at whatever they were on connect), and
|
|
101
|
-
// `once` (so flipping it back to `false` after the element already
|
|
102
|
-
// triggered once — and got unobserved — resumes watching for exit/
|
|
103
|
-
// re-entry, rather than staying silently stuck).
|
|
104
114
|
if (this.isConnected &&
|
|
105
115
|
(changed.has("animation") ||
|
|
116
|
+
changed.has("tabletAnimation") ||
|
|
117
|
+
changed.has("mobileAnimation") ||
|
|
106
118
|
changed.has("threshold") ||
|
|
107
119
|
changed.has("rootMargin") ||
|
|
108
120
|
changed.has("once"))) {
|
|
@@ -111,14 +123,15 @@ let EunomiaAnimate = class EunomiaAnimate extends LitElement {
|
|
|
111
123
|
}
|
|
112
124
|
/**
|
|
113
125
|
* (Re)builds the `IntersectionObserver` for the current `threshold`/
|
|
114
|
-
* `rootMargin`, replacing any previous one — except while
|
|
115
|
-
* `
|
|
116
|
-
* unconditionally, so there'd
|
|
126
|
+
* `rootMargin`, replacing any previous one — except while
|
|
127
|
+
* {@link hasAnyAnimation} is `false`, where no observer is created at
|
|
128
|
+
* all : every viewport width renders unconditionally then, so there'd
|
|
129
|
+
* be nothing for it to drive.
|
|
117
130
|
* @private
|
|
118
131
|
*/
|
|
119
132
|
setupObserver() {
|
|
120
133
|
this.teardownObserver();
|
|
121
|
-
if (this.
|
|
134
|
+
if (!this.hasAnyAnimation) {
|
|
122
135
|
return;
|
|
123
136
|
}
|
|
124
137
|
this.observer = new IntersectionObserver(([entry]) => {
|
|
@@ -172,6 +185,12 @@ __decorate([
|
|
|
172
185
|
__decorate([
|
|
173
186
|
property({ attribute: "root-margin" })
|
|
174
187
|
], EunomiaAnimate.prototype, "rootMargin", void 0);
|
|
188
|
+
__decorate([
|
|
189
|
+
property({ attribute: "tablet-animation", reflect: true })
|
|
190
|
+
], EunomiaAnimate.prototype, "tabletAnimation", void 0);
|
|
191
|
+
__decorate([
|
|
192
|
+
property({ attribute: "mobile-animation", reflect: true })
|
|
193
|
+
], EunomiaAnimate.prototype, "mobileAnimation", void 0);
|
|
175
194
|
EunomiaAnimate = __decorate([
|
|
176
195
|
customElement(EunomiaAnimateTagName)
|
|
177
196
|
], EunomiaAnimate);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const animateStyles: import("lit").CSSResult;
|
|
1
|
+
export declare const animateStyles: import("lit").CSSResult[];
|
|
@@ -100,4 +100,194 @@ const base = css `
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
`;
|
|
103
|
-
|
|
103
|
+
/**
|
|
104
|
+
* \`tablet-animation\`/\`mobile-animation\` overrides — pure CSS \`@media\`
|
|
105
|
+
* switches, mirroring \`base\` above per animation value, so no JS ever
|
|
106
|
+
* needs to read the actual viewport width (see \`animate.ts\`'s own
|
|
107
|
+
* \`tabletAnimation\`/\`mobileAnimation\` doc comments). Placed after \`base\`
|
|
108
|
+
* so equal-specificity ties (e.g. both \`animation="fade"\` and
|
|
109
|
+
* \`tablet-animation="none"\` present at once) resolve in the narrower
|
|
110
|
+
* breakpoint's favor by source order, once its \`@media\` condition is true.
|
|
111
|
+
*
|
|
112
|
+
* \`max-width\` values match \`EUNOMIA_BREAKPOINTS.tablet\`/\`.mobile\`
|
|
113
|
+
* (\`breakpoints.ts\`) — hardcoded here since a plain CSS \`@media\` query
|
|
114
|
+
* can't read a JS constant.
|
|
115
|
+
*/
|
|
116
|
+
const breakpoints = css `
|
|
117
|
+
@media (max-width: 768px) {
|
|
118
|
+
:host([tablet-animation="none"]) {
|
|
119
|
+
opacity: 1;
|
|
120
|
+
transform: none;
|
|
121
|
+
transition-property: none;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
:host([tablet-animation="fade"]) {
|
|
125
|
+
opacity: 0;
|
|
126
|
+
transition-property: opacity;
|
|
127
|
+
}
|
|
128
|
+
:host([tablet-animation="fade"][in-view]) {
|
|
129
|
+
opacity: 1;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
:host([tablet-animation="scroll-right"]) {
|
|
133
|
+
transform: translateX(calc(-1 * var(--_distance)));
|
|
134
|
+
transition-property: transform;
|
|
135
|
+
}
|
|
136
|
+
:host([tablet-animation="scroll-right"][in-view]) {
|
|
137
|
+
transform: translateX(0);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
:host([tablet-animation="scroll-left"]) {
|
|
141
|
+
transform: translateX(var(--_distance));
|
|
142
|
+
transition-property: transform;
|
|
143
|
+
}
|
|
144
|
+
:host([tablet-animation="scroll-left"][in-view]) {
|
|
145
|
+
transform: translateX(0);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
:host([tablet-animation="scroll-top"]) {
|
|
149
|
+
transform: translateY(var(--_distance));
|
|
150
|
+
transition-property: transform;
|
|
151
|
+
}
|
|
152
|
+
:host([tablet-animation="scroll-top"][in-view]) {
|
|
153
|
+
transform: translateY(0);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
:host([tablet-animation="scroll-bottom"]) {
|
|
157
|
+
transform: translateY(calc(-1 * var(--_distance)));
|
|
158
|
+
transition-property: transform;
|
|
159
|
+
}
|
|
160
|
+
:host([tablet-animation="scroll-bottom"][in-view]) {
|
|
161
|
+
transform: translateY(0);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
:host([tablet-animation="faded-scroll-right"]) {
|
|
165
|
+
opacity: 0;
|
|
166
|
+
transform: translateX(calc(-1 * var(--_distance)));
|
|
167
|
+
transition-property: opacity, transform;
|
|
168
|
+
}
|
|
169
|
+
:host([tablet-animation="faded-scroll-right"][in-view]) {
|
|
170
|
+
opacity: 1;
|
|
171
|
+
transform: translateX(0);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
:host([tablet-animation="faded-scroll-left"]) {
|
|
175
|
+
opacity: 0;
|
|
176
|
+
transform: translateX(var(--_distance));
|
|
177
|
+
transition-property: opacity, transform;
|
|
178
|
+
}
|
|
179
|
+
:host([tablet-animation="faded-scroll-left"][in-view]) {
|
|
180
|
+
opacity: 1;
|
|
181
|
+
transform: translateX(0);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
:host([tablet-animation="faded-scroll-top"]) {
|
|
185
|
+
opacity: 0;
|
|
186
|
+
transform: translateY(var(--_distance));
|
|
187
|
+
transition-property: opacity, transform;
|
|
188
|
+
}
|
|
189
|
+
:host([tablet-animation="faded-scroll-top"][in-view]) {
|
|
190
|
+
opacity: 1;
|
|
191
|
+
transform: translateY(0);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
:host([tablet-animation="faded-scroll-bottom"]) {
|
|
195
|
+
opacity: 0;
|
|
196
|
+
transform: translateY(calc(-1 * var(--_distance)));
|
|
197
|
+
transition-property: opacity, transform;
|
|
198
|
+
}
|
|
199
|
+
:host([tablet-animation="faded-scroll-bottom"][in-view]) {
|
|
200
|
+
opacity: 1;
|
|
201
|
+
transform: translateY(0);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@media (max-width: 600px) {
|
|
206
|
+
:host([mobile-animation="none"]) {
|
|
207
|
+
opacity: 1;
|
|
208
|
+
transform: none;
|
|
209
|
+
transition-property: none;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
:host([mobile-animation="fade"]) {
|
|
213
|
+
opacity: 0;
|
|
214
|
+
transition-property: opacity;
|
|
215
|
+
}
|
|
216
|
+
:host([mobile-animation="fade"][in-view]) {
|
|
217
|
+
opacity: 1;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
:host([mobile-animation="scroll-right"]) {
|
|
221
|
+
transform: translateX(calc(-1 * var(--_distance)));
|
|
222
|
+
transition-property: transform;
|
|
223
|
+
}
|
|
224
|
+
:host([mobile-animation="scroll-right"][in-view]) {
|
|
225
|
+
transform: translateX(0);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
:host([mobile-animation="scroll-left"]) {
|
|
229
|
+
transform: translateX(var(--_distance));
|
|
230
|
+
transition-property: transform;
|
|
231
|
+
}
|
|
232
|
+
:host([mobile-animation="scroll-left"][in-view]) {
|
|
233
|
+
transform: translateX(0);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
:host([mobile-animation="scroll-top"]) {
|
|
237
|
+
transform: translateY(var(--_distance));
|
|
238
|
+
transition-property: transform;
|
|
239
|
+
}
|
|
240
|
+
:host([mobile-animation="scroll-top"][in-view]) {
|
|
241
|
+
transform: translateY(0);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
:host([mobile-animation="scroll-bottom"]) {
|
|
245
|
+
transform: translateY(calc(-1 * var(--_distance)));
|
|
246
|
+
transition-property: transform;
|
|
247
|
+
}
|
|
248
|
+
:host([mobile-animation="scroll-bottom"][in-view]) {
|
|
249
|
+
transform: translateY(0);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
:host([mobile-animation="faded-scroll-right"]) {
|
|
253
|
+
opacity: 0;
|
|
254
|
+
transform: translateX(calc(-1 * var(--_distance)));
|
|
255
|
+
transition-property: opacity, transform;
|
|
256
|
+
}
|
|
257
|
+
:host([mobile-animation="faded-scroll-right"][in-view]) {
|
|
258
|
+
opacity: 1;
|
|
259
|
+
transform: translateX(0);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
:host([mobile-animation="faded-scroll-left"]) {
|
|
263
|
+
opacity: 0;
|
|
264
|
+
transform: translateX(var(--_distance));
|
|
265
|
+
transition-property: opacity, transform;
|
|
266
|
+
}
|
|
267
|
+
:host([mobile-animation="faded-scroll-left"][in-view]) {
|
|
268
|
+
opacity: 1;
|
|
269
|
+
transform: translateX(0);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
:host([mobile-animation="faded-scroll-top"]) {
|
|
273
|
+
opacity: 0;
|
|
274
|
+
transform: translateY(var(--_distance));
|
|
275
|
+
transition-property: opacity, transform;
|
|
276
|
+
}
|
|
277
|
+
:host([mobile-animation="faded-scroll-top"][in-view]) {
|
|
278
|
+
opacity: 1;
|
|
279
|
+
transform: translateY(0);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
:host([mobile-animation="faded-scroll-bottom"]) {
|
|
283
|
+
opacity: 0;
|
|
284
|
+
transform: translateY(calc(-1 * var(--_distance)));
|
|
285
|
+
transition-property: opacity, transform;
|
|
286
|
+
}
|
|
287
|
+
:host([mobile-animation="faded-scroll-bottom"][in-view]) {
|
|
288
|
+
opacity: 1;
|
|
289
|
+
transform: translateY(0);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
`;
|
|
293
|
+
export const animateStyles = [base, breakpoints];
|
|
@@ -50,7 +50,7 @@ const base = css `
|
|
|
50
50
|
|
|
51
51
|
#carousel-header {
|
|
52
52
|
display: flex;
|
|
53
|
-
align-items: var(--carousel-header-align,
|
|
53
|
+
align-items: var(--carousel-header-align, flex-end);
|
|
54
54
|
justify-content: space-between;
|
|
55
55
|
gap: var(--carousel-header-gap, var(--eun-space-m, 16px));
|
|
56
56
|
margin-bottom: var(--eun-space-m, 16px);
|
|
@@ -54,6 +54,8 @@ declare const EunomiaToolbar_base: import("../../../utils/constructor.type.js").
|
|
|
54
54
|
* everything behind it, including the logo and any other bar content;
|
|
55
55
|
* the burger is the only thing that stays visible in front of it.
|
|
56
56
|
*
|
|
57
|
+
* @slot [menu-icon] - Replaces the burger's default open icon (an `eun-icon name="menu"`) with any content, shown while the panel is closed. Useful wherever `eun-icon`'s own dynamic SVG resolution doesn't fit, e.g. some bundler setups
|
|
58
|
+
* @slot [close-icon] - Replaces the burger's default close icon (an `eun-icon name="close"`) with any content, shown while the panel is open. See `menu-icon` above
|
|
57
59
|
* @slot start - Left-side content, rendered after a logo image linking to logoHref whenever logoSrc is set
|
|
58
60
|
* @slot center - Center content, truly centered independently of the start and end widths
|
|
59
61
|
* @slot end - Right-side content
|
|
@@ -135,6 +137,7 @@ declare const EunomiaToolbar_base: import("../../../utils/constructor.type.js").
|
|
|
135
137
|
* @cssprop [--toolbar-skip-links-background] - Sets the background of the skip-links bar, defaulting to a darker mix of the bar's own background
|
|
136
138
|
* @cssprop [--toolbar-skip-links-color] - Sets the text color of the skip-links bar
|
|
137
139
|
* @cssprop [--toolbar-skip-links-separator-color] - Sets the color of the divider drawn between skip links
|
|
140
|
+
* @cssprop [--toolbar-skip-links-gap] - Sets the gap between skip links, with the divider centered in it
|
|
138
141
|
* @element eun-toolbar
|
|
139
142
|
*/
|
|
140
143
|
export declare class EunomiaToolbar extends EunomiaToolbar_base {
|
|
@@ -302,6 +305,25 @@ export declare class EunomiaToolbar extends EunomiaToolbar_base {
|
|
|
302
305
|
* @readonly
|
|
303
306
|
*/
|
|
304
307
|
private readonly burgerEl?;
|
|
308
|
+
/**
|
|
309
|
+
* Elements assigned to the `menu-icon` slot, if any ; queried live so the
|
|
310
|
+
* default `eun-icon` fallback correctly appears/disappears as content is
|
|
311
|
+
* slotted/removed, same pattern `eun-collapse`'s `chevron` slot uses.
|
|
312
|
+
* @internal
|
|
313
|
+
*/
|
|
314
|
+
private readonly menuIconSlotEls;
|
|
315
|
+
/**
|
|
316
|
+
* Elements assigned to the `close-icon` slot, if any ; see
|
|
317
|
+
* {@link menuIconSlotEls}.
|
|
318
|
+
* @internal
|
|
319
|
+
*/
|
|
320
|
+
private readonly closeIconSlotEls;
|
|
321
|
+
/**
|
|
322
|
+
* Re-renders once a `menu-icon`/`close-icon` slot's content changes, so
|
|
323
|
+
* the default `eun-icon` fallback correctly appears/disappears.
|
|
324
|
+
* @private
|
|
325
|
+
*/
|
|
326
|
+
private handleIconSlotChange;
|
|
305
327
|
/**
|
|
306
328
|
* The live `matchMedia` list backing {@link mobile}, rebuilt whenever
|
|
307
329
|
* `mobileBreakpoint` changes.
|