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:
Pavel Laptev 2024-07-23 12:15:05 +02:00 committed by GitHub
parent 14702e8c1e
commit eccb896c6d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 39 additions and 180 deletions

View File

@ -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

View File

@ -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';

View File

@ -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;

View File

@ -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';

View File

@ -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;

View File

@ -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';

View File

@ -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;

View File

@ -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';

View File

@ -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'));

View File

@ -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 {

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { pxToRem } from '$lib/utils/pxToRem';
import { pxToRem } from '@gitbutler/ui/utils/pxToRem';
interface Props {
hovered: boolean;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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';

View File

@ -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;

View File

@ -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;

View File

@ -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 = '';

View File

@ -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';

View File

@ -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>

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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';

View File

@ -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;

View File

@ -1,3 +0,0 @@
export function pxToRem(px: number, base: number = 16) {
return `${px / base}rem`;
}

View File

@ -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';

View File

@ -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);
}
};
}

View File

@ -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)
);
}

View File

@ -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';

View File

@ -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';

View File

@ -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);
}
};
}