Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Tab component #1352

Open
wants to merge 67 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
d6afbf8
refactor(tabs): refactor the tab into single component
MonikaKirkova Aug 16, 2024
2abeda6
Merge branch 'master' into mkirkova/feat-1289
MonikaKirkova Aug 16, 2024
f4be0fa
Merge branch 'master' into mkirkova/feat-1289
rkaraivanov Sep 24, 2024
53c96ff
Merge branch 'master' into mkirkova/feat-1289
desig9stein Sep 30, 2024
012fea4
Merge branch 'master' into mkirkova/feat-1289
desig9stein Oct 1, 2024
891831b
Merge branch 'master' into mkirkova/feat-1289
simeonoff Oct 7, 2024
5f6a41f
Merge branch 'master' into mkirkova/feat-1289
desig9stein Oct 8, 2024
dc02e4a
Merge branch 'master' into mkirkova/feat-1289
MonikaKirkova Oct 9, 2024
363621d
chore(*): add tabs-count property
MonikaKirkova Oct 9, 2024
358d732
Merge branch 'master' into mkirkova/feat-1289
desig9stein Oct 10, 2024
b2b0ca6
Merge branch 'master' of https://github.com/IgniteUI/igniteui-webcomp…
MonikaKirkova Oct 15, 2024
ef20827
refactor(tabs): update styles
desig9stein Oct 15, 2024
44ed3e1
Merge branch 'master' into mkirkova/feat-1289
MonikaKirkova Oct 16, 2024
3ece184
refactor(tabs): remove unnecessary methods call
MonikaKirkova Oct 16, 2024
77827f0
fix(tabs): fix failing tests
MonikaKirkova Oct 16, 2024
b346339
refactor(tabs): update styles
desig9stein Oct 17, 2024
c4d0399
Merge branch 'master' into mkirkova/feat-1289
rkaraivanov Oct 18, 2024
b03882e
refactor: Abstract resize observer and code cleanups
rkaraivanov Oct 21, 2024
98fbc67
refactor(tabs): final styles
desig9stein Oct 21, 2024
baf3e9d
refactor(tabs): update tab story
desig9stein Oct 21, 2024
7d5c5ef
refactor: Scroll logic and internal CSS variables
rkaraivanov Oct 22, 2024
3ba3709
refactor(tabs): move scroll-padding-inline to the tabs part
desig9stein Oct 22, 2024
fb0de24
fix: Smooth scroll snap with keyboard in Firefox
rkaraivanov Oct 22, 2024
ca72f48
fix: Indicator in RTL context. Unit tests.
rkaraivanov Oct 22, 2024
e14da4a
refactor: Organized the code along the contribution guidelines
rkaraivanov Oct 22, 2024
ce78e2e
refactor(utils): Removed `getOffset` helper function
rkaraivanov Oct 22, 2024
f8823a7
refactor: Removed unused button references
rkaraivanov Oct 23, 2024
35ef1f9
Merge remote-tracking branch 'origin/master' into mkirkova/feat-1289
rkaraivanov Oct 23, 2024
ec52381
Merge remote-tracking branch 'origin/master' into mkirkova/feat-1289
rkaraivanov Oct 23, 2024
486ec59
fix: Keyboard activation on scroll buttons
rkaraivanov Oct 23, 2024
457d163
refactor(tabs): Cleanup the styles and fix RTL for nav buttons in fir…
desig9stein Oct 23, 2024
a629842
feat: Use scroll snapping for button scrolls
rkaraivanov Oct 23, 2024
7327f3d
refactor(tabs): Update tab styles and variable names
desig9stein Oct 23, 2024
51ad3e6
refactor(tabs): fix scroll behavior under IOS, remove touch-action fr…
desig9stein Oct 23, 2024
8f74bc2
refactor(tabs): fix button icon size in all themes to match the UI kit
desig9stein Oct 24, 2024
6c02fd8
refactor(tabs): fix bootstrap focus to match the UI kit
desig9stein Oct 25, 2024
37b70e5
Merge branch 'master' into mkirkova/feat-1289
rkaraivanov Oct 25, 2024
0cb91e6
Merge remote-tracking branch 'origin/master' into mkirkova/feat-1289
rkaraivanov Oct 31, 2024
1e9339e
fix: Scroll buttons disabled state tolerance
rkaraivanov Oct 31, 2024
cff2072
fix: Scroll buttons tolerance calculation
rkaraivanov Nov 1, 2024
283a8b4
Merge remote-tracking branch 'origin/master' into mkirkova/feat-1289
rkaraivanov Nov 1, 2024
a45a8ce
Merge remote-tracking branch 'origin/master' into mkirkova/feat-1289
rkaraivanov Nov 1, 2024
36842d6
refactor: Post merge fixes and nested tabs support
rkaraivanov Nov 4, 2024
74f3d98
fix(tabs): fix wrong focus styles behavior
desig9stein Nov 4, 2024
e6385f0
refactor(tabs): rename header and body to tab-header and tab-body
desig9stein Nov 4, 2024
405681f
fix(tabs): fix removable tabs stories button focus cut off
desig9stein Nov 4, 2024
3156237
fix: Scroll buttons visiblibity with dynamic tabs
rkaraivanov Nov 4, 2024
192d5fd
fix(tabs): fixing design issues
desig9stein Nov 4, 2024
017ace4
refactor: Minor internal naming changes
rkaraivanov Nov 5, 2024
8e16f30
Merge remote-tracking branch 'origin/master' into mkirkova/feat-1289
rkaraivanov Nov 5, 2024
1cc7aaa
fix(tabs): selected-indicator position.
desig9stein Nov 5, 2024
6398f64
fix(tabs): selected-indicator position.
desig9stein Nov 5, 2024
334a732
fix(tabs): fix color in fluent active hover
desig9stein Nov 5, 2024
5824f46
fix(tabs): remove transitions form bootstrap theme header
desig9stein Nov 5, 2024
c6cec48
refactor(tabs): fix sass warning in the console
desig9stein Nov 5, 2024
5e146d5
chore: Removed stray tooltip specification inclusion
rkaraivanov Nov 11, 2024
a92347b
Merge branch 'master' into mkirkova/feat-1289
rkaraivanov Nov 11, 2024
5f6b2ac
Merge branch 'master' into mkirkova/feat-1289
simeonoff Nov 12, 2024
8ae8fc6
Merge branch 'master' into mkirkova/feat-1289
simeonoff Nov 12, 2024
5a447fa
Merge branch 'master' into mkirkova/feat-1289
simeonoff Nov 18, 2024
29e81b1
fix(tabs): Remove the --tabs-width variable
desig9stein Nov 19, 2024
074d059
fix(tabs): address issues from comments
desig9stein Nov 19, 2024
7599269
Merge branch 'master' into mkirkova/feat-1289
desig9stein Nov 19, 2024
3c05f0c
fix(tabs): address issues from comments
desig9stein Nov 20, 2024
9c4f5f1
Merge branch 'master' into mkirkova/feat-1289
simeonoff Nov 25, 2024
c1e0f50
Merge branch 'master' into mkirkova/feat-1289
rkaraivanov Dec 2, 2024
bbf8d93
Merge remote-tracking branch 'origin/master' into mkirkova/feat-1289
rkaraivanov Dec 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions src/components/common/controllers/resize-observer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import {
type ReactiveController,
type ReactiveControllerHost,
isServer,
} from 'lit';

type ResizeControllerCallback = (
...args: Parameters<ResizeObserverCallback>
) => unknown;

/** Configuration for initializing a resize controller. */
export interface ResizeControllerConfig {
/** The callback function to run when a resize mutation is triggered. */
callback: ResizeControllerCallback;
/** Configuration options passed to the underlying ResizeObserver. */
options?: ResizeObserverOptions;
/**
* The initial target element to observe for resize mutations.
*
* If not provided, the host element will be set as initial target.
* Pass in `null` to skip setting an initial target.
*/
target?: Element | null;
}

class ResizeController implements ReactiveController {
private _host: ReactiveControllerHost & Element;
private _targets = new Set<Element>();
private _config: ResizeControllerConfig;
private _observer!: ResizeObserver;

constructor(
host: ReactiveControllerHost & Element,
config: ResizeControllerConfig
) {
this._host = host;
this._config = config;

if (this._config.target !== null) {
this._targets.add(this._config.target ?? host);
}

if (isServer) {
return;
}

this._observer = new ResizeObserver((entries) =>
this._config.callback.call(this._host, entries, this._observer)
);

host.addController(this);
}

/** Starts observing the `targe` element. */
public observe(target: Element): void {
this._targets.add(target);
this._observer.observe(target, this._config.options);
this._host.requestUpdate();
}

/** Stops observing the `target` element. */
public unobserve(target: Element): void {
this._targets.delete(target);
this._observer.unobserve(target);
}

public hostConnected(): void {
for (const target of this._targets) {
this.observe(target);
}
}

public hostDisconnected(): void {
this.disconnect();
}

protected disconnect(): void {
this._observer.disconnect();
}
}

/**
* Creates a new resize controller bound to the given `host`
* with {@link ResizeControllerConfig | `config`}.
*/
export function createResizeController(
host: ReactiveControllerHost & Element,
config: ResizeControllerConfig
) {
return new ResizeController(host, config);
}
2 changes: 0 additions & 2 deletions src/components/common/definitions/defineAllComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ import IgcSliderComponent from '../../slider/slider.js';
import IgcSnackbarComponent from '../../snackbar/snackbar.js';
import IgcStepComponent from '../../stepper/step.js';
import IgcStepperComponent from '../../stepper/stepper.js';
import IgcTabPanelComponent from '../../tabs/tab-panel.js';
import IgcTabComponent from '../../tabs/tab.js';
import IgcTabsComponent from '../../tabs/tabs.js';
import IgcTextareaComponent from '../../textarea/textarea.js';
Expand Down Expand Up @@ -123,7 +122,6 @@ const allComponents: IgniteComponent[] = [
IgcRangeSliderComponent,
IgcTabsComponent,
IgcTabComponent,
IgcTabPanelComponent,
IgcCircularProgressComponent,
IgcLinearProgressComponent,
IgcCircularGradientComponent,
Expand Down
48 changes: 20 additions & 28 deletions src/components/common/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,6 @@ export function sameObject(a: object, b: object) {
return JSON.stringify(a) === JSON.stringify(b);
}

/**
*
* Returns an element's offset relative to its parent. Similar to element.offsetTop and element.offsetLeft, except the
* parent doesn't have to be positioned relative or absolute.
*
* Work around for the following issues in Chromium based browsers:
*
* https://bugs.chromium.org/p/chromium/issues/detail?id=1330819
* https://bugs.chromium.org/p/chromium/issues/detail?id=1334556
*
*/
export function getOffset(element: HTMLElement, parent: HTMLElement) {
const { top, left, bottom, right } = element.getBoundingClientRect();
const {
top: pTop,
left: pLeft,
bottom: pBottom,
right: pRight,
} = parent.getBoundingClientRect();

return {
top: Math.round(top - pTop),
left: Math.round(left - pLeft),
right: Math.round(right - pRight),
bottom: Math.round(bottom - pBottom),
};
}

export function createCounter() {
let i = 0;
return () => {
Expand Down Expand Up @@ -283,3 +255,23 @@ export function isEmpty<T, U extends string>(
): boolean {
return 'length' in x ? x.length < 1 : x.size < 1;
}

export function scrollIntoView(
element?: HTMLElement,
config?: ScrollIntoViewOptions
): void {
if (!element) {
return;
}

element.scrollIntoView(
Object.assign(
{
behavior: 'auto',
block: 'nearest',
inline: 'nearest',
},
config
)
);
}
44 changes: 0 additions & 44 deletions src/components/tabs/tab-panel.ts

This file was deleted.

71 changes: 38 additions & 33 deletions src/components/tabs/tab.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { LitElement, html } from 'lit';
import { property, query } from 'lit/decorators.js';
import { property } from 'lit/decorators.js';

import { themes } from '../../theming/theming-decorator.js';
import { registerComponent } from '../common/definitions/register.js';
Expand All @@ -13,13 +13,16 @@ import { styles } from './themes/tab.base.css.js';
*
* @element igc-tab
*
* @slot prefix - Renders before the tab header content.
* @slot - Renders the tab header content.
* @slot suffix - Renders after the tab header content.
* @slot - Renders the tab's content.
* @slot label - Renders the tab header's label.
* @slot prefix - Renders the tab header's prefix.
* @slot suffix - Renders the tab header's suffix.
*
* @csspart content - The content wrapper.
* @csspart prefix - The prefix wrapper.
* @csspart suffix - The suffix wrapper.
* @csspart tab-header - The header of a single tab.
* @csspart prefix - Tab header's label prefix.
* @csspart content - Tab header's label slot container.
* @csspart suffix - Tab header's label suffix.
* @csspart tab-body - Holds the body content of a single tab, only the body of the selected tab is visible.
*/

@themes(all)
Expand All @@ -32,17 +35,14 @@ export default class IgcTabComponent extends LitElement {
registerComponent(IgcTabComponent);
}

private static readonly increment = createCounter();

@query('[part="base"]', true)
private tab!: HTMLElement;
private static increment = createCounter();

/**
* The id of the tab panel which will be controlled by the tab.
* The tab item label.
* @attr
*/
@property()
public panel = '';
public label = '';

/**
* Determines whether the tab is selected.
Expand All @@ -60,34 +60,39 @@ export default class IgcTabComponent extends LitElement {

public override connectedCallback(): void {
super.connectedCallback();
this.id =
this.getAttribute('id') || `igc-tab-${IgcTabComponent.increment()}`;
}

/** Sets focus to the tab. */
public override focus(options?: FocusOptions) {
this.tab.focus(options);
}

/** Removes focus from the tab. */
public override blur() {
this.tab.blur();
this.id = this.id || `igc-tab-${IgcTabComponent.increment()}`;
}

protected override render() {
const headerId = `${this.id}-header`;
const contentId = `${this.id}-content`;

return html`
<div
part="base"
part="tab-header"
role="tab"
aria-disabled=${this.disabled ? 'true' : 'false'}
aria-selected=${this.selected ? 'true' : 'false'}
tabindex=${this.disabled || !this.selected ? -1 : 0}
id=${headerId}
aria-disabled=${this.disabled}
aria-selected=${this.selected}
aria-controls=${contentId}
tabindex=${this.selected ? 0 : -1}
>
<slot name="prefix" part="prefix"></slot>
<div part="content">
<slot></slot>
<div part="base">
<slot name="prefix" part="prefix"></slot>
<div part="content">
<slot name="label">${this.label}</slot>
</div>
<slot name="suffix" part="suffix"></slot>
</div>
<slot name="suffix" part="suffix"></slot>
</div>
<div
part="tab-body"
role="tabpanel"
id=${contentId}
aria-labelledby=${headerId}
.inert=${!this.selected}
>
<slot></slot>
</div>
`;
}
Expand Down
Loading