From 104f34fee077f1ee15c2dfe2fab92641ddde91fc Mon Sep 17 00:00:00 2001
From: Felix Thape <67233923+DasProffi@users.noreply.github.com>
Date: Sun, 27 Sep 2026 12:47:24 +0200
Subject: [PATCH 01/25] chore: change data-name to className
---
conventions/Components.md | 66 +++++++++++++
conventions/Interaction and Feedback.md | 99 +++++++++++++++++++
.../display-and-visualization/Avatar.tsx | 30 +++---
.../display-and-visualization/Chip.tsx | 11 ++-
.../ExpansionIcon.tsx | 6 +-
.../ProcessModelActivityNode.tsx | 3 +-
.../process-model/ProcessModelCanvas.tsx | 4 +-
.../process-model/ProcessModelTraceReplay.tsx | 3 +-
.../src/components/form/FieldLayout.tsx | 17 +---
.../src/components/layout/Expandable.tsx | 33 +++----
.../src/components/layout/TabSwitcher.tsx | 19 ++--
.../src/components/layout/app/AppPage.tsx | 22 ++---
.../src/components/layout/dialog/Dialog.tsx | 14 +--
.../layout/drawer/DrawerContainer.tsx | 8 +-
.../layout/navigation/BreadCrumbs.tsx | 7 +-
.../VerticalNavigationMenu.tsx | 3 +-
.../src/components/layout/popup/PopUp.tsx | 21 ++--
.../components/layout/table/FillerCell.tsx | 9 +-
.../src/components/layout/table/TableBody.tsx | 7 +-
.../src/components/layout/table/TableCell.tsx | 3 +-
.../components/layout/table/TableDisplay.tsx | 18 ++--
.../components/layout/table/TableHeader.tsx | 11 +--
.../layout/table/VirtualizedTableBody.tsx | 11 +--
.../layout/table/useNaturalColumnWidthLock.ts | 2 +-
.../virtualization/virtualizationScroll.ts | 2 +-
.../components/user-interaction/Button.tsx | 8 +-
.../components/user-interaction/Checkbox.tsx | 12 +--
.../Combobox/ComboboxList.tsx | 6 +-
.../Combobox/ComboboxOption.tsx | 10 +-
.../FileInput/FileInputMenu.tsx | 13 +--
.../FileInput/FileInputTrigger.tsx | 14 +--
.../MultiSelectChipDisplayTrigger.tsx | 13 ++-
.../MultiSelect/MultiSelectContent.tsx | 6 +-
.../MultiSelect/MultiSelectOption.tsx | 5 +-
.../MultiSelect/MultiSelectTrigger.tsx | 15 ++-
.../user-interaction/Select/SelectContent.tsx | 3 +-
.../user-interaction/Select/SelectOption.tsx | 5 +-
.../user-interaction/Select/SelectTrigger.tsx | 15 ++-
.../components/user-interaction/Switch.tsx | 11 +--
.../components/user-interaction/Textarea.tsx | 9 +-
.../components/user-interaction/Tooltip.tsx | 22 ++---
.../user-interaction/data/FilterPopUp.tsx | 5 +-
.../user-interaction/date/DayPicker.tsx | 18 ++--
.../user-interaction/date/TimeInput.tsx | 17 ++--
.../user-interaction/date/TimePicker.tsx | 15 +--
.../user-interaction/input/DateTimeField.tsx | 15 ++-
.../user-interaction/input/DateTimeInput.tsx | 8 +-
.../user-interaction/input/Input.tsx | 14 +--
.../user-interaction/input/NumberInput.tsx | 8 +-
.../input/NumberStepperInput.tsx | 8 +-
.../input/ToggleableInput.tsx | 3 +-
.../properties/DateProperty.tsx | 3 +-
.../properties/MultiSelectProperty.tsx | 2 +-
.../properties/NumberProperty.tsx | 11 +--
.../properties/PropertyBase.tsx | 17 ++--
.../properties/SelectProperty.tsx | 5 +-
.../properties/TextProperty.tsx | 3 +-
.../src/style/theme/components/app-page.css | 16 +--
.../src/style/theme/components/avatar.css | 14 +--
.../src/style/theme/components/breadcrumb.css | 6 +-
.../src/style/theme/components/button.css | 4 +-
.../components/chat/chat-message-card.css | 2 +-
.../src/style/theme/components/checkbox.css | 4 +-
.../src/style/theme/components/chip.css | 4 +-
.../src/style/theme/components/combobox.css | 10 +-
.../theme/components/date-time-input.css | 8 +-
.../src/style/theme/components/day-picker.css | 10 +-
.../src/style/theme/components/dialog.css | 6 +-
.../src/style/theme/components/drawer.css | 2 +-
.../src/style/theme/components/expandable.css | 6 +-
.../style/theme/components/expansion-icon.css | 2 +-
.../src/style/theme/components/file-input.css | 20 ++--
.../src/style/theme/components/form-field.css | 8 +-
.../style/theme/components/input-elements.css | 2 +-
.../src/style/theme/components/pop-up.css | 2 +-
.../src/style/theme/components/property.css | 44 ++++-----
.../src/style/theme/components/select.css | 20 ++--
.../src/style/theme/components/switch.css | 6 +-
.../src/style/theme/components/table.css | 26 ++---
.../style/theme/components/tabswitcher.css | 8 +-
.../src/style/theme/components/textarea.css | 2 +-
.../style/theme/components/time-picker.css | 4 +-
.../theme/components/toggleable-intput.css | 2 +-
.../src/style/theme/components/tooltip.css | 4 +-
.../theme/components/vertical-navigation.css | 2 +-
packages/hightide-web/src/utils/propsUtil.ts | 8 +-
.../tests/table/naturalColumnSizing.test.tsx | 6 +-
.../virtualizationScroll.test.ts | 4 +-
88 files changed, 551 insertions(+), 459 deletions(-)
create mode 100644 conventions/Components.md
create mode 100644 conventions/Interaction and Feedback.md
diff --git a/conventions/Components.md b/conventions/Components.md
new file mode 100644
index 00000000..d675577b
--- /dev/null
+++ b/conventions/Components.md
@@ -0,0 +1,66 @@
+# Components
+
+How components are structured.
+
+## Anatomy
+
+Every component is split into primitives, and every component has an aggregate.
+
+The aggregate is the component used in the common case. Primitives are the individual elements of that component, attached as static members of the aggregate.
+
+```tsx
+
+```
+
+`` is the aggregate. `Select.Root`, `Select.Trigger`, `Select.Content`, and `Select.Option` are the primitives. Each element of the component has its own primitive.
+
+The aggregate composes those primitives into the default arrangement. Callers who need a different arrangement use the primitives directly. Both forms are part of the public API.
+
+### Aggregate
+
+Props that belong to an individual primitive can be set on the aggregate. A dedicated props object for that primitive overwrites the values the aggregate already applied.
+
+```tsx
+
+```
+
+`value` and `onValueChange` parameterize `Select.Root`. `placeholder` parameterizes `Select.Trigger`. `triggerProps` and `contentProps` are applied on top of the props the aggregate already passed, so they win when both set the same prop.
+
+That aggregate is the same composition as:
+
+```tsx
+
+
+
+ A
+
+
+```
+
+### Primitives
+
+A primitive owns one element: the root, the trigger, the content panel, an option, and so on. Name them `Component.Element`, and export them on the aggregate.
+
+### Root
+
+When primitives share state, the component provides a `Component.Root` primitive. Root parameterizes that state and provides it through context. The other primitives read the context. They do not own the shared state themselves.
+
+`Select.Root` holds the open state, the current value, interaction flags such as disabled, invalid, and read-only, and option registration, and passes them through `Select.Context`.
+
+A component whose primitives do not share state does not have a Root.
+
+## Styling identification
+
+Components identify themselves for styling with class names. Do not use `data-name`, or any other data attribute, as the styling hook.
+
+Data attributes are reserved for states and configuration, for example `data-disabled`, `data-invalid`, and `data-processing="subtle"`.
diff --git a/conventions/Interaction and Feedback.md b/conventions/Interaction and Feedback.md
new file mode 100644
index 00000000..a31477c0
--- /dev/null
+++ b/conventions/Interaction and Feedback.md
@@ -0,0 +1,99 @@
+# Interaction and Feedback
+
+Minimum states an element must differentiate. These apply to mobile and web unless a state is marked web only.
+
+There are three component types: Presentation, Interactive, and DataInput. Each type lists its own states. States are not inherited from another type.
+
+LifeCycle is separate from these types. It describes whether the element is available, waiting on data, blocked by an external operation or dependency, or performing an operation.
+
+## Presentation
+
+Presentation elements display content. They do not take input.
+
+Presentation elements have no interaction states.
+
+## Interactive
+
+Interactive elements can be activated.
+
+| State | Scope |
+| --- | --- |
+| `hover` | web only |
+| `pressed` | mobile and web |
+| `focus` | mobile and web |
+| `focus-visible` | web only, often replacing `focus` |
+| `disabled` | mobile and web |
+
+## DataInput
+
+Data input elements accept or display an editable value.
+
+| State | Scope |
+| --- | --- |
+| `readonly` | data input only |
+| `invalid` | data input only |
+| `hover` | web only |
+| `pressed` | mobile and web |
+| `focus` | mobile and web |
+| `focus-visible` | web only, often replacing `focus` |
+| `disabled` | mobile and web |
+
+## LifeCycle
+
+Every element can be in one lifecycle state:
+
+```ts
+type LifeCycle = 'idle' | 'loading' | 'blocked' | 'processing'
+```
+
+### idle
+
+The element is available to be used.
+
+### loading
+
+The element is loading data. Its content is not ready to show yet.
+
+Show a skeleton or a placeholder in its place. The placeholder is often a rounded rectangle that roughly approximates the element's size.
+
+### blocked
+
+An external operation or dependency is preventing this element from being used.
+
+### processing
+
+This element is updating, or performing an operation, and that operation stops interaction. The element stays visible while the operation runs.
+
+## Interaction states
+
+`readonly`, `invalid`, `hover`, `pressed`, `focus`, `focus-visible`, and `disabled` follow the matching HTML semantics.
+
+### hover
+
+Web only. The pointer is over the element. This matches the CSS `:hover` pseudo-class. Mobile does not use this state.
+
+### pressed
+
+The element is being activated by a pointer or touch press. This matches `:active`.
+
+### focus
+
+The element has focus. This matches `:focus`.
+
+### focus-visible
+
+Web only. The element has focus and that focus should be shown, typically because it came from the keyboard. This matches `:focus-visible`.
+
+On web, `focus-visible` often replaces the `focus` visual, so pointer focus does not draw a focus ring. Mobile does not use this state.
+
+### disabled
+
+The element cannot be interacted with. This matches the `disabled` attribute and `:disabled`.
+
+### readonly
+
+Data input only. The value can be read and is not editable. This matches the `readonly` attribute.
+
+### invalid
+
+Data input only. The current value fails validation. This matches `:invalid` and `aria-invalid`.
diff --git a/packages/hightide-web/src/components/display-and-visualization/Avatar.tsx b/packages/hightide-web/src/components/display-and-visualization/Avatar.tsx
index 61ded924..320b411f 100644
--- a/packages/hightide-web/src/components/display-and-visualization/Avatar.tsx
+++ b/packages/hightide-web/src/components/display-and-visualization/Avatar.tsx
@@ -59,16 +59,14 @@ export const Avatar = ({
return (