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

feat(react-color-picker): Added transparent option to the AlphaSlider #33572

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
ValentinaKozlova marked this conversation as resolved.
Show resolved Hide resolved
"type": "patch",
"comment": "feat: Added `transparent` option to the AlphaSlider",
"packageName": "@fluentui/react-color-picker-preview",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export const AlphaSlider: ForwardRefComponent<AlphaSliderProps>;
export const alphaSliderClassNames: SlotClassNames<AlphaSliderSlots>;

// @public
export type AlphaSliderProps = ColorSliderProps;
export type AlphaSliderProps = ColorSliderProps & {
transparency?: boolean;
};

// @public (undocumented)
export type AlphaSliderSlots = ColorSliderSlots;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ export type AlphaSliderSlots = ColorSliderSlots;
/**
* AlphaSlider Props
*/
export type AlphaSliderProps = ColorSliderProps;
export type AlphaSliderProps = ColorSliderProps & {
transparency?: boolean;
};

/**
* State used in rendering AlphaSlider
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export function adjustToTransparency(value: number, transparency?: boolean) {
return transparency ? 100 - value : value;
}

export function calculateTransparencyValue(value?: number, transparency?: boolean) {
return value !== undefined ? adjustToTransparency(value * 100, transparency) : undefined;
}

export function getSliderDirection(dir: 'ltr' | 'rtl', vertical?: boolean, transparency?: boolean) {
if (vertical) {
return transparency ? '180deg' : '0deg';
} else {
return dir === 'ltr' && !transparency ? '90deg' : '-90deg';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,41 @@ import { useColorPickerContextValue_unstable } from '../../contexts/colorPicker'
import { MIN, MAX } from '../../utils/constants';
import { getPercent } from '../../utils/getPercent';
import type { HsvColor } from '../../types/color';
import { adjustToTransparency, calculateTransparencyValue, getSliderDirection } from './alphaSliderUtils';

export const useAlphaSliderState_unstable = (state: AlphaSliderState, props: AlphaSliderProps) => {
'use no memo';

const { dir } = useFluent();
const onChangeFromContext = useColorPickerContextValue_unstable(ctx => ctx.requestChange);
const colorFromContext = useColorPickerContextValue_unstable(ctx => ctx.color);
const { color, onChange = onChangeFromContext } = props;
const { color, onChange = onChangeFromContext, transparency } = props;
const hsvColor = color || colorFromContext;
const hslColor = tinycolor(hsvColor).toHsl();

const [currentValue, setCurrentValue] = useControllableState({
defaultState: props.defaultColor?.a ? props.defaultColor.a * 100 : undefined,
state: hsvColor?.a ? hsvColor.a * 100 : undefined,
initialState: 100,
defaultState: calculateTransparencyValue(props.defaultColor?.a, transparency),
state: calculateTransparencyValue(hsvColor?.a, transparency),
initialState: adjustToTransparency(100, transparency),
});

const clampedValue = clamp(currentValue, MIN, MAX);
const valuePercent = getPercent(clampedValue, MIN, MAX);

const inputOnChange = state.input.onChange;

const _onChange: React.ChangeEventHandler<HTMLInputElement> = useEventCallback(event => {
const newValue = Number(event.target.value);
const newValue = adjustToTransparency(Number(event.target.value), transparency);
const newColor: HsvColor = { ...hsvColor, a: newValue / 100 };
setCurrentValue(newValue);
inputOnChange?.(event);
onChange?.(event, { type: 'change', event, color: newColor });
});

const sliderDirection = getSliderDirection(dir, state.vertical, transparency);

const rootVariables = {
[alphaSliderCSSVars.sliderDirectionVar]: state.vertical ? '0deg' : dir === 'ltr' ? '90deg' : '-90deg',
[alphaSliderCSSVars.sliderDirectionVar]: sliderDirection,
[alphaSliderCSSVars.sliderProgressVar]: `${valuePercent}%`,
[alphaSliderCSSVars.thumbColorVar]: `transparent`,
[alphaSliderCSSVars.railColorVar]: `hsl(${hslColor.h} ${hslColor.s * 100}%, ${hslColor.l * 100}%)`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ export const AlphaSliderExample = (props: Partial<AlphaSliderProps>) => {
const styles = useStyles();

const [color, setColor] = React.useState(COLOR);
const [transparancyColor, setTransparancyColor] = React.useState(COLOR);
const [value, setValue] = React.useState(COLOR.a * 100);
const onSliderChange: AlphaSliderProps['onChange'] = (_, data) => {
const alpha = data.color.a ?? 1;
setColor({ ...data.color, a: alpha });
setValue(alpha * 100);
};
const onTransparancySliderChange: AlphaSliderProps['onChange'] = (_, data) =>
setTransparancyColor({ ...data.color, a: data.color.a ?? 1 });
const resetSlider = () => setColor(COLOR);
const resetTransparencySlider = () => setTransparancyColor(COLOR);

return (
<div className={styles.example}>
Expand All @@ -48,6 +52,26 @@ export const AlphaSliderExample = (props: Partial<AlphaSliderProps>) => {
/>
<div className={styles.previewColor} style={{ backgroundColor: tinycolor(color).toRgbString() }} />
<Button onClick={resetSlider}>Reset</Button>
<h3>Transparency</h3>
<AlphaSlider
color={transparancyColor}
onChange={onTransparancySliderChange}
aria-valuetext={`${value}%`}
aria-label="Alpha"
transparency
{...props}
/>
<AlphaSlider
color={transparancyColor}
onChange={onTransparancySliderChange}
aria-valuetext={`${value}%`}
aria-label="Vertical alpha"
transparency
vertical
{...props}
/>
<div className={styles.previewColor} style={{ backgroundColor: tinycolor(transparancyColor).toRgbString() }} />
<Button onClick={resetTransparencySlider}>Reset</Button>
</div>
);
};
Expand Down
Loading