Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 5,314 Bytes
94753b6 86c4ad7 3f534ed 86c4ad7 b2041e0 86c4ad7 b2041e0 86c4ad7 3f534ed 86c4ad7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
<script lang="ts" generics="TWidgetExample extends WidgetExample">
import type { ExampleRunOpts, WidgetProps } from "../types.js";
import type { WidgetExample, WidgetExampleAttribute } from "@huggingface/tasks";
import { onMount } from "svelte";
import { slide } from "svelte/transition";
import { randomItem } from "../../../../utils/ViewUtils.js";
import IconCaretDownV2 from "../../..//Icons/IconCaretDownV2.svelte";
import WidgetExamplesGroup from "./WidgetExamplesGroup.svelte";
import { getQueryParamVal } from "../../..//InferenceWidget/shared/helpers.js";
export let isLoading = false;
export let callApiOnMount: WidgetProps["callApiOnMount"];
export let classNames: string;
export let exampleQueryParams: WidgetExampleAttribute[] = [];
export let applyWidgetExample: (sample: TWidgetExample, opts?: ExampleRunOpts) => void;
export let validExamples: TWidgetExample[];
interface ExamplesGroup {
group: string;
examples: TWidgetExample[];
}
$: exampleGroups = getExamplesGroups(validExamples);
$: examples = exampleGroups?.[0]?.examples ?? [];
// for examples with multiple groups, a group needs to be selected first, before an example can be clicked
$: clickable = exampleGroups?.length === 1;
let containerEl: HTMLElement;
let isOptionsVisible = false;
let title = "Examples";
function getExamplesGroups(_examples: TWidgetExample[]): ExamplesGroup[] {
const examples = _examples.map((sample, idx) => ({
example_title: `Example ${++idx}`,
group: "Group 1",
...sample,
}));
const examplesGroups: ExamplesGroup[] = [];
for (const example of examples) {
const groupExists = examplesGroups.find(({ group }) => group === example.group);
if (!groupExists) {
examplesGroups.push({ group: example.group as string, examples: [] });
}
examplesGroups.find(({ group }) => group === example.group)?.examples.push(example);
}
return examplesGroups;
}
function _applyWidgetExample(idx: number) {
if (!isOptionsVisible) {
return;
}
hideOptions();
const sample = examples[idx];
title = sample.example_title as string;
applyWidgetExample(sample);
}
function _previewInputSample(idx: number) {
if (!isOptionsVisible) {
return;
}
const sample = examples[idx];
applyWidgetExample(sample, { isPreview: true });
}
function toggleOptionsVisibility() {
isOptionsVisible = !isOptionsVisible;
}
function onClick(e: MouseEvent | TouchEvent) {
let targetElement = e.target;
do {
if (targetElement === containerEl) {
// This is a click inside. Do nothing, just return.
return;
}
targetElement = (targetElement as HTMLElement).parentElement;
} while (targetElement);
// This is a click outside
hideOptions();
}
function hideOptions() {
isOptionsVisible = false;
}
function changeGroup(e: CustomEvent<string>) {
const selectedGroup = e.detail;
const newGroup = exampleGroups.find(({ group }) => group === selectedGroup);
if (!newGroup) {
return;
}
examples = newGroup?.examples ?? [];
title = "Examples";
clickable = true;
}
onMount(() => {
// run random example onMount
(async () => {
const exampleFromQueryParams = {} as TWidgetExample;
for (const key of exampleQueryParams) {
const val = getQueryParamVal(key);
if (val) {
// @ts-expect-error complicated type
exampleFromQueryParams[key] = val;
}
}
if (Object.keys(exampleFromQueryParams).length) {
// run widget example from query params
applyWidgetExample(exampleFromQueryParams);
} else {
// run random widget example
const example = randomItem(validExamples);
if (callApiOnMount && example) {
applyWidgetExample(example, { inferenceOpts: { isOnLoadCall: true } });
}
}
})();
});
</script>
<svelte:window on:click={onClick} />
<div class={classNames}>
<!-- Example Groups -->
{#if exampleGroups.length > 1}
<WidgetExamplesGroup
on:groupSelected={changeGroup}
{isLoading}
groupNames={exampleGroups.map(({ group }) => group)}
/>
{/if}
<!-- Example picker -->
<div
class="relative mb-1.5
{isLoading || !clickable ? 'pointer-events-none opacity-50' : ''}
{isOptionsVisible ? 'z-10' : ''}"
bind:this={containerEl}
>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class="inline-flex w-32 justify-between rounded-md border border-gray-100 px-4 py-1"
on:click={toggleOptionsVisibility}
>
<div class="truncate text-sm">{title}</div>
<IconCaretDownV2
classNames="-mr-1 ml-2 h-5 w-5 transition ease-in-out transform {isOptionsVisible && '-rotate-180'}"
/>
</div>
{#if isOptionsVisible}
<div
class="absolute right-0 mt-1 w-full origin-top-right rounded-md ring-1 ring-black ring-opacity-10"
transition:slide
>
<div class="rounded-md bg-white py-1" role="none">
{#each examples as { example_title }, i}
<!-- svelte-ignore a11y-click-events-have-key-events a11y-mouse-events-have-key-events -->
<div
class="cursor-pointer truncate px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900 dark:hover:bg-gray-800 dark:hover:text-gray-200"
on:mouseover={() => _previewInputSample(i)}
on:click={() => _applyWidgetExample(i)}
>
{example_title}
</div>
{/each}
</div>
</div>
{/if}
</div>
</div>
|