Custom select elements & more form work

This commit is contained in:
Jake Archibald
2018-10-18 08:17:39 +01:00
parent 2138154ec5
commit 91d165cab9
9 changed files with 119 additions and 56 deletions

View File

@@ -2,6 +2,9 @@ import { h, Component } from 'preact';
import { bind } from '../../lib/initial-util'; import { bind } from '../../lib/initial-util';
import { inputFieldValueAsNumber, konami } from '../../lib/util'; import { inputFieldValueAsNumber, konami } from '../../lib/util';
import { QuantizeOptions } from './processor-meta'; import { QuantizeOptions } from './processor-meta';
import * as style from '../../components/options/style.scss';
import Expander from '../../components/expander';
import Select from '../../components/select';
const konamiPromise = konami(); const konamiPromise = konami();
@@ -28,8 +31,10 @@ export default class QuantizerOptions extends Component<Props, State> {
const form = (event.currentTarget as HTMLInputElement).closest('form') as HTMLFormElement; const form = (event.currentTarget as HTMLInputElement).closest('form') as HTMLFormElement;
const options: QuantizeOptions = { const options: QuantizeOptions = {
zx: inputFieldValueAsNumber(form.zx), zx: form.zx ? inputFieldValueAsNumber(form.zx) : this.props.options.zx,
maxNumColors: inputFieldValueAsNumber(form.maxNumColors), maxNumColors: form.maxNumColors
? inputFieldValueAsNumber(form.maxNumColors)
: this.props.options.maxNumColors,
dither: inputFieldValueAsNumber(form.dither), dither: inputFieldValueAsNumber(form.dither),
}; };
this.props.onChange(options); this.props.onChange(options);
@@ -37,29 +42,37 @@ export default class QuantizerOptions extends Component<Props, State> {
render({ options }: Props, { extendedSettings }: State) { render({ options }: Props, { extendedSettings }: State) {
return ( return (
<form> <form class={style.optionsSection}>
<label style={{ display: extendedSettings ? '' : 'none' }}> <Expander>
Type: {extendedSettings ?
<select <label class={style.optionTextFirst}>
name="zx" Type:
value={'' + options.zx} <Select
onChange={this.onChange} name="zx"
> value={'' + options.zx}
<option value="0">Standard</option> onChange={this.onChange}
<option value="1">ZX</option> >
</select> <option value="0">Standard</option>
</label> <option value="1">ZX</option>
<label style={{ display: options.zx ? 'none' : '' }}> </Select>
Palette Colors: </label>
<range-input : null}
name="maxNumColors" </Expander>
min="2" <Expander>
max="256" {options.zx ? null :
value={'' + options.maxNumColors} <label class={style.optionTextFirst}>
onChange={this.onChange} Colors:
/> <range-input
</label> name="maxNumColors"
<label> min="2"
max="256"
value={'' + options.maxNumColors}
onChange={this.onChange}
/>
</label>
}
</Expander>
<label class={style.optionTextFirst}>
Dithering: Dithering:
<range-input <range-input
name="dither" name="dither"

View File

@@ -6,6 +6,7 @@ import { ResizeOptions } from './processor-meta';
import * as style from '../../components/options/style.scss'; import * as style from '../../components/options/style.scss';
import Checkbox from '../../components/checkbox'; import Checkbox from '../../components/checkbox';
import Expander from '../../components/expander'; import Expander from '../../components/expander';
import Select from '../../components/select';
interface Props { interface Props {
isVector: Boolean; isVector: Boolean;
@@ -73,7 +74,7 @@ export default class ResizerOptions extends Component<Props, State> {
<form ref={linkRef(this, 'form')} class={style.optionsSection}> <form ref={linkRef(this, 'form')} class={style.optionsSection}>
<label class={style.optionTextFirst}> <label class={style.optionTextFirst}>
Method: Method:
<select <Select
name="resizeMethod" name="resizeMethod"
value={options.method} value={options.method}
onChange={this.onChange} onChange={this.onChange}
@@ -83,12 +84,13 @@ export default class ResizerOptions extends Component<Props, State> {
<option value="browser-low">Browser low quality</option> <option value="browser-low">Browser low quality</option>
<option value="browser-medium">Browser medium quality</option> <option value="browser-medium">Browser medium quality</option>
<option value="browser-high">Browser high quality</option> <option value="browser-high">Browser high quality</option>
</select> </Select>
</label> </label>
<label class={style.optionTextFirst}> <label class={style.optionTextFirst}>
Width: Width:
<input <input
required required
class={style.textField}
name="width" name="width"
type="number" type="number"
min="1" min="1"
@@ -101,6 +103,7 @@ export default class ResizerOptions extends Component<Props, State> {
Height: Height:
<input <input
required required
class={style.textField}
name="height" name="height"
type="number" type="number"
min="1" min="1"
@@ -120,14 +123,14 @@ export default class ResizerOptions extends Component<Props, State> {
{maintainAspect ? null : {maintainAspect ? null :
<label class={style.optionTextFirst}> <label class={style.optionTextFirst}>
Fit method: Fit method:
<select <Select
name="fitMethod" name="fitMethod"
value={options.fitMethod} value={options.fitMethod}
onChange={this.onChange} onChange={this.onChange}
> >
<option value="stretch">Stretch</option> <option value="stretch">Stretch</option>
<option value="cover">Cover</option> <option value="cover">Cover</option>
</select> </Select>
</label> </label>
} }
</Expander> </Expander>

View File

@@ -141,7 +141,7 @@ export default class Options extends Component<Props, State> {
return ( return (
<div class={style.options}> <div class={style.options}>
<h2 class={style.optionsTitle}>Process</h2> <h2 class={style.optionsTitle}>Edit</h2>
<label class={style.sectionEnabler}> <label class={style.sectionEnabler}>
<Checkbox <Checkbox
name="resize.enable" name="resize.enable"
@@ -151,34 +151,31 @@ export default class Options extends Component<Props, State> {
Resize Resize
</label> </label>
<Expander> <Expander>
{preprocessorState.resize.enabled {preprocessorState.resize.enabled ?
? <ResizeOptionsComponent
<ResizeOptionsComponent isVector={Boolean(source && source.vectorImage)}
isVector={Boolean(source && source.vectorImage)} aspect={source ? (source.data.width / source.data.height) : 1}
aspect={source ? (source.data.width / source.data.height) : 1} options={preprocessorState.resize}
options={preprocessorState.resize} onChange={this.onResizeOptionsChange}
onChange={this.onResizeOptionsChange} />
/> : null}
: null
}
</Expander> </Expander>
{/* <label class={style.sectionEnabler}>
<label class={style.toggle}> <Checkbox
<input
name="quantizer.enable" name="quantizer.enable"
type="checkbox"
checked={!!preprocessorState.quantizer.enabled} checked={!!preprocessorState.quantizer.enabled}
onChange={this.onPreprocessorEnabledChange} onChange={this.onPreprocessorEnabledChange}
/> />
Quantize Reduce palette
</label> </label>
{preprocessorState.quantizer.enabled && <Expander>
<QuantizerOptionsComponent {preprocessorState.quantizer.enabled ?
options={preprocessorState.quantizer} <QuantizerOptionsComponent
onChange={this.onQuantizerOptionsChange} options={preprocessorState.quantizer}
/> onChange={this.onQuantizerOptionsChange}
} />
*/} : null}
</Expander>
{/*<section class={style.picker}> {/*<section class={style.picker}>
{encoderSupportMap ? {encoderSupportMap ?

View File

@@ -18,6 +18,7 @@ $horizontalPadding: 15px;
.option-text-first { .option-text-first {
display: grid; display: grid;
align-items: center;
grid-template-columns: 87px 1fr; grid-template-columns: 87px 1fr;
grid-gap: 0.7em; grid-gap: 0.7em;
padding: 10px $horizontalPadding; padding: 10px $horizontalPadding;
@@ -41,4 +42,12 @@ $horizontalPadding: 15px;
background: rgba(0, 0, 0, 0.7); background: rgba(0, 0, 0, 0.7);
} }
.text-field {
background: #fff;
font: inherit;
border: none;
padding: 2px 0 2px 10px;
width: 100%;
box-sizing: border-box;
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5);
}

View File

@@ -52,7 +52,7 @@ two-up[legacy-clip-compat] > :not(.two-up-handle) {
height: calc(var(--thumb-size) * 0.9); height: calc(var(--thumb-size) * 0.9);
background: var(--thumb-background); background: var(--thumb-background);
border: 1px solid rgba(0,0,0,0.2); border: 1px solid rgba(0,0,0,0.2);
border-radius: calc(var(--thumb-size) * 0.08); border-radius: var(--thumb-size);
box-shadow: 0 1px 4px rgba(0,0,0,0.1); box-shadow: 0 1px 4px rgba(0,0,0,0.1);
color: var(--thumb-color); color: var(--thumb-color);
box-sizing: border-box; box-sizing: border-box;

View File

@@ -55,14 +55,16 @@ export default class Expander extends Component<Props, State> {
// Set the currently rendered height absolutely. // Set the currently rendered height absolutely.
this.el!.style.height = this.lastElHeight + 'px'; this.el!.style.height = this.lastElHeight + 'px';
this.el!.style.transition = ''; this.el!.style.transition = '';
this.el!.style.overflow = 'hidden';
// Force a style calc so the browser picks up the start value. // Force a style calc so the browser picks up the start value.
getComputedStyle(this.el!).height; getComputedStyle(this.el!).height;
// Animate to the new height. // Animate to the new height.
this.el!.style.height = newHeight + 'px'; this.el!.style.height = newHeight + 'px';
const listener = () => { const listener = () => {
// Unset the height, so element changes do the right thing. // Unset the height & overflow, so element changes do the right thing.
this.el!.style.height = ''; this.el!.style.height = '';
this.el!.style.overflow = '';
this.el!.removeEventListener('transitionend', listener); this.el!.removeEventListener('transitionend', listener);
this.el!.removeEventListener('transitioncancel', listener); this.el!.removeEventListener('transitioncancel', listener);
if (this.state.outgoingChildren[0]) { if (this.state.outgoingChildren[0]) {

View File

@@ -1,5 +1,4 @@
.expander { .expander {
overflow: hidden;
transition: height 200ms ease-in-out; transition: height 200ms ease-in-out;
} }

View File

@@ -0,0 +1,16 @@
import { h, Component } from 'preact';
import * as style from './style.scss';
interface Props extends JSX.HTMLAttributes {}
interface State {}
export default class Select extends Component<Props, State> {
render(props: Props) {
return (
<div class={style.select}>
<select class={style.nativeSelect} {...props}/>
<svg class={style.arrow} viewBox="0 0 10 5"><path d="M0 0l5 5 5-5z"/></svg>
</div>
);
}
}

View File

@@ -0,0 +1,24 @@
.select {
position: relative;
}
.native-select {
background: #2f2f2f;
border-radius: 4px;
font: inherit;
padding: 4px 25px 4px 10px;
-webkit-appearance: none;
-moz-appearance: none;
border: none;
color: #fff;
width: 100%;
}
.arrow {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
fill: #fff;
width: 10px;
}