@sbb-esta/lyne-elements 5.2.0 → 5.3.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.
@@ -1,5 +1,5 @@
1
1
  import { type CSSResultGroup, type PropertyValues, type TemplateResult } from 'lit';
2
- import { type FormRestoreReason, type FormRestoreState, SbbElement } from '../../core.ts';
2
+ import { type FormRestoreReason, type FormRestoreState, SbbElement, type SbbElementType } from '../../core.ts';
3
3
  export declare class SbbChipInputTokenEndEvent<T = string> extends Event {
4
4
  /** The element that triggered the chip creation */
5
5
  origin: 'input' | 'autocomplete';
@@ -26,6 +26,7 @@ declare const SbbChipGroupElement_base: import("../../core.ts").AbstractConstruc
26
26
  */
27
27
  export declare class SbbChipGroupElement<T = string> extends SbbChipGroupElement_base {
28
28
  static readonly elementName: string;
29
+ static elementDependencies: SbbElementType[];
29
30
  static readonly role = "listbox";
30
31
  static styles: CSSResultGroup;
31
32
  static readonly events: {
@@ -237,6 +237,9 @@ let SbbChipGroupElement = (() => {
237
237
  static {
238
238
  this.elementName = "sbb-chip-group";
239
239
  }
240
+ static {
241
+ this.elementDependencies = [SbbChipElement];
242
+ }
240
243
  static {
241
244
  this.role = "listbox";
242
245
  }
@@ -18,6 +18,8 @@ export declare const i18nRestaurantWagonLabel: Record<string, string>;
18
18
  export declare const i18nBlockedPassage: Record<string, Record<string, string>>;
19
19
  export declare const i18nAdditionalWagonInformationHeading: Record<string, string>;
20
20
  export declare const i18nDeparture: Record<string, string>;
21
+ export declare const i18nNonAccessible: Record<string, string>;
22
+ export declare const i18nDownload: Record<string, string>;
21
23
  export declare const i18nDurationMinute: Record<string, Record<string, Record<string, string>>>;
22
24
  export declare const i18nDurationHour: Record<string, Record<string, Record<string, string>>>;
23
25
  export declare const i18nDurationDay: Record<string, Record<string, Record<string, string>>>;
@@ -1817,6 +1817,18 @@ const i18nDeparture = {
1817
1817
  fr: "Départ",
1818
1818
  it: "Partenza"
1819
1819
  };
1820
+ const i18nNonAccessible = {
1821
+ de: "nicht barrierefrei",
1822
+ en: "not accessible",
1823
+ fr: "non accessible",
1824
+ it: "non accessibile"
1825
+ };
1826
+ const i18nDownload = {
1827
+ de: "herunterladen",
1828
+ en: "download",
1829
+ fr: "télécharger",
1830
+ it: "scaricare"
1831
+ };
1820
1832
  const i18nDurationMinute = {
1821
1833
  single: {
1822
1834
  long: {
@@ -6148,4 +6160,4 @@ function removeAriaComboBoxAttributes(trigger) {
6148
6160
  }
6149
6161
 
6150
6162
  //#endregion
6151
- export { DateAdapter, FORMAT_DATE, FRIDAY, ISO8601_FORMAT_DATE, IS_FOCUSABLE_QUERY, InteractivityChecker, IsFocusableConfig, MONDAY, NativeDateAdapter, SATURDAY, SUNDAY, SbbActionBaseElement, SbbAnimationCompleteMixin, SbbButtonBaseElement, SbbButtonLikeBaseElement, SbbDarkModeController, SbbDisabledInteractiveMixin, SbbDisabledMixin, SbbDisabledTabIndexActionMixin, SbbElement, SbbEscapableOverlayController, SbbFocusTrapController, SbbFocusVisibleWithinController, SbbFormAssociatedCheckboxMixin, SbbFormAssociatedInputMixin, SbbFormAssociatedMixin, SbbFormAssociatedRadioButtonMixin, SbbIdReferenceController, SbbInertController, SbbLanguageController, SbbLinkBaseElement, SbbLiveAnnouncer, SbbMediaMatcherController, SbbMediaQueryBreakpointLargeAndAbove, SbbMediaQueryBreakpointLargeAndBelow, SbbMediaQueryBreakpointSmallAndAbove, SbbMediaQueryBreakpointSmallAndBelow, SbbMediaQueryBreakpointUltraAndAbove, SbbMediaQueryBreakpointZeroAndAbove, SbbMediaQueryDarkMode, SbbMediaQueryForcedColors, SbbMediaQueryHover, SbbMediaQueryPointerCoarse, SbbNamedSlotListMixin, SbbNegativeMixin, SbbOpenCloseBaseElement, SbbOverlayOutsidePointerEventListener, SbbOverlayPositionController, SbbPanelMixin, SbbPropertyWatcherController, SbbReadonlyMixin, SbbRequiredMixin, SbbScrollHandler, SbbSelectionGroupBaseElement, SbbSelectionPanelMixin, SbbSlottedChangeEvent, SbbUpdateSchedulerMixin, THURSDAY, TUESDAY, TemporalDateAdapter, WEDNESDAY, appendAriaElements, buttonResetStyles, containsPierceShadowDom, defaultDateAdapter, forceType, forwardEvent, getElementPosition, getElementPositionHorizontal, getElementRectangle, getEventTarget, getNextElementIndex, getOverride, handleDistinctChange, hostScrollbarStyles, i18nAdditionalWagonInformationHeading, i18nAnd, i18nArrival, i18nBlockedPassage, i18nBreadcrumbEllipsisButtonLabel, i18nCalendarDateSelection, i18nCalendarWeekNumber, i18nCarouselArrowsNavigationHint, i18nCarouselItemAriaLabel, i18nCheckboxRequired, i18nChipDelete, i18nChipGroupInputDescription, i18nClass, i18nClearInput, i18nCloseAlert, i18nCloseDialog, i18nCloseNavigation, i18nCloseNotification, i18nClosePopover, i18nCloseSidebar, i18nClosedCompartmentLabel, i18nCollapsed, i18nConnectionFrom, i18nConnectionRoundtrip, i18nConnectionTo, i18nCouchetteWagonLabel, i18nDateChangedTo, i18nDateInvalid, i18nDateMax, i18nDateMin, i18nDatePickerPlaceholder, i18nDeparture, i18nDialog, i18nDirection, i18nDurationDay, i18nDurationHour, i18nDurationMinute, i18nExpanded, i18nFileSelectorButtonLabel, i18nFileSelectorButtonLabelMultiple, i18nFileSelectorCurrentlySelected, i18nFileSelectorDeleteFile, i18nFileSelectorSubtitleLabel, i18nFileSelectorSubtitleLabelMultiple, i18nFlipCard, i18nFromPlatform, i18nGoBack, i18nInputRequired, i18nItemsPerPage, i18nLocomotiveLabel, i18nMapContainerButtonLabel, i18nMeansOfTransport, i18nNew, i18nNextDay, i18nNextMonth, i18nNextPage, i18nNextSlide, i18nNextYear, i18nNextYearRange, i18nOccupancy, i18nPage, i18nPaginatorOf, i18nPaginatorSelected, i18nPreviousDay, i18nPreviousMonth, i18nPreviousPage, i18nPreviousSlide, i18nPreviousYear, i18nPreviousYearRange, i18nRealTimeInfo, i18nRemainingCharacters, i18nRestaurantWagonLabel, i18nReverseCard, i18nSector, i18nSectorShort, i18nSelectNextDay, i18nSelectPreviousDay, i18nSelectionRequired, i18nShowCalendar, i18nSleepingWagonLabel, i18nSlide, i18nSupersaver, i18nTargetOpensInNewWindow, i18nTimeInputChange, i18nTimeInvalid, i18nTimeMax, i18nTimeMaxLength, i18nTimetableFormSwapButtonLabel, i18nToday, i18nTrain, i18nTrains, i18nTransferProcedure, i18nTransferProcedures, i18nTravelhints, i18nTripDuration, i18nTripQuayChange, i18nWagonLabel, i18nWagonLabelNumber, i18nWagonsLabel, i18nWalkingDistanceArrival, i18nWalkingDistanceDeparture, i18nYearMonthSelection, idReference, interactivityChecker, isAndroid, isArrowKeyOrPageKeysPressed, isArrowKeyPressed, isBlink, isChromium, isEdge, isEventOnElement, isEventPrevented, isFakeMousedownFromScreenReader, isFakeTouchstartFromScreenReader, isFirefox, isIOS, isMacOS, isNextArrowKeyPressed, isNextjs, isPreviousArrowKeyPressed, isSafari, isTrident, isWebkit, isZeroAnimationDuration, listResetStyles, mergeConfig, omitEmptyConverter, pageScrollDisabled, plainDate, plainDateConverter, popoverResetStyles, preventScrollOnSpacebarPress, queueDomContentLoaded, radioButtonRegistry, readConfig, removeAriaComboBoxAttributes, removeAriaElements, removeAriaOverlayTriggerProperties, sbbInputModalityDetector, sbbLiveAnnouncer, sbbOverlayOutsidePointerEventListener, screenReaderOnlyStyles, scrollbarStyles, setAriaComboBoxAttributes, setAriaOverlayTriggerProperties, setOrRemoveAttribute, setOverlayPosition, ɵstateController };
6163
+ export { DateAdapter, FORMAT_DATE, FRIDAY, ISO8601_FORMAT_DATE, IS_FOCUSABLE_QUERY, InteractivityChecker, IsFocusableConfig, MONDAY, NativeDateAdapter, SATURDAY, SUNDAY, SbbActionBaseElement, SbbAnimationCompleteMixin, SbbButtonBaseElement, SbbButtonLikeBaseElement, SbbDarkModeController, SbbDisabledInteractiveMixin, SbbDisabledMixin, SbbDisabledTabIndexActionMixin, SbbElement, SbbEscapableOverlayController, SbbFocusTrapController, SbbFocusVisibleWithinController, SbbFormAssociatedCheckboxMixin, SbbFormAssociatedInputMixin, SbbFormAssociatedMixin, SbbFormAssociatedRadioButtonMixin, SbbIdReferenceController, SbbInertController, SbbLanguageController, SbbLinkBaseElement, SbbLiveAnnouncer, SbbMediaMatcherController, SbbMediaQueryBreakpointLargeAndAbove, SbbMediaQueryBreakpointLargeAndBelow, SbbMediaQueryBreakpointSmallAndAbove, SbbMediaQueryBreakpointSmallAndBelow, SbbMediaQueryBreakpointUltraAndAbove, SbbMediaQueryBreakpointZeroAndAbove, SbbMediaQueryDarkMode, SbbMediaQueryForcedColors, SbbMediaQueryHover, SbbMediaQueryPointerCoarse, SbbNamedSlotListMixin, SbbNegativeMixin, SbbOpenCloseBaseElement, SbbOverlayOutsidePointerEventListener, SbbOverlayPositionController, SbbPanelMixin, SbbPropertyWatcherController, SbbReadonlyMixin, SbbRequiredMixin, SbbScrollHandler, SbbSelectionGroupBaseElement, SbbSelectionPanelMixin, SbbSlottedChangeEvent, SbbUpdateSchedulerMixin, THURSDAY, TUESDAY, TemporalDateAdapter, WEDNESDAY, appendAriaElements, buttonResetStyles, containsPierceShadowDom, defaultDateAdapter, forceType, forwardEvent, getElementPosition, getElementPositionHorizontal, getElementRectangle, getEventTarget, getNextElementIndex, getOverride, handleDistinctChange, hostScrollbarStyles, i18nAdditionalWagonInformationHeading, i18nAnd, i18nArrival, i18nBlockedPassage, i18nBreadcrumbEllipsisButtonLabel, i18nCalendarDateSelection, i18nCalendarWeekNumber, i18nCarouselArrowsNavigationHint, i18nCarouselItemAriaLabel, i18nCheckboxRequired, i18nChipDelete, i18nChipGroupInputDescription, i18nClass, i18nClearInput, i18nCloseAlert, i18nCloseDialog, i18nCloseNavigation, i18nCloseNotification, i18nClosePopover, i18nCloseSidebar, i18nClosedCompartmentLabel, i18nCollapsed, i18nConnectionFrom, i18nConnectionRoundtrip, i18nConnectionTo, i18nCouchetteWagonLabel, i18nDateChangedTo, i18nDateInvalid, i18nDateMax, i18nDateMin, i18nDatePickerPlaceholder, i18nDeparture, i18nDialog, i18nDirection, i18nDownload, i18nDurationDay, i18nDurationHour, i18nDurationMinute, i18nExpanded, i18nFileSelectorButtonLabel, i18nFileSelectorButtonLabelMultiple, i18nFileSelectorCurrentlySelected, i18nFileSelectorDeleteFile, i18nFileSelectorSubtitleLabel, i18nFileSelectorSubtitleLabelMultiple, i18nFlipCard, i18nFromPlatform, i18nGoBack, i18nInputRequired, i18nItemsPerPage, i18nLocomotiveLabel, i18nMapContainerButtonLabel, i18nMeansOfTransport, i18nNew, i18nNextDay, i18nNextMonth, i18nNextPage, i18nNextSlide, i18nNextYear, i18nNextYearRange, i18nNonAccessible, i18nOccupancy, i18nPage, i18nPaginatorOf, i18nPaginatorSelected, i18nPreviousDay, i18nPreviousMonth, i18nPreviousPage, i18nPreviousSlide, i18nPreviousYear, i18nPreviousYearRange, i18nRealTimeInfo, i18nRemainingCharacters, i18nRestaurantWagonLabel, i18nReverseCard, i18nSector, i18nSectorShort, i18nSelectNextDay, i18nSelectPreviousDay, i18nSelectionRequired, i18nShowCalendar, i18nSleepingWagonLabel, i18nSlide, i18nSupersaver, i18nTargetOpensInNewWindow, i18nTimeInputChange, i18nTimeInvalid, i18nTimeMax, i18nTimeMaxLength, i18nTimetableFormSwapButtonLabel, i18nToday, i18nTrain, i18nTrains, i18nTransferProcedure, i18nTransferProcedures, i18nTravelhints, i18nTripDuration, i18nTripQuayChange, i18nWagonLabel, i18nWagonLabelNumber, i18nWagonsLabel, i18nWalkingDistanceArrival, i18nWalkingDistanceDeparture, i18nYearMonthSelection, idReference, interactivityChecker, isAndroid, isArrowKeyOrPageKeysPressed, isArrowKeyPressed, isBlink, isChromium, isEdge, isEventOnElement, isEventPrevented, isFakeMousedownFromScreenReader, isFakeTouchstartFromScreenReader, isFirefox, isIOS, isMacOS, isNextArrowKeyPressed, isNextjs, isPreviousArrowKeyPressed, isSafari, isTrident, isWebkit, isZeroAnimationDuration, listResetStyles, mergeConfig, omitEmptyConverter, pageScrollDisabled, plainDate, plainDateConverter, popoverResetStyles, preventScrollOnSpacebarPress, queueDomContentLoaded, radioButtonRegistry, readConfig, removeAriaComboBoxAttributes, removeAriaElements, removeAriaOverlayTriggerProperties, sbbInputModalityDetector, sbbLiveAnnouncer, sbbOverlayOutsidePointerEventListener, screenReaderOnlyStyles, scrollbarStyles, setAriaComboBoxAttributes, setAriaOverlayTriggerProperties, setOrRemoveAttribute, setOverlayPosition, ɵstateController };
@@ -0,0 +1,51 @@
1
+ import { type CSSResultGroup, type PropertyValues, type TemplateResult } from 'lit';
2
+ import { type SbbElementType, SbbLinkBaseElement } from '../../core.ts';
3
+ declare const SbbDownloadElement_base: import("../../core.ts").AbstractConstructor<import("../../icon.pure.ts").SbbIconNameMixinType> & typeof SbbLinkBaseElement;
4
+ /**
5
+ * It displays a downloadable document, styled as a card.
6
+ *
7
+ * Inherits link properties from `SbbLinkBaseElement`: `href`, `target`, `rel`
8
+ * and `accessibilityLabel`. The download behavior is always enabled.
9
+ *
10
+ * @slot - Use the unnamed slot to add custom content. Optional.
11
+ * @slot info - Slot used to render a `sbb-download-info`. A `sbb-download-info`
12
+ * placed in the unnamed slot is automatically moved to this slot. Optional.
13
+ * @slot icon - Use this slot to display a custom icon, by providing a
14
+ * `sbb-icon` component. Optional.
15
+ */
16
+ export declare class SbbDownloadElement extends SbbDownloadElement_base {
17
+ static readonly elementName: string;
18
+ static elementDependencies: SbbElementType[];
19
+ static styles: CSSResultGroup;
20
+ /** Option to set the component's background color. */
21
+ accessor color: 'white' | 'milk';
22
+ /** The label of the download. Defaults to the file name of the `href`. */
23
+ accessor label: string;
24
+ /**
25
+ * The download behavior is always enabled and handled internally, therefore
26
+ * this property cannot be disabled and is not reflected to the host element.
27
+ * @default true
28
+ */
29
+ set download(_value: boolean);
30
+ get download(): boolean;
31
+ /** The file name extracted from the `href` (e.g. `report.pdf`). */
32
+ get fileName(): string;
33
+ /** The lower-cased file extension extracted from the `href` (e.g. `pdf`), if any. */
34
+ get fileExtension(): string;
35
+ private _languageController;
36
+ /**
37
+ * Provides a default icon based on the `href` extension, if no icon name is
38
+ * set.
39
+ */
40
+ protected renderIconName(): string;
41
+ protected firstUpdated(_changedProperties: PropertyValues): void;
42
+ private _updateDescribedByElements;
43
+ private _downloadInfoElements;
44
+ protected renderTemplate(): TemplateResult;
45
+ }
46
+ declare global {
47
+ interface HTMLElementTagNameMap {
48
+ 'sbb-download': SbbDownloadElement;
49
+ }
50
+ }
51
+ export {};
@@ -0,0 +1,59 @@
1
+ import { type CSSResultGroup, type PropertyValues, type TemplateResult } from 'lit';
2
+ import { SbbElement } from '../../core.ts';
3
+ /**
4
+ * It displays metadata of a document; used within a `sbb-download`.
5
+ */
6
+ export declare class SbbDownloadInfoElement extends SbbElement {
7
+ static readonly elementName: string;
8
+ static styles: CSSResultGroup;
9
+ /**
10
+ * The type of the document (e.g. `PDF`). Falls back to the extension of the
11
+ * parent `sbb-download`.
12
+ */
13
+ accessor type: string;
14
+ /**
15
+ * The size of the document. If the value contains non-numeric characters it
16
+ * is rendered as is, otherwise it is interpreted as a number of bytes and
17
+ * shortened to the closest unit.
18
+ */
19
+ accessor size: string;
20
+ /** The date of the latest change of the document, as an ISO 8601 string. */
21
+ accessor changed: string;
22
+ /** Whether the document is not accessible. */
23
+ accessor nonAccessible: boolean;
24
+ private _language;
25
+ private _dateAdapter;
26
+ private _resolvedType;
27
+ private _typeRedundant;
28
+ private _resolvedSize;
29
+ private _resolvedChanged;
30
+ constructor();
31
+ connectedCallback(): void;
32
+ protected willUpdate(changedProperties: PropertyValues<this>): void;
33
+ /** Resolves the type, falling back to the extension of the parent download's
34
+ * href.
35
+ */
36
+ private _resolveType;
37
+ /**
38
+ * Whether the type is already conveyed by the parent download's label.
39
+ * When the parent download has no explicit `label`, it falls back to the file
40
+ * name (e.g. `some-file.pdf`), which already includes the extension. In that
41
+ * case the type is redundant for assistive technology.
42
+ */
43
+ private _isTypeRedundant;
44
+ /**
45
+ * Formats the size, shortening a pure number of bytes to the closest unit.
46
+ */
47
+ private _resolveSize;
48
+ /**
49
+ * Formats the ISO 8601 change date using the configured date adapter, or
50
+ * renders it as is if invalid.
51
+ */
52
+ private _resolveChanged;
53
+ protected render(): TemplateResult;
54
+ }
55
+ declare global {
56
+ interface HTMLElementTagNameMap {
57
+ 'sbb-download-info': SbbDownloadInfoElement;
58
+ }
59
+ }
@@ -0,0 +1 @@
1
+ export * from './download.pure.ts';
@@ -0,0 +1,10 @@
1
+ import { SbbDownloadElement, SbbDownloadInfoElement } from "./download.pure.js";
2
+
3
+ export * from "./download.pure.js"
4
+
5
+ //#region src/elements/download.ts
6
+ /** @entrypoint */
7
+ SbbDownloadElement.define();
8
+ SbbDownloadInfoElement.define();
9
+
10
+ //#endregion
@@ -0,0 +1,3 @@
1
+ /** @entrypoint */
2
+ export * from './download/download/download.component.ts';
3
+ export * from './download/download-info/download-info.component.ts';
@@ -0,0 +1,436 @@
1
+ import { __esDecorate, __runInitializers } from "tslib";
2
+ import { html, nothing, unsafeCSS } from "lit";
3
+ import { property } from "lit/decorators.js";
4
+ import { SbbSecondaryButtonStaticElement } from "./button.pure.js";
5
+ import { SbbElement, SbbLanguageController, SbbLinkBaseElement, SbbPropertyWatcherController, defaultDateAdapter, forceType, i18nDownload, i18nNonAccessible, omitEmptyConverter, readConfig, screenReaderOnlyStyles } from "./core.js";
6
+ import { SbbIconNameMixin } from "./icon.pure.js";
7
+
8
+ //#region src/elements/download/download/download.scss?inline
9
+ var download_default = ":host {\n --sbb-card-background-color: var(--sbb-background-color-1);\n --sbb-card-border-color: transparent;\n --sbb-card-border-radius: var(--sbb-border-radius-4x);\n --sbb-card-animation-easing: var(--sbb-animation-easing);\n --sbb-card-border-style: solid;\n --sbb-card-padding-inline-default: var(--sbb-spacing-responsive-s);\n --sbb-card-padding-block-default: var(--sbb-spacing-responsive-xxxs);\n --sbb-card-with-badge-padding-block-default: var(--sbb-spacing-fixed-6x) var(--sbb-spacing-responsive-xxxs);\n --sbb-card-padding-block: var(--sbb-card-padding-block-default);\n --sbb-card-with-badge-padding-block: var(--sbb-card-with-badge-padding-block-default);\n --sbb-card-padding-inline: var(--sbb-card-padding-inline-default);\n display: block;\n}\n\n:host(:where([color=white])) {\n --sbb-card-background-color: var(--sbb-background-color-1);\n --sbb-card-border-color: transparent;\n}\n\n:host(:where([color=milk])) {\n --sbb-card-background-color: var(--sbb-background-color-3);\n --sbb-card-border-color: transparent;\n}\n\n.sbb-download {\n --sbb-focus-outline-color: var(--sbb-focus-outline-color-default);\n --sbb-focus-outline-color: light-dark(\n var(--sbb-focus-outline-color-default),\n var(--sbb-focus-outline-color-dark)\n );\n --sbb-card-animation-duration: var(\n --sbb-disable-animation-duration,\n var(--sbb-animation-duration-1x)\n );\n display: block;\n position: relative;\n padding-inline: var(--sbb-card-padding-inline);\n padding-block: var(--sbb-card-padding-block);\n border-radius: var(--sbb-card-border-radius);\n background-color: var(--sbb-card-background-color);\n box-shadow: none;\n transition: box-shadow var(--sbb-card-animation-duration) var(--sbb-card-animation-easing);\n color: var(--sbb-card-color);\n}\n.sbb-download::after {\n content: \"\";\n position: absolute;\n inset: 0;\n background-color: transparent;\n border: var(--sbb-card-border-width) var(--sbb-card-border-style) var(--sbb-card-border-color);\n border-radius: var(--sbb-card-border-radius);\n pointer-events: none;\n}\n@media (forced-colors: active) {\n .sbb-download {\n --sbb-title-color: var(--sbb-card-color);\n }\n}\n.sbb-download {\n display: flex;\n align-items: center;\n gap: var(--sbb-download-gap);\n text-decoration: none;\n translate: 0 var(--sbb-card-hover-shift, 0);\n transition: box-shadow var(--sbb-card-animation-duration) var(--sbb-card-animation-easing), translate var(--sbb-card-animation-duration) var(--sbb-card-animation-easing);\n}\n\n.sbb-download:focus-visible {\n outline-offset: var(--sbb-focus-outline-offset);\n outline: var(--sbb-focus-outline-color) var(--sbb-focus-outline-style, solid) var(--sbb-focus-outline-width);\n}\n\n@media (any-hover: hover) {\n :host(:hover) .sbb-download {\n --sbb-card-hover-shift: -0.125rem;\n box-shadow: var(--sbb-box-shadow-level-9-hard);\n }\n}\n@media (any-hover: hover) and (forced-colors: active) {\n :host(:hover) .sbb-download {\n --sbb-card-border-color: Highlight;\n }\n}\n\n.sbb-download__icon {\n flex: 0 0 auto;\n}\n\n.sbb-download__content {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.sbb-download__label {\n overflow-wrap: break-word;\n font-weight: bold;\n color: var(--sbb-download-label-color);\n}\n\n.sbb-download__custom-content,\n.sbb-download__info {\n line-height: var(--sbb-typo-line-height-text);\n letter-spacing: var(--sbb-typo-letter-spacing-text);\n font-size: var(--sbb-text-font-size-xxs);\n color: var(--sbb-download-info-color);\n}\n\n.sbb-download__button {\n flex: 0 0 auto;\n margin-inline-start: auto;\n}\n";
10
+
11
+ //#endregion
12
+ //#region src/elements/download/download/download.component.ts
13
+ const fileExtensionIcons = /* @__PURE__ */ new Map([
14
+ ["pdf", "document-pdf-small"],
15
+ ["xls", "document-xls-small"],
16
+ ["xlsx", "document-xls-small"],
17
+ ["ppt", "document-ppt-small"],
18
+ ["pptx", "document-ppt-small"],
19
+ ["doc", "document-doc-small"],
20
+ ["docx", "document-doc-small"],
21
+ ["zip", "document-zip-small"],
22
+ ["jpg", "document-image-small"],
23
+ ["jpeg", "document-image-small"],
24
+ ["png", "document-image-small"],
25
+ ["gif", "document-image-small"],
26
+ ["svg", "document-image-small"],
27
+ ["webp", "document-image-small"]
28
+ ]);
29
+ /**
30
+ * It displays a downloadable document, styled as a card.
31
+ *
32
+ * Inherits link properties from `SbbLinkBaseElement`: `href`, `target`, `rel`
33
+ * and `accessibilityLabel`. The download behavior is always enabled.
34
+ *
35
+ * @slot - Use the unnamed slot to add custom content. Optional.
36
+ * @slot info - Slot used to render a `sbb-download-info`. A `sbb-download-info`
37
+ * placed in the unnamed slot is automatically moved to this slot. Optional.
38
+ * @slot icon - Use this slot to display a custom icon, by providing a
39
+ * `sbb-icon` component. Optional.
40
+ */
41
+ let SbbDownloadElement = (() => {
42
+ let _classSuper = SbbIconNameMixin(SbbLinkBaseElement);
43
+ let _instanceExtraInitializers = [];
44
+ let _color_decorators;
45
+ let _color_initializers = [];
46
+ let _color_extraInitializers = [];
47
+ let _label_decorators;
48
+ let _label_initializers = [];
49
+ let _label_extraInitializers = [];
50
+ let _set_download_decorators;
51
+ return class SbbDownloadElement extends _classSuper {
52
+ constructor() {
53
+ super(...arguments);
54
+ this.#color_accessor_storage = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _color_initializers, "white"));
55
+ this.#label_accessor_storage = (__runInitializers(this, _color_extraInitializers), __runInitializers(this, _label_initializers, ""));
56
+ this._languageController = (__runInitializers(this, _label_extraInitializers), new SbbLanguageController(this));
57
+ }
58
+ static {
59
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
60
+ _color_decorators = [property({ reflect: true })];
61
+ _label_decorators = [forceType(), property({ converter: omitEmptyConverter })];
62
+ _set_download_decorators = [property({
63
+ type: Boolean,
64
+ reflect: false
65
+ })];
66
+ __esDecorate(this, null, _color_decorators, {
67
+ kind: "accessor",
68
+ name: "color",
69
+ static: false,
70
+ private: false,
71
+ access: {
72
+ has: (obj) => "color" in obj,
73
+ get: (obj) => obj.color,
74
+ set: (obj, value) => {
75
+ obj.color = value;
76
+ }
77
+ },
78
+ metadata: _metadata
79
+ }, _color_initializers, _color_extraInitializers);
80
+ __esDecorate(this, null, _label_decorators, {
81
+ kind: "accessor",
82
+ name: "label",
83
+ static: false,
84
+ private: false,
85
+ access: {
86
+ has: (obj) => "label" in obj,
87
+ get: (obj) => obj.label,
88
+ set: (obj, value) => {
89
+ obj.label = value;
90
+ }
91
+ },
92
+ metadata: _metadata
93
+ }, _label_initializers, _label_extraInitializers);
94
+ __esDecorate(this, null, _set_download_decorators, {
95
+ kind: "setter",
96
+ name: "download",
97
+ static: false,
98
+ private: false,
99
+ access: {
100
+ has: (obj) => "download" in obj,
101
+ set: (obj, value) => {
102
+ obj.download = value;
103
+ }
104
+ },
105
+ metadata: _metadata
106
+ }, null, _instanceExtraInitializers);
107
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, {
108
+ enumerable: true,
109
+ configurable: true,
110
+ writable: true,
111
+ value: _metadata
112
+ });
113
+ }
114
+ static {
115
+ this.elementName = "sbb-download";
116
+ }
117
+ static {
118
+ this.elementDependencies = [SbbSecondaryButtonStaticElement];
119
+ }
120
+ static {
121
+ this.styles = [screenReaderOnlyStyles, unsafeCSS(download_default)];
122
+ }
123
+ #color_accessor_storage;
124
+ /** Option to set the component's background color. */
125
+ get color() {
126
+ return this.#color_accessor_storage;
127
+ }
128
+ set color(value) {
129
+ this.#color_accessor_storage = value;
130
+ }
131
+ #label_accessor_storage;
132
+ /** The label of the download. Defaults to the file name of the `href`. */
133
+ get label() {
134
+ return this.#label_accessor_storage;
135
+ }
136
+ set label(value) {
137
+ this.#label_accessor_storage = value;
138
+ }
139
+ /**
140
+ * The download behavior is always enabled and handled internally, therefore
141
+ * this property cannot be disabled and is not reflected to the host element.
142
+ * @default true
143
+ */
144
+ set download(_value) {}
145
+ get download() {
146
+ return true;
147
+ }
148
+ /** The file name extracted from the `href` (e.g. `report.pdf`). */
149
+ get fileName() {
150
+ return this.href.split(/[?#]/)[0].split("/").filter(Boolean).at(-1) ?? "";
151
+ }
152
+ /** The lower-cased file extension extracted from the `href` (e.g. `pdf`), if any. */
153
+ get fileExtension() {
154
+ const fileName = this.fileName;
155
+ return fileName.includes(".") ? fileName.split(".").at(-1)?.toLowerCase() ?? "" : "";
156
+ }
157
+ /**
158
+ * Provides a default icon based on the `href` extension, if no icon name is
159
+ * set.
160
+ */
161
+ renderIconName() {
162
+ if (this.iconName) return this.iconName;
163
+ else if (!this.href) return "";
164
+ const extension = this.fileExtension;
165
+ return extension && fileExtensionIcons.get(extension) || "document-standard-small";
166
+ }
167
+ firstUpdated(_changedProperties) {
168
+ super.firstUpdated(_changedProperties);
169
+ this._updateDescribedByElements();
170
+ }
171
+ _updateDescribedByElements() {
172
+ const link = this.shadowRoot?.querySelector?.("a");
173
+ if (link) {
174
+ const customContentElement = this.shadowRoot?.querySelector?.(".sbb-download__custom-content");
175
+ link.ariaDescribedByElements = [...customContentElement ? [customContentElement] : [], ...this._downloadInfoElements()];
176
+ }
177
+ }
178
+ _downloadInfoElements() {
179
+ return this.querySelectorAll?.("sbb-download-info") ?? [];
180
+ }
181
+ renderTemplate() {
182
+ return html`
183
+ ${this.renderIconSlot("sbb-download__icon")}
184
+ <span class="sbb-download__content">
185
+ <span class="sbb-download__label">${this.label || this.fileName}</span>
186
+ <span class="sbb-screen-reader-only">
187
+ ${!this._downloadInfoElements().length ? html`&nbsp;${this.fileExtension}` : nothing}&nbsp;${i18nDownload[this._languageController.current]}
188
+ </span>
189
+ <span class="sbb-download__custom-content" aria-hidden="true">
190
+ <slot></slot>
191
+ </span>
192
+ <span class="sbb-download__info">
193
+ <slot name="info" @slotchange="${() => this._updateDescribedByElements()}"></slot>
194
+ </span>
195
+ </span>
196
+ <sbb-secondary-button-static
197
+ class="sbb-download__button"
198
+ icon-name="download-small"
199
+ ></sbb-secondary-button-static>
200
+ `;
201
+ }
202
+ };
203
+ })();
204
+
205
+ //#endregion
206
+ //#region src/elements/download/download-info/download-info.scss?inline
207
+ var download_info_default = ":host {\n display: block;\n}\n";
208
+
209
+ //#endregion
210
+ //#region src/elements/download/download-info/download-info.component.ts
211
+ const fileSizeSuffixes = [
212
+ "B",
213
+ "KB",
214
+ "MB",
215
+ "GB",
216
+ "TB"
217
+ ];
218
+ /**
219
+ * It displays metadata of a document; used within a `sbb-download`.
220
+ */
221
+ let SbbDownloadInfoElement = (() => {
222
+ let _classSuper = SbbElement;
223
+ let _type_decorators;
224
+ let _type_initializers = [];
225
+ let _type_extraInitializers = [];
226
+ let _size_decorators;
227
+ let _size_initializers = [];
228
+ let _size_extraInitializers = [];
229
+ let _changed_decorators;
230
+ let _changed_initializers = [];
231
+ let _changed_extraInitializers = [];
232
+ let _nonAccessible_decorators;
233
+ let _nonAccessible_initializers = [];
234
+ let _nonAccessible_extraInitializers = [];
235
+ return class SbbDownloadInfoElement extends _classSuper {
236
+ static {
237
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
238
+ _type_decorators = [forceType(), property({ converter: omitEmptyConverter })];
239
+ _size_decorators = [forceType(), property({ converter: omitEmptyConverter })];
240
+ _changed_decorators = [forceType(), property({ converter: omitEmptyConverter })];
241
+ _nonAccessible_decorators = [forceType(), property({
242
+ attribute: "non-accessible",
243
+ type: Boolean
244
+ })];
245
+ __esDecorate(this, null, _type_decorators, {
246
+ kind: "accessor",
247
+ name: "type",
248
+ static: false,
249
+ private: false,
250
+ access: {
251
+ has: (obj) => "type" in obj,
252
+ get: (obj) => obj.type,
253
+ set: (obj, value) => {
254
+ obj.type = value;
255
+ }
256
+ },
257
+ metadata: _metadata
258
+ }, _type_initializers, _type_extraInitializers);
259
+ __esDecorate(this, null, _size_decorators, {
260
+ kind: "accessor",
261
+ name: "size",
262
+ static: false,
263
+ private: false,
264
+ access: {
265
+ has: (obj) => "size" in obj,
266
+ get: (obj) => obj.size,
267
+ set: (obj, value) => {
268
+ obj.size = value;
269
+ }
270
+ },
271
+ metadata: _metadata
272
+ }, _size_initializers, _size_extraInitializers);
273
+ __esDecorate(this, null, _changed_decorators, {
274
+ kind: "accessor",
275
+ name: "changed",
276
+ static: false,
277
+ private: false,
278
+ access: {
279
+ has: (obj) => "changed" in obj,
280
+ get: (obj) => obj.changed,
281
+ set: (obj, value) => {
282
+ obj.changed = value;
283
+ }
284
+ },
285
+ metadata: _metadata
286
+ }, _changed_initializers, _changed_extraInitializers);
287
+ __esDecorate(this, null, _nonAccessible_decorators, {
288
+ kind: "accessor",
289
+ name: "nonAccessible",
290
+ static: false,
291
+ private: false,
292
+ access: {
293
+ has: (obj) => "nonAccessible" in obj,
294
+ get: (obj) => obj.nonAccessible,
295
+ set: (obj, value) => {
296
+ obj.nonAccessible = value;
297
+ }
298
+ },
299
+ metadata: _metadata
300
+ }, _nonAccessible_initializers, _nonAccessible_extraInitializers);
301
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, {
302
+ enumerable: true,
303
+ configurable: true,
304
+ writable: true,
305
+ value: _metadata
306
+ });
307
+ }
308
+ static {
309
+ this.elementName = "sbb-download-info";
310
+ }
311
+ static {
312
+ this.styles = [unsafeCSS(download_info_default)];
313
+ }
314
+ #type_accessor_storage;
315
+ /**
316
+ * The type of the document (e.g. `PDF`). Falls back to the extension of the
317
+ * parent `sbb-download`.
318
+ */
319
+ get type() {
320
+ return this.#type_accessor_storage;
321
+ }
322
+ set type(value) {
323
+ this.#type_accessor_storage = value;
324
+ }
325
+ #size_accessor_storage;
326
+ /**
327
+ * The size of the document. If the value contains non-numeric characters it
328
+ * is rendered as is, otherwise it is interpreted as a number of bytes and
329
+ * shortened to the closest unit.
330
+ */
331
+ get size() {
332
+ return this.#size_accessor_storage;
333
+ }
334
+ set size(value) {
335
+ this.#size_accessor_storage = value;
336
+ }
337
+ #changed_accessor_storage;
338
+ /** The date of the latest change of the document, as an ISO 8601 string. */
339
+ get changed() {
340
+ return this.#changed_accessor_storage;
341
+ }
342
+ set changed(value) {
343
+ this.#changed_accessor_storage = value;
344
+ }
345
+ #nonAccessible_accessor_storage;
346
+ /** Whether the document is not accessible. */
347
+ get nonAccessible() {
348
+ return this.#nonAccessible_accessor_storage;
349
+ }
350
+ set nonAccessible(value) {
351
+ this.#nonAccessible_accessor_storage = value;
352
+ }
353
+ constructor() {
354
+ super();
355
+ this.#type_accessor_storage = __runInitializers(this, _type_initializers, "");
356
+ this.#size_accessor_storage = (__runInitializers(this, _type_extraInitializers), __runInitializers(this, _size_initializers, ""));
357
+ this.#changed_accessor_storage = (__runInitializers(this, _size_extraInitializers), __runInitializers(this, _changed_initializers, ""));
358
+ this.#nonAccessible_accessor_storage = (__runInitializers(this, _changed_extraInitializers), __runInitializers(this, _nonAccessible_initializers, false));
359
+ this._language = (__runInitializers(this, _nonAccessible_extraInitializers), new SbbLanguageController(this));
360
+ this._dateAdapter = readConfig().datetime?.dateAdapter ?? defaultDateAdapter;
361
+ this._resolvedType = "";
362
+ this._typeRedundant = false;
363
+ this._resolvedSize = "";
364
+ this._resolvedChanged = "";
365
+ /** @internal **/
366
+ this.internals.ariaHidden = "true";
367
+ this.addController(new SbbPropertyWatcherController(this, () => this.closest("sbb-download"), {
368
+ href: () => this.requestUpdate(),
369
+ label: () => this.requestUpdate()
370
+ }));
371
+ }
372
+ connectedCallback() {
373
+ super.connectedCallback();
374
+ this.slot ||= "info";
375
+ this.requestUpdate();
376
+ }
377
+ willUpdate(changedProperties) {
378
+ super.willUpdate(changedProperties);
379
+ this._resolvedType = this._resolveType();
380
+ this._typeRedundant = this._isTypeRedundant();
381
+ if (changedProperties.has("size")) this._resolvedSize = this._resolveSize();
382
+ if (changedProperties.has("changed")) this._resolvedChanged = this._resolveChanged();
383
+ }
384
+ /** Resolves the type, falling back to the extension of the parent download's
385
+ * href.
386
+ */
387
+ _resolveType() {
388
+ return this.type || (this.closest?.("sbb-download")?.fileExtension.toUpperCase() ?? "");
389
+ }
390
+ /**
391
+ * Whether the type is already conveyed by the parent download's label.
392
+ * When the parent download has no explicit `label`, it falls back to the file
393
+ * name (e.g. `some-file.pdf`), which already includes the extension. In that
394
+ * case the type is redundant for assistive technology.
395
+ */
396
+ _isTypeRedundant() {
397
+ const parent = this.closest?.("sbb-download");
398
+ return !!parent && !parent.label && !!parent.fileExtension;
399
+ }
400
+ /**
401
+ * Formats the size, shortening a pure number of bytes to the closest unit.
402
+ */
403
+ _resolveSize() {
404
+ const size = this.size.trim();
405
+ if (!size || !/^\d+$/.test(size)) return size;
406
+ const bytes = Number(size);
407
+ if (bytes <= 0) return `0 ${fileSizeSuffixes[0]}`;
408
+ const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), fileSizeSuffixes.length - 1);
409
+ return `${(bytes / 1024 ** i).toFixed(0)} ${fileSizeSuffixes[i]}`;
410
+ }
411
+ /**
412
+ * Formats the ISO 8601 change date using the configured date adapter, or
413
+ * renders it as is if invalid.
414
+ */
415
+ _resolveChanged() {
416
+ if (!this.changed) return "";
417
+ const date = this._dateAdapter.deserialize(this.changed);
418
+ if (!this._dateAdapter.isValid(date)) return this.changed;
419
+ return this._dateAdapter.format(date, { weekdayStyle: "none" });
420
+ }
421
+ render() {
422
+ const separator = ", ";
423
+ const items = [
424
+ this._resolvedType,
425
+ this._resolvedSize,
426
+ this.nonAccessible ? i18nNonAccessible[this._language.current] : "",
427
+ this._resolvedChanged
428
+ ].filter(Boolean);
429
+ this.internals.ariaLabel = items.slice(this._typeRedundant && this._resolvedType ? 1 : 0).join(separator);
430
+ return html`${items.join(separator)}`;
431
+ }
432
+ };
433
+ })();
434
+
435
+ //#endregion
436
+ export { SbbDownloadElement, SbbDownloadInfoElement };
@@ -232,7 +232,7 @@ let SbbFlipCardElement = (() => {
232
232
  }
233
233
  /** Returns the card details content element wrapper. */
234
234
  get _detailsContentElement() {
235
- return this.details.shadowRoot.firstElementChild;
235
+ return this.details?.shadowRoot?.querySelector(".sbb-flip-card-details") ?? null;
236
236
  }
237
237
  /** Whether the flip card is flipped. */
238
238
  get isFlipped() {
@@ -268,10 +268,11 @@ let SbbFlipCardElement = (() => {
268
268
  /** Toggles the state of the sbb-flip-card. */
269
269
  toggle() {
270
270
  this._flipped = !this._flipped;
271
- if (this._flipped) {
271
+ const detailsContentElement = this._detailsContentElement;
272
+ if (this._flipped && detailsContentElement) {
272
273
  this._setCardDetailsHeight();
273
- this._cardDetailsResizeObserver.observe(this._detailsContentElement);
274
- } else this._cardDetailsResizeObserver.unobserve(this._detailsContentElement);
274
+ this._cardDetailsResizeObserver.observe(detailsContentElement);
275
+ } else if (detailsContentElement) this._cardDetailsResizeObserver.unobserve(detailsContentElement);
275
276
  this.toggleState("flipped", this._flipped);
276
277
  ɵstateController(this.details)?.toggle("flipped", this._flipped);
277
278
  this.summary.inert = this._flipped;