mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-24 01:51:57 +03:00
Use UI package functions instead of app utility functions (#4471)
* replace `pxToRem` * replace `tooltip` and `typeguards` * replace `tooltip` * `Actions` updated * draggable.ts update
This commit is contained in:
parent
14702e8c1e
commit
eccb896c6d
6
.github/actions/init-env-node/action.yaml
vendored
6
.github/actions/init-env-node/action.yaml
vendored
@ -32,4 +32,8 @@ runs:
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: pnpm install
|
||||
run: pnpm install
|
||||
|
||||
- name: Build UI
|
||||
shell: bash
|
||||
run: cd packages/ui && pnpm package
|
@ -1,7 +1,7 @@
|
||||
import { LONG_DEFAULT_BRANCH_TEMPLATE, LONG_DEFAULT_COMMIT_TEMPLATE } from '$lib/ai/prompts';
|
||||
import { MessageRole, type PromptMessage, type AIClient, type Prompt } from '$lib/ai/types';
|
||||
import { andThen, buildFailureFromAny, ok, wrap, wrapAsync, type Result } from '$lib/result';
|
||||
import { isNonEmptyObject } from '$lib/utils/typeguards';
|
||||
import { isNonEmptyObject } from '@gitbutler/ui/utils/typeguards';
|
||||
import { fetch, Body, Response } from '@tauri-apps/api/http';
|
||||
|
||||
export const DEFAULT_OLLAMA_ENDPOINT = 'http://127.0.0.1:11434';
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
|
||||
export let name: 'remote-branch' | 'virtual-branch' | 'pr' | 'pr-draft' | 'pr-closed' | undefined;
|
||||
export let help: string | undefined;
|
||||
|
@ -5,9 +5,9 @@
|
||||
import Icon from '$lib/shared/Icon.svelte';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import { error } from '$lib/utils/toasts';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { openExternalUrl } from '$lib/utils/url';
|
||||
import { BranchController } from '$lib/vbranches/branchController';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
import type { BaseBranch } from '$lib/baseBranch/baseBranch';
|
||||
import type { PullRequest } from '$lib/gitHost/interface/types';
|
||||
import type { Branch } from '$lib/vbranches/types';
|
||||
|
@ -13,7 +13,6 @@
|
||||
import { copyToClipboard } from '$lib/utils/clipboard';
|
||||
import { getContext, getContextStore } from '$lib/utils/context';
|
||||
import { getTimeAgo } from '$lib/utils/timeAgo';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { openExternalUrl } from '$lib/utils/url';
|
||||
import { BranchController } from '$lib/vbranches/branchController';
|
||||
import { createCommitStore } from '$lib/vbranches/contexts';
|
||||
@ -25,6 +24,7 @@
|
||||
VirtualBranch,
|
||||
type CommitStatus
|
||||
} from '$lib/vbranches/types';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
import { type Snippet } from 'svelte';
|
||||
|
||||
export let branch: VirtualBranch | undefined = undefined;
|
||||
|
@ -19,9 +19,9 @@
|
||||
import { splitMessage } from '$lib/utils/commitMessage';
|
||||
import { getContext, getContextStore } from '$lib/utils/context';
|
||||
import { resizeObserver } from '$lib/utils/resizeObserver';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { Ownership } from '$lib/vbranches/ownership';
|
||||
import { VirtualBranch, LocalFile } from '$lib/vbranches/types';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { fly } from 'svelte/transition';
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
import Button from '$lib/shared/Button.svelte';
|
||||
import Modal from '$lib/shared/Modal.svelte';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { BranchController } from '$lib/vbranches/branchController';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
import type { BaseBranch } from '$lib/baseBranch/baseBranch';
|
||||
|
||||
export let base: BaseBranch;
|
||||
|
@ -2,7 +2,7 @@
|
||||
import UpdateBaseButton from './UpdateBaseButton.svelte';
|
||||
import { BaseBranch } from '$lib/baseBranch/baseBranch';
|
||||
import { getContextStore } from '$lib/utils/context';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { dropzoneRegistry } from './dropzone';
|
||||
import { getFileIcon } from '$lib/ext-icons';
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { type CommitStatus } from '$lib/vbranches/types';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
import type { Draggable } from './draggables';
|
||||
|
||||
export interface DraggableConfig {
|
||||
@ -76,7 +76,7 @@ function setupDragHandlers(
|
||||
clone.style.width = node.clientWidth + 'px';
|
||||
}
|
||||
if (params.maxHeight) {
|
||||
clone.style.maxHeight = pxToRem(params.maxHeight);
|
||||
clone.style.maxHeight = pxToRem(params.maxHeight) as string;
|
||||
}
|
||||
|
||||
selectedElements.forEach((el) => el.classList.add('drag-handle'));
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
import { scale } from 'svelte/transition';
|
||||
|
||||
interface Props {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
|
||||
interface Props {
|
||||
hovered: boolean;
|
||||
|
@ -3,9 +3,9 @@
|
||||
import Icon from '$lib/shared/Icon.svelte';
|
||||
import LargeDiffMessage from '$lib/shared/LargeDiffMessage.svelte';
|
||||
import { computeAddedRemovedByHunk } from '$lib/utils/metrics';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { getLocalCommits, getLocalAndRemoteCommits } from '$lib/vbranches/contexts';
|
||||
import { getLockText } from '$lib/vbranches/tooltip';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
import type { HunkSection, ContentSection } from '$lib/utils/fileSections';
|
||||
|
||||
export let filePath: string;
|
||||
|
@ -2,10 +2,10 @@
|
||||
import FileStatusCircle from './FileStatusCircle.svelte';
|
||||
import Icon from '$lib/shared/Icon.svelte';
|
||||
import { computeFileStatus } from '$lib/utils/fileStatus';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { getLocalCommits, getLocalAndRemoteCommits } from '$lib/vbranches/contexts';
|
||||
import { getLockText } from '$lib/vbranches/tooltip';
|
||||
import { type AnyFile, LocalFile } from '$lib/vbranches/types';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
|
||||
export let file: AnyFile;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Icon from '../shared/Icon.svelte';
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let foldable: boolean = false;
|
||||
|
@ -5,7 +5,7 @@
|
||||
import Badge from '$lib/shared/Badge.svelte';
|
||||
import Icon from '$lib/shared/Icon.svelte';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
import { Project } from '$lib/backend/projects';
|
||||
import Icon from '$lib/shared/Icon.svelte';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
|
||||
export let isNavCollapsed: boolean;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Spacer from '$lib/shared/Spacer.svelte';
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
|
||||
export let spacer = false;
|
||||
export let gap = 20;
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
|
||||
export let count: string | number;
|
||||
export let help = '';
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Icon from '$lib/shared/Icon.svelte';
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
import type iconsJson from '$lib/icons/icons.json';
|
||||
import type { ComponentColor, ComponentStyleKind } from '$lib/vbranches/types';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts" context="module">
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
import type { ComponentColor } from '$lib/vbranches/types';
|
||||
export type IconColor = ComponentColor | undefined;
|
||||
</script>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
// The element that is being resized
|
||||
|
@ -5,7 +5,7 @@
|
||||
<script lang="ts">
|
||||
import { SETTINGS, type Settings } from '$lib/settings/userSettings';
|
||||
import { getContextStoreBySymbol } from '$lib/utils/context';
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
import { onDestroy, createEventDispatcher } from 'svelte';
|
||||
|
||||
const userSettings = getContextStoreBySymbol<Settings>(SETTINGS);
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
export let margin: number | undefined = 16;
|
||||
export let noLine = false;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { autoHeight } from '$lib/utils/autoHeight';
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { resizeObserver } from '$lib/utils/resizeObserver';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
export let value: string | undefined;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Icon from '$lib/shared/Icon.svelte';
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import type iconsJson from '$lib/icons/icons.json';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { tooltip } from '$lib/utils/tooltip';
|
||||
import { tooltip } from '@gitbutler/ui/utils/tooltip';
|
||||
|
||||
export let small = false;
|
||||
export let disabled = false;
|
||||
|
@ -1,3 +0,0 @@
|
||||
export function pxToRem(px: number, base: number = 16) {
|
||||
return `${px / base}rem`;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { pxToRem } from '$lib/utils/pxToRem';
|
||||
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
|
||||
import { sineInOut } from 'svelte/easing';
|
||||
import { slide, type SlideParams, type TransitionConfig } from 'svelte/transition';
|
||||
|
||||
|
@ -1,119 +0,0 @@
|
||||
export interface ToolTipOptions {
|
||||
text: string;
|
||||
noMaxWidth?: boolean;
|
||||
delay?: number;
|
||||
}
|
||||
|
||||
const defaultOptions: Partial<ToolTipOptions> = {
|
||||
delay: 1200,
|
||||
noMaxWidth: false
|
||||
};
|
||||
|
||||
export function tooltip(node: HTMLElement, optsOrString: ToolTipOptions | string | undefined) {
|
||||
// The tooltip element we are adding to the dom
|
||||
let tooltip: HTMLDivElement | undefined;
|
||||
|
||||
// Note that we use this both for delaying show, as well as delaying hide
|
||||
let timeoutId: any;
|
||||
|
||||
// Options
|
||||
let { text, delay, noMaxWidth } = defaultOptions;
|
||||
|
||||
// Most use cases only involve passing a string, so we allow either opts of
|
||||
// simple text.
|
||||
function setOpts(opts: ToolTipOptions | string | undefined) {
|
||||
if (typeof opts === 'string') {
|
||||
text = opts;
|
||||
} else if (opts) {
|
||||
({ text, delay, noMaxWidth } = opts || {});
|
||||
}
|
||||
if (tooltip && text) tooltip.innerText = text;
|
||||
}
|
||||
|
||||
setOpts(optsOrString);
|
||||
|
||||
function onMouseOver() {
|
||||
// If tooltip is displayed we clear hide timeout
|
||||
if (tooltip && timeoutId) clearTimeout(timeoutId);
|
||||
// If no tooltip and no timeout id we set a show timeout
|
||||
else if (!tooltip && !timeoutId) timeoutId = setTimeout(() => show(), delay);
|
||||
}
|
||||
|
||||
function onMouseLeave() {
|
||||
// If tooltip shown when mouse out then we hide after delay
|
||||
if (tooltip) hide();
|
||||
// But if we mouse out before tooltip is shown, we cancel the show timer
|
||||
else if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function show() {
|
||||
if (!text || !node.isConnected) return;
|
||||
tooltip = document.createElement('div') as HTMLDivElement;
|
||||
// TODO: Can we co-locate tooltip.js & tooltip.postcss?
|
||||
tooltip.classList.add('tooltip', 'text-base-11'); // see tooltip.postcss
|
||||
if (noMaxWidth) tooltip.classList.add('no-max-width');
|
||||
tooltip.innerText = text;
|
||||
document.body.appendChild(tooltip);
|
||||
adjustPosition();
|
||||
}
|
||||
|
||||
function hide() {
|
||||
if (tooltip) tooltip.remove();
|
||||
tooltip = undefined;
|
||||
timeoutId = undefined;
|
||||
}
|
||||
|
||||
function adjustPosition() {
|
||||
if (!tooltip) return;
|
||||
|
||||
// Dimensions and position of target element
|
||||
const nodeRect = node.getBoundingClientRect();
|
||||
const nodeHeight = nodeRect.height;
|
||||
const nodeWidth = nodeRect.width;
|
||||
const nodeLeft = nodeRect.left;
|
||||
const nodeTop = nodeRect.top;
|
||||
|
||||
// Padding
|
||||
const padding = 4;
|
||||
|
||||
// Window dimensions
|
||||
const windowHeight = window.innerHeight;
|
||||
const windowWidth = window.innerWidth;
|
||||
|
||||
const tooltipHeight = tooltip.offsetHeight;
|
||||
const tooltipWidth = tooltip.offsetWidth;
|
||||
|
||||
const showBelow = windowHeight > nodeTop + nodeHeight + tooltipHeight + padding;
|
||||
|
||||
// Note that we don't check if width of tooltip is wider than the window.
|
||||
|
||||
if (showBelow) {
|
||||
tooltip.style.top = `${nodeTop + nodeHeight + padding}px`;
|
||||
} else {
|
||||
tooltip.style.top = `${nodeTop - tooltipHeight - padding}px`;
|
||||
}
|
||||
|
||||
let leftPos = nodeLeft - (tooltipWidth - nodeWidth) / 2;
|
||||
if (leftPos < padding) leftPos = padding;
|
||||
if (leftPos + tooltipWidth > windowWidth) leftPos = windowWidth - tooltipWidth - padding;
|
||||
tooltip.style.left = `${leftPos}px`;
|
||||
}
|
||||
|
||||
node.addEventListener('pointerenter', onMouseOver);
|
||||
node.addEventListener('pointerleave', onMouseLeave);
|
||||
|
||||
return {
|
||||
update(opts: ToolTipOptions | string | undefined) {
|
||||
setOpts(opts);
|
||||
},
|
||||
destroy() {
|
||||
tooltip?.remove();
|
||||
timeoutId && clearTimeout(timeoutId);
|
||||
node.removeEventListener('pointerenter', onMouseOver);
|
||||
node.removeEventListener('pointerleave', onMouseLeave);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
export function isDefined<T>(file: T | undefined | null): file is T {
|
||||
return file !== undefined;
|
||||
}
|
||||
|
||||
export function notNull<T>(file: T | undefined | null): file is T {
|
||||
return file !== null;
|
||||
}
|
||||
|
||||
export type UnknownObject = Record<string, unknown>;
|
||||
|
||||
/**
|
||||
* Checks if the provided value is a non-empty object.
|
||||
* @param something - The value to be checked.
|
||||
* @returns A boolean indicating whether the value is a non-empty object.
|
||||
*/
|
||||
export function isNonEmptyObject(something: unknown): something is UnknownObject {
|
||||
return (
|
||||
typeof something === 'object' &&
|
||||
something !== null &&
|
||||
!Array.isArray(something) &&
|
||||
(Object.keys(something).length > 0 || Object.getOwnPropertySymbols(something).length > 0)
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { isDefined } from '$lib/utils/typeguards';
|
||||
import { listRemoteCommitFiles } from '$lib/vbranches/remoteCommits';
|
||||
import { isDefined } from '@gitbutler/ui/utils/typeguards';
|
||||
import { derived, type Readable } from 'svelte/store';
|
||||
import type { AnyFile, LocalFile } from '$lib/vbranches/types';
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'reflect-metadata';
|
||||
import { splitMessage } from '$lib/utils/commitMessage';
|
||||
import { hashCode } from '$lib/utils/string';
|
||||
import { isDefined, notNull } from '$lib/utils/typeguards';
|
||||
import { isDefined, notNull } from '@gitbutler/ui/utils/typeguards';
|
||||
import { Type, Transform } from 'class-transformer';
|
||||
import type { PullRequest } from '$lib/gitHost/interface/types';
|
||||
|
||||
|
@ -102,8 +102,8 @@ export function tooltip(node: HTMLElement, optsOrString: ToolTipOptions | string
|
||||
tooltip.style.left = `${leftPos}px`;
|
||||
}
|
||||
|
||||
node.addEventListener('mouseover', onMouseOver);
|
||||
node.addEventListener('mouseleave', onMouseLeave);
|
||||
node.addEventListener('pointerenter', onMouseOver);
|
||||
node.addEventListener('pointerleave', onMouseLeave);
|
||||
|
||||
return {
|
||||
update(opts: ToolTipOptions | string | undefined) {
|
||||
@ -112,8 +112,8 @@ export function tooltip(node: HTMLElement, optsOrString: ToolTipOptions | string
|
||||
destroy() {
|
||||
tooltip?.remove();
|
||||
timeoutId && clearTimeout(timeoutId);
|
||||
node.removeEventListener('mouseover', onMouseOver);
|
||||
node.removeEventListener('mouseleave', onMouseLeave);
|
||||
node.removeEventListener('pointerenter', onMouseOver);
|
||||
node.removeEventListener('pointerleave', onMouseLeave);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user