-
Notifications
You must be signed in to change notification settings - Fork 206
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
fix(button): adds pending button, fixes #3162 #3163
Changes from 9 commits
305c7e6
52417fe
470b0f5
56e822c
dfc98fe
0be1ae7
b31e47a
49d9a8d
c34de46
312b676
9353e4f
e305d44
fe59c9b
f327507
3233d75
6acf088
80f4baf
e1650cb
1235028
c1b54b5
3201c55
3c6eaeb
cdad70d
4b3f03f
a96ae36
f67a9a5
db88621
740fb8c
b5e3523
07e63b9
0258c3a
4c99a45
e8720ac
d65480f
f36e8ad
3ffb308
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,12 +12,15 @@ governing permissions and limitations under the License. | |
|
||
import { | ||
CSSResultArray, | ||
html, | ||
PropertyValues, | ||
SizedMixin, | ||
TemplateResult, | ||
} from '@spectrum-web-components/base'; | ||
import { property } from '@spectrum-web-components/base/src/decorators.js'; | ||
import { ButtonBase } from './ButtonBase.js'; | ||
import buttonStyles from './button.css.js'; | ||
import { when } from '@spectrum-web-components/base/src/directives.js'; | ||
|
||
export type DeprecatedButtonVariants = 'cta' | 'overBackground'; | ||
export type ButtonStatics = 'white' | 'black'; | ||
|
@@ -51,6 +54,27 @@ export class Button extends SizedMixin(ButtonBase, { noDefaultSize: true }) { | |
return [...super.styles, buttonStyles]; | ||
} | ||
|
||
protected pendingCooldown = -1; | ||
|
||
// isPending represents the state of the button being in a pending state | ||
// This also helps us show the progress circle and update the aria-label when the button is in pending state | ||
@property({ type: Boolean, reflect: true, attribute: 'is-pending' }) | ||
public isPending = false; | ||
|
||
@property({ type: String, attribute: 'pending-label' }) | ||
public pendingLabel = 'Pending'; | ||
|
||
// pending is the property that consumers can use to set the button into a pending state | ||
@property({ type: Boolean, reflect: true, attribute: true }) | ||
public pending = false; | ||
|
||
public override click(): void { | ||
if (this.isPending) { | ||
return; | ||
} | ||
super.click(); | ||
} | ||
|
||
/** | ||
* The visual variant to apply to this button. | ||
*/ | ||
|
@@ -127,11 +151,30 @@ export class Button extends SizedMixin(ButtonBase, { noDefaultSize: true }) { | |
public set quiet(quiet: boolean) { | ||
this.treatment = quiet ? 'outline' : 'fill'; | ||
} | ||
|
||
public get quiet(): boolean { | ||
return this.treatment === 'outline'; | ||
} | ||
|
||
protected override willUpdate( | ||
changedProperties: PropertyValues<this> | ||
): void { | ||
super.willUpdate(changedProperties); | ||
if (changedProperties.has('pending')) { | ||
if (this.pending) { | ||
this.pendingCooldown = window.setTimeout(() => { | ||
if (!this.disabled) { | ||
this.isPending = true; | ||
this.setAttribute('aria-label', this.pendingLabel); | ||
} | ||
}, 1000); | ||
} else if (this.pending === false && this.isPending) { | ||
window.clearTimeout(this.pendingCooldown); | ||
this.isPending = false; | ||
this.setAttribute('aria-label', this.label || ''); | ||
} | ||
} | ||
} | ||
|
||
protected override firstUpdated(changes: PropertyValues<this>): void { | ||
super.firstUpdated(changes); | ||
// There is no Spectrum design context for an `<sp-button>` without a variant | ||
|
@@ -140,4 +183,22 @@ export class Button extends SizedMixin(ButtonBase, { noDefaultSize: true }) { | |
this.setAttribute('variant', this.variant); | ||
} | ||
} | ||
|
||
protected override renderButton(): TemplateResult { | ||
return html` | ||
${this.buttonContent} | ||
${when(this.isPending, () => { | ||
import( | ||
'@spectrum-web-components/progress-circle/sp-progress-circle.js' | ||
); | ||
return html` | ||
<sp-progress-circle | ||
indeterminate | ||
static="white" | ||
label=${this.pendingLabel + 'progress circle'} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need the Separately, is it even possible to get to the Progress Circle in the accessibility tree? Would it be better to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you're right! this is just a visible affordance so it makes much more sense to have aria-hidden="true" |
||
></sp-progress-circle> | ||
`; | ||
})} | ||
`; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,3 +21,20 @@ governing permissions and limitations under the License. | |
border-color: highlight; | ||
} | ||
} | ||
|
||
:host([pending][is-pending]) { | ||
cursor: default; | ||
pointer-events: none; | ||
} | ||
|
||
:host([pending][is-pending]) sp-progress-circle { | ||
display: block; | ||
position: absolute; | ||
left: 50%; | ||
transform: translate(-50%, 0); | ||
Comment on lines
+81
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For reference: |
||
} | ||
|
||
:host([pending][is-pending]) slot[name='icon'], | ||
:host([pending][is-pending]) #label { | ||
visibility: hidden; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't remember what visibly hiding this content does to the accessibility tree right off, so making a note to confirm. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Checked in voiceover and the label seems to be hidden? Is there some other way I can test? |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
Copyright 2020 Adobe. All rights reserved. | ||
This file is licensed to you under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. You may obtain a copy | ||
of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software distributed under | ||
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS | ||
OF ANY KIND, either express or implied. See the License for the specific language | ||
governing permissions and limitations under the License. | ||
*/ | ||
import { TemplateResult } from '@spectrum-web-components/base'; | ||
import { Properties, renderButtonSet } from './index.js'; | ||
import { args, argTypes } from './index.js'; | ||
|
||
const variant = 'accent'; | ||
const treatment = 'fill'; | ||
const pending = true; | ||
|
||
export default { | ||
component: 'sp-button', | ||
title: 'Button/Accent/Fill/Pending', | ||
args: { | ||
...args, | ||
variant, | ||
treatment, | ||
pending, | ||
}, | ||
argTypes, | ||
}; | ||
|
||
export const s = (args: Properties): TemplateResult => renderButtonSet(args); | ||
s.args = { | ||
size: 's', | ||
}; | ||
|
||
export const m = (args: Properties): TemplateResult => renderButtonSet(args); | ||
m.args = { | ||
size: 'm', | ||
}; | ||
|
||
export const l = (args: Properties): TemplateResult => renderButtonSet(args); | ||
l.args = { | ||
size: 'l', | ||
}; | ||
|
||
export const XL = (args: Properties): TemplateResult => renderButtonSet(args); | ||
XL.args = { | ||
size: 'xl', | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
Copyright 2020 Adobe. All rights reserved. | ||
This file is licensed to you under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. You may obtain a copy | ||
of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software distributed under | ||
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS | ||
OF ANY KIND, either express or implied. See the License for the specific language | ||
governing permissions and limitations under the License. | ||
*/ | ||
import { TemplateResult } from '@spectrum-web-components/base'; | ||
import { Properties, renderButtonSet } from './index.js'; | ||
import { args, argTypes } from './index.js'; | ||
|
||
const variant = 'accent'; | ||
const treatment = 'outline'; | ||
const pending = true; | ||
|
||
export default { | ||
component: 'sp-button', | ||
title: 'Button/Accent/Outline/Pending', | ||
args: { | ||
...args, | ||
variant, | ||
treatment, | ||
pending, | ||
}, | ||
argTypes, | ||
}; | ||
|
||
export const s = (args: Properties): TemplateResult => renderButtonSet(args); | ||
s.args = { | ||
size: 's', | ||
}; | ||
|
||
export const m = (args: Properties): TemplateResult => renderButtonSet(args); | ||
m.args = { | ||
size: 'm', | ||
}; | ||
|
||
export const l = (args: Properties): TemplateResult => renderButtonSet(args); | ||
l.args = { | ||
size: 'l', | ||
}; | ||
|
||
export const XL = (args: Properties): TemplateResult => renderButtonSet(args); | ||
XL.args = { | ||
size: 'xl', | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
Copyright 2020 Adobe. All rights reserved. | ||
This file is licensed to you under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. You may obtain a copy | ||
of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software distributed under | ||
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS | ||
OF ANY KIND, either express or implied. See the License for the specific language | ||
governing permissions and limitations under the License. | ||
*/ | ||
import { TemplateResult } from '@spectrum-web-components/base'; | ||
import { Properties, renderButtonSet } from './index.js'; | ||
import { args, argTypes } from './index.js'; | ||
|
||
const variant = 'black'; | ||
const treatment = 'fill'; | ||
const pending = true; | ||
|
||
export default { | ||
component: 'sp-button', | ||
title: 'Button/Black/Fill/Pending', | ||
args: { | ||
...args, | ||
variant, | ||
treatment, | ||
pending, | ||
}, | ||
argTypes, | ||
}; | ||
|
||
export const s = (args: Properties): TemplateResult => renderButtonSet(args); | ||
s.args = { | ||
size: 's', | ||
}; | ||
|
||
export const m = (args: Properties): TemplateResult => renderButtonSet(args); | ||
m.args = { | ||
size: 'm', | ||
}; | ||
|
||
export const l = (args: Properties): TemplateResult => renderButtonSet(args); | ||
l.args = { | ||
size: 'l', | ||
}; | ||
|
||
export const XL = (args: Properties): TemplateResult => renderButtonSet(args); | ||
XL.args = { | ||
size: 'xl', | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
Copyright 2020 Adobe. All rights reserved. | ||
This file is licensed to you under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. You may obtain a copy | ||
of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software distributed under | ||
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS | ||
OF ANY KIND, either express or implied. See the License for the specific language | ||
governing permissions and limitations under the License. | ||
*/ | ||
import { TemplateResult } from '@spectrum-web-components/base'; | ||
import { Properties, renderButtonSet } from './index.js'; | ||
import { args, argTypes } from './index.js'; | ||
|
||
const variant = 'black'; | ||
const treatment = 'outline'; | ||
const pending = true; | ||
|
||
export default { | ||
component: 'sp-button', | ||
title: 'Button/Black/Outline/Pending', | ||
args: { | ||
...args, | ||
variant, | ||
treatment, | ||
pending, | ||
}, | ||
argTypes, | ||
}; | ||
|
||
export const s = (args: Properties): TemplateResult => renderButtonSet(args); | ||
s.args = { | ||
size: 's', | ||
}; | ||
|
||
export const m = (args: Properties): TemplateResult => renderButtonSet(args); | ||
m.args = { | ||
size: 'm', | ||
}; | ||
|
||
export const l = (args: Properties): TemplateResult => renderButtonSet(args); | ||
l.args = { | ||
size: 'l', | ||
}; | ||
|
||
export const XL = (args: Properties): TemplateResult => renderButtonSet(args); | ||
XL.args = { | ||
size: 'xl', | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add back this line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done hehe