Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
10e33fc
refactor(bem): replace Block/Elem with cn() in Badge
luarmr Nov 4, 2025
b43b0c2
refactor(bem): replace Block/Elem with cn() in Tag
luarmr Nov 4, 2025
b526aa3
refactor(bem): replace Block/Elem with cn() in SkeletonGap
luarmr Nov 4, 2025
21aec05
refactor(bem): replace Block/Elem with cn() in SkeletonLine
luarmr Nov 4, 2025
09fbe6e
refactor(bem): replace Block/Elem with cn() in Counter
luarmr Nov 4, 2025
f19164a
refactor(bem): replace Block/Elem with cn() in Form Label
luarmr Nov 4, 2025
db9c659
refactor(bem): replace Block/Elem with cn() in RadioGroup
luarmr Nov 4, 2025
d3c540b
refactor(bem): replace Block/Elem with cn() in Form Indicator
luarmr Nov 4, 2025
5e5252a
refactor(bem): replace Block/Elem with cn() in Range
luarmr Nov 4, 2025
7fcb713
refactor(bem): replace Block/Elem with cn() in Pagination
luarmr Nov 4, 2025
e83a218
refactor(bem): replace Block/Elem with cn() in Resizer
luarmr Nov 4, 2025
6d515c9
refactor(bem): replace Block/Elem with cn() in FieldsButton
luarmr Nov 4, 2025
e13ac9d
refactor(bem): replace Block/Elem with cn() in MediaPlayer
luarmr Nov 4, 2025
ab3b935
refactor(bem): replace Block/Elem with cn() in MediaSeeker
luarmr Nov 4, 2025
883c110
refactor(bem): replace Block/Elem with cn() in SkeletonLoader
luarmr Nov 4, 2025
4ef5b0d
refactor(bem): replace Block/Elem with cn() in Table
luarmr Nov 4, 2025
67d1866
refactor(bem): replace Block/Elem with cn() in GridView
luarmr Nov 4, 2025
f5ce30f
refactor(bem): replace Block/Elem with cn() in Toolbar
luarmr Nov 4, 2025
4dea121
refactor(bem): replace Block/Elem with cn() in ActionsButton
luarmr Nov 4, 2025
85caa22
refactor(bem): replace Block/Elem with cn() in instruments
luarmr Nov 4, 2025
6694317
refactor(bem): replace Block/Elem with cn() in Filters
luarmr Nov 4, 2025
4a5da19
refactor(bem): replace Block/Elem with cn() in FilterSidebar
luarmr Nov 4, 2025
f40cf4a
refactor(bem): replace Block/Elem with cn() in ImageDataGroup
luarmr Nov 4, 2025
d8ab6b9
refactor(bem): replace Block/Elem with cn() in Label
luarmr Nov 4, 2025
ea75e48
refactor(bem): update GridView.test.tsx mocks to use cn()
luarmr Nov 4, 2025
54059df
refactor(bem): clean up bem.tsx exports after migration
luarmr Nov 4, 2025
41ea23f
bioming
luarmr Nov 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions web/libs/datamanager/src/components/Common/Badge/Badge.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Block } from "../../../utils/bem";
import { cn } from "../../../utils/bem";
import "./Badge.scss";

export const Badge = ({ children, size, className, color, style }) => {
return (
<Block name="badge-dm" mod={{ size }} className={className} style={{ ...(style ?? {}), backgroundColor: color }}>
<div
className={cn("badge-dm").mod({ size }).mix(className).toClassName()}
style={{ ...(style ?? {}), backgroundColor: color }}
>
{children}
</Block>
</div>
);
};
6 changes: 3 additions & 3 deletions web/libs/datamanager/src/components/Common/FieldsButton.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button, Checkbox } from "@humansignal/ui";
import { inject, observer } from "mobx-react";
import React from "react";
import { Elem } from "../../utils/bem";
import { cn } from "../../utils/bem";
import { Dropdown } from "./Dropdown/Dropdown";
import { Menu } from "./Menu/Menu";

Expand Down Expand Up @@ -112,7 +112,7 @@ export const FieldsButton = injector(
openUpwardForShortViewport={openUpwardForShortViewport}
>
{tooltip ? (
<Elem name={"field-button"} style={{ zIndex: 1000 }} rawClassName="h-[40px] flex items-center">
<div className={`${cn("field-button").toClassName()} h-[40px] flex items-center`} style={{ zIndex: 1000 }}>
<Button
tooltip={tooltip}
variant="neutral"
Expand All @@ -124,7 +124,7 @@ export const FieldsButton = injector(
>
{content.length ? content : null}
</Button>
</Elem>
</div>
) : (
renderButton()
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createContext, useCallback, useContext, useEffect, useState } from "react";
import { IconPlus, IconMinus } from "@humansignal/icons";
import { Block, Elem } from "../../../../../utils/bem";
import { cn } from "../../../../../utils/bem";
import { isDefined } from "../../../../../utils/utils";
import { Oneof } from "../../../Oneof/Oneof";
import { FormField } from "../../FormField";
Expand Down Expand Up @@ -152,15 +152,16 @@ const Counter = ({

return (
<CounterContext.Provider value={contextValue}>
<Block name="counter" mod={{ focused, disabled: fieldDisabled }} mix={className} style={style}>
<div
className={cn("counter").mod({ focused, disabled: fieldDisabled }).mix(className).toClassName()}
style={style}
>
<CounterButton type="decrease" />

<Elem
<input
ref={ref}
tag="input"
name="input"
className={cn("counter").elem("input").mod({ withPostfix: !!postfix }).toClassName()}
type="text"
mod={{ withPostfix: !!postfix }}
readOnly={editable === false}
disabled={fieldDisabled}
value={currentValue}
Expand All @@ -172,13 +173,13 @@ const Counter = ({
/>

{postfix && (
<Elem name="input" mod={{ under: true, withPostfix: !!postfix }}>
<div className={cn("counter").elem("input").mod({ under: true, withPostfix: !!postfix }).toClassName()}>
{displayValue.join(" ")}
</Elem>
</div>
)}

<CounterButton type="increase" />
</Block>
</div>
</CounterContext.Provider>
);
}}
Expand All @@ -194,22 +195,24 @@ const CounterButton = ({ type }) => {
const compareLimit = type === "increase" ? max : min;

return (
<Elem
tag="a"
// biome-ignore lint/a11y/useValidAnchor: anchor used for styling purposes, todo after bem migration
<a
href="#"
name="btn"
mod={{
type,
disabled: currentValue === compareLimit || disabled,
}}
className={cn("counter")
.elem("btn")
.mod({
type,
disabled: currentValue === compareLimit || disabled,
})
.toClassName()}
onClick={onClickHandler(type, ref)}
onMouseDownCapture={(e) => e.preventDefault()}
>
<Oneof value={type}>
<IconMinus case="decrease" />
<IconPlus case="increase" />
</Oneof>
</Elem>
</a>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { forwardRef } from "react";
import { Block, Elem } from "../../../../../utils/bem";
import { forwardRef, createElement } from "react";
import { cn } from "../../../../../utils/bem";
import "./Label.scss";
/** @deprecated - needs to be replaced with @humansignal/ui Label - visualizes differently currently */
const Label = forwardRef(
Expand All @@ -14,16 +14,21 @@ const Label = forwardRef(
empty: !children,
};

return (
<Block ref={ref} name="label-dm" tag={tagName} style={style} mod={mods} data-required={required}>
<Elem name="text">
<Elem name="content">
{text}
{description && <Elem name="description">{description}</Elem>}
</Elem>
</Elem>
<Elem name="field">{children}</Elem>
</Block>
return createElement(
tagName,
{
ref,
className: cn("label-dm").mod(mods).toClassName(),
style,
"data-required": required,
},
<div className={cn("label-dm").elem("text").toClassName()}>
<div className={cn("label-dm").elem("content").toClassName()}>
{text}
{description && <div className={cn("label-dm").elem("description").toClassName()}>{description}</div>}
</div>
</div>,
<div className={cn("label-dm").elem("field").toClassName()}>{children}</div>,
);
},
);
Expand Down
10 changes: 5 additions & 5 deletions web/libs/datamanager/src/components/Common/Form/Form.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, createRef, forwardRef, useCallback, useContext, useEffect, useRef, useState } from "react";
import { shallowEqualObjects } from "shallow-equal";
import { Block, cn, Elem } from "../../../utils/bem";
import { cn } from "../../../utils/bem";
import { objectClean } from "../../../utils/helpers";
import { Button } from "@humansignal/ui";
import { Oneof } from "../Oneof/Oneof";
Expand Down Expand Up @@ -565,13 +565,13 @@ Form.Indicator = () => {
const state = useContext(FormStateContext);

return (
<Block name="form-indicator-dm">
<div className={cn("form-indicator-dm").toClassName()}>
<Oneof value={state}>
<Elem tag="span" mod={{ type: state }} name="item" case="success">
<span className={cn("form-indicator-dm").elem("item").mod({ type: state }).toClassName()} case="success">
Saved!
</Elem>
</span>
</Oneof>
</Block>
</div>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import { createRef, useCallback, useEffect, useMemo, useReducer, useRef, useState } from "react";
import {
createRef,
useCallback,
useEffect,
useMemo,
useReducer,
useRef,
useState,
forwardRef,
createElement,
} from "react";
import { IconTimelinePause, IconTimelinePlay } from "@humansignal/icons";
import { Block, Elem } from "../../../utils/bem";
import { cn } from "../../../utils/bem";
import { filename } from "../../../utils/helpers";
import { Space } from "../Space/Space";
import { Spinner } from "../Spinner";
import "./MediaPlayer.scss";
import { MediaSeeker } from "./MediaSeeker";
import { Duration } from "./Duration";
import { forwardRef } from "react";

const mediaDefaultProps = { crossOrigin: "anonymous" };

Expand Down Expand Up @@ -139,25 +148,25 @@ export const MediaPlayer = ({ src, video = false }) => {
const showError = !state.resetSource && state.error;

return enabled ? (
<Block name="player" mod={{ video }} onClick={(e) => e.stopPropagation()}>
<div className={cn("player").mod({ video }).toClassName()} onClick={(e) => e.stopPropagation()}>
{video && <MediaSource type="video" onClick={togglePlay} {...mediaProps} />}
{showError ? (
<Elem name="loading">Unable to play</Elem>
<div className={cn("player").elem("loading").toClassName()}>Unable to play</div>
) : state.loaded ? (
<Elem name="playback">
<Elem name="controls" tag={Space} spread>
<div className={cn("player").elem("playback").toClassName()}>
<Space className={cn("player").elem("controls").toClassName()} spread>
<Space size="small">
<Elem name="play" onClick={togglePlay}>
<div className={cn("player").elem("play").toClassName()} onClick={togglePlay}>
{state.playing ? <IconTimelinePause /> : <IconTimelinePlay />}
</Elem>
{!video && <Elem name="track">{filename(src)}</Elem>}
</div>
{!video && <div className={cn("player").elem("track").toClassName()}>{filename(src)}</div>}
</Space>
<Elem tag={Space} size="small" name="time">
<Space className={cn("player").elem("time").toClassName()} size="small">
<Duration value={state.currentTime} format={format} />
{" / "}
<Duration value={state.duration} format={format} />
</Elem>
</Elem>
</Space>
</Space>

<MediaSeeker
video={video}
Expand All @@ -168,41 +177,46 @@ export const MediaPlayer = ({ src, video = false }) => {
onSeekEnd={onSeekEnd}
onChange={onSeek}
/>
</Elem>
</div>
) : (
<Elem name="loading">
<div className={cn("player").elem("loading").toClassName()}>
<Spinner size="24" />
</Elem>
</div>
)}

{!video && <MediaSource type="audio" {...mediaProps} ref={media} />}
</Block>
</div>
) : (
<Block
name="player"
<div
className={cn("player").toClassName()}
onClick={(e) => {
e.stopPropagation();
setEnabled(true);
waitForPlayer();
}}
>
<Elem name="controls" tag={Space} spread>
<Space className={cn("player").elem("controls").toClassName()} spread>
<Space size="small">
<Elem name="play">
<div className={cn("player").elem("play").toClassName()}>
<IconTimelinePlay />
</Elem>
<Elem name="track">Click to load</Elem>
</div>
<div className={cn("player").elem("track").toClassName()}>Click to load</div>
</Space>
<Elem tag={Space} size="small" name="time" />
</Elem>
</Block>
<Space className={cn("player").elem("time").toClassName()} size="small" />
</Space>
</div>
);
};

const MediaSource = forwardRef(({ type = "audio", src, ...props }, ref) => {
return (
<Elem {...mediaDefaultProps} name="media" tag={type} ref={ref} {...props}>
<source src={src} />
</Elem>
return createElement(
type,
{
...mediaDefaultProps,
className: cn("player").elem("media").toClassName(),
ref,
...props,
},
<source src={src} />,
);
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { Block, cn, Elem } from "../../../utils/bem";
import { cn } from "../../../utils/bem";
import "./MediaSeeker.scss";

export const MediaSeeker = ({ currentTime, duration, buffer, onSeekStart, onSeekEnd, onChange, video }) => {
Expand Down Expand Up @@ -61,11 +61,11 @@ export const MediaSeeker = ({ currentTime, duration, buffer, onSeekStart, onSeek
}, [buffer, duration, currentTime]);

return (
<Block name="audio-seeker" ref={seekerRef} onMouseDownCapture={handleMouseDown}>
<Elem name="wrapper" mod={{ video }}>
<Elem name="progress" style={{ width: `${progress}%` }} />
<Elem name="buffer" style={{ width: `${buffered}%` }} />
</Elem>
</Block>
<div className={cn("audio-seeker").toClassName()} ref={seekerRef} onMouseDownCapture={handleMouseDown}>
<div className={cn("audio-seeker").elem("wrapper").mod({ video }).toClassName()}>
<div className={cn("audio-seeker").elem("progress").toClassName()} style={{ width: `${progress}%` }} />
<div className={cn("audio-seeker").elem("buffer").toClassName()} style={{ width: `${buffered}%` }} />
</div>
</div>
);
};
Loading
Loading