Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions packages/@react-spectrum/s2/src/Meter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export interface MeterProps extends Omit<AriaMeterProps, 'children' | 'className

export const MeterContext = createContext<ContextValue<MeterProps, DOMRefValue<HTMLDivElement>>>(null);

const wrapper = style<MeterStyleProps>({
const wrapper = style({
...bar(),
width: {
default: 208,
Expand Down Expand Up @@ -123,7 +123,8 @@ function Meter(props: MeterProps, ref: DOMRef<HTMLDivElement>) {
className={UNSAFE_className + wrapper({
size,
variant,
staticColor
staticColor,
labelPosition: 'top'
}, styles)}>
{({percentage, valueText}) => (
<>
Expand Down
28 changes: 22 additions & 6 deletions packages/@react-spectrum/s2/src/ProgressBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from 'react-aria-components';
import {bar, track} from './bar-utils' with {type: 'macro'};
import {createContext, forwardRef, ReactNode} from 'react';
import {DOMRef, DOMRefValue} from '@react-types/shared';
import {DOMRef, DOMRefValue, LabelPosition} from '@react-types/shared';
import {FieldLabel} from './Field';
import {fieldLabel, getAllowedOverrides, StyleProps} from './style-utils' with {type: 'macro'};
import {keyframes} from '../style/style-macro' with {type: 'macro'};
Expand All @@ -37,8 +37,16 @@ interface ProgressBarStyleProps {
* Whether presentation is indeterminate when progress isn't known.
*/
isIndeterminate?: boolean,
/** The static color style to apply. Useful when the button appears over a color background. */
staticColor?: 'white' | 'black'
/**
* The static color style to apply. Useful when the button appears over a color background.
*/
staticColor?: 'white' | 'black',
/**
* The label's overall position relative to the element it is labeling.
* @default 'top'
*/
labelPosition?: LabelPosition

}

export interface ProgressBarProps extends Omit<AriaProgressBarProps, 'children' | 'className' | 'style'>, ProgressBarStyleProps, StyleProps {
Expand Down Expand Up @@ -89,6 +97,7 @@ const trackStyles = style({
const fill = style<ProgressBarStyleProps>({
height: 'full',
borderStyle: 'none',
borderRadius: 'full',
backgroundColor: {
default: 'accent',
staticColor: {
Expand Down Expand Up @@ -117,17 +126,24 @@ const indeterminateAnimation = style({

function ProgressBar(props: ProgressBarProps, ref: DOMRef<HTMLDivElement>) {
[props, ref] = useSpectrumContextProps(props, ref, ProgressBarContext);
let {label, size = 'M', staticColor, isIndeterminate, UNSAFE_style, UNSAFE_className = ''} = props;
let {
label, size = 'M',
staticColor,
isIndeterminate,
labelPosition = 'top',
UNSAFE_style,
UNSAFE_className = ''
} = props;
let domRef = useDOMRef(ref);
return (
<AriaProgressBar
{...props}
ref={domRef}
style={UNSAFE_style}
className={UNSAFE_className + wrapper({...props, size}, props.styles)}>
className={UNSAFE_className + wrapper({...props, size, labelPosition}, props.styles)}>
{({percentage, valueText}) => (
<>
{label && <FieldLabel size={size} labelAlign="start" labelPosition="top" staticColor={staticColor}>{label}</FieldLabel>}
{label && <FieldLabel size={size} labelAlign="start" labelPosition={labelPosition} staticColor={staticColor}>{label}</FieldLabel>}
{label && <span className={valueStyles({size, labelAlign: 'end', staticColor})}>{valueText}</span>}
<div className={trackStyles({...props})}>
<div
Expand Down
41 changes: 33 additions & 8 deletions packages/@react-spectrum/s2/src/bar-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,51 @@ import {centerPadding} from './style-utils' with {type: 'macro'};
export const bar = () => ({
position: 'relative',
display: 'grid',
gridTemplateColumns: '1fr auto',
gridTemplateAreas: [
'label value',
'bar bar'
],
gridTemplateColumns: {
labelPosition: {
top: ['1fr', 'auto'],
side: ['auto', '1fr']
}
},
gridTemplateAreas: {
labelPosition: {
top: [
'label value',
'bar bar',
],
side: [
'label bar value'
]
}
},
alignItems: 'baseline',
isolation: 'isolate',
minWidth: 48, // progress-bar-minimum-width
maxWidth: '[768px]', // progress-bar-maximum-width
minHeight: 'control',
'--field-height': {
type: 'height',
value: 'control'
},
'--track-to-label': {
type: 'height',
value: 4
},
// Spectrum defines the field label/help text with a (minimum) height, with text centered inside.
// Calculate what the gap should be based on the height and line height.
// Use a variable here rather than rowGap since it is applied to the children as padding.
// This allows the gap to collapse when the label/help text is not present.
// Eventually this may be possible to do in pure CSS: https://github.com/w3c/csswg-drafts/issues/5813
'--field-gap': {
type: 'rowGap',
value: centerPadding()
value: centerPadding('calc(var(--field-height) + var(--track-to-label))')
},

columnGap: 12 // spacing-200
} as const);

export const track = () => ({
gridArea: 'bar',
overflow: 'hidden',
marginTop: 4,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, thought we'd just set this to 0 when no label
was there a reason you did it this other way?
not wrong necessarily, just caught me by surprise

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah i tried that, i guess the reason i went the other route is because i didn't really want to have to add an hasLabel to both progress bar and meter (even though i know it would be internal). it worked so if we want to go that direction i'd be fine with it.

plus i read the comment above --field-gap a bit more closely (which was copied from field() and i believe devon wrote) and it mentioned that it would collapse the gap when the label isn't present which is what we wanted to do here. so i figured we could just apply the margin there instead and it would handle the work of having to remove the margin when there is no label

borderRadius: 'full',
backgroundColor: {
default: 'gray-300',
Expand Down