From 1dff26e8ac2aa67f436a76d146ea0a5412258023 Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Thu, 7 Aug 2025 16:12:52 +0200 Subject: [PATCH 1/5] finalize Fab component with size and color props, token support, and default icon --- package-lock.json | 10 + package.json | 1 + src/App.tsx | 6 +- src/components/common/atoms/Fab/Fab.tsx | 53 ++++- src/components/common/atoms/Fab/index.ts | 3 + src/components/common/atoms/Fab/styled.ts | 73 ++++-- src/core/theme.ts | 278 +++++++++++----------- src/core/tokens.ts | 103 ++++---- src/main.tsx | 23 +- 9 files changed, 323 insertions(+), 227 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3eec3ee..ab81a5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "fs": "^0.0.1-security", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-icons": "^5.5.0", "react-router": "^7.7.1" }, "devDependencies": { @@ -3512,6 +3513,15 @@ "react": "^19.1.0" } }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index a874ef1..7365886 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "fs": "^0.0.1-security", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-icons": "^5.5.0", "react-router": "^7.7.1" }, "devDependencies": { diff --git a/src/App.tsx b/src/App.tsx index fe3e326..6d97159 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,19 +1,15 @@ - import './App.css' import { Typography } from './core/typography' function App() { - - return ( <> - + Welcome to React Vite Template This is a simple template to get you started with React and Vite. - ) } diff --git a/src/components/common/atoms/Fab/Fab.tsx b/src/components/common/atoms/Fab/Fab.tsx index e8adb8b..cc454ed 100644 --- a/src/components/common/atoms/Fab/Fab.tsx +++ b/src/components/common/atoms/Fab/Fab.tsx @@ -1,15 +1,48 @@ -import type { FC } from "react"; -import * as S from "./styled"; +import type { FC } from 'react' +import * as S from './styled' +import { MdAdd } from 'react-icons/md' -export type FabColor = "primary" | "secondary" | "danger" | "success" | "info"; +export type FabBgColor = + | 'primary' + | 'secondary' + | 'danger' + | 'success' + | 'warning' +export type FabTextColor = 'primary' | 'secondary' | 'white' +export type Fabsize = 'SMALL' | 'MEDIUM' | 'LARGE' type Props = { - onClick: () => void; - color?: FabColor; -}; + onClick: () => void + bgColor?: FabBgColor + textColor?: FabTextColor + size?: Fabsize + position?: 'absolute' | 'fixed' | 'relative' + bottom?: number + right?: number + top?: number + left?: number + zIndex?: number +} -const Fab: FC = ({ onClick, color = "primary" }) => { - return ; -}; +const Fab: FC = ({ + onClick, + bgColor = 'primary', + textColor = 'white', + size = 'MEDIUM', + ...positioning +}) => { + return ( + + + + ) +} -export default Fab; +export default Fab diff --git a/src/components/common/atoms/Fab/index.ts b/src/components/common/atoms/Fab/index.ts index e69de29..a1e7b23 100644 --- a/src/components/common/atoms/Fab/index.ts +++ b/src/components/common/atoms/Fab/index.ts @@ -0,0 +1,3 @@ +import Fab from './Fab' + +export default Fab diff --git a/src/components/common/atoms/Fab/styled.ts b/src/components/common/atoms/Fab/styled.ts index 64778e6..a441c80 100644 --- a/src/components/common/atoms/Fab/styled.ts +++ b/src/components/common/atoms/Fab/styled.ts @@ -1,17 +1,60 @@ import styled from '@emotion/styled' +import type { FabBgColor, Fabsize } from './Fab' +import type { FabTextColor } from './Fab' +import tokens from '../../../../core/tokens' -export const Container = styled.div<{ - position?: 'absolute' | 'fixed' | 'relative' - bottom?: number - right?: number - top?: number - left?: number - zIndex?: number -}>` - position: ${({ position }) => position ?? 'fixed'}; - bottom: ${({ bottom }) => bottom ?? 20}px; - right: ${({ right }) => right ?? 20}px; - top: ${({ top }) => top ?? 'auto'}; - left: ${({ left }) => left ?? 'auto'}; - z-index: ${({ zIndex }) => zIndex ?? 1000}; -`; +export const Container = styled.button<{ + bgColor: FabBgColor + textColor: FabTextColor + size: Fabsize + position?: 'absolute' | 'fixed' | 'relative' + bottom?: number + right?: number + top?: number + left?: number + zIndex?: number +}>( + ({ + theme, + bgColor, + textColor, + size, + position, + bottom, + right, + top, + left, + zIndex, + }) => ({ + position: position ?? 'fixed', + bottom: bottom ?? 'auto', + right: right ?? 'auto', + top: top ?? tokens.padding.CONTAINER, + left: left ?? tokens.padding.CONTAINER, + zIndex: zIndex ?? 1000, + backgroundColor: theme.colors[bgColor], + color: theme.colors.text[textColor], + width: tokens.fabSize[size], + height: tokens.fabSize[size], + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + border: 'none', + borderRadius: tokens.borderRadius.ROUND, + cursor: 'pointer', + boxShadow: theme.colors.boxShadow, + padding: tokens.padding.ZERO, + fontWeight: tokens.text.fontWeight.semiBold, + lineHeight: 0, + + svg: { + width: tokens.size.LARGE, + height: tokens.size.LARGE, + }, + + '&:focus, &:focus-visible': { + outline: 'none !important', + boxShadow: 'none !important', + }, + }) +) diff --git a/src/core/theme.ts b/src/core/theme.ts index 82042e1..65ea1ef 100644 --- a/src/core/theme.ts +++ b/src/core/theme.ts @@ -1,184 +1,184 @@ const neutrals = { - black: '#0F0F0F', - blackOpacity: '#00000010', - grayOpacity: '#D1D5DBB3', - white: '#FFFFFF', - whiteOpacity: '#FFFFFFE6', + black: '#0F0F0F', + blackOpacity: '#00000010', + grayOpacity: '#D1D5DBB3', + white: '#FFFFFF', + whiteOpacity: '#FFFFFFE6', } const brandColors = { - primary: '#', - secondary: '#', - tertiary: '#' + primary: '#f8485e', + secondary: '#3c3c3a', + tertiary: '#fca2ae', } const background = { - primaryGrey: '#EFEFE9', - secondaryGrey: '#F5F5F5', - tertiaryGrey: '#CCCCCC', + primaryGrey: '#EFEFE9', + secondaryGrey: '#F5F5F5', + tertiaryGrey: '#CCCCCC', } const systemColors = { - error: '#', - danger: '#', - success: '#', - warning: '#', + error: '#D32F2F', + danger: '#C62828', + success: '#2E7D32', + warning: '#ED6C02', } const textColors = { - primary: '#000000E5', - secondary: '#0000009E', - disabled: '#0000006D', - iconColor: '#3C4A63', - black: neutrals.black, + primary: '#000000E5', + secondary: '#0000009E', + disabled: '#0000006D', + iconColor: '#3C4A63', + black: neutrals.black, + white: neutrals.white, } const hover = { - primaryGrey: '#EFEFE966', + primaryGrey: '#EFEFE966', } - const brandPalette = { - // Primary - primary: brandColors.primary, - secondary: brandColors.secondary, - tertiary: brandColors.tertiary, - - // Background - primaryBackground: background.primaryGrey, - secondaryBackground: background.secondaryGrey, - tertiaryBackground: background.tertiaryGrey, - - // System colors - error: systemColors.error, - danger: systemColors.danger, - success: systemColors.success, - warning: systemColors.warning, - - // Neutrals - black: neutrals.black, - white: neutrals.white, - boxShadow: neutrals.blackOpacity, - scrollBar: neutrals.grayOpacity, - - // Text - text: { - primary: textColors.primary, - secondary: textColors.secondary, - disabled: textColors.disabled, - iconColor: textColors.iconColor, - black: textColors.black, - }, - - - // Hover - hoverPrimaryBackground: hover.primaryGrey, - hoverIconDisabled: background.tertiaryGrey, - - // Buttons - primaryButton: brandColors.primary, + // Primary + primary: brandColors.primary, + secondary: brandColors.secondary, + tertiary: brandColors.tertiary, + + // Background + primaryBackground: background.primaryGrey, + secondaryBackground: background.secondaryGrey, + tertiaryBackground: background.tertiaryGrey, + + // System colors + error: systemColors.error, + danger: systemColors.danger, + success: systemColors.success, + warning: systemColors.warning, + + // Neutrals + black: neutrals.black, + white: neutrals.white, + boxShadow: neutrals.blackOpacity, + scrollBar: neutrals.grayOpacity, + + // Text + text: { + primary: textColors.primary, + secondary: textColors.secondary, + disabled: textColors.disabled, + iconColor: textColors.iconColor, + black: textColors.black, + white: textColors.white, + }, + + // Hover + hoverPrimaryBackground: hover.primaryGrey, + hoverIconDisabled: background.tertiaryGrey, + + // Buttons + primaryButton: brandColors.primary, } type ButtonVariantStyle = { - background: string - text: string - hover: string - border: string + background: string + text: string + hover: string + border: string } type ButtonStyles = { - - [key: string]: { - filled: ButtonVariantStyle - outlined: ButtonVariantStyle - } + [key: string]: { + filled: ButtonVariantStyle + outlined: ButtonVariantStyle + } } type ThemeConfig = { - colors: { - primary: string - secondary: string - tertiary: string + colors: { + primary: string + secondary: string + tertiary: string - primaryBackground: string - secondaryBackground: string - tertiaryBackground: string + primaryBackground: string + secondaryBackground: string + tertiaryBackground: string - error: string - danger: string - success: string - warning: string + error: string + danger: string + success: string + warning: string - black: string - white: string + black: string + white: string - boxShadow: string - scrollBar: string + boxShadow: string + scrollBar: string - text: { - primary: string - secondary: string - disabled: string - iconColor: string - } - - } - typography: { - fontFamily?: string - fontSize?: number + text: { + primary: string + secondary: string + disabled: string + iconColor: string + white: string } - buttonStyles: ButtonStyles + } + typography: { + fontFamily?: string + fontSize?: number + } + buttonStyles: ButtonStyles } const light: ThemeConfig = { - colors: { - ...brandPalette, - + colors: { + ...brandPalette, + }, + typography: { + fontFamily: 'Inter, sans-serif', + fontSize: 16, + }, + buttonStyles: { + primary: { + filled: { + background: brandPalette.primaryButton, + text: brandPalette.white, + border: 'none', + hover: brandPalette.primaryButton, + }, + outlined: { + background: 'transparent', + text: brandPalette.primaryButton, + border: `inset 0 0 0 1px ${brandPalette.primaryButton}`, + hover: brandPalette.primaryButton, + }, }, - typography: { - fontFamily: 'Inter, sans-serif', - fontSize: 16, - }, - buttonStyles: { - primary: { - filled: { - background: brandPalette.primaryButton, - text: brandPalette.white, - border: 'none', - hover: brandPalette.primaryButton, - }, - outlined: { - background: 'transparent', - text: brandPalette.primaryButton, - border: `inset 0 0 0 1px ${brandPalette.primaryButton}`, - hover: brandPalette.primaryButton, - }, - }, - danger: { - filled: { - text: brandPalette.white, - border: 'none', - background: brandPalette.danger, - hover: brandPalette.danger, - }, - outlined: { - background: 'transparent', - text: brandPalette.danger, - border: `inset 0 0 0 1px ${brandPalette.danger}`, - hover: brandPalette.danger, - }, - }, + danger: { + filled: { + text: brandPalette.white, + border: 'none', + background: brandPalette.danger, + hover: brandPalette.danger, + }, + outlined: { + background: 'transparent', + text: brandPalette.danger, + border: `inset 0 0 0 1px ${brandPalette.danger}`, + hover: brandPalette.danger, + }, }, + }, } export const themes = { - light, + light, } declare module '@emotion/react' { - export interface Theme { - colors: ThemeConfig['colors'] - typography: ThemeConfig['typography'] - buttonStyles: ThemeConfig['buttonStyles'] - } -} \ No newline at end of file + export interface Theme { + colors: ThemeConfig['colors'] + typography: ThemeConfig['typography'] + buttonStyles: ThemeConfig['buttonStyles'] + } +} + +export default themes.light diff --git a/src/core/tokens.ts b/src/core/tokens.ts index 6c976f7..e4b8289 100644 --- a/src/core/tokens.ts +++ b/src/core/tokens.ts @@ -1,78 +1,85 @@ // https://dev.to/gerryleonugroho/responsive-design-breakpoints-2025-playbook-53ih#:~:text=Breakpoints%20are%20specific%20screen%20widths,keeping%20users%20engaged%20and%20satisfied. const breakpoints = { - laptop: '1600px', - tablet: '911px', - tabletLarge: '1025px', - phone: '480px', + laptop: '1600px', + tablet: '911px', + tabletLarge: '1025px', + phone: '480px', } const text = { - lineHeight: 6, - fontSize: { - SMALL: 14, - BASELINE: 16, - MEDIUM: 20, - LARGE: 24, - HEADING_SMALL: 32, - HEADING_MEDIUM: 48, - HEADING_LARGE: 64, - }, - fontWeight: { - light: 300, - normal: 400, - medium: 500, - semiBold: 600, - bold: 700, - }, + lineHeight: 6, + fontSize: { + SMALL: 14, + BASELINE: 16, + MEDIUM: 20, + LARGE: 24, + HEADING_SMALL: 32, + HEADING_MEDIUM: 48, + HEADING_LARGE: 64, + }, + fontWeight: { + light: 300, + normal: 400, + medium: 500, + semiBold: 600, + bold: 700, + }, } const padding = { - ZERO: 0, - BASELINE: 8, - CONTAINER: 40, + ZERO: 0, + BASELINE: 8, + CONTAINER: 40, } const borderRadius = { - ZERO: 0, - BASELINE: 8, - SMALL: 16, - MEDIUM: 24, - LARGE: 32, - ROUND: 50, + ZERO: 0, + BASELINE: 8, + SMALL: 16, + MEDIUM: 24, + LARGE: 32, + ROUND: 50, } const margin = { - ZERO: 0, - BASELINE: 8, + ZERO: 0, + BASELINE: 8, } const spacing = { - ZERO: 0, - BASELINE: 8, + ZERO: 0, + BASELINE: 8, } const gap = { - BASELINE: 8, - LARGE: 16, + BASELINE: 8, + LARGE: 16, } const size = { - BASELINE: 8, - SMALL: 16, - MEDIUM: 24, - LARGE: 32, + BASELINE: 8, + SMALL: 16, + MEDIUM: 24, + LARGE: 32, +} + +const fabSize = { + SMALL: 40, + MEDIUM: 56, + LARGE: 72, } const tokens = { - breakpoints, - gap, - padding, - margin, - spacing, - text, - borderRadius, - size, + breakpoints, + gap, + padding, + margin, + spacing, + text, + borderRadius, + size, + fabSize, } export default tokens diff --git a/src/main.tsx b/src/main.tsx index c353f6f..17f8167 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,17 +2,20 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App.tsx' -import { BrowserRouter, Route, Routes } from "react-router"; - +import { BrowserRouter, Route, Routes } from 'react-router' +import { ThemeProvider } from '@emotion/react' +import theme from './core/theme.ts' createRoot(document.getElementById('root')!).render( - - - //TODO: Add more routes that takes you to different template pages - } /> - About Page} /> - - - , + + + + {/* TODO: Add more routes that takes you to different template pages */} + } /> + About Page} /> + + + + ) From 69da1ed004b83c2d71615b11a295ee91c93f845b Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Mon, 11 Aug 2025 15:42:57 +0200 Subject: [PATCH 2/5] Add info as FabBgColor again --- src/components/common/atoms/Fab/Fab.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/common/atoms/Fab/Fab.tsx b/src/components/common/atoms/Fab/Fab.tsx index cc454ed..2ca439d 100644 --- a/src/components/common/atoms/Fab/Fab.tsx +++ b/src/components/common/atoms/Fab/Fab.tsx @@ -8,6 +8,7 @@ export type FabBgColor = | 'danger' | 'success' | 'warning' + | 'info' export type FabTextColor = 'primary' | 'secondary' | 'white' export type Fabsize = 'SMALL' | 'MEDIUM' | 'LARGE' From f080da0e03de49a3a3b5a7239ddea27b72684785 Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Mon, 11 Aug 2025 15:45:45 +0200 Subject: [PATCH 3/5] Update: Fabsize props to lower case. --- src/components/common/atoms/Fab/Fab.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/common/atoms/Fab/Fab.tsx b/src/components/common/atoms/Fab/Fab.tsx index 2ca439d..e302bbd 100644 --- a/src/components/common/atoms/Fab/Fab.tsx +++ b/src/components/common/atoms/Fab/Fab.tsx @@ -10,7 +10,7 @@ export type FabBgColor = | 'warning' | 'info' export type FabTextColor = 'primary' | 'secondary' | 'white' -export type Fabsize = 'SMALL' | 'MEDIUM' | 'LARGE' +export type Fabsize = 'small' | 'medium' | 'large' type Props = { onClick: () => void @@ -29,7 +29,7 @@ const Fab: FC = ({ onClick, bgColor = 'primary', textColor = 'white', - size = 'MEDIUM', + size = 'medium', ...positioning }) => { return ( From 257b4af22cf0b6c8b9fcbd0ada2c73b09ed97516 Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Mon, 11 Aug 2025 18:31:35 +0200 Subject: [PATCH 4/5] Add color for info. Change fabSize token to small capitals. Update secondary textColor to white. --- src/App.tsx | 6 ++++++ src/components/common/atoms/Fab/Fab.tsx | 4 ++-- src/core/theme.ts | 5 ++++- src/core/tokens.ts | 6 +++--- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 6d97159..e5e78d2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,9 +1,15 @@ import './App.css' +import Fab from './components/common/atoms/Fab' import { Typography } from './core/typography' function App() { return ( <> + Welcome to React Vite Template diff --git a/src/components/common/atoms/Fab/Fab.tsx b/src/components/common/atoms/Fab/Fab.tsx index e302bbd..35d9567 100644 --- a/src/components/common/atoms/Fab/Fab.tsx +++ b/src/components/common/atoms/Fab/Fab.tsx @@ -9,7 +9,7 @@ export type FabBgColor = | 'success' | 'warning' | 'info' -export type FabTextColor = 'primary' | 'secondary' | 'white' +export type FabTextColor = 'primary' | 'secondary' export type Fabsize = 'small' | 'medium' | 'large' type Props = { @@ -28,7 +28,7 @@ type Props = { const Fab: FC = ({ onClick, bgColor = 'primary', - textColor = 'white', + textColor = 'secondary', size = 'medium', ...positioning }) => { diff --git a/src/core/theme.ts b/src/core/theme.ts index 65ea1ef..e1f49d6 100644 --- a/src/core/theme.ts +++ b/src/core/theme.ts @@ -23,11 +23,12 @@ const systemColors = { danger: '#C62828', success: '#2E7D32', warning: '#ED6C02', + info: '#0288D1', } const textColors = { primary: '#000000E5', - secondary: '#0000009E', + secondary: '#FFFFFF', disabled: '#0000006D', iconColor: '#3C4A63', black: neutrals.black, @@ -54,6 +55,7 @@ const brandPalette = { danger: systemColors.danger, success: systemColors.success, warning: systemColors.warning, + info: systemColors.info, // Neutrals black: neutrals.black, @@ -107,6 +109,7 @@ type ThemeConfig = { danger: string success: string warning: string + info: string black: string white: string diff --git a/src/core/tokens.ts b/src/core/tokens.ts index e4b8289..59c26f2 100644 --- a/src/core/tokens.ts +++ b/src/core/tokens.ts @@ -65,9 +65,9 @@ const size = { } const fabSize = { - SMALL: 40, - MEDIUM: 56, - LARGE: 72, + small: 40, + medium: 56, + large: 72, } const tokens = { From e5bce5713a5dca4c88a8c6a121ac83808562830c Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Tue, 12 Aug 2025 09:51:33 +0200 Subject: [PATCH 5/5] Refactor Fab placement promps and reduce opptional props for simpler use. Change to Fab element to DIV. --- src/App.tsx | 6 --- src/components/common/atoms/Fab/Fab.tsx | 31 ++++++------- src/components/common/atoms/Fab/styled.ts | 56 ++++++++--------------- src/core/tokens.ts | 6 +-- 4 files changed, 38 insertions(+), 61 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index e5e78d2..6d97159 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,15 +1,9 @@ import './App.css' -import Fab from './components/common/atoms/Fab' import { Typography } from './core/typography' function App() { return ( <> - Welcome to React Vite Template diff --git a/src/components/common/atoms/Fab/Fab.tsx b/src/components/common/atoms/Fab/Fab.tsx index 35d9567..6839f8d 100644 --- a/src/components/common/atoms/Fab/Fab.tsx +++ b/src/components/common/atoms/Fab/Fab.tsx @@ -1,4 +1,3 @@ -import type { FC } from 'react' import * as S from './styled' import { MdAdd } from 'react-icons/md' @@ -10,35 +9,35 @@ export type FabBgColor = | 'warning' | 'info' export type FabTextColor = 'primary' | 'secondary' -export type Fabsize = 'small' | 'medium' | 'large' +export type Fabsize = 'sm' | 'md' | 'lg' +export type FabPlacement = + | 'bottom-right' + | 'bottom-left' + | 'top-right' + | 'top-left' type Props = { onClick: () => void bgColor?: FabBgColor textColor?: FabTextColor size?: Fabsize - position?: 'absolute' | 'fixed' | 'relative' - bottom?: number - right?: number - top?: number - left?: number - zIndex?: number + placement?: FabPlacement } -const Fab: FC = ({ +function Fab({ onClick, bgColor = 'primary', textColor = 'secondary', - size = 'medium', - ...positioning -}) => { + size = 'md', + placement = 'top-left', +}: Props) { return ( diff --git a/src/components/common/atoms/Fab/styled.ts b/src/components/common/atoms/Fab/styled.ts index a441c80..802e420 100644 --- a/src/components/common/atoms/Fab/styled.ts +++ b/src/components/common/atoms/Fab/styled.ts @@ -1,41 +1,24 @@ import styled from '@emotion/styled' -import type { FabBgColor, Fabsize } from './Fab' +import type { FabBgColor, Fabsize, FabPlacement } from './Fab' import type { FabTextColor } from './Fab' import tokens from '../../../../core/tokens' -export const Container = styled.button<{ - bgColor: FabBgColor - textColor: FabTextColor - size: Fabsize - position?: 'absolute' | 'fixed' | 'relative' - bottom?: number - right?: number - top?: number - left?: number - zIndex?: number -}>( - ({ - theme, - bgColor, - textColor, - size, - position, - bottom, - right, - top, - left, - zIndex, - }) => ({ - position: position ?? 'fixed', - bottom: bottom ?? 'auto', - right: right ?? 'auto', - top: top ?? tokens.padding.CONTAINER, - left: left ?? tokens.padding.CONTAINER, - zIndex: zIndex ?? 1000, - backgroundColor: theme.colors[bgColor], - color: theme.colors.text[textColor], - width: tokens.fabSize[size], - height: tokens.fabSize[size], +export const Container = styled.div<{ + $bgColor: FabBgColor + $textColor: FabTextColor + $size: Fabsize + $placement: FabPlacement +}>(({ theme, $bgColor, $textColor, $size, $placement }) => { + const pos = $placement || 'bottom-right' + return { + position: 'fixed', + ...(pos.includes('top') ? { top: 16 } : { bottom: 16 }), + ...(pos.includes('right') ? { right: 16 } : { left: 16 }), + + backgroundColor: theme.colors[$bgColor], + color: theme.colors.text[$textColor], + width: tokens.fabSize[$size], + height: tokens.fabSize[$size], display: 'flex', alignItems: 'center', justifyContent: 'center', @@ -46,6 +29,7 @@ export const Container = styled.button<{ padding: tokens.padding.ZERO, fontWeight: tokens.text.fontWeight.semiBold, lineHeight: 0, + zIndex: 1000, svg: { width: tokens.size.LARGE, @@ -56,5 +40,5 @@ export const Container = styled.button<{ outline: 'none !important', boxShadow: 'none !important', }, - }) -) + } +}) diff --git a/src/core/tokens.ts b/src/core/tokens.ts index 59c26f2..6f20ac3 100644 --- a/src/core/tokens.ts +++ b/src/core/tokens.ts @@ -65,9 +65,9 @@ const size = { } const fabSize = { - small: 40, - medium: 56, - large: 72, + sm: 40, + md: 56, + lg: 72, } const tokens = {