Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 1 addition & 3 deletions apps/dev/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ const compat = new FlatCompat({
baseDirectory: __dirname,
});

const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
];
const eslintConfig = [...compat.extends("next/core-web-vitals", "next/typescript")];

export default eslintConfig;
44 changes: 44 additions & 0 deletions apps/dev/src/components/ComponentsCheckPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ export default function ComponentsCheck() {
];

return (
<>
<Column fill padding="l" gap="xl">
<Column gap="m" maxWidth="xl">
<Grid columns={3} gap="s">
Expand Down Expand Up @@ -368,6 +369,49 @@ export default function ComponentsCheck() {
</Column>
))}
</Grid>

{/* Size Variant Tests */}
<Column padding="24" gap="16" background="neutral-alpha-weak" radius="m">
<Heading as="h2" variant="heading-default-l">Size Variants Test</Heading>

<Column gap="12">
<Text variant="body-default-m">IconButton Sizes:</Text>
<Row gap="8" vertical="center">
<IconButton size="xs" icon="refresh" />
<IconButton size="s" icon="refresh" />
<IconButton size="m" icon="refresh" />
<IconButton size="l" icon="refresh" />
<IconButton size="xl" icon="refresh" />
</Row>
<Text variant="body-default-m">IconButton Sizes (Rounded):</Text>
<Row gap="8" vertical="center">
<IconButton rounded size="xs" icon="refresh" />
<IconButton rounded size="s" icon="refresh" />
<IconButton rounded size="m" icon="refresh" />
<IconButton rounded size="l" icon="refresh" />
<IconButton rounded size="xl" icon="refresh" />
</Row>
</Column>

<Column gap="8">
<Text variant="body-default-m">Input Heights:</Text>
<Input id="test-xs" componentHeight="xs" placeholder="XS Input" />
<Input id="test-s" componentHeight="s" placeholder="S Input" />
<Input id="test-m" componentHeight="m" placeholder="M Input" />
<Input id="test-l" componentHeight="l" placeholder="L Input" />
<Input id="test-xl" componentHeight="xl" placeholder="XL Input" />
</Column>

<Column gap="8">
<Text variant="body-default-m">Textarea Heights:</Text>
<Textarea id="textarea-xs" componentHeight="xs" placeholder="XS Textarea" />
<Textarea id="textarea-s" componentHeight="s" placeholder="S Textarea" />
<Textarea id="textarea-m" componentHeight="m" placeholder="M Textarea" />
<Textarea id="textarea-l" componentHeight="l" placeholder="L Textarea" />
<Textarea id="textarea-xl" componentHeight="xl" placeholder="XL Textarea" />
</Column>
</Column>
</Column>
</>
);
}
24 changes: 14 additions & 10 deletions apps/docs/src/content/once-ui/components/toggleButton.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,29 +58,33 @@ You can attach icons to the left or right using `prefixIcon` and `suffixIcon`.

## Sizes

Available in small, medium, and large.
Available in extra small, small, medium, large, and extra large.

<CodeBlock
marginTop="16"
marginBottom="24"
preview={
<Row gap="12" vertical="center">
<ToggleButton label="Small" size="s" />
<ToggleButton label="Medium" size="m" />
<ToggleButton label="Large" size="l" />
<ToggleButton label="XS" size="xs" />
<ToggleButton label="S" size="s" />
<ToggleButton label="M" size="m" />
<ToggleButton label="L" size="l" />
<ToggleButton label="XL" size="xl" />
</Row>
}
codes={[
{
code:
`<ToggleButton label="Small" size="s" />
<ToggleButton label="Medium" size="m" />
<ToggleButton label="Large" size="l" />`,
`<ToggleButton label="XS" size="xs" />
<ToggleButton label="S" size="s" />
<ToggleButton label="M" size="m" />
<ToggleButton label="L" size="l" />
<ToggleButton label="XL" size="xl" />`,
language: "tsx",
label: "Sizes"
}
]}
/>
/>

## Variants

Expand Down Expand Up @@ -199,7 +203,7 @@ You can pass custom content to the toggle button.
["label", "ReactNode"],
["selected", "boolean", "false"],
["variant", ["ghost", "outline"], "ghost"],
["size", ["s", "m", "l"], "m"],
["size", ["xs", "s", "m", "l", "xl"], "m"],
["radius", [
"none", "top", "right", "bottom", "left",
"top-left", "top-right", "bottom-right", "bottom-left"
Expand All @@ -216,4 +220,4 @@ You can pass custom content to the toggle button.
["style"],
["...ButtonHTMLAttributes", "ButtonAttributes"],
]}
/>
/>
32 changes: 31 additions & 1 deletion apps/docs/src/content/once-ui/form-controls/input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,36 @@ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
]}
/>

## Sizes

The Input component supports five sizes: extra small, small, medium, large, and extra large.

<CodeBlock
marginTop="16"
marginBottom="24"
preview={
<Column fillWidth gap="16">
<Input id="size-xs" placeholder="Extra Small" componentHeight="xs" />
<Input id="size-s" placeholder="Small" componentHeight="s" />
<Input id="size-m" placeholder="Medium" componentHeight="m" />
<Input id="size-l" placeholder="Large" componentHeight="l" />
<Input id="size-xl" placeholder="Extra Large" componentHeight="xl" />
</Column>
}
codes={[
{
code:
`<Input placeholder="Extra Small" componentHeight="xs" />
<Input placeholder="Small" componentHeight="s" />
<Input placeholder="Medium" componentHeight="m" />
<Input placeholder="Large" componentHeight="l" />
<Input placeholder="Extra Large" componentHeight="xl" />`,
language: "tsx",
label: "Sizes"
}
]}
/>

## NumberInput

The `NumberInput` component provides a specialized input for numeric values with increment and decrement buttons. It supports min, max, and step values to control the range and increments.
Expand Down Expand Up @@ -425,7 +455,7 @@ You can use the `radius` prop to apply custom radius to sides or corners. It wor
["id", "string"],
["label", "string"],
["placeholder", "string"],
["height", ["s", "m"], "m"],
["componentHeight", ["xs", "s", "m", "l", "xl"], "m"],
["error", "boolean", "false"],
["errorMessage", "ReactNode"],
["description", "ReactNode"],
Expand Down
31 changes: 31 additions & 0 deletions apps/docs/src/content/once-ui/form-controls/textarea.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,36 @@ const handleChange = (e) => {
]}
/>

## Sizes

The Textarea component supports five sizes: extra small, small, medium, large, and extra large.

<CodeBlock
marginTop="16"
marginBottom="24"
preview={
<Column fillWidth gap="16">
<Textarea id="size-xs" placeholder="Extra Small" componentHeight="xs" />
<Textarea id="size-s" placeholder="Small" componentHeight="s" />
<Textarea id="size-m" placeholder="Medium" componentHeight="m" />
<Textarea id="size-l" placeholder="Large" componentHeight="l" />
<Textarea id="size-xl" placeholder="Extra Large" componentHeight="xl" />
</Column>
}
codes={[
{
code:
`<Textarea placeholder="Extra Small" componentHeight="xs" />
<Textarea placeholder="Small" componentHeight="s" />
<Textarea placeholder="Medium" componentHeight="m" />
<Textarea placeholder="Large" componentHeight="l" />
<Textarea placeholder="Extra Large" componentHeight="xl" />`,
language: "tsx",
label: "Sizes"
}
]}
/>

## Validation

Use the `validate` prop to add custom validation to the `Textarea`.
Expand Down Expand Up @@ -329,6 +359,7 @@ const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
["id", "string"],
["label", "string"],
["placeholder", "string"],
["componentHeight", ["xs", "s", "m", "l", "xl"], "m"],
["lines", ["number", "auto"], "3"],
["error", "boolean", "false"],
["errorMessage", "ReactNode"],
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
],
"scripts": {
"dev": "turbo dev",
"build": "turbo build --filter=docs..."
"build": "turbo build --filter=@once-ui-system/docs...",
"format": "pnpm -r --if-present run format && pnpm -r --if-present run biome-write"
},
"engines": {
"node": "20.x"
Expand All @@ -16,4 +17,4 @@
"devDependencies": {
"turbo": "^2.5.6"
}
}
}
13 changes: 10 additions & 3 deletions packages/core/src/components/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface ContextMenuProps {
isOpen?: boolean;
onOpenChange?: (isOpen: boolean) => void;
selectedOption?: string;
disabled?: boolean;
}

const ContextMenu = forwardRef<HTMLDivElement, ContextMenuProps>(
Expand All @@ -46,6 +47,7 @@ const ContextMenu = forwardRef<HTMLDivElement, ContextMenuProps>(
maxWidth,
fillWidth = false,
placement = "bottom-end",
disabled = false,
className,
style,
...rest
Expand Down Expand Up @@ -82,6 +84,8 @@ const ContextMenu = forwardRef<HTMLDivElement, ContextMenuProps>(

const handleContextMenu = useCallback(
(e: ReactMouseEvent) => {
if (disabled) return;

e.preventDefault();
e.stopPropagation();

Expand All @@ -91,12 +95,14 @@ const ContextMenu = forwardRef<HTMLDivElement, ContextMenuProps>(
// Open the dropdown
handleOpenChange(true);
},
[handleOpenChange],
[disabled, handleOpenChange],
);

// Handle click events for MacBook support (Control+click)
const handleClick = useCallback(
(e: ReactMouseEvent) => {
if (disabled) return;

// Check if it's a control+click (common right-click equivalent on Mac)
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
Expand All @@ -109,7 +115,7 @@ const ContextMenu = forwardRef<HTMLDivElement, ContextMenuProps>(
handleOpenChange(true);
}
},
[handleOpenChange],
[disabled, handleOpenChange],
);

// Close dropdown when clicking outside
Expand Down Expand Up @@ -297,7 +303,8 @@ const ContextMenu = forwardRef<HTMLDivElement, ContextMenuProps>(
onContextMenu={handleContextMenu}
onClick={handleClick}
className={className || ""}
style={style}
style={{...style, opacity: disabled ? 0.6 : undefined}}
aria-disabled={disabled}
>
{children}
{isDropdownOpen &&
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/components/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ interface DropdownProps extends Omit<React.ComponentProps<typeof Row>, "onSelect
children?: ReactNode;
onEscape?: () => void;
onSelect?: (event: string) => void;
disabled?: boolean;
}

const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(
({ selectedOption, className, children, onEscape, onSelect, ...flex }, ref) => {
({ selectedOption, className, children, onEscape, onSelect, disabled = false, ...flex }, ref) => {
const handleSelect = (event: SyntheticEvent<HTMLDivElement>) => {
if (disabled) return;

// Only handle clicks on elements that have a data-value attribute
const target = event.target as HTMLElement;
const value =
Expand All @@ -33,6 +36,9 @@ const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(
border="neutral-medium"
background="surface"
overflow="hidden"
className={disabled ? "cursor-not-allowed" : undefined}
style={{ opacity: disabled ? 0.6 : undefined }}
aria-disabled={disabled}
{...flex}
>
<Column flex={1} overflowY="auto" gap="2">
Expand Down
14 changes: 14 additions & 0 deletions packages/core/src/components/IconButton.module.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
.xs {
min-height: var(--static-space-20);
min-width: var(--static-space-20);
height: var(--static-space-20);
width: var(--static-space-20);
}

.s {
min-height: var(--static-space-24);
min-width: var(--static-space-24);
Expand All @@ -17,4 +24,11 @@
min-width: var(--static-space-40);
height: var(--static-space-40);
width: var(--static-space-40);
}

.xl {
min-height: var(--static-space-48);
min-width: var(--static-space-48);
height: var(--static-space-48);
width: var(--static-space-48);
}
Loading