aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/vendor/svelte-range-slider/range-pips.svelte
diff options
context:
space:
mode:
authorLibravatarLarge Libravatar memdmp <memdmpestrogenzone>2025-07-31 22:48:01 +0200
committerLibravatarLarge Libravatar memdmp <memdmpestrogenzone>2025-07-31 22:48:01 +0200
commite55f4c2fe8a6e1d62a0b005777b46c80e360d37e (patch)
tree1f9ad00b914f04677ffaf8b395a4c5d4ff659756 /src/lib/vendor/svelte-range-slider/range-pips.svelte
downloadvideotool-e55f4c2fe8a6e1d62a0b005777b46c80e360d37e.tar.gz
videotool-e55f4c2fe8a6e1d62a0b005777b46c80e360d37e.tar.bz2
videotool-e55f4c2fe8a6e1d62a0b005777b46c80e360d37e.tar.lz
videotool-e55f4c2fe8a6e1d62a0b005777b46c80e360d37e.zip

feat: initial commit

Diffstat (limited to 'src/lib/vendor/svelte-range-slider/range-pips.svelte')
-rw-r--r--src/lib/vendor/svelte-range-slider/range-pips.svelte303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/lib/vendor/svelte-range-slider/range-pips.svelte b/src/lib/vendor/svelte-range-slider/range-pips.svelte
new file mode 100644
index 0000000..418fc7e
--- /dev/null
+++ b/src/lib/vendor/svelte-range-slider/range-pips.svelte
@@ -0,0 +1,303 @@
+<script lang="ts" module>
+ export interface PipsProps {
+ min?: number;
+ max?: number;
+ step?: number;
+ values?: number[];
+ vertical?: boolean;
+ reversed?: boolean;
+ hoverable?: boolean;
+ disabled?: boolean;
+ pipstep?: number;
+ prefix?: string;
+ suffix?: string;
+ focus?: boolean;
+ range?: undefined | boolean | 'min' | 'max';
+ all?: undefined | boolean | 'pip' | 'label';
+ first?: boolean | 'pip' | 'label';
+ last?: boolean | 'pip' | 'label';
+ rest?: boolean | 'pip' | 'label';
+ percentOf: (v: number) => number;
+ fixFloat: (v: number) => number;
+ orientationStart?: 'top' | 'bottom' | 'left' | 'right';
+ orientationEnd?: 'top' | 'bottom' | 'left' | 'right';
+ formatter?: (v: number, i: number, p: number) => string;
+ moveHandle: undefined | ((index: number | undefined, value: number) => number);
+ normalisedClient: (e: MouseEvent | TouchEvent) => { x: number; y: number };
+ }
+</script>
+
+<script lang="ts">
+ let {
+ range = false,
+ min = 0,
+ max = 100,
+ step = 1,
+ values = [(max + min) / 2],
+ vertical = false,
+ reversed = false,
+ hoverable = true,
+ disabled = false,
+ pipstep,
+ all = true,
+ first,
+ last,
+ rest,
+ prefix = '',
+ suffix = '',
+ focus,
+ orientationStart,
+ // eslint-disable-next-line no-unused-vars
+ formatter = (v, i, p) => v.toString(),
+ percentOf,
+ moveHandle,
+ fixFloat,
+ normalisedClient
+ }: PipsProps = $props();
+
+ let clientStart = $state({ x: 0, y: 0 });
+ let pipStep = $derived(
+ pipstep ||
+ ((max - min) / step >= (vertical ? 50 : 100) ? (max - min) / (vertical ? 10 : 20) : 1)
+ );
+ let pipCount = $derived(parseInt(((max - min) / (step * pipStep)).toString(), 10));
+ let pipVal = $derived((val: number) => fixFloat(min + val * step * pipStep));
+ let isSelected = $derived((val: number) => values.some((v) => fixFloat(v) === fixFloat(val)));
+ let inRange = $derived((val: number) => {
+ if (range === 'min') {
+ return values[0] > val;
+ }
+ if (range === 'max') {
+ return values[0] < val;
+ }
+ if (range) {
+ return values[0] < val && values[1] > val;
+ }
+ });
+
+ /**
+ * function to run when the user clicks on a label
+ * we store the original client position so we can check if the user has moved the mouse/finger
+ * @param {MouseEvent} e the event from browser
+ **/
+ const labelDown = (e: MouseEvent) => {
+ clientStart = { x: e.clientX, y: e.clientY };
+ };
+
+ /**
+ * function to run when the user releases the mouse/finger
+ * we check if the user has moved the mouse/finger, if not we "click" the label
+ * and move the handle it to the label position
+ * @param {number} val the value of the label
+ * @param {MouseEvent|TouchEvent} e the event from browser
+ */
+ function labelUp(val: number, e: MouseEvent | TouchEvent) {
+ if (disabled) {
+ return;
+ }
+
+ const clientPos = normalisedClient(e);
+ const distanceMoved = Math.sqrt(
+ Math.pow(clientStart.x - clientPos.x, 2) + Math.pow(clientStart.y - clientPos.y, 2)
+ );
+
+ if (clientStart && distanceMoved <= 5) {
+ moveHandle?.(undefined, val);
+ }
+ }
+</script>
+
+<div
+ class="rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6"
+ class:disabled
+ class:hoverable
+ class:vertical
+ class:reversed
+ class:focus
+>
+ {#if (all && first !== false) || first}
+ <span
+ class="pip-680f0f01-664b-43b5-9e1c-789449c63c62 first"
+ class:selected={isSelected(min)}
+ class:in-range={inRange(min)}
+ style="{orientationStart}: 0%;"
+ onpointerdown={labelDown}
+ onpointerup={(e) => labelUp(min, e)}
+ >
+ {#if all === 'label' || first === 'label'}
+ <span class="pipVal-c41e7185-de59-40a7-90f2-e3d98b1e844b">
+ {prefix}{formatter(fixFloat(min), 0, 0)}{suffix}
+ </span>
+ {/if}
+ </span>
+ {/if}
+
+ {#if (all && rest !== false) || rest}
+ <!-- eslint-disable-next-line no-unused-vars -->
+ {#each Array(pipCount + 1) as _, i}
+ {#if pipVal(i) !== min && pipVal(i) !== max}
+ <span
+ class="pip-680f0f01-664b-43b5-9e1c-789449c63c62"
+ class:selected={isSelected(pipVal(i))}
+ class:in-range={inRange(pipVal(i))}
+ style="{orientationStart}: {percentOf(pipVal(i))}%;"
+ onpointerdown={labelDown}
+ onpointerup={(e) => labelUp(pipVal(i), e)}
+ >
+ {#if all === 'label' || rest === 'label'}
+ <span class="pipVal-c41e7185-de59-40a7-90f2-e3d98b1e844b">
+ {prefix}{formatter(pipVal(i), i, percentOf(pipVal(i)))}{suffix}
+ </span>
+ {/if}
+ </span>
+ {/if}
+ {/each}
+ {/if}
+
+ {#if (all && last !== false) || last}
+ <span
+ class="pip last"
+ class:selected={isSelected(max)}
+ class:in-range={inRange(max)}
+ style="{orientationStart}: 100%;"
+ onpointerdown={labelDown}
+ onpointerup={(e) => labelUp(max, e)}
+ >
+ {#if all === 'label' || last === 'label'}
+ <span class="pipVal">
+ {prefix}{formatter(fixFloat(max), pipCount, 100)}{suffix}
+ </span>
+ {/if}
+ </span>
+ {/if}
+</div>
+
+<style>
+ :global(._rangeslider-0f6d4a99-47b0-4108-8415-b2aefa867e28) {
+ --pip: var(--range-pip, lightslategray);
+ --pip-text: var(--range-pip-text, var(--pip));
+ --pip-active: var(--range-pip-active, darkslategrey);
+ --pip-active-text: var(--range-pip-active-text, var(--pip-active));
+ --pip-hover: var(--range-pip-hover, darkslategrey);
+ --pip-hover-text: var(--range-pip-hover-text, var(--pip-hover));
+ --pip-in-range: var(--range-pip-in-range, var(--pip-active));
+ --pip-in-range-text: var(--range-pip-in-range-text, var(--pip-active-text));
+ }
+ :global(.rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6) {
+ position: absolute;
+ height: 1em;
+ left: 0;
+ right: 0;
+ bottom: -1em;
+ }
+ :global(.rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6.vertical) {
+ height: auto;
+ width: 1em;
+ left: 100%;
+ right: auto;
+ top: 0;
+ bottom: 0;
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6 .pip-680f0f01-664b-43b5-9e1c-789449c63c62
+ ) {
+ height: 0.4em;
+ position: absolute;
+ top: 0.25em;
+ width: 1px;
+ white-space: nowrap;
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6.vertical
+ .pip-680f0f01-664b-43b5-9e1c-789449c63c62
+ ) {
+ height: 1px;
+ width: 0.4em;
+ left: 0.25em;
+ top: auto;
+ bottom: auto;
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6 .pipVal-c41e7185-de59-40a7-90f2-e3d98b1e844b
+ ) {
+ position: absolute;
+ top: 0.4em;
+ transform: translate(-50%, 25%);
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6.vertical
+ .pipVal-c41e7185-de59-40a7-90f2-e3d98b1e844b
+ ) {
+ position: absolute;
+ top: 0;
+ left: 0.4em;
+ transform: translate(25%, -50%);
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6 .pip-680f0f01-664b-43b5-9e1c-789449c63c62
+ ) {
+ transition: all 0.15s ease;
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6 .pipVal-c41e7185-de59-40a7-90f2-e3d98b1e844b
+ ) {
+ transition:
+ all 0.15s ease,
+ font-weight 0s linear;
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6 .pip-680f0f01-664b-43b5-9e1c-789449c63c62
+ ) {
+ color: var(--pip-text, lightslategray);
+ background-color: var(--pip, lightslategray);
+ }
+ :global(.rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6 .pip.selected) {
+ color: var(--pip-active-text, darkslategrey);
+ background-color: var(--pip-active, darkslategrey);
+ }
+ :global(.rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6.hoverable:not(.disabled) .pip:hover) {
+ color: var(--pip-hover-text, darkslategrey);
+ background-color: var(--pip-hover, darkslategrey);
+ }
+ :global(.rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6 .pip.in-range) {
+ color: var(--pip-in-range-text, darkslategrey);
+ background-color: var(--pip-in-range, darkslategrey);
+ }
+ :global(.rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6 .pip.selected) {
+ height: 0.75em;
+ }
+ :global(.rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6.vertical .pip.selected) {
+ height: 1px;
+ width: 0.75em;
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6
+ .pip.selected
+ .pipVal-c41e7185-de59-40a7-90f2-e3d98b1e844b
+ ) {
+ font-weight: bold;
+ top: 0.75em;
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6.vertical
+ .pip.selected
+ .pipVal-c41e7185-de59-40a7-90f2-e3d98b1e844b
+ ) {
+ top: 0;
+ left: 0.75em;
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6.hoverable:not(.disabled)
+ .pip:not(.selected):hover
+ ) {
+ transition: none;
+ }
+ :global(
+ .rangePips-f75c52e3-b799-4c81-8238-035d862cc2e6.hoverable:not(.disabled)
+ .pip:not(.selected):hover
+ .pipVal-c41e7185-de59-40a7-90f2-e3d98b1e844b
+ ) {
+ transition: none;
+ font-weight: bold;
+ }
+</style>