@solid-design-system/components 2.5.0 → 2.6.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/dist/components/es/solid-components2.js +1 -1
- package/dist/components/es/solid-element.js +5 -5
- package/dist/components/es/tab-group.js +1 -0
- package/dist/components/es/tab-panel.js +1 -0
- package/dist/components/es/tab.js +1 -0
- package/dist/components/umd/solid-components.js +18 -18
- package/dist/custom-elements.json +1 -1
- package/dist/package/components/tab/tab.d.ts +22 -0
- package/dist/package/components/tab/tab.js +94 -0
- package/dist/package/components/tab-group/tab-group.d.ts +40 -0
- package/dist/package/components/tab-group/tab-group.js +249 -0
- package/dist/package/components/tab-panel/tab-panel.d.ts +16 -0
- package/dist/package/components/tab-panel/tab-panel.js +59 -0
- package/dist/package/solid-components.d.ts +3 -0
- package/dist/package/solid-components.js +18 -12
- package/dist/package/styles/tailwind.css.js +1 -1
- package/dist/versioned-components/es/accordion-group.js +1 -1
- package/dist/versioned-components/es/accordion.js +1 -1
- package/dist/versioned-components/es/badge.js +1 -1
- package/dist/versioned-components/es/brandshape.js +1 -1
- package/dist/versioned-components/es/button.js +1 -1
- package/dist/versioned-components/es/carousel-item.js +1 -1
- package/dist/versioned-components/es/carousel.js +3 -3
- package/dist/versioned-components/es/checkbox-group.js +1 -1
- package/dist/versioned-components/es/checkbox.js +1 -1
- package/dist/versioned-components/es/dialog.js +1 -1
- package/dist/versioned-components/es/divider.js +1 -1
- package/dist/versioned-components/es/drawer.js +1 -1
- package/dist/versioned-components/es/dropdown.js +1 -1
- package/dist/versioned-components/es/form.js +1 -1
- package/dist/versioned-components/es/header.js +1 -1
- package/dist/versioned-components/es/icon.js +1 -1
- package/dist/versioned-components/es/include.js +1 -1
- package/dist/versioned-components/es/input.js +1 -1
- package/dist/versioned-components/es/link.js +1 -1
- package/dist/versioned-components/es/navigation-item.js +1 -1
- package/dist/versioned-components/es/notification.js +1 -1
- package/dist/versioned-components/es/option.js +1 -1
- package/dist/versioned-components/es/popup.js +1 -1
- package/dist/versioned-components/es/radio-button.js +1 -1
- package/dist/versioned-components/es/radio-group.js +1 -1
- package/dist/versioned-components/es/radio.js +1 -1
- package/dist/versioned-components/es/select.js +3 -3
- package/dist/versioned-components/es/solid-components2.js +1 -1
- package/dist/versioned-components/es/solid-element.js +5 -5
- package/dist/versioned-components/es/spinner.js +1 -1
- package/dist/versioned-components/es/switch.js +1 -1
- package/dist/versioned-components/es/tab-group.js +1 -0
- package/dist/versioned-components/es/tab-panel.js +1 -0
- package/dist/versioned-components/es/tab.js +1 -0
- package/dist/versioned-components/es/tag.js +1 -1
- package/dist/versioned-components/es/teaser-media.js +1 -1
- package/dist/versioned-components/es/teaser.js +1 -1
- package/dist/versioned-components/es/textarea.js +1 -1
- package/dist/versioned-components/es/tooltip.js +2 -2
- package/dist/versioned-components/es/video.js +1 -1
- package/dist/versioned-package/_components/button-group/button-group.d.ts +1 -1
- package/dist/versioned-package/_components/button-group/button-group.js +11 -11
- package/dist/versioned-package/components/accordion/accordion.d.ts +1 -1
- package/dist/versioned-package/components/accordion/accordion.js +2 -2
- package/dist/versioned-package/components/accordion-group/accordion-group.d.ts +1 -1
- package/dist/versioned-package/components/accordion-group/accordion-group.js +3 -3
- package/dist/versioned-package/components/badge/badge.d.ts +1 -1
- package/dist/versioned-package/components/badge/badge.js +1 -1
- package/dist/versioned-package/components/brandshape/brandshape.d.ts +1 -1
- package/dist/versioned-package/components/brandshape/brandshape.js +1 -1
- package/dist/versioned-package/components/button/button.d.ts +1 -1
- package/dist/versioned-package/components/button/button.js +4 -4
- package/dist/versioned-package/components/carousel/carousel.d.ts +1 -1
- package/dist/versioned-package/components/carousel/carousel.js +6 -6
- package/dist/versioned-package/components/carousel-item/carousel-item.d.ts +1 -1
- package/dist/versioned-package/components/carousel-item/carousel-item.js +1 -1
- package/dist/versioned-package/components/checkbox/checkbox.d.ts +1 -1
- package/dist/versioned-package/components/checkbox/checkbox.js +4 -4
- package/dist/versioned-package/components/checkbox-group/checkbox-group.d.ts +1 -1
- package/dist/versioned-package/components/checkbox-group/checkbox-group.js +5 -5
- package/dist/versioned-package/components/dialog/dialog.d.ts +1 -1
- package/dist/versioned-package/components/dialog/dialog.js +2 -2
- package/dist/versioned-package/components/divider/divider.d.ts +1 -1
- package/dist/versioned-package/components/divider/divider.js +2 -2
- package/dist/versioned-package/components/drawer/drawer.d.ts +1 -1
- package/dist/versioned-package/components/drawer/drawer.js +2 -2
- package/dist/versioned-package/components/dropdown/dropdown.d.ts +1 -1
- package/dist/versioned-package/components/dropdown/dropdown.js +8 -8
- package/dist/versioned-package/components/header/header.d.ts +1 -1
- package/dist/versioned-package/components/header/header.js +4 -4
- package/dist/versioned-package/components/icon/icon.d.ts +1 -1
- package/dist/versioned-package/components/icon/icon.js +1 -1
- package/dist/versioned-package/components/include/include.d.ts +1 -1
- package/dist/versioned-package/components/include/include.js +1 -1
- package/dist/versioned-package/components/input/input.d.ts +1 -1
- package/dist/versioned-package/components/input/input.js +4 -4
- package/dist/versioned-package/components/link/link.d.ts +1 -1
- package/dist/versioned-package/components/link/link.js +2 -2
- package/dist/versioned-package/components/navigation-item/navigation-item.d.ts +1 -1
- package/dist/versioned-package/components/navigation-item/navigation-item.js +3 -3
- package/dist/versioned-package/components/notification/notification.d.ts +1 -1
- package/dist/versioned-package/components/notification/notification.js +5 -5
- package/dist/versioned-package/components/option/option.d.ts +1 -1
- package/dist/versioned-package/components/option/option.js +2 -2
- package/dist/versioned-package/components/popup/popup.d.ts +1 -1
- package/dist/versioned-package/components/popup/popup.js +1 -1
- package/dist/versioned-package/components/radio/radio.d.ts +1 -1
- package/dist/versioned-package/components/radio/radio.js +2 -2
- package/dist/versioned-package/components/radio-button/radio-button.d.ts +1 -1
- package/dist/versioned-package/components/radio-button/radio-button.js +2 -2
- package/dist/versioned-package/components/radio-group/radio-group.d.ts +2 -2
- package/dist/versioned-package/components/radio-group/radio-group.js +15 -15
- package/dist/versioned-package/components/select/select.d.ts +4 -4
- package/dist/versioned-package/components/select/select.js +28 -28
- package/dist/versioned-package/components/spinner/spinner.d.ts +1 -1
- package/dist/versioned-package/components/spinner/spinner.js +1 -1
- package/dist/versioned-package/components/switch/switch.d.ts +1 -1
- package/dist/versioned-package/components/switch/switch.js +2 -2
- package/dist/versioned-package/components/tab/tab.d.ts +22 -0
- package/dist/versioned-package/components/tab/tab.js +94 -0
- package/dist/versioned-package/components/tab-group/tab-group.d.ts +40 -0
- package/dist/versioned-package/components/tab-group/tab-group.js +249 -0
- package/dist/versioned-package/components/tab-panel/tab-panel.d.ts +16 -0
- package/dist/versioned-package/components/tab-panel/tab-panel.js +59 -0
- package/dist/versioned-package/components/tag/tag.d.ts +1 -1
- package/dist/versioned-package/components/tag/tag.js +2 -2
- package/dist/versioned-package/components/teaser/teaser.js +1 -1
- package/dist/versioned-package/components/teaser-media/teaser-media.js +1 -1
- package/dist/versioned-package/components/textarea/textarea.d.ts +1 -1
- package/dist/versioned-package/components/textarea/textarea.js +3 -3
- package/dist/versioned-package/components/tooltip/tooltip.d.ts +1 -1
- package/dist/versioned-package/components/tooltip/tooltip.js +5 -5
- package/dist/versioned-package/components/video/video.d.ts +1 -1
- package/dist/versioned-package/components/video/video.js +2 -2
- package/dist/versioned-package/internal/form.js +3 -3
- package/dist/versioned-package/solid-components.d.ts +3 -0
- package/dist/versioned-package/solid-components.js +18 -12
- package/dist/versioned-package/styles/headline/headline.css.js +1 -1
- package/dist/versioned-package/styles/tailwind.css.js +1 -1
- package/dist/versioned-styles/solid-styles.css +1 -1
- package/dist/vscode.html-custom-data.json +174 -34
- package/dist/web-types.json +573 -35
- package/package.json +3 -3
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import SolidElement from '../../internal/solid-element';
|
|
2
|
+
export default class SdTab extends SolidElement {
|
|
3
|
+
private readonly attrId;
|
|
4
|
+
private readonly componentId;
|
|
5
|
+
tab: HTMLElement;
|
|
6
|
+
panel: string;
|
|
7
|
+
variant: 'default' | 'container';
|
|
8
|
+
active: boolean;
|
|
9
|
+
disabled: boolean;
|
|
10
|
+
connectedCallback(): void;
|
|
11
|
+
handleActiveChange(): void;
|
|
12
|
+
handleDisabledChange(): void;
|
|
13
|
+
focus(options?: FocusOptions): void;
|
|
14
|
+
blur(): void;
|
|
15
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
16
|
+
static styles: import("lit").CSSResultGroup[];
|
|
17
|
+
}
|
|
18
|
+
declare global {
|
|
19
|
+
interface HTMLElementTagNameMap {
|
|
20
|
+
'sd-tab': SdTab;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { css, html } from "lit";
|
|
2
|
+
import { customElement } from "../../internal/register-custom-element.js";
|
|
3
|
+
import { query, property } from "lit/decorators.js";
|
|
4
|
+
import { watch } from "../../internal/watch.js";
|
|
5
|
+
import componentStyles from "../../styles/component.styles.js";
|
|
6
|
+
import cx from "classix";
|
|
7
|
+
import SolidElement from "../../internal/solid-element.js";
|
|
8
|
+
var __defProp = Object.defineProperty;
|
|
9
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
10
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
11
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
12
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
13
|
+
if (decorator = decorators[i])
|
|
14
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
15
|
+
if (kind && result)
|
|
16
|
+
__defProp(target, key, result);
|
|
17
|
+
return result;
|
|
18
|
+
};
|
|
19
|
+
let id = 0;
|
|
20
|
+
let SdTab = class extends SolidElement {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
this.attrId = ++id;
|
|
24
|
+
this.componentId = `sd-tab-${this.attrId}`;
|
|
25
|
+
this.panel = "";
|
|
26
|
+
this.variant = "default";
|
|
27
|
+
this.active = false;
|
|
28
|
+
this.disabled = false;
|
|
29
|
+
}
|
|
30
|
+
connectedCallback() {
|
|
31
|
+
super.connectedCallback();
|
|
32
|
+
this.setAttribute("role", "tab");
|
|
33
|
+
}
|
|
34
|
+
handleActiveChange() {
|
|
35
|
+
this.setAttribute("aria-selected", this.active ? "true" : "false");
|
|
36
|
+
}
|
|
37
|
+
handleDisabledChange() {
|
|
38
|
+
this.setAttribute("aria-disabled", this.disabled ? "true" : "false");
|
|
39
|
+
}
|
|
40
|
+
/** Sets focus to the tab. */
|
|
41
|
+
focus(options) {
|
|
42
|
+
this.tab.focus(options);
|
|
43
|
+
}
|
|
44
|
+
/** Removes focus from the tab. */
|
|
45
|
+
blur() {
|
|
46
|
+
this.tab.blur();
|
|
47
|
+
}
|
|
48
|
+
render() {
|
|
49
|
+
this.id = this.id.length > 0 ? this.id : this.componentId;
|
|
50
|
+
return html`<div part="base" class="${cx(
|
|
51
|
+
"inline-flex gap-2 w-20 h-12 px-3 leading-none items-center justify-center whitespace-nowrap select-none cursor-pointer hover:bg-neutral-200 group relative focus-visible:focus-outline outline-2 !-outline-offset-2",
|
|
52
|
+
!this.active && "hover:border-b hover:border-neutral-400",
|
|
53
|
+
this.variant === "container" && " rounded-[4px_4px_0_0]",
|
|
54
|
+
this.variant === "container" && this.active && "tab--active-container-border bg-white",
|
|
55
|
+
this.disabled && "opacity-50 !cursor-not-allowed"
|
|
56
|
+
)}" tabindex="${this.disabled ? "-1" : "0"}"><slot name="left" class="pr-2"></slot><slot class="${cx(this.disabled ? "text-neutral-500" : "text-primary")}"></slot><div part="active-tab-indicator" class="${cx(
|
|
57
|
+
(!this.active || this.disabled) && "hidden",
|
|
58
|
+
"absolute bottom-0 h-1 bg-accent",
|
|
59
|
+
this.variant === "default" ? "w-full" : "w-1/2 group-hover:w-full transition-all duration-200 ease-in-out"
|
|
60
|
+
)}"></div></div>`;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
SdTab.styles = [
|
|
64
|
+
SolidElement.styles,
|
|
65
|
+
componentStyles,
|
|
66
|
+
css`:host{box-sizing:border-box;display:block}.tab--active-container-border::after{content:'';position:absolute;height:100%;width:100%;border-width:1px;--tw-border-opacity:1;border-color:rgb(var(--sd-color-neutral-400,195 195 195) / var(--tw-border-opacity));border-bottom:none;border-radius:4px 4px 0 0}`
|
|
67
|
+
];
|
|
68
|
+
__decorateClass([
|
|
69
|
+
query("[part=base]")
|
|
70
|
+
], SdTab.prototype, "tab", 2);
|
|
71
|
+
__decorateClass([
|
|
72
|
+
property({ reflect: true })
|
|
73
|
+
], SdTab.prototype, "panel", 2);
|
|
74
|
+
__decorateClass([
|
|
75
|
+
property({ type: String, reflect: true })
|
|
76
|
+
], SdTab.prototype, "variant", 2);
|
|
77
|
+
__decorateClass([
|
|
78
|
+
property({ type: Boolean, reflect: true })
|
|
79
|
+
], SdTab.prototype, "active", 2);
|
|
80
|
+
__decorateClass([
|
|
81
|
+
property({ type: Boolean, reflect: true })
|
|
82
|
+
], SdTab.prototype, "disabled", 2);
|
|
83
|
+
__decorateClass([
|
|
84
|
+
watch("active")
|
|
85
|
+
], SdTab.prototype, "handleActiveChange", 1);
|
|
86
|
+
__decorateClass([
|
|
87
|
+
watch("disabled")
|
|
88
|
+
], SdTab.prototype, "handleDisabledChange", 1);
|
|
89
|
+
SdTab = __decorateClass([
|
|
90
|
+
customElement("sd-tab")
|
|
91
|
+
], SdTab);
|
|
92
|
+
export {
|
|
93
|
+
SdTab as default
|
|
94
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import SolidElement from '../../internal/solid-element';
|
|
2
|
+
import type SdTab from '../tab/tab';
|
|
3
|
+
export default class SdTabGroup extends SolidElement {
|
|
4
|
+
private readonly localize;
|
|
5
|
+
private activeTab?;
|
|
6
|
+
private mutationObserver;
|
|
7
|
+
private resizeObserver;
|
|
8
|
+
private tabs;
|
|
9
|
+
private panels;
|
|
10
|
+
tabGroup: HTMLElement;
|
|
11
|
+
body: HTMLSlotElement;
|
|
12
|
+
nav: HTMLElement;
|
|
13
|
+
hasScrollControls: boolean;
|
|
14
|
+
variant: string;
|
|
15
|
+
activation: 'auto' | 'manual';
|
|
16
|
+
connectedCallback(): void;
|
|
17
|
+
disconnectedCallback(): void;
|
|
18
|
+
private getAllTabs;
|
|
19
|
+
private getAllPanels;
|
|
20
|
+
private getActiveTab;
|
|
21
|
+
private handleClick;
|
|
22
|
+
private handleKeyDown;
|
|
23
|
+
private handleScrollToStart;
|
|
24
|
+
private handleScrollToEnd;
|
|
25
|
+
setActiveTab(tab: SdTab, options?: {
|
|
26
|
+
emitEvents?: boolean;
|
|
27
|
+
scrollBehavior?: 'auto' | 'smooth';
|
|
28
|
+
}): void;
|
|
29
|
+
private setAriaLabels;
|
|
30
|
+
private syncTabsAndPanels;
|
|
31
|
+
private updateScrollControls;
|
|
32
|
+
show(panel: string): void;
|
|
33
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
34
|
+
static styles: import("lit").CSSResultGroup[];
|
|
35
|
+
}
|
|
36
|
+
declare global {
|
|
37
|
+
interface HTMLElementTagNameMap {
|
|
38
|
+
'sd-tab-group': SdTabGroup;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { unsafeCSS, css, html } from "lit";
|
|
2
|
+
import { customElement } from "../../internal/register-custom-element.js";
|
|
3
|
+
import { LocalizeController } from "../../utilities/localize.js";
|
|
4
|
+
import { query, state, property } from "lit/decorators.js";
|
|
5
|
+
import { scrollIntoView } from "../../internal/scroll.js";
|
|
6
|
+
import componentStyles from "../../styles/component.styles.js";
|
|
7
|
+
import cx from "classix";
|
|
8
|
+
import InteractiveStyles from "../../styles/interactive/interactive.css.js";
|
|
9
|
+
import SolidElement from "../../internal/solid-element.js";
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
13
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
14
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
15
|
+
if (decorator = decorators[i])
|
|
16
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
17
|
+
if (kind && result)
|
|
18
|
+
__defProp(target, key, result);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
let SdTabGroup = class extends SolidElement {
|
|
22
|
+
constructor() {
|
|
23
|
+
super(...arguments);
|
|
24
|
+
this.localize = new LocalizeController(this);
|
|
25
|
+
this.tabs = [];
|
|
26
|
+
this.panels = [];
|
|
27
|
+
this.hasScrollControls = false;
|
|
28
|
+
this.variant = "default";
|
|
29
|
+
this.activation = "auto";
|
|
30
|
+
}
|
|
31
|
+
connectedCallback() {
|
|
32
|
+
const whenAllDefined = Promise.all([
|
|
33
|
+
customElements.whenDefined("sd-tab"),
|
|
34
|
+
customElements.whenDefined("sd-tab-panel")
|
|
35
|
+
]);
|
|
36
|
+
super.connectedCallback();
|
|
37
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
38
|
+
this.updateScrollControls();
|
|
39
|
+
});
|
|
40
|
+
this.mutationObserver = new MutationObserver((mutations) => {
|
|
41
|
+
if (mutations.some((m) => !["aria-labelledby", "aria-controls"].includes(m.attributeName))) {
|
|
42
|
+
setTimeout(() => this.setAriaLabels());
|
|
43
|
+
}
|
|
44
|
+
if (mutations.some((m) => m.attributeName === "disabled")) {
|
|
45
|
+
this.syncTabsAndPanels();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
this.updateComplete.then(() => {
|
|
49
|
+
this.syncTabsAndPanels();
|
|
50
|
+
this.mutationObserver.observe(this, { attributes: true, childList: true, subtree: true });
|
|
51
|
+
this.resizeObserver.observe(this.nav);
|
|
52
|
+
whenAllDefined.then(() => {
|
|
53
|
+
const intersectionObserver = new IntersectionObserver((entries, observer) => {
|
|
54
|
+
if (entries[0].intersectionRatio > 0) {
|
|
55
|
+
this.setAriaLabels();
|
|
56
|
+
this.setActiveTab(this.activeTab ?? this.tabs[0], { emitEvents: false });
|
|
57
|
+
observer.unobserve(entries[0].target);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
intersectionObserver.observe(this.tabGroup);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
disconnectedCallback() {
|
|
65
|
+
this.mutationObserver.disconnect();
|
|
66
|
+
this.resizeObserver.unobserve(this.nav);
|
|
67
|
+
}
|
|
68
|
+
getAllTabs(options = { includeDisabled: true }) {
|
|
69
|
+
const slot = this.shadowRoot.querySelector('slot[name="nav"]');
|
|
70
|
+
return [...slot.assignedElements()].filter((el) => {
|
|
71
|
+
return options.includeDisabled ? el.tagName.toLowerCase() === "sd-tab" : el.tagName.toLowerCase() === "sd-tab" && !el.disabled;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
getAllPanels() {
|
|
75
|
+
return [...this.body.assignedElements()].filter((el) => el.tagName.toLowerCase() === "sd-tab-panel");
|
|
76
|
+
}
|
|
77
|
+
getActiveTab() {
|
|
78
|
+
return this.tabs.find((t) => t.matches(":focus"));
|
|
79
|
+
}
|
|
80
|
+
handleClick(event) {
|
|
81
|
+
const target = event.target;
|
|
82
|
+
const tab = target.closest("sd-tab");
|
|
83
|
+
const tabGroup = tab == null ? void 0 : tab.closest("sd-tab-group");
|
|
84
|
+
if (tabGroup !== this) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (tab !== null) {
|
|
88
|
+
this.setActiveTab(tab, { scrollBehavior: "smooth" });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
handleKeyDown(event) {
|
|
92
|
+
const target = event.target;
|
|
93
|
+
const tab = target.closest("sd-tab");
|
|
94
|
+
const tabGroup = tab == null ? void 0 : tab.closest("sd-tab-group");
|
|
95
|
+
if (tabGroup !== this) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (["Enter", " "].includes(event.key)) {
|
|
99
|
+
if (tab !== null) {
|
|
100
|
+
this.setActiveTab(tab, { scrollBehavior: "smooth" });
|
|
101
|
+
event.preventDefault();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (["Tab"].includes(event.key)) {
|
|
105
|
+
const index = this.tabs.indexOf(this.getActiveTab());
|
|
106
|
+
if (tab !== null) {
|
|
107
|
+
scrollIntoView(this.tabs[index + 1], this.nav, "horizontal");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (["Shift", "Tab"].includes(event.key)) {
|
|
111
|
+
const index = this.tabs.indexOf(this.getActiveTab());
|
|
112
|
+
if (tab !== null) {
|
|
113
|
+
scrollIntoView(this.tabs[index - 1], this.nav, "horizontal");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End"].includes(event.key)) {
|
|
117
|
+
const activeEl = this.tabs.find((t) => t.matches(":focus"));
|
|
118
|
+
const isRtl = this.localize.dir() === "rtl";
|
|
119
|
+
if ((activeEl == null ? void 0 : activeEl.tagName.toLowerCase()) === "sd-tab") {
|
|
120
|
+
let index = this.tabs.indexOf(activeEl);
|
|
121
|
+
if (event.key === "Home") {
|
|
122
|
+
index = 0;
|
|
123
|
+
} else if (event.key === "End") {
|
|
124
|
+
index = this.tabs.length - 1;
|
|
125
|
+
} else if (event.key === (isRtl ? "ArrowRight" : "ArrowLeft") || event.key === "ArrowUp") {
|
|
126
|
+
index--;
|
|
127
|
+
} else if (event.key === (isRtl ? "ArrowLeft" : "ArrowRight") || event.key === "ArrowDown") {
|
|
128
|
+
index++;
|
|
129
|
+
}
|
|
130
|
+
if (index < 0) {
|
|
131
|
+
index = this.tabs.length - 1;
|
|
132
|
+
}
|
|
133
|
+
if (index > this.tabs.length - 1) {
|
|
134
|
+
index = 0;
|
|
135
|
+
}
|
|
136
|
+
this.tabs[index].focus({ preventScroll: true });
|
|
137
|
+
if (this.activation === "auto") {
|
|
138
|
+
this.setActiveTab(this.tabs[index], { scrollBehavior: "smooth" });
|
|
139
|
+
}
|
|
140
|
+
scrollIntoView(this.tabs[index], this.nav, "horizontal");
|
|
141
|
+
event.preventDefault();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
handleScrollToStart() {
|
|
146
|
+
this.nav.scroll({
|
|
147
|
+
left: this.localize.dir() === "rtl" ? this.nav.scrollLeft + this.nav.clientWidth : this.nav.scrollLeft - this.nav.clientWidth,
|
|
148
|
+
behavior: "smooth"
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
handleScrollToEnd() {
|
|
152
|
+
this.nav.scroll({
|
|
153
|
+
left: this.localize.dir() === "rtl" ? this.nav.scrollLeft - this.nav.clientWidth : this.nav.scrollLeft + this.nav.clientWidth,
|
|
154
|
+
behavior: "smooth"
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/** Sets the active tab and panel. */
|
|
158
|
+
setActiveTab(tab, options) {
|
|
159
|
+
options = {
|
|
160
|
+
emitEvents: true,
|
|
161
|
+
scrollBehavior: "auto",
|
|
162
|
+
...options
|
|
163
|
+
};
|
|
164
|
+
if (tab !== this.activeTab && !tab.disabled) {
|
|
165
|
+
const previousTab = this.activeTab;
|
|
166
|
+
this.activeTab = tab;
|
|
167
|
+
this.tabs.map((el) => el.active = el === this.activeTab);
|
|
168
|
+
this.panels.map((el) => {
|
|
169
|
+
var _a;
|
|
170
|
+
return el.active = el.name === ((_a = this.activeTab) == null ? void 0 : _a.panel);
|
|
171
|
+
});
|
|
172
|
+
scrollIntoView(this.activeTab, this.nav, "horizontal", options.scrollBehavior);
|
|
173
|
+
if (options.emitEvents) {
|
|
174
|
+
if (previousTab) {
|
|
175
|
+
this.emit("sd-tab-hide", { detail: { name: previousTab.panel } });
|
|
176
|
+
}
|
|
177
|
+
this.emit("sd-tab-show", { detail: { name: this.activeTab.panel } });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
setAriaLabels() {
|
|
182
|
+
this.tabs.forEach((tab) => {
|
|
183
|
+
const panel = this.panels.find((el) => el.name === tab.panel);
|
|
184
|
+
if (panel) {
|
|
185
|
+
tab.setAttribute("aria-controls", panel.getAttribute("id"));
|
|
186
|
+
panel.setAttribute("aria-labelledby", tab.getAttribute("id"));
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
// This stores tabs and panels so we can refer to a cache instead of calling querySelectorAll() multiple times.
|
|
191
|
+
syncTabsAndPanels() {
|
|
192
|
+
this.tabs = this.getAllTabs({ includeDisabled: false });
|
|
193
|
+
this.panels = this.getAllPanels();
|
|
194
|
+
this.updateComplete.then(() => this.updateScrollControls());
|
|
195
|
+
if (this.tabs.length !== 0 && this.tabs[0].variant === "container") {
|
|
196
|
+
this.variant = "container";
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
updateScrollControls() {
|
|
200
|
+
this.hasScrollControls = this.nav.scrollWidth > this.nav.clientWidth;
|
|
201
|
+
}
|
|
202
|
+
/** Shows the specified tab panel. */
|
|
203
|
+
show(panel) {
|
|
204
|
+
const tab = this.tabs.find((el) => el.panel === panel);
|
|
205
|
+
if (tab) {
|
|
206
|
+
this.setActiveTab(tab, { scrollBehavior: "smooth" });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
render() {
|
|
210
|
+
const isRtl = this.localize.dir() === "rtl";
|
|
211
|
+
return html`<div part="base" class="${cx("flex flex-col rounded-none")}" @click="${this.handleClick}" @keydown="${this.handleKeyDown}"><div part="nav" class="${cx(this.hasScrollControls && "relative py-0 px-12")}">${this.hasScrollControls ? html`<button part="scroll-button--start" exportparts="base:scroll-button__base" class="${cx(
|
|
212
|
+
"sd-interactive flex items-center justify-center absolute top-0 bottom-0 left-0 !outline-offset-0 border-b border-neutral-400 z-10",
|
|
213
|
+
this.localize.dir() === "rtl" && "left-auto right-0"
|
|
214
|
+
)}" @click="${this.handleScrollToStart}"><sd-icon library="system" name="${isRtl ? "chevron-up" : "chevron-down"}" class="${cx("h-6 w-12 rotate-90 grid place-items-center")}"></sd-icon></button>` : ""}<div part="scroll-container" class="flex overflow-x-auto focus-visible:focus-outline !outline-offset-0"><div part="tabs" class="${cx("flex flex-auto relative flex-row")}" role="tablist"><div part="separation" class="w-full h-[1px] bg-neutral-400 absolute bottom-0"></div><slot name="nav" @slotchange="${this.syncTabsAndPanels}"></slot></div></div>${this.hasScrollControls ? html`<button part="scroll-button--end" exportparts="base:scroll-button__base" class="${cx(
|
|
215
|
+
"sd-interactive flex items-center justify-center absolute top-0 bottom-0 right-0 !outline-offset-0 border-b border-neutral-400 z-10",
|
|
216
|
+
this.localize.dir() === "rtl" && "right-auto left-0"
|
|
217
|
+
)}" @click="${this.handleScrollToEnd}"><sd-icon library="system" name="${isRtl ? "chevron-down" : "chevron-up"}" class="${cx("h-6 w-12 rotate-90 grid place-items-center")}"></sd-icon></button>` : ""}</div><slot part="body" class="${cx("block auto py-8 px-6", this.variant === "container" && "border border-neutral-400 border-t-0")}" @slotchange="${this.syncTabsAndPanels}"></slot></div>`;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
SdTabGroup.styles = [
|
|
221
|
+
SolidElement.styles,
|
|
222
|
+
unsafeCSS(InteractiveStyles),
|
|
223
|
+
componentStyles,
|
|
224
|
+
css`:host{box-sizing:border-box;display:block}[part=scroll-container]{scrollbar-width:none}[part=scroll-container]::-webkit-scrollbar{height:var(--sd-spacing-0,0);width:var(--sd-spacing-0,0)}::slotted(sd-tab-panel){--padding:1rem 0}`
|
|
225
|
+
];
|
|
226
|
+
__decorateClass([
|
|
227
|
+
query("[part=base]")
|
|
228
|
+
], SdTabGroup.prototype, "tabGroup", 2);
|
|
229
|
+
__decorateClass([
|
|
230
|
+
query("[part=body]")
|
|
231
|
+
], SdTabGroup.prototype, "body", 2);
|
|
232
|
+
__decorateClass([
|
|
233
|
+
query("[part=scroll-container]")
|
|
234
|
+
], SdTabGroup.prototype, "nav", 2);
|
|
235
|
+
__decorateClass([
|
|
236
|
+
state()
|
|
237
|
+
], SdTabGroup.prototype, "hasScrollControls", 2);
|
|
238
|
+
__decorateClass([
|
|
239
|
+
state()
|
|
240
|
+
], SdTabGroup.prototype, "variant", 2);
|
|
241
|
+
__decorateClass([
|
|
242
|
+
property()
|
|
243
|
+
], SdTabGroup.prototype, "activation", 2);
|
|
244
|
+
SdTabGroup = __decorateClass([
|
|
245
|
+
customElement("sd-tab-group")
|
|
246
|
+
], SdTabGroup);
|
|
247
|
+
export {
|
|
248
|
+
SdTabGroup as default
|
|
249
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import SolidElement from '../../internal/solid-element';
|
|
2
|
+
export default class SdTabPanel extends SolidElement {
|
|
3
|
+
private readonly attrId;
|
|
4
|
+
private readonly componentId;
|
|
5
|
+
name: string;
|
|
6
|
+
active: boolean;
|
|
7
|
+
connectedCallback(): void;
|
|
8
|
+
handleActiveChange(): void;
|
|
9
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
10
|
+
static styles: import("lit").CSSResultGroup[];
|
|
11
|
+
}
|
|
12
|
+
declare global {
|
|
13
|
+
interface HTMLElementTagNameMap {
|
|
14
|
+
'sd-tab-panel': SdTabPanel;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { css, html } from "lit";
|
|
2
|
+
import { customElement } from "../../internal/register-custom-element.js";
|
|
3
|
+
import { property } from "lit/decorators.js";
|
|
4
|
+
import { watch } from "../../internal/watch.js";
|
|
5
|
+
import componentStyles from "../../styles/component.styles.js";
|
|
6
|
+
import cx from "classix";
|
|
7
|
+
import SolidElement from "../../internal/solid-element.js";
|
|
8
|
+
var __defProp = Object.defineProperty;
|
|
9
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
10
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
11
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
12
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
13
|
+
if (decorator = decorators[i])
|
|
14
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
15
|
+
if (kind && result)
|
|
16
|
+
__defProp(target, key, result);
|
|
17
|
+
return result;
|
|
18
|
+
};
|
|
19
|
+
let id = 0;
|
|
20
|
+
let SdTabPanel = class extends SolidElement {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
this.attrId = ++id;
|
|
24
|
+
this.componentId = `sd-tab-panel-${this.attrId}`;
|
|
25
|
+
this.name = "";
|
|
26
|
+
this.active = false;
|
|
27
|
+
}
|
|
28
|
+
connectedCallback() {
|
|
29
|
+
super.connectedCallback();
|
|
30
|
+
this.id = this.id.length > 0 ? this.id : this.componentId;
|
|
31
|
+
this.setAttribute("role", "tabpanel");
|
|
32
|
+
}
|
|
33
|
+
handleActiveChange() {
|
|
34
|
+
this.setAttribute("aria-hidden", this.active ? "false" : "true");
|
|
35
|
+
}
|
|
36
|
+
render() {
|
|
37
|
+
return html`<slot part="base" class="${cx("block", this.active && "tab-panel--active")}"></slot>`;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
SdTabPanel.styles = [
|
|
41
|
+
SolidElement.styles,
|
|
42
|
+
componentStyles,
|
|
43
|
+
css`:host{--padding:0;display:none}:host([active]){display:block}::part(base){padding:var(--padding)}`
|
|
44
|
+
];
|
|
45
|
+
__decorateClass([
|
|
46
|
+
property({ reflect: true })
|
|
47
|
+
], SdTabPanel.prototype, "name", 2);
|
|
48
|
+
__decorateClass([
|
|
49
|
+
property({ type: Boolean, reflect: true })
|
|
50
|
+
], SdTabPanel.prototype, "active", 2);
|
|
51
|
+
__decorateClass([
|
|
52
|
+
watch("active")
|
|
53
|
+
], SdTabPanel.prototype, "handleActiveChange", 1);
|
|
54
|
+
SdTabPanel = __decorateClass([
|
|
55
|
+
customElement("sd-tab-panel")
|
|
56
|
+
], SdTabPanel);
|
|
57
|
+
export {
|
|
58
|
+
SdTabPanel as default
|
|
59
|
+
};
|
|
@@ -26,6 +26,9 @@ export { default as SdRadioGroup } from './components/radio-group/radio-group';
|
|
|
26
26
|
export { default as SdSelect } from './components/select/select';
|
|
27
27
|
export { default as SdSpinner } from './components/spinner/spinner';
|
|
28
28
|
export { default as SdSwitch } from './components/switch/switch';
|
|
29
|
+
export { default as SdTab } from './components/tab/tab';
|
|
30
|
+
export { default as SdTabGroup } from './components/tab-group/tab-group';
|
|
31
|
+
export { default as SdTabPanel } from './components/tab-panel/tab-panel';
|
|
29
32
|
export { default as SdTag } from './components/tag/tag';
|
|
30
33
|
export { default as SdTeaser } from './components/teaser/teaser';
|
|
31
34
|
export { default as SdTeaserMedia } from './components/teaser-media/teaser-media';
|
|
@@ -26,12 +26,15 @@ import { default as default26 } from "./components/radio-group/radio-group.js";
|
|
|
26
26
|
import { default as default27 } from "./components/select/select.js";
|
|
27
27
|
import { default as default28 } from "./components/spinner/spinner.js";
|
|
28
28
|
import { default as default29 } from "./components/switch/switch.js";
|
|
29
|
-
import { default as default30 } from "./components/
|
|
30
|
-
import { default as default31 } from "./components/
|
|
31
|
-
import { default as default32 } from "./components/
|
|
32
|
-
import { default as default33 } from "./components/
|
|
33
|
-
import { default as default34 } from "./components/
|
|
34
|
-
import { default as default35 } from "./components/
|
|
29
|
+
import { default as default30 } from "./components/tab/tab.js";
|
|
30
|
+
import { default as default31 } from "./components/tab-group/tab-group.js";
|
|
31
|
+
import { default as default32 } from "./components/tab-panel/tab-panel.js";
|
|
32
|
+
import { default as default33 } from "./components/tag/tag.js";
|
|
33
|
+
import { default as default34 } from "./components/teaser/teaser.js";
|
|
34
|
+
import { default as default35 } from "./components/teaser-media/teaser-media.js";
|
|
35
|
+
import { default as default36 } from "./components/textarea/textarea.js";
|
|
36
|
+
import { default as default37 } from "./components/tooltip/tooltip.js";
|
|
37
|
+
import { default as default38 } from "./components/video/video.js";
|
|
35
38
|
import { registerIconLibrary, unregisterIconLibrary } from "./components/icon/library.js";
|
|
36
39
|
import { LocalizeController } from "./utilities/localize.js";
|
|
37
40
|
export {
|
|
@@ -64,12 +67,15 @@ export {
|
|
|
64
67
|
default27 as SdSelect,
|
|
65
68
|
default28 as SdSpinner,
|
|
66
69
|
default29 as SdSwitch,
|
|
67
|
-
default30 as
|
|
68
|
-
default31 as
|
|
69
|
-
default32 as
|
|
70
|
-
default33 as
|
|
71
|
-
default34 as
|
|
72
|
-
default35 as
|
|
70
|
+
default30 as SdTab,
|
|
71
|
+
default31 as SdTabGroup,
|
|
72
|
+
default32 as SdTabPanel,
|
|
73
|
+
default33 as SdTag,
|
|
74
|
+
default34 as SdTeaser,
|
|
75
|
+
default35 as SdTeaserMedia,
|
|
76
|
+
default36 as SdTextarea,
|
|
77
|
+
default37 as SdTooltip,
|
|
78
|
+
default38 as SdVideo,
|
|
73
79
|
registerIconLibrary,
|
|
74
80
|
unregisterIconLibrary
|
|
75
81
|
};
|