mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-13 09:17:20 +00:00
Custom select elements & more form work
This commit is contained in:
@@ -2,6 +2,9 @@ import { h, Component } from 'preact';
|
||||
import { bind } from '../../lib/initial-util';
|
||||
import { inputFieldValueAsNumber, konami } from '../../lib/util';
|
||||
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();
|
||||
|
||||
@@ -28,8 +31,10 @@ export default class QuantizerOptions extends Component<Props, State> {
|
||||
const form = (event.currentTarget as HTMLInputElement).closest('form') as HTMLFormElement;
|
||||
|
||||
const options: QuantizeOptions = {
|
||||
zx: inputFieldValueAsNumber(form.zx),
|
||||
maxNumColors: inputFieldValueAsNumber(form.maxNumColors),
|
||||
zx: form.zx ? inputFieldValueAsNumber(form.zx) : this.props.options.zx,
|
||||
maxNumColors: form.maxNumColors
|
||||
? inputFieldValueAsNumber(form.maxNumColors)
|
||||
: this.props.options.maxNumColors,
|
||||
dither: inputFieldValueAsNumber(form.dither),
|
||||
};
|
||||
this.props.onChange(options);
|
||||
@@ -37,20 +42,26 @@ export default class QuantizerOptions extends Component<Props, State> {
|
||||
|
||||
render({ options }: Props, { extendedSettings }: State) {
|
||||
return (
|
||||
<form>
|
||||
<label style={{ display: extendedSettings ? '' : 'none' }}>
|
||||
<form class={style.optionsSection}>
|
||||
<Expander>
|
||||
{extendedSettings ?
|
||||
<label class={style.optionTextFirst}>
|
||||
Type:
|
||||
<select
|
||||
<Select
|
||||
name="zx"
|
||||
value={'' + options.zx}
|
||||
onChange={this.onChange}
|
||||
>
|
||||
<option value="0">Standard</option>
|
||||
<option value="1">ZX</option>
|
||||
</select>
|
||||
</Select>
|
||||
</label>
|
||||
<label style={{ display: options.zx ? 'none' : '' }}>
|
||||
Palette Colors:
|
||||
: null}
|
||||
</Expander>
|
||||
<Expander>
|
||||
{options.zx ? null :
|
||||
<label class={style.optionTextFirst}>
|
||||
Colors:
|
||||
<range-input
|
||||
name="maxNumColors"
|
||||
min="2"
|
||||
@@ -59,7 +70,9 @@ export default class QuantizerOptions extends Component<Props, State> {
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
}
|
||||
</Expander>
|
||||
<label class={style.optionTextFirst}>
|
||||
Dithering:
|
||||
<range-input
|
||||
name="dither"
|
||||
|
||||
@@ -6,6 +6,7 @@ import { ResizeOptions } from './processor-meta';
|
||||
import * as style from '../../components/options/style.scss';
|
||||
import Checkbox from '../../components/checkbox';
|
||||
import Expander from '../../components/expander';
|
||||
import Select from '../../components/select';
|
||||
|
||||
interface Props {
|
||||
isVector: Boolean;
|
||||
@@ -73,7 +74,7 @@ export default class ResizerOptions extends Component<Props, State> {
|
||||
<form ref={linkRef(this, 'form')} class={style.optionsSection}>
|
||||
<label class={style.optionTextFirst}>
|
||||
Method:
|
||||
<select
|
||||
<Select
|
||||
name="resizeMethod"
|
||||
value={options.method}
|
||||
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-medium">Browser medium quality</option>
|
||||
<option value="browser-high">Browser high quality</option>
|
||||
</select>
|
||||
</Select>
|
||||
</label>
|
||||
<label class={style.optionTextFirst}>
|
||||
Width:
|
||||
<input
|
||||
required
|
||||
class={style.textField}
|
||||
name="width"
|
||||
type="number"
|
||||
min="1"
|
||||
@@ -101,6 +103,7 @@ export default class ResizerOptions extends Component<Props, State> {
|
||||
Height:
|
||||
<input
|
||||
required
|
||||
class={style.textField}
|
||||
name="height"
|
||||
type="number"
|
||||
min="1"
|
||||
@@ -120,14 +123,14 @@ export default class ResizerOptions extends Component<Props, State> {
|
||||
{maintainAspect ? null :
|
||||
<label class={style.optionTextFirst}>
|
||||
Fit method:
|
||||
<select
|
||||
<Select
|
||||
name="fitMethod"
|
||||
value={options.fitMethod}
|
||||
onChange={this.onChange}
|
||||
>
|
||||
<option value="stretch">Stretch</option>
|
||||
<option value="cover">Cover</option>
|
||||
</select>
|
||||
</Select>
|
||||
</label>
|
||||
}
|
||||
</Expander>
|
||||
|
||||
@@ -141,7 +141,7 @@ export default class Options extends Component<Props, State> {
|
||||
|
||||
return (
|
||||
<div class={style.options}>
|
||||
<h2 class={style.optionsTitle}>Process</h2>
|
||||
<h2 class={style.optionsTitle}>Edit</h2>
|
||||
<label class={style.sectionEnabler}>
|
||||
<Checkbox
|
||||
name="resize.enable"
|
||||
@@ -151,34 +151,31 @@ export default class Options extends Component<Props, State> {
|
||||
Resize
|
||||
</label>
|
||||
<Expander>
|
||||
{preprocessorState.resize.enabled
|
||||
?
|
||||
{preprocessorState.resize.enabled ?
|
||||
<ResizeOptionsComponent
|
||||
isVector={Boolean(source && source.vectorImage)}
|
||||
aspect={source ? (source.data.width / source.data.height) : 1}
|
||||
options={preprocessorState.resize}
|
||||
onChange={this.onResizeOptionsChange}
|
||||
/>
|
||||
: null
|
||||
}
|
||||
: null}
|
||||
</Expander>
|
||||
{/*
|
||||
<label class={style.toggle}>
|
||||
<input
|
||||
<label class={style.sectionEnabler}>
|
||||
<Checkbox
|
||||
name="quantizer.enable"
|
||||
type="checkbox"
|
||||
checked={!!preprocessorState.quantizer.enabled}
|
||||
onChange={this.onPreprocessorEnabledChange}
|
||||
/>
|
||||
Quantize
|
||||
Reduce palette
|
||||
</label>
|
||||
{preprocessorState.quantizer.enabled &&
|
||||
<Expander>
|
||||
{preprocessorState.quantizer.enabled ?
|
||||
<QuantizerOptionsComponent
|
||||
options={preprocessorState.quantizer}
|
||||
onChange={this.onQuantizerOptionsChange}
|
||||
/>
|
||||
}
|
||||
*/}
|
||||
: null}
|
||||
</Expander>
|
||||
|
||||
{/*<section class={style.picker}>
|
||||
{encoderSupportMap ?
|
||||
|
||||
@@ -18,6 +18,7 @@ $horizontalPadding: 15px;
|
||||
|
||||
.option-text-first {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
grid-template-columns: 87px 1fr;
|
||||
grid-gap: 0.7em;
|
||||
padding: 10px $horizontalPadding;
|
||||
@@ -41,4 +42,12 @@ $horizontalPadding: 15px;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ two-up[legacy-clip-compat] > :not(.two-up-handle) {
|
||||
height: calc(var(--thumb-size) * 0.9);
|
||||
background: var(--thumb-background);
|
||||
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);
|
||||
color: var(--thumb-color);
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -55,14 +55,16 @@ export default class Expander extends Component<Props, State> {
|
||||
// Set the currently rendered height absolutely.
|
||||
this.el!.style.height = this.lastElHeight + 'px';
|
||||
this.el!.style.transition = '';
|
||||
this.el!.style.overflow = 'hidden';
|
||||
// Force a style calc so the browser picks up the start value.
|
||||
getComputedStyle(this.el!).height;
|
||||
// Animate to the new height.
|
||||
this.el!.style.height = newHeight + 'px';
|
||||
|
||||
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.overflow = '';
|
||||
this.el!.removeEventListener('transitionend', listener);
|
||||
this.el!.removeEventListener('transitioncancel', listener);
|
||||
if (this.state.outgoingChildren[0]) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
.expander {
|
||||
overflow: hidden;
|
||||
transition: height 200ms ease-in-out;
|
||||
}
|
||||
|
||||
|
||||
16
src/components/select/index.tsx
Normal file
16
src/components/select/index.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
}
|
||||
24
src/components/select/style.scss
Normal file
24
src/components/select/style.scss
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user