Skip to content

Commit

Permalink
feat: icon only button
Browse files Browse the repository at this point in the history
  • Loading branch information
craigyu committed Dec 30, 2024
1 parent 50beb53 commit db8e0ba
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 53 deletions.
75 changes: 59 additions & 16 deletions packages/@fds-design/button/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Meta } from "@storybook/react";
import { Meta, StoryObj } from "@storybook/react";
import { Button } from ".";
import { action } from "@storybook/addon-actions";
import { SpectrumButtonProps } from "@react-spectrum/button";
import { Link } from "@react-spectrum/link";
import { Tree } from "@carbon/icons-react";
import { Tree, Add, TrashCan } from "@carbon/icons-react";

export default {
const meta: Meta<SpectrumButtonProps<"button">> = {
title: "Button",
component: Button,
args: {
Expand Down Expand Up @@ -92,27 +92,28 @@ export default {
defaultValue: false,
},
},
} as Meta<SpectrumButtonProps<"button">>;
};

// Default Primary
export const Default = {
render: () => (
export default meta;

// Default Story
export const Default: StoryObj<SpectrumButtonProps<"button">> = {
args: {
children: "Click Me",
variant: "accent",
style: "fill",
isDisabled: false,
},
render: (args) => (
<>
<Link
href="https://react-spectrum.adobe.com/react-spectrum/Button.html"
target="_blank"
>
See the full documentation at React Spectrum
</Link>

<div className="story-container">
{/* Accent */}
<Button
variant="accent"
onPress={() => alert("I'm an FDS button.")}
>
Click me!
</Button>
<Button {...args} />
</div>
</>
),
Expand Down Expand Up @@ -156,6 +157,14 @@ export const Accent = {
>
Disabled
</Button>

{/* Icon only */}
<Button
variant="accent"
onPress={() => alert("I'm an FDS button.")}
>
<Add />
</Button>
</div>
),
};
Expand All @@ -171,6 +180,15 @@ export const Secondary = {
Secondary
</Button>

{/* Secondary Icon */}
<Button
variant="secondary"
onPress={() => alert("I'm a secondary button.")}
>
Secondary Icon
<Tree />
</Button>

{/* Secondary Tertiary */}
<Button
onPress={() => alert("I'm a tertiary button.")}
Expand All @@ -187,6 +205,14 @@ export const Secondary = {
>
Disabled
</Button>

{/* Icon only */}
<Button
variant="secondary"
onPress={() => alert("I'm an FDS button.")}
>
<Add />
</Button>
</div>
),
};
Expand All @@ -202,7 +228,16 @@ export const Negative = {
Negative
</Button>

{/* Secondary Tertiary */}
{/* Negative Icon */}
<Button
variant="negative"
onPress={() => alert("I'm a negative button.")}
>
Negative Icon
<Tree />
</Button>

{/* Negative Tertiary */}
<Button
onPress={() => alert("I'm a tertiary button.")}
variant="negative"
Expand All @@ -218,6 +253,14 @@ export const Negative = {
>
Disabled
</Button>

{/* Icon only */}
<Button
variant="negative"
onPress={() => alert("I'm an FDS button.")}
>
<TrashCan />
</Button>
</div>
),
};
49 changes: 38 additions & 11 deletions packages/@fds-design/button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,39 @@
import React from 'react';
import { Button as SpectrumButton, SpectrumButtonProps } from '@react-spectrum/button';
import './styles.scss';

export const Button: React.FC<SpectrumButtonProps> = (props: SpectrumButtonProps) => {
const defaultProps = {
...props,
variant: props.variant ?? 'accent',
style: props.style ?? 'fill'
}
return <SpectrumButton {...defaultProps} UNSAFE_className="fds-button"/>;
import React from "react";
import {
Button as SpectrumButton,
SpectrumButtonProps,
} from "@react-spectrum/button";
import "./styles.scss";

// Check if children is an icon-only button
function isIconOnly(children: React.ReactNode): boolean {
// Check if it's undefined, null, or an empty string
if (!children || (typeof children === "string" && children.trim() === "")) {
return true;
}

// Check if children is a single React element without text content
if (React.isValidElement(children)) {
const textContent = React.Children.toArray(children).filter(
(child) => typeof child === "string" && child.trim() !== ""
);
return textContent.length === 0; // No text, likely an icon
}

return false;
}

export const Button: React.FC<SpectrumButtonProps> = (
props: SpectrumButtonProps
) => {
// Check if it's icon-only and conditionally add the class
const className = isIconOnly(props.children) ? "fds-icon-only-button" : "fds-button";

const defaultProps = {
...props,
variant: props.variant ?? "accent",
style: props.style ?? "fill",
};

return <SpectrumButton {...defaultProps} UNSAFE_className={className} />;
};
40 changes: 40 additions & 0 deletions packages/@fds-design/button/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,43 @@
margin-left: 8px;
}
}

.fds-icon-only-button{
min-inline-size: 48px;
width: 48px;
height: 48px;
--spectrum-button-border-radius: 4px;
padding: 0;
}

body.spectrum--light .fds-icon-only-button:not([data-static-color])[data-variant="secondary"][data-style="fill"],
body.spectrum--light .fds-button:not([data-static-color])[data-variant="secondary"][data-style="fill"] {
--spectrum-button-color: var(--spectrum-gray-800);
--spectrum-button-color-hover: var(--spectrum-gray-900);
--spectrum-button-color-down: var(--spectrum-gray-900);
--spectrum-button-color-key-focus: var(--spectrum-gray-900);
}

body.spectrum--light .fds-icon-only-button:not([data-static-color])[data-variant="secondary"][data-style="fill"],
body.spectrum--light .fds-button:not([data-static-color])[data-variant="secondary"][data-style="fill"] {
--spectrum-button-text-color: var(--spectrum-gray-200);
--spectrum-button-text-color-hover: var(--spectrum-gray-300);
--spectrum-button-text-color-down: var(--spectrum-gray-400);
--spectrum-button-text-color-key-focus: var(--spectrum-gray-400);
}

body.spectrum--dark .fds-icon-only-button:not([data-static-color])[data-variant="secondary"][data-style="fill"]
body.spectrum--dark .fds-button:not([data-static-color])[data-variant="secondary"][data-style="fill"] {
--spectrum-button-color: var(--spectrum-gray-200);
--spectrum-button-color-hover: var(--spectrum-gray-300);
--spectrum-button-color-down: var(--spectrum-gray-400);
--spectrum-button-color-key-focus: var(--spectrum-gray-300);
}

body.spectrum--dark .fds-icon-only-button:not([data-static-color])[data-variant="secondary"][data-style="fill"]
body.spectrum--dark .fds-button:not([data-static-color])[data-variant="secondary"][data-style="fill"] {
--spectrum-button-text-color: var(--spectrum-gray-800);
--spectrum-button-text-color-hover: var(--spectrum-gray-900);
--spectrum-button-text-color-down: var(--spectrum-gray-900);
--spectrum-button-text-color-key-focus: var(--spectrum-gray-900);
}
27 changes: 1 addition & 26 deletions packages/fds-theme/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,6 @@ import { defineConfig } from 'vite';
import path from 'path';
import dts from 'vite-plugin-dts';

const themeHashes = {
global: 'XhWg9q',
light: 'YqfL3a',
dark: 'R-l9gW',
medium: 'rfm_fq',
large: '_1DrGeG',
};

// Generate hash based on theme
const generateScopedName = (name, theme) => {
const hash = themeHashes[theme] || themeHashes.global; // Default to global
return `${hash}_${name}`;
};

export default defineConfig({
build: {
lib: {
Expand All @@ -32,19 +18,8 @@ export default defineConfig({
},
plugins: [
dts({
outputDir: 'dist',
outDir: 'dist',
insertTypesEntry: true,
}),
],
css: {
modules: {
generateScopedName: (name, filename) => {
if (filename.includes('light')) return generateScopedName(name, 'light');
if (filename.includes('dark')) return generateScopedName(name, 'dark');
if (filename.includes('medium')) return generateScopedName(name, 'medium');
if (filename.includes('large')) return generateScopedName(name, 'large');
return generateScopedName(name, 'global');
},
},
},
});

0 comments on commit db8e0ba

Please sign in to comment.