Skip to content

Commit

Permalink
refactor(segment): improves loading of the component and solves neste…
Browse files Browse the repository at this point in the history
…d size issues
  • Loading branch information
Amir Ashkan Baghdoust committed Oct 16, 2024
1 parent f657202 commit 64c1a9b
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 45 deletions.
9 changes: 2 additions & 7 deletions packages/components/src/components/segment/segment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class Segment {
/** (optional) If `true`, the segment is disabled */
@Prop() disabled?: boolean = false;
/** (optional) segment's id */
@Prop({ reflect: true, mutable: true }) segmentId?: string;
@Prop({ reflect: true }) segmentId?: string = 'segment-' + i++;
/** (optional) aria-label attribute needed for icon-only segments */
@Prop() ariaLabelSegment: string;
/** (optional) Segment width set to ensure that all segments have the same width */
Expand Down Expand Up @@ -85,12 +85,7 @@ export class Segment {
this.focusableElement.focus();
}

componentWillLoad() {
if (this.segmentId == null) {
this.segmentId = 'segment-' + i++;
}
}
componentDidUpdate() {
componentWillUpdate() {
this.handleIcon();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`SegmentedButton should match selected button snapshot 1`] = `
<scale-segmented-button>
<mock:shadow-root>
<div aria-label="segment button with 2" class="segmented-button segmented-button--small" part="segmented-button small" role="group" style="grid-template-columns: repeat(2, 0px);">
<div aria-label="segment button with 2" class="segmented-button segmented-button--small" part="segmented-button small" role="group" style="grid-template-columns: repeat(2, auto);">
<slot></slot>
</div>
</mock:shadow-root>
Expand All @@ -19,7 +19,7 @@ exports[`SegmentedButton should match selected button snapshot 1`] = `
exports[`SegmentedButton should match standard snapshot 1`] = `
<scale-segmented-button>
<mock:shadow-root>
<div aria-label="segment button with 4" class="segmented-button segmented-button--small" part="segmented-button small" role="group" style="grid-template-columns: repeat(4, 14px);">
<div aria-label="segment button with 4" class="segmented-button segmented-button--small" part="segmented-button small" role="group" style="grid-template-columns: repeat(4, auto);">
<slot></slot>
</div>
</mock:shadow-root>
Expand All @@ -36,4 +36,4 @@ exports[`SegmentedButton should match standard snapshot 1`] = `
Label
</scale-segment>
</scale-segmented-button>
`;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class SegmentedButton {
/** (optional) Allow more than one button to be selected */
@Prop() multiSelect: boolean = false;
/** (optional) the index of the selected segment */
@Prop() selectedIndex?: number;
@Prop({ mutable: true }) selectedIndex?: number;
/** (optional) If `true`, the button is disabled */
@Prop({ reflect: true }) disabled?: boolean = false;
/** (optional) If `true`, expand to container width */
Expand Down Expand Up @@ -119,36 +119,36 @@ export class SegmentedButton {
});
}

componentDidLoad() {
componentWillLoad() {
const tempState: SegmentStatus[] = [];
const segments = this.getAllSegments();
this.slottedSegments = segments.length;
const longestButtonWidth = this.getLongestButtonWidth();
segments.forEach((segment) => {
this.position++;
segments.forEach((segment, i) => {
tempState.push({
id: segment.getAttribute('segment-id') || segment.segmentId,
selected: segment.hasAttribute('selected') || segment.selected,
});
segment.setAttribute('position', this.position.toString());
segment.setAttribute('position', `${i + 1}`);
segment.setAttribute(
'aria-description-translation',
'$position $selected'
);
});
this.setState(tempState);
this.selectedIndex = this.getSelectedIndex();
}
componentDidLoad() {
const longestButtonWidth = this.getLongestButtonWidth();
if (!this.fullWidth) {
this.container.style.gridTemplateColumns = `repeat(${
this.hostElement.children.length
}, ${Math.ceil(longestButtonWidth)}px)`;
this.container.style.gridTemplateColumns = longestButtonWidth
? `repeat(${this.hostElement.children.length}, ${Math.ceil(
longestButtonWidth
)}px)`
: `repeat(${this.hostElement.children.length}, auto)`;
} else {
this.container.style.display = 'flex';
}

this.selectedIndex = this.getSelectedIndex();
this.propagatePropsToChildren();
this.position = 0;
this.status = tempState;
this.setState(tempState);
}

componentWillUpdate() {
Expand Down Expand Up @@ -195,27 +195,29 @@ export class SegmentedButton {
// all segmented buttons should have the same width, based on the largest one
getLongestButtonWidth() {
let tempWidth = 0;
Array.from(this.hostElement.children).forEach((child) => {
const selected = child.hasAttribute('selected');
const iconOnly = child.hasAttribute('icon-only');
const checkmark =
this.size === 'small'
? CHECKMARK_WIDTH_SMALL
: this.size === 'medium'
? CHECKMARK_WIDTH_MEDIUM
: CHECKMARK_WIDTH_LARGE;
if (selected || iconOnly) {
tempWidth =
child.getBoundingClientRect().width > tempWidth
? child.getBoundingClientRect().width
: tempWidth;
} else {
tempWidth =
child.getBoundingClientRect().width + checkmark > tempWidth
? child.getBoundingClientRect().width + checkmark
: tempWidth;
}
});
Array.from(this.hostElement.children)
.filter((child) => child.getBoundingClientRect().width)
.forEach((child) => {
const selected = child.hasAttribute('selected');
const iconOnly = child.hasAttribute('icon-only');
const checkmark =
this.size === 'small'
? CHECKMARK_WIDTH_SMALL
: this.size === 'medium'
? CHECKMARK_WIDTH_MEDIUM
: CHECKMARK_WIDTH_LARGE;
if (selected || iconOnly) {
tempWidth =
child.getBoundingClientRect().width > tempWidth
? child.getBoundingClientRect().width
: tempWidth;
} else {
tempWidth =
child.getBoundingClientRect().width + checkmark > tempWidth
? child.getBoundingClientRect().width + checkmark
: tempWidth;
}
});
return tempWidth;
}

Expand Down
48 changes: 48 additions & 0 deletions packages/components/src/html/segment-button.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0"
/>
<title>Loading spinners</title>

<script type="module" src="build/scale-components.esm.js"></script>
<script nomodule src="build/scale-components.js"></script>
<link rel="stylesheet" href="build/scale-components.css" />
<style>
section {
padding: 1rem;
}
.bg-black {
background: black;
color: white;
}
</style>
</head>

<body>
<scale-collapsible>
<div slot="heading">Open Me for Disaster</div>
<scale-segmented-button>
<scale-segment selected>Apple</scale-segment>
<scale-segment>One+</scale-segment>
<scale-segment>Samsung</scale-segment>
<scale-segment>Huawei</scale-segment>
</scale-segmented-button>
</scale-collapsible>

<scale-segmented-button>
<scale-segment>Apple</scale-segment>
<scale-segment>One+</scale-segment>
<scale-segment>Samsung</scale-segment>
<scale-segment>Huawei</scale-segment>
</scale-segmented-button>

<scale-segmented-button>
<scale-segment selected>Label</scale-segment>
<scale-segment selected>Label</scale-segment>
</scale-segmented-button>
</body>
</html>

0 comments on commit 64c1a9b

Please sign in to comment.