Skip to content

Commit c73cba7

Browse files
committed
ui: render exactly one element — move composition to components (field, toast, tabs)
A ui part renders a single element + {children}; composition is the components tier's job (rule 1/2). - field: FieldLabel and FieldItemContent each became a single-element ui slot; the required-marker and label+description composition moved to new components/field ready-mades. Repointed the 4 field consumers + required-passing call sites. - toast: the solid-* glyph assets + the tone->glyph map moved to components/toast; ui/toast keeps only the single-element styled status-icon slot (cva sizes/colors the svg child). - tabs: the underline track+bar split into TabUnderlineBarTrack + TabUnderlineBar; the track-wraps-bar nesting moved into components/tabs (the underline Tab).
1 parent 278d703 commit c73cba7

28 files changed

Lines changed: 179 additions & 96 deletions

packages/propel/src/components/checkbox-field/checkbox-field.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
import type { CheckboxTone } from "../../ui/checkbox/index";
88
import { Field } from "../../ui/field/field";
99
import { FieldItem } from "../../ui/field/field-item";
10-
import { FieldItemContent } from "../../ui/field/field-item-content";
1110
import type { FieldMagnitude } from "../../ui/field/variants";
11+
import { FieldItemContent } from "../field";
1212
import { FieldHelperText } from "../field/field-helper-text";
1313

1414
export type CheckboxFieldProps = Omit<

packages/propel/src/components/checkbox-group-field/checkbox-group-field-option.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
import { useFieldOptionMagnitude } from "../../internal/field-option-magnitude";
88
import type { CheckboxTone } from "../../ui/checkbox/index";
99
import { FieldItem } from "../../ui/field/field-item";
10-
import { FieldItemContent } from "../../ui/field/field-item-content";
1110
import type { FieldMagnitude } from "../../ui/field/variants";
11+
import { FieldItemContent } from "../field";
1212

1313
export type CheckboxGroupFieldOptionProps = Omit<
1414
CheckboxFieldControlProps,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import type * as React from "react";
2+
3+
import { FieldDescription } from "../../ui/field/field-description";
4+
import { FieldItemContent as FieldItemContentElement } from "../../ui/field/field-item-content";
5+
import { FieldLabel } from "../../ui/field/field-label";
6+
import { type InputMagnitude } from "../../ui/field/variants";
7+
8+
/** The label + description column for a single choice option (checkbox/radio/switch row). */
9+
export function FieldItemContent({
10+
children,
11+
description,
12+
magnitude,
13+
}: {
14+
children: React.ReactNode;
15+
description?: React.ReactNode;
16+
magnitude: InputMagnitude;
17+
}) {
18+
return (
19+
<FieldItemContentElement>
20+
<FieldLabel magnitude={magnitude} inset={false}>
21+
{children}
22+
</FieldLabel>
23+
{description != null ? (
24+
<FieldDescription magnitude={magnitude}>{description}</FieldDescription>
25+
) : null}
26+
</FieldItemContentElement>
27+
);
28+
}

packages/propel/src/components/field/field-label-group.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import type * as React from "react";
22

3-
import { FieldDescription, FieldLabel } from "../../ui/field";
3+
import { FieldDescription } from "../../ui/field";
44
import { FieldLabelGroup as FieldLabelGroupContainer } from "../../ui/field/field-label-group";
55
import { type FieldLabelGroupVariantProps, type InputMagnitude } from "../../ui/field/variants";
6+
import { FieldLabel } from "./field-label";
67

78
export type FieldLabelGroupProps = FieldLabelGroupVariantProps & {
89
magnitude: InputMagnitude;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import {
2+
FieldLabel as FieldLabelElement,
3+
type FieldLabelProps as FieldLabelElementProps,
4+
} from "../../ui/field/field-label";
5+
import { FieldLabelRequiredMarker } from "../../ui/field/field-label-required-marker";
6+
7+
export type FieldLabelProps = FieldLabelElementProps & { required?: boolean };
8+
9+
/**
10+
* The ready-made field label: the `FieldLabel` slot, plus a `FieldLabelRequiredMarker` when
11+
* `required`.
12+
*/
13+
export function FieldLabel({ required, children, ...props }: FieldLabelProps) {
14+
return (
15+
<FieldLabelElement {...props}>
16+
{children}
17+
{required ? <FieldLabelRequiredMarker>*</FieldLabelRequiredMarker> : null}
18+
</FieldLabelElement>
19+
);
20+
}

packages/propel/src/components/field/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ export {
77
type FieldErrorProps,
88
FieldItem,
99
type FieldItemProps,
10-
FieldLabel,
11-
type FieldLabelProps,
1210
} from "../../ui/field/index";
11+
export * from "./field-item-content";
12+
export * from "./field-label";
1313
export * from "./field-helper-text";
1414
export * from "./field-label-group";

packages/propel/src/components/radio-group-field/radio-group-field-option.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import type * as React from "react";
22

33
import { useFieldOptionMagnitude } from "../../internal/field-option-magnitude";
44
import { FieldItem } from "../../ui/field/field-item";
5-
import { FieldItemContent } from "../../ui/field/field-item-content";
65
import type { FieldMagnitude } from "../../ui/field/variants";
6+
import { FieldItemContent } from "../field";
77
import { Radio, type RadioProps } from "../radio/radio";
88

99
export type RadioGroupFieldOptionProps = RadioProps & {

packages/propel/src/components/switch-field/switch-field.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import type * as React from "react";
22

33
import { Field } from "../../ui/field/field";
44
import { FieldItem } from "../../ui/field/field-item";
5-
import { FieldItemContent } from "../../ui/field/field-item-content";
65
import type { FieldMagnitude } from "../../ui/field/variants";
6+
import { FieldItemContent } from "../field";
77
import { FieldHelperText } from "../field/field-helper-text";
88
import { Switch, type SwitchMagnitude, type SwitchProps } from "../switch/index";
99

packages/propel/src/components/tabs/tab.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Tab as TabElement,
66
type TabProps as TabElementProps,
77
TabUnderlineBar,
8+
TabUnderlineBarTrack,
89
TabUnderlineLabel,
910
} from "../../ui/tabs";
1011
import { TabsAppearanceContext } from "./tabs-context";
@@ -33,7 +34,9 @@ export function Tab({ inlineStartNode, children, ...props }: TabProps) {
3334
{iconNode}
3435
{children}
3536
</TabUnderlineLabel>
36-
<TabUnderlineBar />
37+
<TabUnderlineBarTrack>
38+
<TabUnderlineBar />
39+
</TabUnderlineBarTrack>
3740
</TabElement>
3841
);
3942
}

packages/propel/src/components/toast/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from "./toast";
2+
export * from "./toast-status-icon";
23
export * from "./toast-list";
34
export * from "./toast-provider";
45

0 commit comments

Comments
 (0)