diff --git a/packages/components/src/components/segment/readme.md b/packages/components/src/components/segment/readme.md
index 249d97f3ad..089e5cd0ec 100644
--- a/packages/components/src/components/segment/readme.md
+++ b/packages/components/src/components/segment/readme.md
@@ -20,7 +20,7 @@
| `position` | `position` | (optional) position within group | `number` | `undefined` |
| `segmentId` | `segment-id` | (optional) segment's id | `string` | `'segment-' + i++` |
| `selected` | `selected` | (optional) If `true`, the segment is selected | `boolean` | `false` |
-| `selectedIndex` | `selected-index` | (optional) the index of the currently selected segment in the segmented-button | `string` | `undefined` |
+| `selectedIndex` | `selected-index` | (optional) the index of the currently selected segment in the segmented-button | `number` | `undefined` |
| `size` | `size` | (optional) The size of the segment | `"large" \| "medium" \| "small"` | `'small'` |
| `styles` | `styles` | (optional) Injected CSS styles | `string` | `undefined` |
| `textOnly` | `text-only` | (optional) position within group | `boolean` | `undefined` |
diff --git a/packages/components/src/components/segment/segment.tsx b/packages/components/src/components/segment/segment.tsx
index 67b45ffa82..29ddffb507 100644
--- a/packages/components/src/components/segment/segment.tsx
+++ b/packages/components/src/components/segment/segment.tsx
@@ -18,6 +18,7 @@ import {
Event,
EventEmitter,
Method,
+ Watch,
} from '@stencil/core';
import classNames from 'classnames';
import { emitEvent } from '../../utils/utils';
@@ -65,7 +66,7 @@ export class Segment {
/** (optional) position within group */
@Prop({ mutable: true }) iconOnly?: boolean;
/** (optional) the index of the currently selected segment in the segmented-button */
- @Prop({ mutable: true }) selectedIndex?: string;
+ @Prop({ mutable: true }) selectedIndex?: number;
/** Emitted when button is clicked */
@Event({ eventName: 'scale-click' }) scaleClick!: EventEmitter<{
@@ -80,6 +81,14 @@ export class Segment {
private focusableElement: HTMLElement;
+ @Watch('selected')
+ selectionChanged() {
+ emitEvent(this, 'scaleClick', {
+ id: this.segmentId,
+ selected: this.selected,
+ });
+ }
+
@Method()
async setFocus() {
this.focusableElement.focus();
@@ -150,15 +159,11 @@ export class Segment {
}
handleClick = (event: MouseEvent) => {
- if (parseInt(this.selectedIndex, 10) + 1 === this.position) {
+ if (this.selectedIndex === this.position) {
return;
}
event.preventDefault();
this.selected = !this.selected;
- emitEvent(this, 'scaleClick', {
- id: this.segmentId,
- selected: this.selected,
- });
};
render() {
diff --git a/packages/components/src/components/segmented-button/__snapshots__/segmented-button.spec.ts.snap b/packages/components/src/components/segmented-button/__snapshots__/segmented-button.spec.ts.snap
index 82e5bc5170..f3cc15e81d 100644
--- a/packages/components/src/components/segmented-button/__snapshots__/segmented-button.spec.ts.snap
+++ b/packages/components/src/components/segmented-button/__snapshots__/segmented-button.spec.ts.snap
@@ -7,10 +7,10 @@ exports[`SegmentedButton should match selected button snapshot 1`] = `
-
+
Label
-
+
Label
@@ -23,17 +23,17 @@ exports[`SegmentedButton should match standard snapshot 1`] = `
-
+
Label
-
+
Label
-
+
Label
-
+
Label
-`;
\ No newline at end of file
+`;
diff --git a/packages/components/src/components/segmented-button/segmented-button.spec.ts b/packages/components/src/components/segmented-button/segmented-button.spec.ts
index aadc728f1e..51392c20e6 100644
--- a/packages/components/src/components/segmented-button/segmented-button.spec.ts
+++ b/packages/components/src/components/segmented-button/segmented-button.spec.ts
@@ -43,7 +43,7 @@ describe('SegmentedButton', () => {
html: `
Label
- Label
+ Label
`,
});
expect(page.root).toMatchSnapshot();
diff --git a/packages/components/src/components/segmented-button/segmented-button.tsx b/packages/components/src/components/segmented-button/segmented-button.tsx
index e32fbc09ef..11982f9805 100644
--- a/packages/components/src/components/segmented-button/segmented-button.tsx
+++ b/packages/components/src/components/segmented-button/segmented-button.tsx
@@ -15,7 +15,6 @@ import {
h,
Host,
Element,
- State,
Listen,
Event,
EventEmitter,
@@ -45,8 +44,6 @@ export class SegmentedButton {
slottedSegments = 0;
@Element() hostElement: HTMLElement;
- /** state */
- @State() status: SegmentStatus[] = [];
/** (optional) The size of the button */
@Prop() size?: 'small' | 'medium' | 'large' = 'small';
/** (optional) Allow more than one button to be selected */
@@ -79,24 +76,26 @@ export class SegmentedButton {
showHelperText = false;
@Listen('scaleClick')
scaleClickHandler(ev: { detail: { id: string; selected: boolean } }) {
- let tempState: SegmentStatus[];
+ let tempState = this.getAllSegments().map((segment) => {
+ return {
+ id: segment.segmentId,
+ selected: segment.selected,
+ };
+ });
if (!this.multiSelect) {
if (!ev.detail.selected) {
- tempState = this.status.map((obj) =>
+ tempState = tempState.map((obj) =>
ev.detail.id === obj.id ? ev.detail : { ...obj }
);
- /* clicked button has now selected state */
} else {
- tempState = this.status.map((obj) =>
+ tempState = tempState.map((obj) =>
ev.detail.id === obj.id ? ev.detail : { ...obj, selected: false }
);
}
+ this.setState(tempState, ev.detail.selected);
} else {
- tempState = this.status.map((obj) =>
- ev.detail.id === obj.id ? ev.detail : { ...obj }
- );
+ this.setState(tempState);
}
- this.setState(tempState);
}
@Watch('disabled')
@@ -111,10 +110,10 @@ export class SegmentedButton {
*/
propagatePropsToChildren() {
this.getAllSegments().forEach((segment) => {
- segment.setAttribute('size', this.size);
- segment.setAttribute('selected-index', this.selectedIndex.toString());
+ segment.size = this.size;
+ segment.selectedIndex = this.selectedIndex;
if (this.disabled) {
- segment.setAttribute('disabled', true && 'disabled');
+ segment.disabled = true;
}
});
}
@@ -125,17 +124,13 @@ export class SegmentedButton {
this.slottedSegments = segments.length;
segments.forEach((segment, i) => {
tempState.push({
- id: segment.getAttribute('segment-id') || segment.segmentId,
- selected: segment.hasAttribute('selected') || segment.selected,
+ id: segment.segmentId,
+ selected: segment.selected,
});
- segment.setAttribute('position', `${i + 1}`);
- segment.setAttribute(
- 'aria-description-translation',
- '$position $selected'
- );
+ segment.position = i;
+ segment.ariaDescriptionTranslation = '$position $selected';
});
- this.setState(tempState);
- this.selectedIndex = this.getSelectedIndex();
+ this.setState(tempState, false);
this.showHelperText = this.shouldShowHelperText();
}
componentDidLoad() {
@@ -153,15 +148,11 @@ export class SegmentedButton {
}
componentWillUpdate() {
- this.selectedIndex = this.getSelectedIndex();
this.showHelperText = this.shouldShowHelperText();
}
shouldShowHelperText() {
let showHelperText = false;
- if (
- this.invalid &&
- this.status.filter((e) => e.selected === true).length <= 0
- ) {
+ if (this.invalid && this.selectedIndex < 0) {
showHelperText = true;
}
return showHelperText;
@@ -176,12 +167,13 @@ export class SegmentedButton {
const selectedIndex = allSegments.findIndex(
(el: HTMLScaleSegmentElement) => el.selected === true
);
- return selectedIndex;
+ // we need to return -2 if no segment is selected
+ return selectedIndex >= 0 ? selectedIndex : -2;
}
}
getAdjacentSiblings = (tempState, i) => {
- let adjacentSiblings = '';
+ let adjacentSiblings = null;
if (i !== 0 && tempState[i].selected && tempState[i - 1].selected) {
adjacentSiblings = 'left';
}
@@ -226,22 +218,18 @@ export class SegmentedButton {
return tempWidth;
}
- setState(tempState: SegmentStatus[]) {
+ setState(tempState: SegmentStatus[], handleEvent: boolean = true) {
const segments = Array.from(
this.hostElement.querySelectorAll('scale-segment')
);
segments.forEach((segment, i) => {
- segment.setAttribute(
- 'adjacent-siblings',
- this.getAdjacentSiblings(tempState, i)
- );
- segment.setAttribute(
- 'selected',
- tempState[i].selected ? 'true' : 'false'
- );
+ segment.adjacentSiblings = this.getAdjacentSiblings(tempState, i);
+ segment.selected = tempState[i].selected;
});
- this.status = tempState;
- emitEvent(this, 'scaleChange', this.status);
+ this.selectedIndex = this.getSelectedIndex();
+ if (handleEvent) {
+ emitEvent(this, 'scaleChange', { segments });
+ }
}
getAllSegments() {