mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-07 16:30:49 +00:00
Cleaning the Editbox (#5012)
Signed-off-by: Alexander Platov <alexander.platov@hardcoreeng.com> Signed-off-by: Alex Velichko <alex@hardcoreeng.com> Co-authored-by: Alex Velichko <alex@hardcoreeng.com>
This commit is contained in:
parent
5b1fd6a9b7
commit
23a3c8e94f
@ -27,14 +27,20 @@
|
|||||||
&:focus { box-shadow: 0 0 0 1px var(--theme-editbox-focus-border); }
|
&:focus { box-shadow: 0 0 0 1px var(--theme-editbox-focus-border); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.focusable:not(.default, .default-large, .ghost, .ghost-large, .modern-ghost-large) {
|
.focusable:not(.underline, .default, .default-large, .ghost, .ghost-large, .modern-ghost-large) {
|
||||||
margin: 0 -0.75rem;
|
position: relative;
|
||||||
padding: 0.625rem 0.75rem;
|
padding: 0.625rem 0;
|
||||||
width: calc(100% + 1.5rem);
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
transition: border-color 0.15s ease-in-out;
|
|
||||||
|
|
||||||
&:focus-within { box-shadow: 0 0 0 1px var(--theme-editbox-focus-border); }
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -0.75rem;
|
||||||
|
width: calc(100% + 1.5rem);
|
||||||
|
height: 100%;
|
||||||
|
border: 1px solid var(--theme-editbox-focus-border);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
&:focus-within::after { content: ''; }
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
@ -128,4 +134,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.required::after {
|
||||||
|
content: ' *';
|
||||||
|
color: var(--theme-error-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,21 +13,18 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Asset, IntlString } from '@hcengineering/platform'
|
import type { IntlString } from '@hcengineering/platform'
|
||||||
import { translate } from '@hcengineering/platform'
|
import { translate } from '@hcengineering/platform'
|
||||||
import { afterUpdate, createEventDispatcher, onMount } from 'svelte'
|
import { createEventDispatcher, onMount } from 'svelte'
|
||||||
import { registerFocus } from '../focus'
|
import { registerFocus } from '../focus'
|
||||||
import plugin from '../plugin'
|
import plugin from '../plugin'
|
||||||
import type { AnySvelteComponent, EditStyle } from '../types'
|
import type { EditStyle } from '../types'
|
||||||
import Icon from './Icon.svelte'
|
|
||||||
import Label from './Label.svelte'
|
import Label from './Label.svelte'
|
||||||
import { resizeObserver } from '../resize'
|
|
||||||
import { floorFractionDigits } from '../utils'
|
import { floorFractionDigits } from '../utils'
|
||||||
import { themeStore } from '@hcengineering/theme'
|
import { themeStore } from '@hcengineering/theme'
|
||||||
|
|
||||||
export let label: IntlString | undefined = undefined
|
export let label: IntlString | undefined = undefined
|
||||||
export let icon: Asset | AnySvelteComponent | undefined = undefined
|
export let maxWidth: string = '100%'
|
||||||
export let maxWidth: string | undefined = undefined
|
|
||||||
export let value: string | number | undefined = undefined
|
export let value: string | number | undefined = undefined
|
||||||
export let placeholder: IntlString = plugin.string.EditBoxPlaceholder
|
export let placeholder: IntlString = plugin.string.EditBoxPlaceholder
|
||||||
export let placeholderParam: any | undefined = undefined
|
export let placeholderParam: any | undefined = undefined
|
||||||
@ -45,11 +42,8 @@
|
|||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
let text: HTMLElement
|
|
||||||
let input: HTMLInputElement
|
let input: HTMLInputElement
|
||||||
let style: string
|
|
||||||
let phTraslate: string = ''
|
let phTraslate: string = ''
|
||||||
let parentWidth: number | undefined
|
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (
|
if (
|
||||||
@ -61,38 +55,11 @@
|
|||||||
value = floorFractionDigits(Number(value), maxDigitsAfterPoint)
|
value = floorFractionDigits(Number(value), maxDigitsAfterPoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$: style = `max-width: ${
|
|
||||||
maxWidth || (parentWidth ? (icon ? `calc(${parentWidth}px - 1.25rem)` : `${parentWidth}px`) : 'max-content')
|
|
||||||
};`
|
|
||||||
$: void translate(placeholder, placeholderParam ?? {}, $themeStore.language).then((res) => {
|
$: void translate(placeholder, placeholderParam ?? {}, $themeStore.language).then((res) => {
|
||||||
phTraslate = res
|
phTraslate = res
|
||||||
})
|
})
|
||||||
|
|
||||||
function computeSize (t: HTMLInputElement | EventTarget | null): void {
|
function handleInput (): void {
|
||||||
if (t == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const target = t as HTMLInputElement
|
|
||||||
const value = target.value
|
|
||||||
text.innerHTML = (value === '' ? phTraslate : value)
|
|
||||||
.replaceAll(' ', ' ')
|
|
||||||
.replaceAll('<', '<')
|
|
||||||
.replaceAll('>', '>')
|
|
||||||
if (format === 'number') {
|
|
||||||
target.style.width = maxWidth ?? '5rem'
|
|
||||||
} else if (kind === 'underline') {
|
|
||||||
target.style.width = `calc(${text.clientWidth}px + 1.125rem)`
|
|
||||||
} else {
|
|
||||||
target.style.width = Math.max(text.clientWidth, 50) + 'px'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleInput (ev: Event): void {
|
|
||||||
const t: HTMLInputElement | EventTarget | null = ev.target
|
|
||||||
if (t !== null && t !== undefined) {
|
|
||||||
computeSize(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch('input')
|
dispatch('input')
|
||||||
dispatch('value', value)
|
dispatch('value', value)
|
||||||
}
|
}
|
||||||
@ -106,11 +73,6 @@
|
|||||||
input.select()
|
input.select()
|
||||||
select = false
|
select = false
|
||||||
}
|
}
|
||||||
computeSize(input)
|
|
||||||
})
|
|
||||||
|
|
||||||
afterUpdate(() => {
|
|
||||||
computeSize(input)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export function focusInput (): void {
|
export function focusInput (): void {
|
||||||
@ -148,6 +110,7 @@
|
|||||||
class:flex-grow={fullSize}
|
class:flex-grow={fullSize}
|
||||||
class:w-full={focusable || fullSize}
|
class:w-full={focusable || fullSize}
|
||||||
class:uppercase
|
class:uppercase
|
||||||
|
style:width={maxWidth}
|
||||||
on:click={(event) => {
|
on:click={(event) => {
|
||||||
if (!propagateClick) {
|
if (!propagateClick) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
@ -155,33 +118,29 @@
|
|||||||
|
|
||||||
input.focus()
|
input.focus()
|
||||||
}}
|
}}
|
||||||
use:resizeObserver={(element) => {
|
|
||||||
parentWidth = element.parentElement?.getBoundingClientRect().width
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<!-- {focusIndex} -->
|
<!-- {focusIndex} -->
|
||||||
<div class="hidden-text {kind}" bind:this={text} />
|
|
||||||
{#if label}
|
{#if label}
|
||||||
<div class="mb-1 text-sm font-medium caption-color select-text">
|
<div class="mb-1 text-sm font-medium caption-color select-text" class:required>
|
||||||
<Label {label} />
|
<Label {label} />
|
||||||
{#if required}<span class="error-color">*</span>{/if}
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="{kind} flex-row-center clear-mins" class:focusable class:disabled class:w-full={fullSize}>
|
<div
|
||||||
{#if icon}
|
class="{kind} flex-row-center clear-mins"
|
||||||
<div class="dark-color mr-1">
|
class:focusable
|
||||||
<Icon {icon} size={'small'} />
|
class:disabled
|
||||||
</div>
|
class:w-full={fullSize}
|
||||||
{/if}
|
style:width={maxWidth}
|
||||||
|
>
|
||||||
{#if format === 'password'}
|
{#if format === 'password'}
|
||||||
<input
|
<input
|
||||||
{disabled}
|
{disabled}
|
||||||
|
style:width={maxWidth}
|
||||||
id="userPassword"
|
id="userPassword"
|
||||||
bind:this={input}
|
bind:this={input}
|
||||||
type="Password"
|
type="Password"
|
||||||
bind:value
|
bind:value
|
||||||
placeholder={phTraslate}
|
placeholder={phTraslate}
|
||||||
{style}
|
|
||||||
on:input={handleInput}
|
on:input={handleInput}
|
||||||
on:change
|
on:change
|
||||||
on:keydown
|
on:keydown
|
||||||
@ -193,12 +152,12 @@
|
|||||||
{:else if format === 'number'}
|
{:else if format === 'number'}
|
||||||
<input
|
<input
|
||||||
{disabled}
|
{disabled}
|
||||||
|
style:width={maxWidth}
|
||||||
bind:this={input}
|
bind:this={input}
|
||||||
type="number"
|
type="number"
|
||||||
class="number"
|
class="number"
|
||||||
bind:value
|
bind:value
|
||||||
placeholder={phTraslate}
|
placeholder={phTraslate}
|
||||||
{style}
|
|
||||||
on:input={handleInput}
|
on:input={handleInput}
|
||||||
on:change
|
on:change
|
||||||
on:keydown
|
on:keydown
|
||||||
@ -210,11 +169,11 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<input
|
<input
|
||||||
{disabled}
|
{disabled}
|
||||||
|
style:width={maxWidth}
|
||||||
bind:this={input}
|
bind:this={input}
|
||||||
type="text"
|
type="text"
|
||||||
bind:value
|
bind:value
|
||||||
placeholder={phTraslate}
|
placeholder={phTraslate}
|
||||||
{style}
|
|
||||||
on:input={handleInput}
|
on:input={handleInput}
|
||||||
on:change
|
on:change
|
||||||
on:keydown
|
on:keydown
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import { Ref } from '@hcengineering/core'
|
import { Ref } from '@hcengineering/core'
|
||||||
import { getClient, SpaceCreateCard } from '@hcengineering/presentation'
|
import { getClient, SpaceCreateCard } from '@hcengineering/presentation'
|
||||||
import task, { ProjectType } from '@hcengineering/task'
|
import task, { ProjectType } from '@hcengineering/task'
|
||||||
import { Component, EditBox, Grid, IconFolder } from '@hcengineering/ui'
|
import { Component, EditBox, Grid } from '@hcengineering/ui'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import board from '../plugin'
|
import board from '../plugin'
|
||||||
import { createBoard } from '../utils/BoardUtils'
|
import { createBoard } from '../utils/BoardUtils'
|
||||||
@ -51,13 +51,7 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Grid column={1} rowGap={1.5}>
|
<Grid column={1} rowGap={1.5}>
|
||||||
<EditBox
|
<EditBox label={board.string.BoardName} bind:value={name} placeholder={board.string.Board} autoFocus />
|
||||||
label={board.string.BoardName}
|
|
||||||
icon={IconFolder}
|
|
||||||
bind:value={name}
|
|
||||||
placeholder={board.string.Board}
|
|
||||||
autoFocus
|
|
||||||
/>
|
|
||||||
<!-- <ToggleWithLabel label={board.string.MakePrivate} description={board.string.MakePrivateDescription} /> -->
|
<!-- <ToggleWithLabel label={board.string.MakePrivate} description={board.string.MakePrivateDescription} /> -->
|
||||||
|
|
||||||
<Component
|
<Component
|
||||||
|
@ -110,12 +110,6 @@
|
|||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<StatusControl slot="error" {status} />
|
<StatusControl slot="error" {status} />
|
||||||
<Grid column={1} rowGap={1.5}>
|
<Grid column={1} rowGap={1.5}>
|
||||||
<EditBox
|
<EditBox label={board.string.CardName} bind:value={title} placeholder={board.string.CardPlaceholder} autoFocus />
|
||||||
label={board.string.CardName}
|
|
||||||
bind:value={title}
|
|
||||||
icon={board.icon.Card}
|
|
||||||
placeholder={board.string.CardPlaceholder}
|
|
||||||
autoFocus
|
|
||||||
/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
import { DirectMessage } from '@hcengineering/chunter'
|
import { DirectMessage } from '@hcengineering/chunter'
|
||||||
import workbench from '@hcengineering/workbench'
|
import workbench from '@hcengineering/workbench'
|
||||||
import { getResource } from '@hcengineering/platform'
|
import { getResource } from '@hcengineering/platform'
|
||||||
import { EditBox, IconFolder } from '@hcengineering/ui'
|
import { EditBox } from '@hcengineering/ui'
|
||||||
|
|
||||||
import chunter from '../plugin'
|
import chunter from '../plugin'
|
||||||
|
|
||||||
@ -63,7 +63,6 @@
|
|||||||
>
|
>
|
||||||
<EditBox
|
<EditBox
|
||||||
label={chunter.string.ChannelName}
|
label={chunter.string.ChannelName}
|
||||||
icon={IconFolder}
|
|
||||||
bind:value={name}
|
bind:value={name}
|
||||||
placeholder={chunter.string.ChannelNamePlaceholder}
|
placeholder={chunter.string.ChannelNamePlaceholder}
|
||||||
autoFocus
|
autoFocus
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Ref } from '@hcengineering/core'
|
import { Ref } from '@hcengineering/core'
|
||||||
import { Department } from '@hcengineering/hr'
|
import { Department } from '@hcengineering/hr'
|
||||||
import { Scroller, Separator } from '@hcengineering/ui'
|
import { Scroller, Separator, EditBox } from '@hcengineering/ui'
|
||||||
import { TreeNode } from '@hcengineering/view-resources'
|
import { TreeNode } from '@hcengineering/view-resources'
|
||||||
import { NavFooter, NavHeader } from '@hcengineering/workbench-resources'
|
import { NavFooter, NavHeader } from '@hcengineering/workbench-resources'
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
import { Funnel } from '@hcengineering/lead'
|
import { Funnel } from '@hcengineering/lead'
|
||||||
import presentation, { getClient, SpaceCreateCard } from '@hcengineering/presentation'
|
import presentation, { getClient, SpaceCreateCard } from '@hcengineering/presentation'
|
||||||
import task, { ProjectType } from '@hcengineering/task'
|
import task, { ProjectType } from '@hcengineering/task'
|
||||||
import ui, { Component, EditBox, Grid, IconFolder, Label, ToggleWithLabel } from '@hcengineering/ui'
|
import ui, { Component, EditBox, Grid, Label, ToggleWithLabel } from '@hcengineering/ui'
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import lead from '../plugin'
|
import lead from '../plugin'
|
||||||
|
|
||||||
@ -73,13 +73,7 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Grid column={1} rowGap={1.5}>
|
<Grid column={1} rowGap={1.5}>
|
||||||
<EditBox
|
<EditBox label={lead.string.FunnelName} bind:value={name} placeholder={lead.string.FunnelName} autoFocus />
|
||||||
label={lead.string.FunnelName}
|
|
||||||
icon={IconFolder}
|
|
||||||
bind:value={name}
|
|
||||||
placeholder={lead.string.FunnelName}
|
|
||||||
autoFocus
|
|
||||||
/>
|
|
||||||
<ToggleWithLabel
|
<ToggleWithLabel
|
||||||
label={presentation.string.MakePrivate}
|
label={presentation.string.MakePrivate}
|
||||||
description={presentation.string.MakePrivateDescription}
|
description={presentation.string.MakePrivateDescription}
|
||||||
|
@ -241,20 +241,18 @@
|
|||||||
}}
|
}}
|
||||||
on:changeContent
|
on:changeContent
|
||||||
>
|
>
|
||||||
{typeType?.name}
|
<span>{typeType?.name}</span>
|
||||||
<div class="flex-row-center clear-mins">
|
<div class="flex-row-center clear-mins">
|
||||||
<div class="mr-3">
|
<div class="mr-3">
|
||||||
<Button focusIndex={1} icon={Vacancy} size={'medium'} kind={'link-bordered'} noFocus />
|
<Button focusIndex={1} icon={Vacancy} size={'medium'} kind={'link-bordered'} noFocus />
|
||||||
</div>
|
</div>
|
||||||
<div class="clear-mins flex-grow">
|
<EditBox
|
||||||
<EditBox
|
focusIndex={2}
|
||||||
focusIndex={2}
|
bind:value={name}
|
||||||
bind:value={name}
|
placeholder={recruit.string.VacancyPlaceholder}
|
||||||
placeholder={recruit.string.VacancyPlaceholder}
|
kind={'large-style'}
|
||||||
kind={'large-style'}
|
autoFocus
|
||||||
autoFocus
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{#key appliedTemplateId}
|
{#key appliedTemplateId}
|
||||||
<AttachmentStyledBox
|
<AttachmentStyledBox
|
||||||
|
@ -141,16 +141,14 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
|
||||||
<span class="fs-title flex-grow">
|
<EditBox
|
||||||
<EditBox
|
bind:value={rawName}
|
||||||
bind:value={rawName}
|
placeholder={recruit.string.VacancyPlaceholder}
|
||||||
placeholder={recruit.string.VacancyPlaceholder}
|
kind={'large-style'}
|
||||||
kind={'large-style'}
|
focusable
|
||||||
focusable
|
autoFocus={!embedded}
|
||||||
autoFocus={!embedded}
|
on:blur={save}
|
||||||
on:blur={save}
|
/>
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<svelte:fragment slot="pre-utils">
|
<svelte:fragment slot="pre-utils">
|
||||||
{#if saved}
|
{#if saved}
|
||||||
|
@ -69,12 +69,6 @@
|
|||||||
okLabel={recruit.string.OpinionSave}
|
okLabel={recruit.string.OpinionSave}
|
||||||
on:changeContent
|
on:changeContent
|
||||||
>
|
>
|
||||||
<EditBox
|
<EditBox label={recruit.string.OpinionValue} bind:value placeholder={recruit.string.OpinionValue} autoFocus />
|
||||||
label={recruit.string.OpinionValue}
|
|
||||||
bind:value
|
|
||||||
icon={recruit.icon.Application}
|
|
||||||
placeholder={recruit.string.OpinionValue}
|
|
||||||
autoFocus
|
|
||||||
/>
|
|
||||||
<StyledTextArea placeholder={recruit.string.Description} bind:content={description} kind={'emphasized'} />
|
<StyledTextArea placeholder={recruit.string.Description} bind:content={description} kind={'emphasized'} />
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -54,7 +54,6 @@
|
|||||||
<Grid column={1} rowGap={1.5}>
|
<Grid column={1} rowGap={1.5}>
|
||||||
<EditBox
|
<EditBox
|
||||||
label={templates.string.TemplateCategory}
|
label={templates.string.TemplateCategory}
|
||||||
icon={IconFolder}
|
|
||||||
bind:value={name}
|
bind:value={name}
|
||||||
placeholder={templates.string.TemplateCategory}
|
placeholder={templates.string.TemplateCategory}
|
||||||
autoFocus
|
autoFocus
|
||||||
|
@ -71,7 +71,6 @@
|
|||||||
{#if space}
|
{#if space}
|
||||||
<EditBox
|
<EditBox
|
||||||
label={clazz.label}
|
label={clazz.label}
|
||||||
icon={clazz.icon}
|
|
||||||
bind:value={space.name}
|
bind:value={space.name}
|
||||||
placeholder={clazz.label}
|
placeholder={clazz.label}
|
||||||
autoFocus
|
autoFocus
|
||||||
|
@ -178,7 +178,7 @@ export async function checkIssue (page: Page, props: IssueProps): Promise<void>
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function checkIssueDraft (page: Page, props: IssueProps): Promise<void> {
|
export async function checkIssueDraft (page: Page, props: IssueProps): Promise<void> {
|
||||||
await expect(page.locator('#issue-name')).toHaveText(props.name)
|
await expect(page.locator('#issue-name input')).toHaveValue(props.name)
|
||||||
|
|
||||||
if (props.description !== undefined) {
|
if (props.description !== undefined) {
|
||||||
await expect(page.locator('#issue-description')).toHaveText(props.description)
|
await expect(page.locator('#issue-description')).toHaveText(props.description)
|
||||||
|
Loading…
Reference in New Issue
Block a user