diff --git a/example/package.json b/example/package.json index 1f4102b..44f4129 100644 --- a/example/package.json +++ b/example/package.json @@ -14,7 +14,7 @@ "dependencies": { "@emotion/react": "link:../node_modules/@emotion/react", "@emotion/styled": "link:../node_modules/@emotion/styled", - "@floating-ui/react-dom-interactions": "link:../node_modules/@floating-ui/react-dom-interactions", + "@floating-ui/react": "link:../node_modules/@floating-ui/react", "@solved-ac/ui-react": "link:..", "@testing-library/jest-dom": "link:../node_modules/@testing-library/jest-dom", "@testing-library/react": "link:../node_modules/@testing-library/react", diff --git a/package.json b/package.json index 6cdf71a..2c60927 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "peerDependencies": { "@emotion/react": ">=11", "@emotion/styled": ">=11", - "@floating-ui/react-dom-interactions": "^0.13.3", - "framer-motion": "6.x", + "@floating-ui/react": "^0.24.3", + "framer-motion": ">=6", "react": ">=17", "react-dom": ">=17" }, @@ -42,7 +42,7 @@ "@babel/plugin-proposal-optional-chaining": "^7.16.7", "@emotion/react": "^11.1.5", "@emotion/styled": "^11.1.5", - "@floating-ui/react-dom-interactions": "^0.13.3", + "@floating-ui/react": "^0.24.3", "@tabler/icons-react": "^2.11.0", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.5.0", diff --git a/src/components/$Table/Cell.tsx b/src/components/$Table/Cell.tsx index 37ce03d..c5af95d 100644 --- a/src/components/$Table/Cell.tsx +++ b/src/components/$Table/Cell.tsx @@ -15,6 +15,7 @@ const paddingMap = { interface CellContainerProps { padding: 'none' | 'dense' | 'normal' | 'wide' + verticalAlign: 'top' | 'middle' | 'bottom' numeric: boolean header: boolean } @@ -28,6 +29,7 @@ const CellContainer = styled.td` display: table-cell; border-bottom: ${({ theme }) => theme.styles.border()}; ${({ padding }) => paddingMap[padding]} + ${({ verticalAlign }) => `vertical-align: ${verticalAlign};`} ${({ numeric }) => numeric && "text-align: right; font-feature-settings: 'tnum';"} ${({ header }) => header && whenHeader} @@ -35,6 +37,7 @@ const CellContainer = styled.td` export interface CellProps { padding?: 'none' | 'dense' | 'normal' | 'wide' + verticalAlign?: 'top' | 'middle' | 'bottom' header?: boolean numeric?: boolean } @@ -45,6 +48,7 @@ export const Cell: PC<'td', CellProps> = forwardRefWithGenerics( const tableRowGroupContext = useContext(TableRowGroupContext) const { padding = tableContext.padding, + verticalAlign = tableRowGroupContext.verticalAlign, header = tableRowGroupContext.header, as, numeric = false, @@ -56,6 +60,7 @@ export const Cell: PC<'td', CellProps> = forwardRefWithGenerics( return ( ` export interface RowProps { header?: boolean padding?: 'none' | 'dense' | 'normal' | 'wide' + verticalAlign?: 'top' | 'middle' | 'bottom' } export const Row: PC<'tr', RowProps> = forwardRefWithGenerics( @@ -24,12 +25,15 @@ export const Row: PC<'tr', RowProps> = forwardRefWithGenerics( const { header = false, padding = tableContext.padding, + verticalAlign = tableContext.verticalAlign, as = 'tr', ...rest } = props return ( - + ) diff --git a/src/components/$Table/TableContext.ts b/src/components/$Table/TableContext.ts index e67ea2c..97c253a 100644 --- a/src/components/$Table/TableContext.ts +++ b/src/components/$Table/TableContext.ts @@ -3,9 +3,11 @@ import React from 'react' export interface TableContextProps { padding: 'none' | 'dense' | 'normal' | 'wide' sticky: boolean | number | string + verticalAlign: 'top' | 'middle' | 'bottom' } export const TableContext = React.createContext({ padding: 'normal', sticky: false, + verticalAlign: 'top', }) diff --git a/src/components/$Table/TableHead.tsx b/src/components/$Table/TableHead.tsx index 9c2f332..e842db2 100644 --- a/src/components/$Table/TableHead.tsx +++ b/src/components/$Table/TableHead.tsx @@ -28,15 +28,21 @@ const TableHeadContainer = styled.thead` export interface TableHeadProps { sticky?: boolean | number | string + verticalAlign?: 'top' | 'middle' | 'bottom' } export const TableHead: PC<'thead', TableHeadProps> = forwardRefWithGenerics( (props: PP, ref?: PR) => { const tableContext = useContext(TableContext) - const { sticky = tableContext.sticky, as = 'thead', ...rest } = props + const { + sticky = tableContext.sticky, + verticalAlign = tableContext.verticalAlign, + as = 'thead', + ...rest + } = props return ( - + ) diff --git a/src/components/$Table/TableRowGroupContext.ts b/src/components/$Table/TableRowGroupContext.ts index 9169fd5..0b98800 100644 --- a/src/components/$Table/TableRowGroupContext.ts +++ b/src/components/$Table/TableRowGroupContext.ts @@ -2,9 +2,11 @@ import React from 'react' export interface TableRowGroupContextProps { header: boolean + verticalAlign: 'top' | 'middle' | 'bottom' } export const TableRowGroupContext = React.createContext({ header: false, + verticalAlign: 'top', }) diff --git a/src/components/Select.tsx b/src/components/Select.tsx index 57736e4..a9ab1e2 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -16,7 +16,7 @@ import { useListNavigation, useRole, useTypeahead, -} from '@floating-ui/react-dom-interactions' +} from '@floating-ui/react' import { IconChevronDown } from '@tabler/icons-react' import { AnimatePresence, motion } from 'framer-motion' import { ellipsis } from 'polished' @@ -142,7 +142,7 @@ export const Select = forwardRefWithGenerics( } }, [value]) - const { x, y, reference, floating, strategy, context, refs } = useFloating({ + const { x, y, refs, strategy, context } = useFloating({ placement: 'bottom', open, onOpenChange: setOpen, @@ -168,6 +168,8 @@ export const Select = forwardRefWithGenerics( ], }) + const { reference } = refs + useImperativeHandle(ref, () => reference) const { getReferenceProps, getFloatingProps, getItemProps } = @@ -251,12 +253,12 @@ export const Select = forwardRefWithGenerics( return ( = (props) => { const { x, y, - reference, - floating, + refs, strategy, context, placement, @@ -115,11 +114,7 @@ export const Tooltip: React.FC = (props) => { return ( - + {children} @@ -128,8 +123,8 @@ export const Tooltip: React.FC = (props) => { {isOpen && ( string - shadow: (color?: string, length?: number) => string + shadow: (color?: string, length?: CSSLength) => string } } @@ -139,10 +139,11 @@ const Light: SolvedTheme = { styles: { border: (color?: string) => `1px solid ${color || defaultPalette.gray[200]}`, - shadow: (color?: string, length?: number) => - `${transparentize(0.6, color || defaultPalette.gray[200])} 0px ${ - (length || 8) / 2 - }px ${length || 8}px`, + shadow: (color?: string, length?: CSSLength) => + `${transparentize( + 0.6, + color || defaultPalette.gray[200] + )} 0px ${cssLength(cssDiv(length || 8, 2))} ${cssLength(length || 8)}`, }, } @@ -177,10 +178,11 @@ const Dark: SolvedTheme = { styles: { border: (color?: string) => `1px solid ${(color || defaultPalette.gray[700]).toString()}`, - shadow: (color?: string, length?: number) => - `${transparentize(0.6, color || defaultPalette.gray[200])} 0px ${ - (length || 8) / 2 - }px ${length || 8}px`, + shadow: (color?: string, length?: CSSLength) => + `${transparentize( + 0.6, + color || defaultPalette.gray[200] + )} 0px ${cssLength(cssDiv(length || 8, 2))} ${cssLength(length || 8)}`, }, } @@ -200,10 +202,11 @@ const Black: SolvedTheme = { styles: { border: (color?: string) => `1px solid ${(color || defaultPalette.gray[900]).toString()}`, - shadow: (color?: string, length?: number) => - `${transparentize(0.6, color || defaultPalette.gray[200])} 0px ${ - (length || 8) / 2 - }px ${length || 8}px`, + shadow: (color?: string, length?: CSSLength) => + `${transparentize( + 0.6, + color || defaultPalette.gray[200] + )} 0px ${cssLength(cssDiv(length || 8, 2))} ${cssLength(length || 8)}`, }, } diff --git a/src/types/length.ts b/src/types/length.ts new file mode 100644 index 0000000..54064e0 --- /dev/null +++ b/src/types/length.ts @@ -0,0 +1 @@ +export type CSSLength = number | string diff --git a/src/utils/css.ts b/src/utils/css.ts new file mode 100644 index 0000000..44b2fa8 --- /dev/null +++ b/src/utils/css.ts @@ -0,0 +1,30 @@ +import { CSSLength } from '../types/length' +import { cssLength } from './length' + +export const cssAdd = (a: CSSLength, b: CSSLength): CSSLength => { + if (typeof a === 'number' && typeof b === 'number') { + return a + b + } + return `calc(${cssLength(a)} + ${cssLength(b)})` +} + +export const cssSub = (a: CSSLength, b: CSSLength): CSSLength => { + if (typeof a === 'number' && typeof b === 'number') { + return a - b + } + return `calc(${cssLength(a)} - ${cssLength(b)})` +} + +export const cssMul = (a: CSSLength, b: number): CSSLength => { + if (typeof a === 'number') { + return a * b + } + return `calc(${cssLength(a)} * ${b})` +} + +export const cssDiv = (a: CSSLength, b: number): CSSLength => { + if (typeof a === 'number') { + return a / b + } + return `calc(${cssLength(a)} / ${b})` +} diff --git a/src/utils/length.ts b/src/utils/length.ts new file mode 100644 index 0000000..f2071d2 --- /dev/null +++ b/src/utils/length.ts @@ -0,0 +1,8 @@ +import { CSSLength } from '../types/length' + +export const cssLength = (cssLength?: CSSLength | null | undefined): string => { + if (typeof cssLength === 'number') { + return `${cssLength}px` + } + return cssLength || '0px' +} diff --git a/yarn.lock b/yarn.lock index 9cd808b..4705609 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1369,34 +1369,34 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@floating-ui/core@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.2.2.tgz#66f62cf1b7de2ed23a09c101808536e68caffaec" - integrity sha512-FaO9KVLFnxknZaGWGmNtjD2CVFuc0u4yeGEofoyXO2wgRA7fLtkngT6UB0vtWQWuhH3iMTZZ/Y89CMeyGfn8pA== +"@floating-ui/core@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.3.0.tgz#113bc85fa102cf890ae801668f43ee265c547a09" + integrity sha512-vX1WVAdPjZg9DkDkC+zEx/tKtnST6/qcNpwcjeBgco3XRNHz5PUA+ivi/yr6G3o0kMR60uKBJcfOdfzOFI7PMQ== -"@floating-ui/dom@^1.2.1": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.2.3.tgz#8dc6fbf799fbb5c29f705b54bdd51f3ab0ee03a2" - integrity sha512-lK9cZUrHSJLMVAdCvDqs6Ug8gr0wmqksYiaoj/bxj2gweRQkSuhg2/V6Jswz2KiQ0RAULbqw1oQDJIMpQ5GfGA== +"@floating-ui/dom@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.3.0.tgz#69456f2164fc3d33eb40837686eaf71537235ac9" + integrity sha512-qIAwejE3r6NeA107u4ELDKkH8+VtgRKdXqtSPaKflL2S2V+doyN+Wt9s5oHKXPDo4E8TaVXaHT3+6BbagH31xw== + dependencies: + "@floating-ui/core" "^1.3.0" + +"@floating-ui/react-dom@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.1.tgz#7972a4fc488a8c746cded3cfe603b6057c308a91" + integrity sha512-rZtAmSht4Lry6gdhAJDrCp/6rKN7++JnL1/Anbr/DdeyYXQPxvg/ivrbYvJulbRf4vL8b212suwMM2lxbv+RQA== dependencies: - "@floating-ui/core" "^1.2.2" + "@floating-ui/dom" "^1.3.0" -"@floating-ui/react-dom-interactions@^0.13.3": - version "0.13.3" - resolved "https://registry.yarnpkg.com/@floating-ui/react-dom-interactions/-/react-dom-interactions-0.13.3.tgz#6c49dda9e16fff64d188603c1efc139588ce925d" - integrity sha512-AnCW06eIZxzD/Hl1Qbi2JkQRU5KpY7Dn81k3xRfbvs+HylhB+t3x88/GNKLK39mMTlJ/ylxm5prUpiLrTWvifQ== +"@floating-ui/react@^0.24.3": + version "0.24.3" + resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.24.3.tgz#4f11f09c7245555724f5167dd6925133457db89c" + integrity sha512-wWC9duiog4HmbgKSKObDRuXqMjZR/6m75MIG+slm5CVWbridAjK9STcnCsGYmdpK78H/GmzYj4ADVP8paZVLYQ== dependencies: - "@floating-ui/react-dom" "^1.0.1" + "@floating-ui/react-dom" "^2.0.1" aria-hidden "^1.1.3" tabbable "^6.0.1" -"@floating-ui/react-dom@^1.0.1": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-1.3.0.tgz#4d35d416eb19811c2b0e9271100a6aa18c1579b3" - integrity sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g== - dependencies: - "@floating-ui/dom" "^1.2.1" - "@humanwhocodes/config-array@^0.9.2": version "0.9.5" resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz"