Show the whole Rule on one review card, with quiet flags for missing cards and Continue once each question has one.
This commit is contained in:
1 parent
cc878e3c19
commit
6e2e1915ae
30 files changed
+571
-218
No files matched your search
@@ -6,6 +6,10 @@ export interface Category {
|
||||
chipOptions: ChipOption[];
|
||||
/** When `false`, hide the row’s + affordance. Default: show when the Rule allows adds. */
|
||||
addButton?: boolean;
|
||||
/** Label on the add control. Empty string keeps the icon-only circle. */
|
||||
addButtonText?: string;
|
||||
/** Figma Has Flag: short line after the add chip in the same row. */
|
||||
flag?: string;
|
||||
onChipClick?: (categoryName: string, chipId: string) => void;
|
||||
onAddClick?: (categoryName: string) => void;
|
||||
onCustomChipConfirm?: (
|
||||
|
||||
@@ -472,7 +472,8 @@ export function RuleView({
|
||||
addButton={
|
||||
!hideCategoryAddButton && category.addButton !== false
|
||||
}
|
||||
addButtonText="" // Empty text for icon-only circular button
|
||||
addButtonText={category.addButtonText ?? ""}
|
||||
flag={category.flag}
|
||||
className="w-full"
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -21,6 +21,7 @@ const ChipContainer = memo<ChipProps>(
|
||||
onRemove,
|
||||
onCheck,
|
||||
onClose,
|
||||
hasWarning = false,
|
||||
ariaLabel,
|
||||
}) => {
|
||||
const t = useTranslation("controlsChrome");
|
||||
@@ -89,11 +90,19 @@ const ChipContainer = memo<ChipProps>(
|
||||
onRemove={onRemove}
|
||||
onCheck={handleCheck}
|
||||
onClose={handleClose}
|
||||
hasWarning={hasWarning}
|
||||
inputValue={isCustom ? inputValue : undefined}
|
||||
onInputChange={isCustom ? setInputValue : undefined}
|
||||
onInputKeyDown={isCustom ? handleKeyDown : undefined}
|
||||
inputRef={isCustom ? inputRef : undefined}
|
||||
ariaLabel={ariaLabel ?? (isCustom ? undefined : label)}
|
||||
ariaLabel={
|
||||
ariaLabel ??
|
||||
(isCustom
|
||||
? undefined
|
||||
: hasWarning
|
||||
? t("chipMissingWords").replace("{label}", label)
|
||||
: label)
|
||||
}
|
||||
confirmAriaLabel={t("chipConfirm")}
|
||||
typeToAddPlaceholder={t("chipTypeToAdd")}
|
||||
closeAriaLabel={t("chipClose")}
|
||||
|
||||
@@ -48,6 +48,11 @@ export interface ChipProps {
|
||||
* Optional callback when custom chip is closed/removed.
|
||||
*/
|
||||
onClose?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
/**
|
||||
* Figma Has Warning: show a warning icon in place of the selected check.
|
||||
* Used on final review when a card or value is missing its words.
|
||||
*/
|
||||
hasWarning?: boolean;
|
||||
ariaLabel?: string;
|
||||
}
|
||||
|
||||
@@ -62,6 +67,7 @@ export interface ChipViewProps {
|
||||
onRemove?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
onCheck?: (value: string, event: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
onClose?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
hasWarning?: boolean;
|
||||
inputValue?: string;
|
||||
onInputChange?: (value: string) => void;
|
||||
onInputKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { memo, type CSSProperties } from "react";
|
||||
import Icon from "../../asset/icon/Icon";
|
||||
import type { ChipViewProps } from "./Chip.types";
|
||||
|
||||
function chipSurfaceStyle(
|
||||
@@ -87,6 +88,7 @@ function ChipView({
|
||||
onRemove,
|
||||
onCheck,
|
||||
onClose,
|
||||
hasWarning = false,
|
||||
inputValue,
|
||||
onInputChange,
|
||||
onInputKeyDown,
|
||||
@@ -280,7 +282,13 @@ function ChipView({
|
||||
onClick={handleClick}
|
||||
{...sharedA11y}
|
||||
>
|
||||
{isSelected ? (
|
||||
{hasWarning ? (
|
||||
<Icon
|
||||
name="warning"
|
||||
size={isSmall ? 12 : 16}
|
||||
className="shrink-0 text-current"
|
||||
/>
|
||||
) : isSelected ? (
|
||||
<svg
|
||||
aria-hidden
|
||||
viewBox="0 0 12 12"
|
||||
|
||||
@@ -20,6 +20,7 @@ const MultiSelectContainer = memo<MultiSelectProps>(
|
||||
onAddClick,
|
||||
addButton: addButtonProp = true,
|
||||
addButtonText,
|
||||
flag,
|
||||
formHeader = true,
|
||||
helperText,
|
||||
errorMessage,
|
||||
@@ -45,11 +46,13 @@ const MultiSelectContainer = memo<MultiSelectProps>(
|
||||
onAddClick={onAddClick}
|
||||
addButton={addButtonProp}
|
||||
addButtonText={addButtonText}
|
||||
flag={flag}
|
||||
addButtonAriaLabel={
|
||||
addButtonText || t("multiSelectAddFallback")
|
||||
}
|
||||
chipSelectAriaLabel={t("chipSelect")}
|
||||
chipDeselectAriaLabel={t("chipDeselect")}
|
||||
chipMissingWordsAriaLabel={t("chipMissingWords")}
|
||||
formHeader={formHeader}
|
||||
helperText={helperText}
|
||||
errorMessage={errorMessage}
|
||||
|
||||
@@ -7,6 +7,8 @@ export interface ChipOption {
|
||||
id: string;
|
||||
label: string;
|
||||
state?: ChipStateValue;
|
||||
/** Figma Has Warning on Control / Chip. */
|
||||
hasWarning?: boolean;
|
||||
}
|
||||
|
||||
export type MultiSelectSizeValue = "s" | "m";
|
||||
@@ -49,6 +51,11 @@ export interface MultiSelectProps {
|
||||
* Text for the add button
|
||||
*/
|
||||
addButtonText?: string;
|
||||
/**
|
||||
* Figma Has Flag: short line after the add chip in the same row, with no
|
||||
* fill and no extra height.
|
||||
*/
|
||||
flag?: string;
|
||||
/**
|
||||
* Whether to show form header (label and help icon) above multi-select (Figma prop).
|
||||
* @default true
|
||||
@@ -93,7 +100,9 @@ export interface MultiSelectViewProps {
|
||||
onAddClick?: () => void;
|
||||
addButton: boolean;
|
||||
addButtonText?: string;
|
||||
flag?: string;
|
||||
addButtonAriaLabel: string;
|
||||
chipMissingWordsAriaLabel: string;
|
||||
chipSelectAriaLabel: string;
|
||||
chipDeselectAriaLabel: string;
|
||||
formHeader: boolean;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { memo } from "react";
|
||||
import Chip from "../Chip";
|
||||
import Icon from "../../asset/icon/Icon";
|
||||
import InputLabel from "../../type/InputLabel";
|
||||
import type { MultiSelectViewProps } from "./MultiSelect.types";
|
||||
|
||||
@@ -15,9 +16,11 @@ function MultiSelectView({
|
||||
onAddClick,
|
||||
addButton,
|
||||
addButtonText,
|
||||
flag,
|
||||
addButtonAriaLabel,
|
||||
chipSelectAriaLabel,
|
||||
chipDeselectAriaLabel,
|
||||
chipMissingWordsAriaLabel,
|
||||
formHeader = true,
|
||||
helperText: helperTextProp,
|
||||
errorMessage,
|
||||
@@ -94,13 +97,19 @@ function MultiSelectView({
|
||||
palette={palette}
|
||||
size={chipSize}
|
||||
disabled={chipDisabled}
|
||||
hasWarning={option.hasWarning}
|
||||
ariaLabel={
|
||||
isCustom || !option.label
|
||||
? undefined
|
||||
: (isSelected
|
||||
? chipDeselectAriaLabel
|
||||
: chipSelectAriaLabel
|
||||
).replace("{label}", option.label)
|
||||
: option.hasWarning
|
||||
? chipMissingWordsAriaLabel.replace(
|
||||
"{label}",
|
||||
option.label,
|
||||
)
|
||||
: (isSelected
|
||||
? chipDeselectAriaLabel
|
||||
: chipSelectAriaLabel
|
||||
).replace("{label}", option.label)
|
||||
}
|
||||
onClick={() => {
|
||||
if (!isCustom && !chipDisabled && onChipClick) {
|
||||
@@ -180,6 +189,22 @@ function MultiSelectView({
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
{flag ? (
|
||||
<span
|
||||
className={`inline-flex items-center gap-[var(--space-100)] text-x-small-paragraph ${
|
||||
isInverse
|
||||
? "text-[color:var(--color-content-invert-primary)]"
|
||||
: "text-[color:var(--color-content-default-primary)]"
|
||||
}`}
|
||||
>
|
||||
<Icon
|
||||
name="warning"
|
||||
size={12}
|
||||
className="shrink-0 text-current"
|
||||
/>
|
||||
{flag}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
{errorMessage ? (
|
||||
<p
|
||||
|
||||
Reference in new issue
Block a user