Skip to content

Commit

Permalink
CanWidget was migrated to TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanBluefox committed Jul 11, 2024
1 parent fa93b3d commit a14dbd2
Show file tree
Hide file tree
Showing 10 changed files with 634 additions and 470 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@ npm run start
### **WORK IN PROGRESS**
-->
## Changelog
### **WORK IN PROGRESS**
* (bluefox) Converted the CanJSWidget to typescript
* (bluefox) Added "clone" button to the attribute groups

### 2.10.2 (2024-07-10)
* (bluefox) Removed incompatible package for styles
* (bluefox) All widgets must be updated
Expand Down
2 changes: 1 addition & 1 deletion packages/iobroker.vis-2/src/src/Utils/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const NOTHING_SELECTED = 'nothing_selected';
*
* @param style the style to modify
*/
export function calculateOverflow(style: React.CSSProperties): void {
export function calculateOverflow(style: CSSStyleDeclaration | React.CSSProperties): void {
if (!style.overflowX && !style.overflowY) {
style.overflow = 'visible';
} else if (style.overflow) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,34 @@
*/

import React from 'react';
import PropTypes from 'prop-types';

import { Tab, Tabs } from '@mui/material';
import { Icon } from '@iobroker/adapter-react-v5';

// eslint-disable-next-line import/no-cycle
import VisRxWidget from '../../visRxWidget';
import VisRxWidget, { type VisRxWidgetState } from '../../visRxWidget';
import type {RxRenderWidgetProps} from "@iobroker/types-vis-2";

class TabsSliderTabs extends VisRxWidget {
interface RxData {
show_tabs: number;
vertical: boolean;
variant: '' | 'centered' | 'fullWidth';
color: string;
[key: `title_tab_${number}`]: string;
[key: `contains_view_${number}`]: string;
[key: `icon_tab_${number}`]: string;
[key: `image_tab_${number}`]: string;
[key: `icon_size_${number}`]: number;
[key: `icon_color_${number}`]: string;
[key: `overflow_x_${number}`]: '' | 'visible' | 'hidden' | 'scroll' | 'auto' | 'initial' | 'inherit';
[key: `overflow_y_${number}`]: '' | 'visible' | 'hidden' | 'scroll' | 'auto' | 'initial' | 'inherit';
}

interface TabsSliderTabsState extends VisRxWidgetState {
tabIndex: number;
}

class TabsSliderTabs extends VisRxWidget<RxData, TabsSliderTabsState> {
static getWidgetInfo() {
return {
id: 'tplSTab',
Expand Down Expand Up @@ -53,7 +72,7 @@ class TabsSliderTabs extends VisRxWidget {
name: 'variant',
type: 'select',
label: 'vis_2_widgets_widgets_tabs_variant',
hidden: data => data.vertical,
hidden: '!!data.vertical',
options: [
{ value: '', label: 'vis_2_widgets_widgets_tabs_variant_default' },
{ value: 'centered', label: 'vis_2_widgets_widgets_tabs_variant_centered' },
Expand Down Expand Up @@ -88,27 +107,27 @@ class TabsSliderTabs extends VisRxWidget {
name: 'icon_tab_',
type: 'icon64',
label: 'vis_2_widgets_widgets_tabs_tab_icon',
hidden: (data, index) => data[`image_tab_${index}`],
hidden: '!!data["image_tab_" + index"]',
},
{
name: 'image_tab_',
type: 'image',
label: 'vis_2_widgets_widgets_tabs_tab_image',
hidden: (data, index) => data[`icon_tab_${index}`],
hidden: '!!data["icon_tab_" + index"]',
},
{
name: 'icon_size_',
type: 'slider',
min: 0,
max: 100,
label: 'vis_2_widgets_widgets_tabs_tab_icon_size',
hidden: (data, index) => !data[`icon_tab_${index}`] && !data[`image_tab_${index}`],
hidden: '!data["icon_tab_" + index"] && !data["image_tab_" + index"]',
},
{
name: 'icon_color_',
type: 'color',
label: 'vis_2_widgets_widgets_tabs_tab_icon_color',
hidden: (data, index) => !data[`icon_tab_${index}`],
hidden: '!data["icon_tab_" + index"]',
},
{
name: 'overflow_x_',
Expand All @@ -131,14 +150,15 @@ class TabsSliderTabs extends VisRxWidget {
width: 250,
height: 250,
},
};
} as const;
}

async componentDidMount() {
super.componentDidMount();
let tabIndex = window.localStorage.getItem(`${this.props.id}-tabIndex`);
if (tabIndex) {
tabIndex = parseInt(tabIndex, 10) || 0;
const tabIndexStr = window.localStorage.getItem(`${this.props.id}-tabIndex`);
let tabIndex = 0;
if (tabIndexStr) {
tabIndex = parseInt(tabIndexStr, 10) || 0;
}
this.setState({ tabIndex });
}
Expand All @@ -150,7 +170,7 @@ class TabsSliderTabs extends VisRxWidget {

getWidgetView() {
const view = this.state.rxData[`contains_view_${this.state.tabIndex + 1}`];
const style = {
const style: React.CSSProperties = {
flex: 1,
position: 'relative',
};
Expand Down Expand Up @@ -181,7 +201,7 @@ class TabsSliderTabs extends VisRxWidget {
</div>;
}

renderWidgetBody(props) {
renderWidgetBody(props: RxRenderWidgetProps): React.JSX.Element {
super.renderWidgetBody(props);

// set default width and height
Expand All @@ -193,7 +213,7 @@ class TabsSliderTabs extends VisRxWidget {
}

const tabs = [];
for (let t = 0; t < parseInt(this.state.rxData.show_tabs, 10); t++) {
for (let t = 0; t < parseInt(this.state.rxData.show_tabs as unknown as string, 10); t++) {
const color = this.state.rxData[`icon_color_${t + 1}`];
const icon = this.state.rxData[`icon_tab_${t + 1}`];
let image = this.state.rxData[`image_tab_${t + 1}`];
Expand Down Expand Up @@ -247,11 +267,4 @@ class TabsSliderTabs extends VisRxWidget {
}
}

TabsSliderTabs.propTypes = {
id: PropTypes.string.isRequired,
context: PropTypes.object.isRequired,
view: PropTypes.string.isRequired,
editMode: PropTypes.bool.isRequired,
};

export default TabsSliderTabs;
50 changes: 29 additions & 21 deletions packages/iobroker.vis-2/src/src/Vis/visBaseWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,23 +101,23 @@ export interface WidgetStyleState extends WidgetStyle {
}

export interface VisBaseWidgetState {
applyBindings?: false | true | { top: string | number; left: string | number };
data: WidgetDataState | GroupDataState;
style: WidgetStyleState;
draggable?: boolean;
editMode: boolean;
rxStyle?: WidgetStyleState;
applyBindings?: false | true | { top: string | number; left: string | number };
gap?: number;
hideHelper?: boolean;
isHidden?: boolean;
multiViewWidget?: boolean;
selected?: boolean;
selectedOne?: boolean;
resizable?: boolean;
resizeHandles?: ResizeHandler[];
widgetHint?: 'light' | 'dark' | 'hide';
hideHelper?: boolean;
isHidden?: boolean;
gap?: number;
draggable?: boolean;
rxStyle?: WidgetStyleState;
selected?: boolean;
selectedOne?: boolean;
showRelativeMoveMenu?: boolean;
style: WidgetStyleState;
usedInWidget: boolean;
widgetHint?: 'light' | 'dark' | 'hide';
}

export interface VisBaseWidgetMovement {
Expand Down Expand Up @@ -156,6 +156,14 @@ interface VisBaseWidget {
renderLastChange(style: unknown): React.ReactNode;
}

interface CanHTMLDivElement extends HTMLDivElement {
_customHandlers?: {
onShow: (el: HTMLDivElement, id: string) => void;
onHide: (el: HTMLDivElement, id: string) => void;
};
_storedDisplay?: React.CSSProperties['display'];
}

class VisBaseWidget<TState extends Partial<VisBaseWidgetState> = VisBaseWidgetState> extends React.Component<VisBaseWidgetProps, TState & VisBaseWidgetState> {
static FORBIDDEN_CHARS = /[^._\-/ :!#$%&()+=@^{}|~]+/g; // from https://github.com/ioBroker/ioBroker.js-controller/blob/master/packages/common/lib/common/tools.js

Expand All @@ -169,7 +177,7 @@ class VisBaseWidget<TState extends Partial<VisBaseWidgetState> = VisBaseWidgetSt

protected refService = React.createRef<HTMLDivElement>();

protected widDiv: null | HTMLDivElement = null;
protected widDiv: null | CanHTMLDivElement = null;

readonly onCommandBound: typeof this.onCommand;

Expand Down Expand Up @@ -519,8 +527,8 @@ class VisBaseWidget<TState extends Partial<VisBaseWidgetState> = VisBaseWidgetSt
});
}

static parseStyle(style: string, isRxStyle: boolean) {
const result: Record<string, unknown> = {};
static parseStyle(style: string, isRxStyle?: boolean): Record<string, string | number> {
const result: Record<string, string | number> = {};
// style is like "height: 10; width: 20"
(style || '').split(';').forEach(part => {
part = part.trim();
Expand Down Expand Up @@ -1304,7 +1312,7 @@ class VisBaseWidget<TState extends Partial<VisBaseWidgetState> = VisBaseWidgetSt
* @param _props
*/
// eslint-disable-next-line class-methods-use-this,no-unused-vars, @typescript-eslint/no-unused-vars
renderWidgetBody(_props: RxRenderWidgetProps): React.JSX.Element | null {
renderWidgetBody(_props: RxRenderWidgetProps): React.JSX.Element | React.JSX.Element[] | null {
// Default render method. Normally it should be overwritten
return <div
style={{
Expand Down Expand Up @@ -1922,13 +1930,13 @@ class VisBaseWidget<TState extends Partial<VisBaseWidgetState> = VisBaseWidgetSt
if (value && typeof value === 'string' && !value.includes('{')) {
anyStyle[attr] = VisBaseWidget.correctStylePxValue(value);
}
} else if (this.props.context.allWidgets[this.props.id] &&
this.props.context.allWidgets[this.props.id].style &&
this.props.context.allWidgets[this.props.id].style[attr] !== undefined
) {
// try to steal style by canWidget
if (!(this.props.context.allWidgets[this.props.id].style[attr] as string).includes('{')) {
anyStyle[attr] = VisBaseWidget.correctStylePxValue(this.props.context.allWidgets[this.props.id].style[attr]);
} else {
const styleVal: string | number | undefined | null = (this.props.context.allWidgets[this.props.id]?.style as unknown as Record<string, string | number>)?.[attr];
if (styleVal !== undefined && styleVal !== null) {
// try to steal style by canWidget
if (!styleVal.toString().includes('{')) {
anyStyle[attr] = VisBaseWidget.correctStylePxValue(styleVal);
}
}
}
}
Expand Down
Loading

0 comments on commit a14dbd2

Please sign in to comment.