mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-16 18:49:50 +00:00
wip
# Conflicts: # codecs/cpp.Dockerfile # codecs/imagequant/example.html # codecs/webp/dec/webp_dec.d.ts # codecs/webp/dec/webp_dec.js # codecs/webp/dec/webp_dec.wasm # codecs/webp/enc/webp_enc.d.ts # codecs/webp/enc/webp_enc.js # codecs/webp/enc/webp_enc.wasm # package-lock.json # package.json # src/codecs/tiny.webp # src_old/codecs/encoders.ts # src_old/codecs/processor-worker/tiny.avif # src_old/codecs/processor-worker/tiny.webp # src_old/codecs/tiny.webp # src_old/components/compress/index.tsx # src_old/lib/util.ts # src_old/sw/util.ts
This commit is contained in:
95
src_old/lib/SnackBar/index.ts
Normal file
95
src_old/lib/SnackBar/index.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import * as style from './styles.css';
|
||||
|
||||
export interface SnackOptions {
|
||||
timeout?: number;
|
||||
actions?: string[];
|
||||
}
|
||||
|
||||
function createSnack(
|
||||
message: string,
|
||||
options: SnackOptions,
|
||||
): [Element, Promise<string>] {
|
||||
const { timeout = 0, actions = ['dismiss'] } = options;
|
||||
|
||||
const el = document.createElement('div');
|
||||
el.className = style.snackbar;
|
||||
el.setAttribute('aria-live', 'assertive');
|
||||
el.setAttribute('aria-atomic', 'true');
|
||||
el.setAttribute('aria-hidden', 'false');
|
||||
|
||||
const text = document.createElement('div');
|
||||
text.className = style.text;
|
||||
text.textContent = message;
|
||||
el.appendChild(text);
|
||||
|
||||
const result = new Promise<string>((resolve) => {
|
||||
let timeoutId: number;
|
||||
|
||||
// Add action buttons
|
||||
for (const action of actions) {
|
||||
const button = document.createElement('button');
|
||||
button.className = style.button;
|
||||
button.textContent = action;
|
||||
button.addEventListener('click', () => {
|
||||
clearTimeout(timeoutId);
|
||||
resolve(action);
|
||||
});
|
||||
el.appendChild(button);
|
||||
}
|
||||
|
||||
// Add timeout
|
||||
if (timeout) {
|
||||
timeoutId = self.setTimeout(() => resolve(''), timeout);
|
||||
}
|
||||
});
|
||||
|
||||
return [el, result];
|
||||
}
|
||||
|
||||
export default class SnackBarElement extends HTMLElement {
|
||||
private _snackbars: [
|
||||
string,
|
||||
SnackOptions,
|
||||
(action: Promise<string>) => void,
|
||||
][] = [];
|
||||
private _processingQueue = false;
|
||||
|
||||
/**
|
||||
* Show a snackbar. Returns a promise for the name of the action clicked, or an empty string if no
|
||||
* action is clicked.
|
||||
*/
|
||||
showSnackbar(message: string, options: SnackOptions = {}): Promise<string> {
|
||||
return new Promise<string>((resolve) => {
|
||||
this._snackbars.push([message, options, resolve]);
|
||||
if (!this._processingQueue) this._processQueue();
|
||||
});
|
||||
}
|
||||
|
||||
private async _processQueue() {
|
||||
this._processingQueue = true;
|
||||
|
||||
while (this._snackbars[0]) {
|
||||
const [message, options, resolver] = this._snackbars[0];
|
||||
const [el, result] = createSnack(message, options);
|
||||
// Pass the result back to the original showSnackbar call.
|
||||
resolver(result);
|
||||
this.appendChild(el);
|
||||
|
||||
// Wait for the user to click an action, or for the snack to timeout.
|
||||
await result;
|
||||
|
||||
// Transition the snack away.
|
||||
el.setAttribute('aria-hidden', 'true');
|
||||
await new Promise((resolve) => {
|
||||
el.addEventListener('animationend', () => resolve());
|
||||
});
|
||||
el.remove();
|
||||
|
||||
this._snackbars.shift();
|
||||
}
|
||||
|
||||
this._processingQueue = false;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('snack-bar', SnackBarElement);
|
||||
13
src_old/lib/SnackBar/missing-types.d.ts
vendored
Normal file
13
src_old/lib/SnackBar/missing-types.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { SnackOptions, SnackShowResult } from '.';
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
'snack-bar': SnackBarAttributes;
|
||||
}
|
||||
|
||||
interface SnackBarAttributes extends HTMLAttributes {
|
||||
showSnackbar?: (options: SnackOptions) => Promise<SnackShowResult>;
|
||||
}
|
||||
}
|
||||
}
|
||||
105
src_old/lib/SnackBar/styles.css
Normal file
105
src_old/lib/SnackBar/styles.css
Normal file
@@ -0,0 +1,105 @@
|
||||
snack-bar {
|
||||
display: block;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.snackbar {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
left: 50%;
|
||||
bottom: 24px;
|
||||
width: 344px;
|
||||
margin-left: -172px;
|
||||
background: #2a2a2a;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
|
||||
transform-origin: center;
|
||||
color: #eee;
|
||||
z-index: 100;
|
||||
cursor: default;
|
||||
will-change: transform;
|
||||
animation: snackbar-show 300ms ease forwards 1;
|
||||
}
|
||||
.snackbar[aria-hidden='true'] {
|
||||
animation: snackbar-hide 300ms ease forwards 1;
|
||||
}
|
||||
@keyframes snackbar-show {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
}
|
||||
@keyframes snackbar-hide {
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 400px) {
|
||||
.snackbar {
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin-left: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
flex: 1 1 auto;
|
||||
padding: 16px;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.button {
|
||||
position: relative;
|
||||
flex: 0 1 auto;
|
||||
padding: 8px;
|
||||
height: 36px;
|
||||
margin: auto 8px auto -8px;
|
||||
min-width: 5em;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
color: lightgreen;
|
||||
font-weight: inherit;
|
||||
letter-spacing: 0.05em;
|
||||
font-size: 100%;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
transition: background-color 200ms ease;
|
||||
outline: none;
|
||||
}
|
||||
.button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.button:focus:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 120%;
|
||||
height: 0;
|
||||
padding: 0 0 120%;
|
||||
margin: -60% 0 0 -60%;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
transform-origin: center;
|
||||
will-change: transform;
|
||||
animation: focus-ring 300ms ease-out forwards 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
@keyframes focus-ring {
|
||||
from {
|
||||
transform: scale(0.01);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user