Skip to content

Commit

Permalink
Merge branch 'devel' into CB-4686-migrate-from-scheduled-touch-sessio…
Browse files Browse the repository at this point in the history
…n-api-call-to-a-websocket-event
  • Loading branch information
s.teleshev committed Mar 20, 2024
2 parents d0566d9 + a591122 commit 474c7b4
Show file tree
Hide file tree
Showing 10 changed files with 232 additions and 212 deletions.
108 changes: 108 additions & 0 deletions webapp/packages/core-blocks/src/PropertiesTable/PropertyItem.m.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
.container,
.button {
composes: theme-ripple from global;
}

.container {
box-sizing: border-box;
display: inline-flex;
padding: 0px 1px;
}

.name,
.value {
composes: theme-typography--caption from global;
position: relative;
display: flex;
align-items: center;
box-sizing: border-box;
flex: 1;
padding: 4px 0;

& .shadowInput {
height: 24px;
padding: 0 36px 0 12px;
}
}

.value,
.name {
margin-left: 24px;
}

.name {
flex: 0 0 auto;
width: 276px;
}

.remove {
position: relative;
flex: 0 0 auto;
align-items: center;
display: flex;
opacity: 0;
}

.select {
flex: 0 0 auto;
align-items: center;
display: flex;
}

.container:hover .remove {
opacity: 1;
}

.shadowInput {
composes: theme-background-surface from global;
}

.name .shadowInput,
.value .shadowInput {
box-sizing: border-box;
font: inherit;
color: inherit;
width: 100%;
outline: none;

&.edited {
font-weight: 600;
}

&:global([readonly]),
&:not(:focus):not([data-focus='true']) {
background: transparent !important;
border: solid 2px transparent !important;
}
}

.icon,
.iconOrImage {
height: 16px;
display: block;
}

.select .icon,
.select .iconOrImage {
&.focus {
transform: rotate(180deg);
}
}

.button {
background: transparent;
outline: none;
padding: 4px;
cursor: pointer;
}

.button,
.propertyValueSelector {
composes: theme-form-element-radius from global;
margin: 2px;
overflow: hidden;
}

.error {
composes: theme-text-error from global;
}
141 changes: 25 additions & 116 deletions webapp/packages/core-blocks/src/PropertiesTable/PropertyItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,111 +7,17 @@
*/
import { observer } from 'mobx-react-lite';
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
import styled, { css, use } from 'reshadow';

import { ShadowInput } from '../FormControls/ShadowInput';
import { Icon } from '../Icon';
import { IconOrImage } from '../IconOrImage';
import { useTranslate } from '../localization/useTranslate';
import { s } from '../s';
import { useS } from '../useS';
import type { IProperty } from './IProperty';
import classes from './PropertyItem.m.css';
import { PropertyValueSelector } from './PropertyValueSelector';

const styles = css`
[|error] {
composes: theme-text-error from global;
}
property-item,
button {
composes: theme-ripple from global;
}
property-item {
box-sizing: border-box;
display: inline-flex;
padding: 0px 1px;
}
property-name,
property-value {
composes: theme-typography--caption from global;
position: relative;
display: flex;
align-items: center;
box-sizing: border-box;
flex: 1;
padding: 4px 0;
& ShadowInput {
height: 24px;
padding: 0 36px 0 12px;
}
}
property-value,
property-name {
margin-left: 24px;
}
property-name {
flex: 0 0 auto;
width: 276px;
}
property-remove {
position: relative;
flex: 0 0 auto;
align-items: center;
display: flex;
opacity: 0;
}
property-select {
flex: 0 0 auto;
align-items: center;
display: flex;
}
property-item:hover property-remove {
opacity: 1;
}
ShadowInput {
composes: theme-background-surface from global;
}
property-name ShadowInput,
property-value ShadowInput {
box-sizing: border-box;
font: inherit;
color: inherit;
width: 100%;
outline: none;
&[|edited] {
font-weight: 600;
}
&:global([readonly]),
&:not(:focus):not([|focus]) {
background: transparent !important;
border: solid 2px transparent !important;
}
}
Icon,
IconOrImage {
height: 16px;
display: block;
}
property-select Icon,
property-select IconOrImage {
&[|focus] {
transform: rotate(180deg);
}
}
button {
background: transparent;
outline: none;
padding: 4px;
cursor: pointer;
}
button,
PropertyValueSelector {
composes: theme-form-element-radius from global;
margin: 2px;
overflow: hidden;
}
`;

interface Props {
property: IProperty;
value?: string;
Expand All @@ -123,6 +29,7 @@ interface Props {
}

export const PropertyItem = observer<Props>(function PropertyItem({ property, value, onNameChange, onValueChange, onRemove, error, readOnly }) {
const styles = useS(classes);
const translate = useTranslate();
const isDeletable = !readOnly && !property.displayName;
const edited = value !== undefined && value !== property.defaultValue;
Expand All @@ -148,11 +55,12 @@ export const PropertyItem = observer<Props>(function PropertyItem({ property, va
const keyPlaceholder = String(property.keyPlaceholder);
const valuePlaceholder = String(property.valuePlaceholder);

return styled(styles)(
<property-item>
<property-name title={property.description} {...use({ error })}>
return (
<div className={s(styles, { container: true })}>
<div className={s(styles, { name: true, error })} title={property.description}>
<ShadowInput
ref={keyInputRef}
className={s(styles, { shadowInput: true })}
type="text"
name={property.id}
placeholder={keyPlaceholder}
Expand All @@ -162,48 +70,49 @@ export const PropertyItem = observer<Props>(function PropertyItem({ property, va
>
{property.displayName || property.key}
</ShadowInput>
</property-name>
<property-value ref={setValueRef} title={String(propertyValue)}>
</div>
<div ref={setValueRef} className={s(styles, { value: true })} title={String(propertyValue)}>
<ShadowInput
className={s(styles, { shadowInput: true, edited })}
type="text"
name={`${property.id}_value`}
placeholder={valuePlaceholder}
autoComplete="none"
readOnly={readOnly}
data-focus={focus}
onChange={handleValueChange}
{...use({ focus, edited })}
>
{propertyValue}
</ShadowInput>
{edited && !isDeletable && (
<property-remove title={translate('core_blocks_properties_table_item_reset')}>
<button type="button" onClick={handleRevert}>
<IconOrImage icon="/icons/data_revert_all_sm.svg" viewBox="0 0 16 16" />
<div className={s(styles, { remove: true })} title={translate('core_blocks_properties_table_item_reset')}>
<button className={s(styles, { button: true })} type="button" onClick={handleRevert}>
<IconOrImage className={s(styles, { iconOrImage: true })} icon="/icons/data_revert_all_sm.svg" viewBox="0 0 16 16" />
</button>
</property-remove>
</div>
)}
{isDeletable && (
<property-remove title={translate('core_blocks_properties_table_item_remove')}>
<button type="button" onClick={handleRemove}>
<Icon name="reject" viewBox="0 0 11 11" />
<div className={s(styles, { remove: true })} title={translate('core_blocks_properties_table_item_remove')}>
<button className={s(styles, { button: true })} type="button" onClick={handleRemove}>
<Icon className={s(styles, { icon: true })} name="reject" viewBox="0 0 11 11" />
</button>
</property-remove>
</div>
)}
{!readOnly && property.validValues && property.validValues.length > 0 && (
<property-select>
<div className={s(styles, { select: true })}>
<PropertyValueSelector
className={s(styles, { propertyValueSelector: true })}
propertyName={property.id}
values={property.validValues}
container={valueRef}
onSelect={handleValueChange}
onSwitch={setMenuOpen}
>
<Icon name="arrow" viewBox="0 0 16 16" {...use({ focus })} />
<Icon className={s(styles, { icon: true, focus })} name="arrow" viewBox="0 0 16 16" />
</PropertyValueSelector>
</property-select>
</div>
)}
</property-value>
</property-item>,
</div>
</div>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.menuButton {
composes: theme-ripple from global;
background: transparent;
outline: none;
padding: 4px;
cursor: pointer;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,12 @@
import { observer } from 'mobx-react-lite';
import { useCallback, useEffect, useRef } from 'react';
import { Menu, MenuButton, MenuItem, useMenuState } from 'reakit/Menu';
import styled, { css } from 'reshadow';
import styled from 'reshadow';

import { BASE_DROPDOWN_STYLES } from '../FormControls/BASE_DROPDOWN_STYLES';

const styles = css`
MenuButton {
composes: theme-ripple from global;
background: transparent;
outline: none;
padding: 4px;
cursor: pointer;
}
`;
import { s } from '../s';
import { useS } from '../useS';
import classes from './PropertyValueSelector.m.css';

interface Props {
propertyName?: string;
Expand All @@ -40,6 +33,7 @@ export const PropertyValueSelector = observer<React.PropsWithChildren<Props>>(fu
onSelect,
onSwitch,
}) {
const styles = useS(classes);
const menuRef = useRef<HTMLDivElement>(null);
const menu = useMenuState({
placement: 'bottom-end',
Expand Down Expand Up @@ -76,12 +70,9 @@ export const PropertyValueSelector = observer<React.PropsWithChildren<Props>>(fu

const visible = menu.visible;

return styled(
BASE_DROPDOWN_STYLES,
styles,
)(
return styled(BASE_DROPDOWN_STYLES)(
<>
<MenuButton {...menu} className={className} visible={visible}>
<MenuButton {...menu} className={s(styles, { menuButton: true }, className)} visible={visible}>
{children}
</MenuButton>
<Menu {...menu} ref={menuRef} visible={visible} aria-label={propertyName} modal>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.wrapper {
composes: theme-background-surface from global;
display: flex;
width: 100%;
flex: 1 1 auto;
padding-top: 16px;
}
Loading

0 comments on commit 474c7b4

Please sign in to comment.