Fix failing tests
CI Pipeline / test (20) (pull_request) Successful in 2m30s
CI Pipeline / test (18) (pull_request) Successful in 3m51s
CI Pipeline / e2e (firefox) (pull_request) Successful in 3m22s
CI Pipeline / e2e (webkit) (pull_request) Successful in 3m45s
CI Pipeline / e2e (chromium) (pull_request) Successful in 11m49s
CI Pipeline / visual-regression (pull_request) Successful in 6m48s
CI Pipeline / storybook (pull_request) Successful in 1m35s
CI Pipeline / lint (pull_request) Successful in 1m12s
CI Pipeline / build (pull_request) Successful in 1m54s
CI Pipeline / performance (pull_request) Successful in 4m6s
CI Pipeline / test (20) (pull_request) Successful in 2m30s
CI Pipeline / test (18) (pull_request) Successful in 3m51s
CI Pipeline / e2e (firefox) (pull_request) Successful in 3m22s
CI Pipeline / e2e (webkit) (pull_request) Successful in 3m45s
CI Pipeline / e2e (chromium) (pull_request) Successful in 11m49s
CI Pipeline / visual-regression (pull_request) Successful in 6m48s
CI Pipeline / storybook (pull_request) Successful in 1m35s
CI Pipeline / lint (pull_request) Successful in 1m12s
CI Pipeline / build (pull_request) Successful in 1m54s
CI Pipeline / performance (pull_request) Successful in 4m6s
This commit is contained in:
@@ -160,7 +160,7 @@ const Checkbox = memo(
|
||||
/>
|
||||
</label>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Checkbox.displayName = "Checkbox";
|
||||
|
||||
@@ -80,7 +80,7 @@ const RadioButton = ({
|
||||
onChange({ checked: true, value });
|
||||
}
|
||||
},
|
||||
[disabled, onChange, checked, value]
|
||||
[disabled, onChange, checked, value],
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -24,7 +24,7 @@ const RadioGroup = ({
|
||||
onChange({ value: optionValue });
|
||||
}
|
||||
},
|
||||
[disabled, onChange]
|
||||
[disabled, onChange],
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
+15
-17
@@ -9,10 +9,8 @@ import React, {
|
||||
useCallback,
|
||||
memo,
|
||||
} from "react";
|
||||
import ContextMenu from "./ContextMenu";
|
||||
import ContextMenuItem from "./ContextMenuItem";
|
||||
import ContextMenuSection from "./ContextMenuSection";
|
||||
import ContextMenuDivider from "./ContextMenuDivider";
|
||||
import SelectDropdown from "./SelectDropdown";
|
||||
import SelectOption from "./SelectOption";
|
||||
|
||||
const Select = forwardRef(
|
||||
(
|
||||
@@ -31,7 +29,7 @@ const Select = forwardRef(
|
||||
onChange,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
ref,
|
||||
) => {
|
||||
const generatedId = useId();
|
||||
const selectId = id || `select-${generatedId}`;
|
||||
@@ -74,7 +72,7 @@ const Select = forwardRef(
|
||||
selectRef.current.focus();
|
||||
}
|
||||
},
|
||||
[onChange]
|
||||
[onChange],
|
||||
);
|
||||
|
||||
// Handle select button click
|
||||
@@ -96,7 +94,7 @@ const Select = forwardRef(
|
||||
setIsOpen(false);
|
||||
}
|
||||
},
|
||||
[disabled, isOpen]
|
||||
[disabled, isOpen],
|
||||
);
|
||||
|
||||
const getSizeStyles = () => {
|
||||
@@ -230,14 +228,14 @@ const Select = forwardRef(
|
||||
// Handle options prop
|
||||
if (props.options && Array.isArray(props.options)) {
|
||||
const selectedOption = props.options.find(
|
||||
(option) => option.value === selectedValue
|
||||
(option) => option.value === selectedValue,
|
||||
);
|
||||
return selectedOption ? selectedOption.label : placeholder;
|
||||
}
|
||||
|
||||
// Handle children (option elements)
|
||||
const selectedOption = React.Children.toArray(children).find(
|
||||
(child) => child.props.value === selectedValue
|
||||
(child) => child.props.value === selectedValue,
|
||||
);
|
||||
return selectedOption ? selectedOption.props.children : placeholder;
|
||||
};
|
||||
@@ -294,10 +292,10 @@ const Select = forwardRef(
|
||||
ref={menuRef}
|
||||
className="absolute top-full left-0 right-0 z-50 mt-1"
|
||||
>
|
||||
<ContextMenu>
|
||||
<SelectDropdown>
|
||||
{props.options && Array.isArray(props.options)
|
||||
? props.options.map((option) => (
|
||||
<ContextMenuItem
|
||||
<SelectOption
|
||||
key={option.value}
|
||||
selected={option.value === selectedValue}
|
||||
size={size}
|
||||
@@ -306,35 +304,35 @@ const Select = forwardRef(
|
||||
}
|
||||
>
|
||||
{option.label}
|
||||
</ContextMenuItem>
|
||||
</SelectOption>
|
||||
))
|
||||
: React.Children.map(children, (child) => {
|
||||
if (child.type === "option") {
|
||||
return (
|
||||
<ContextMenuItem
|
||||
<SelectOption
|
||||
key={child.props.value}
|
||||
selected={child.props.value === selectedValue}
|
||||
size={size}
|
||||
onClick={() =>
|
||||
handleOptionSelect(
|
||||
child.props.value,
|
||||
child.props.children
|
||||
child.props.children,
|
||||
)
|
||||
}
|
||||
>
|
||||
{child.props.children}
|
||||
</ContextMenuItem>
|
||||
</SelectOption>
|
||||
);
|
||||
}
|
||||
return child;
|
||||
})}
|
||||
</ContextMenu>
|
||||
</SelectDropdown>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Select.displayName = "Select";
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
"use client";
|
||||
|
||||
import React, { forwardRef, memo } from "react";
|
||||
|
||||
const SelectDropdown = forwardRef(
|
||||
({ className = "", children, ...props }, ref) => {
|
||||
const menuClasses = `
|
||||
bg-black
|
||||
border border-[var(--color-border-default-tertiary)]
|
||||
rounded-[var(--measures-radius-medium)]
|
||||
shadow-lg
|
||||
p-[4px]
|
||||
min-w-[200px]
|
||||
max-w-[300px]
|
||||
${className}
|
||||
`
|
||||
.trim()
|
||||
.replace(/\s+/g, " ");
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={menuClasses}
|
||||
role="listbox"
|
||||
aria-label="Select an option"
|
||||
style={{ backgroundColor: "#000000" }}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
SelectDropdown.displayName = "SelectDropdown";
|
||||
|
||||
export default memo(SelectDropdown);
|
||||
@@ -0,0 +1,111 @@
|
||||
"use client";
|
||||
|
||||
import React, { forwardRef, memo, useCallback } from "react";
|
||||
|
||||
const SelectOption = forwardRef(
|
||||
(
|
||||
{
|
||||
children,
|
||||
selected = false,
|
||||
disabled = false,
|
||||
className = "",
|
||||
onClick,
|
||||
size = "medium",
|
||||
...props
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const getTextSize = () => {
|
||||
switch (size) {
|
||||
case "small":
|
||||
return "text-[10px] leading-[14px]";
|
||||
case "medium":
|
||||
return "text-[14px] leading-[20px]";
|
||||
case "large":
|
||||
return "text-[16px] leading-[24px]";
|
||||
default:
|
||||
return "text-[14px] leading-[20px]";
|
||||
}
|
||||
};
|
||||
|
||||
const itemClasses = `
|
||||
flex items-center justify-between
|
||||
px-[8px] py-[4px]
|
||||
text-[var(--color-content-default-brand-primary)]
|
||||
${getTextSize()}
|
||||
cursor-pointer
|
||||
transition-colors duration-150
|
||||
${
|
||||
selected
|
||||
? "bg-[var(--color-surface-default-secondary)] rounded-[var(--measures-radius-small)]"
|
||||
: ""
|
||||
}
|
||||
${
|
||||
disabled
|
||||
? "opacity-50 cursor-not-allowed"
|
||||
: "hover:!bg-[var(--color-surface-default-secondary)] hover:!rounded-[var(--measures-radius-small)]"
|
||||
}
|
||||
${className}
|
||||
`
|
||||
.trim()
|
||||
.replace(/\s+/g, " ");
|
||||
|
||||
const handleClick = useCallback(
|
||||
(e) => {
|
||||
if (!disabled && onClick) {
|
||||
onClick(e);
|
||||
}
|
||||
},
|
||||
[disabled, onClick],
|
||||
);
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
if (!disabled && onClick) {
|
||||
onClick(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
[disabled, onClick],
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={itemClasses}
|
||||
role="option"
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
aria-selected={selected}
|
||||
aria-disabled={disabled}
|
||||
onClick={handleClick}
|
||||
onKeyDown={handleKeyDown}
|
||||
{...props}
|
||||
>
|
||||
<div className="flex items-center gap-[8px]">
|
||||
{selected && (
|
||||
<svg
|
||||
className="w-4 h-4 text-[var(--color-content-default-brand-primary)]"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M5 13l4 4L19 7"
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
<span>{children}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
SelectOption.displayName = "SelectOption";
|
||||
|
||||
export default memo(SelectOption);
|
||||
@@ -1,90 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import Switch from "../components/Switch";
|
||||
|
||||
export default function FormsPlayground() {
|
||||
const [switchStates, setSwitchStates] = useState({
|
||||
switch1: false,
|
||||
switch2: true,
|
||||
switch3: false,
|
||||
switch4: true,
|
||||
});
|
||||
|
||||
const handleSwitchChange = (switchName) => {
|
||||
setSwitchStates((prev) => ({
|
||||
...prev,
|
||||
[switchName]: !prev[switchName],
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-[24px] space-y-[24px]">
|
||||
<h1 className="font-bricolage text-[24px]">Forms Playground</h1>
|
||||
|
||||
<section className="space-y-[12px]">
|
||||
<h2 className="font-space text-[18px]">Switch Examples</h2>
|
||||
<div
|
||||
className="max-w-[520px] space-y-[16px] bg-white p-6 rounded-lg border border-gray-200 shadow-lg"
|
||||
//style={{ backgroundColor: "white" }}
|
||||
>
|
||||
<div>
|
||||
<h3 className="font-space text-[14px] mb-[8px]">Switch States</h3>
|
||||
<div className="space-y-4">
|
||||
<Switch
|
||||
checked={switchStates.switch1}
|
||||
onChange={() => handleSwitchChange("switch1")}
|
||||
label="Switch label"
|
||||
/>
|
||||
<Switch
|
||||
checked={switchStates.switch2}
|
||||
onChange={() => handleSwitchChange("switch2")}
|
||||
label="Switch label"
|
||||
/>
|
||||
<Switch
|
||||
checked={switchStates.switch3}
|
||||
onChange={() => handleSwitchChange("switch3")}
|
||||
state="focus"
|
||||
label="Switch label"
|
||||
/>
|
||||
<Switch
|
||||
checked={switchStates.switch4}
|
||||
onChange={() => handleSwitchChange("switch4")}
|
||||
state="focus"
|
||||
label="Switch label"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="font-space text-[14px] mb-[8px]">
|
||||
Interactive Example
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<Switch
|
||||
checked={switchStates.switch1}
|
||||
onChange={() => handleSwitchChange("switch1")}
|
||||
label="Enable notifications"
|
||||
/>
|
||||
<Switch
|
||||
checked={switchStates.switch2}
|
||||
onChange={() => handleSwitchChange("switch2")}
|
||||
label="Auto-save documents"
|
||||
/>
|
||||
<Switch
|
||||
checked={switchStates.switch3}
|
||||
onChange={() => handleSwitchChange("switch3")}
|
||||
label="Dark mode"
|
||||
/>
|
||||
<Switch
|
||||
checked={switchStates.switch4}
|
||||
onChange={() => handleSwitchChange("switch4")}
|
||||
label="Email updates"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user