Skip to content
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
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
### Changelog

#### 5.6.0

##### Fixes

- Fixed an issue where alpha value was reset to 1 after sliding both alpha and
any of the r/g/b sliders (#227).
- Fixed an issue with inaccurate kelvin conversion (replaced with more accurate script).

##### Additions

- Added optional label and input elements. Picker color can now be set via input field.
- Added optional `showInput`, `showLabel` and `disabled` slider options for displaying an input field and/or label field next to a slider.
- Added optional `sliderLength` slider option to set each slider's dimension seperately.

##### Changes
- Utilize display:flex on the entire wrapper component.
- Wrap Slider components in a flex wrapper for easy positioning of elements.
- Add IroColor.raw_rgb getter for kelvin conversion issues (returns float numbers instead of int).

#### 5.5.2

##### Fixes
Expand Down
20 changes: 20 additions & 0 deletions dist/Input.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { h } from 'preact';
import { LayoutDirection } from '@irojs/iro-core';
import { IroColor, SliderType } from '@irojs/iro-core';
interface IroInputProps {
sliderType: SliderType;
sliderSize: number;
activeColor: IroColor;
layoutDirection: LayoutDirection;
handleRadius: number;
disabled: boolean;
minTemperature: number;
maxTemperature: number;
}
export declare function IroInput(props: IroInputProps): h.JSX.Element;
export declare namespace IroInput {
var defaultProps: {
disabled: boolean;
};
}
export {};
10 changes: 10 additions & 0 deletions dist/Label.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { h } from 'preact';
import { LayoutDirection } from '@irojs/iro-core';
import { SliderType } from '@irojs/iro-core';
interface IroLabelProps {
sliderType: SliderType;
layoutDirection: LayoutDirection;
handleRadius: number;
}
export declare function IroLabel(props: IroLabelProps): h.JSX.Element;
export {};
4 changes: 4 additions & 0 deletions dist/Slider.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import { IroComponentProps } from './ComponentTypes';
interface IroSliderProps extends IroComponentProps {
sliderType: SliderType;
sliderShape: SliderShape;
sliderSize: number;
minTemperature: number;
maxTemperature: number;
showInput: boolean;
showLabel: boolean;
disabled: boolean;
}
export declare function IroSlider(props: IroSliderProps): h.JSX.Element;
export declare namespace IroSlider {
Expand Down
419 changes: 335 additions & 84 deletions dist/iro.es.js

Large diffs are not rendered by default.

423 changes: 337 additions & 86 deletions dist/iro.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/iro.min.js

Large diffs are not rendered by default.

419 changes: 335 additions & 84 deletions docs/.vuepress/theme/js/iro.es.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"main": "dist/iro.js",
"types": "dist/index.d.ts",
"dependencies": {
"@irojs/iro-core": "^1.2.1",
"@irojs/iro-core": "file:../iro-core",
"preact": "^10.0.0"
},
"devDependencies": {
Expand Down
5 changes: 3 additions & 2 deletions src/ColorPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class IroColorPicker extends Component<ColorPickerProps, ColorPickerState
public static defaultProps: ColorPickerProps = {
...iroColorPickerOptionDefaults,
colors: [],
display: 'block',
display: 'flex',
id: null,
layout: 'default',
margin: null
Expand Down Expand Up @@ -310,7 +310,8 @@ export class IroColorPicker extends Component<ColorPickerProps, ColorPickerState
class="IroColorPicker"
id={ state.id }
style={{
display: state.display
display: state.display,
flexDirection: props.layoutDirection === 'horizontal' ? 'row' : 'column'
}}
>
{ layout.map(({component: UiComponent, options: options }, componentIndex: number) => (
Expand Down
2 changes: 1 addition & 1 deletion src/ComponentWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class IroComponentWrapper extends Component<Props, State> {

const rootStyles = {
overflow: 'visible',
display: isHorizontal ? 'inline-block' : 'block'
display: isHorizontal ? 'inline-flex' : 'flex'
};

// first component shouldn't have any margin
Expand Down
96 changes: 96 additions & 0 deletions src/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { h } from 'preact';
import { cssValue, LayoutDirection } from '@irojs/iro-core';
import { useCallback, useState } from 'preact/hooks';
import {
IroColor,
SliderType,
getSliderValueFromInputField,
getSliderValueFromClipboard,
getInputDimensions,
clampSliderValue
} from '@irojs/iro-core';

interface IroInputProps {
sliderType: SliderType;
sliderSize: number;
activeColor: IroColor;
layoutDirection: LayoutDirection;
handleRadius: number;
disabled: boolean;
minTemperature: number;
maxTemperature: number;
}

export function IroInput(props: IroInputProps) {
const disabled = props.disabled;
const type = props.sliderType;
const {inputWidth, fontSize} = getInputDimensions(props);
const activeColor = props.activeColor;
const [sliderValue, setSliderValue] = useState(activeColor[props.sliderType]);
const val = (type === 'alpha') ? activeColor[props.sliderType].toFixed(2) : Math.round(activeColor[props.sliderType]);
setSliderValue(val);

const onKeypress = useCallback((e: KeyboardEvent) => {
const value = getSliderValueFromInputField(e);

if (type === 'kelvin') {
let strlen = value.toString().length,
minlen = props.minTemperature.toString().length,
maxlen = props.maxTemperature.toString().length;

if (strlen > maxlen) {
e.preventDefault();
activeColor[props.sliderType] = props.maxTemperature;
} else if (strlen >= minlen) {
if (value < props.minTemperature) {
if (maxlen === minlen) {
e.preventDefault();
activeColor[props.sliderType] = props.minTemperature;
}
} else if (value > props.maxTemperature) {
e.preventDefault();
activeColor[props.sliderType] = props.maxTemperature;
} else {
e.preventDefault();
activeColor[props.sliderType] = value;
}
}
} else {
e.preventDefault();
activeColor[props.sliderType] = clampSliderValue(props, value);
}
return value;
}, [setSliderValue, props.sliderType]);

const onPaste = useCallback((e: ClipboardEvent) => {
e.preventDefault();
const value = getSliderValueFromClipboard(props, e);
activeColor[props.sliderType] = value;
return value;
}, [setSliderValue, props.sliderType]);

return (
<div className="IroSliderValue">
<input
onKeyPress={ onKeypress }
onPaste={ onPaste }
className="IroSliderInput"
style={{
display: 'inline-block',
width: type === 'kelvin' ? cssValue(40) : inputWidth,
height: cssValue(18),
fontSize: fontSize,
padding: cssValue(2)
}}
type="text"
disabled={ disabled }
value={ sliderValue }
>
</input>
</div>
);
}

IroInput.defaultProps = {
disabled: false
};
28 changes: 28 additions & 0 deletions src/Label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { h } from 'preact';
import { cssValue, LayoutDirection } from '@irojs/iro-core';
import { SliderType } from '@irojs/iro-core';

interface IroLabelProps {
sliderType: SliderType;
layoutDirection: LayoutDirection;
handleRadius: number;
}

export function IroLabel(props: IroLabelProps) {
const name = props.sliderType[0].toUpperCase();

return (
<div
className="IroSliderLabel"
style={{
display: 'inline-block',
width: cssValue(10),
height: cssValue(12),
lineHeight: cssValue(12),
fontSize: props.layoutDirection === 'horizontal' ? cssValue(12) : cssValue(14)
}}
>
{name}
</div>
);
}
107 changes: 73 additions & 34 deletions src/Slider.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { h } from 'preact';
import {
IroColor,
SliderShape,
SliderType,
sliderDefaultOptions,
getSliderDimensions,
getSliderValueFromInput,
getSliderValueFromInput,
getSliderHandlePosition,
getSliderGradient,
cssBorderStyles,
Expand All @@ -16,12 +15,18 @@ import {
import { IroComponentWrapper } from './ComponentWrapper';
import { IroComponentProps, IroInputType } from './ComponentTypes';
import { IroHandle } from './Handle';
import { IroInput } from './Input';
import { IroLabel } from './Label';

interface IroSliderProps extends IroComponentProps {
sliderType: SliderType;
sliderShape: SliderShape;
sliderSize: number;
minTemperature: number;
maxTemperature: number;
showInput: boolean; // show input fields for manual value input
showLabel: boolean; // show label for slider
disabled: boolean; // enable / disable manual value input
};

export function IroSlider(props: IroSliderProps) {
Expand All @@ -35,52 +40,86 @@ export function IroSlider(props: IroSliderProps) {
const value = getSliderValueFromInput(props, x, y);
props.parent.inputActive = true;
activeColor[props.sliderType] = value;
if (props.sliderType === 'kelvin') {
activeColor._kelvin = value;
}
props.onInput(type, props.id);
}

return (
<IroComponentWrapper {...props} onInput={ handleInput }>
{(uid, rootProps, rootStyles) => (
// add wrapper element
<div
{ ...rootProps }
className="IroSlider"
style={{
position: 'relative',
width: cssValue(width),
height: cssValue(height),
borderRadius: cssValue(radius),
// checkered bg to represent alpha
background: `conic-gradient(#ccc 25%, #fff 0 50%, #ccc 0 75%, #fff 0)`,
backgroundSize: '8px 8px',
className="IroSliderWrapper"
style={{
width: props.layoutDirection === 'vertical' ? cssValue(props.width) : 'unset',
height: props.layoutDirection === 'horizontal' ? cssValue(props.width) : 'unset',
flexDirection: props.layoutDirection === 'horizontal' ? 'column' : 'row',
alignItems: 'center',
justifyContent: 'space-between',
...rootStyles
}}
>
<div
className="IroSliderGradient"
{ ...rootProps }
className="IroSlider"
style={{
position: 'absolute',
top: 0,
left: 0,
width: `100%`,
height: `100%`,
position: 'relative',
display: 'block',
width: cssValue(width),
height: cssValue(height),
borderRadius: cssValue(radius),
background: cssGradient(
'linear',
props.layoutDirection === 'horizontal' ? 'to top' : 'to right',
gradient
),
...cssBorderStyles(props)
// checkered bg to represent alpha
background: `conic-gradient(#ccc 25%, #fff 0 50%, #ccc 0 75%, #fff 0)`,
backgroundSize: '8px 8px',
}}
/>
<IroHandle
isActive={ true }
index={ activeColor.index }
r={ props.handleRadius }
url={ props.handleSvg }
props={ props.handleProps }
x={ handlePos.x }
y={ handlePos.y } // todo: use percentage
/>
>
<div
className="IroSliderGradient"
style={{
position: 'absolute',
top: 0,
left: 0,
width: `100%`,
height: `100%`,
borderRadius: cssValue(radius),
background: cssGradient(
'linear',
props.layoutDirection === 'horizontal' ? 'to top' : 'to right',
gradient
),
...cssBorderStyles(props)
}}
/>
<IroHandle
isActive={ true }
index={ activeColor.index }
r={ props.handleRadius }
url={ props.handleSvg }
props={ props.handleProps }
x={ handlePos.x }
y={ handlePos.y } // todo: use percentage
/>
</div>
{props.showLabel && (<IroLabel
sliderType={props.sliderType}
layoutDirection={ props.layoutDirection }
handleRadius={ props.handleRadius }
/>
)}
{props.showInput && (
<IroInput
disabled={ props.disabled }
sliderType={ props.sliderType }
sliderSize={ props.sliderSize }
activeColor={ activeColor }
handleRadius={ props.handleRadius }
layoutDirection={ props.layoutDirection }
minTemperature={ props.minTemperature }
maxTemperature={ props.maxTemperature }
/>
)}
</div>
)}
</IroComponentWrapper>
Expand Down