From 3d7fab9a250631457149f4343deef787db92ac3b Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Thu, 28 Nov 2024 21:39:25 +0000 Subject: [PATCH] Fixed Inline + Stack Signed-off-by: Charles de Dreuille --- .../canon/src/components/Box/docs/padding.tsx | 4 +- .../src/components/Inline/Inline.stories.tsx | 90 ++++++++++++++++--- .../canon/src/components/Inline/Inline.tsx | 69 +++++++------- .../src/components/Inline/sprinkles.css.ts | 34 +++++++ .../canon/src/components/Inline/styles.css | 4 + packages/canon/src/components/Inline/types.ts | 35 ++++++++ .../src/components/Stack/Stack.stories.tsx | 3 +- packages/canon/src/components/Stack/types.ts | 13 ++- packages/canon/src/theme/styles.css | 1 + 9 files changed, 199 insertions(+), 54 deletions(-) create mode 100644 packages/canon/src/components/Inline/sprinkles.css.ts create mode 100644 packages/canon/src/components/Inline/styles.css create mode 100644 packages/canon/src/components/Inline/types.ts diff --git a/packages/canon/src/components/Box/docs/padding.tsx b/packages/canon/src/components/Box/docs/padding.tsx index 486b1bcec5..86a7c801a2 100644 --- a/packages/canon/src/components/Box/docs/padding.tsx +++ b/packages/canon/src/components/Box/docs/padding.tsx @@ -42,7 +42,7 @@ export const Padding = () => { paddingY="xl" style={{ border: '1px solid #e7e7e7' }} > - + { paddingY - + ; export default meta; type Story = StoryObj; -const FakeBox = () => ( +const FakeBox = ({ + width = 120, + height = 80, +}: { + width?: number; + height?: number; +}) => ( - Fake Box - + style={{ background: '#1f47ff', color: 'white', width, height }} + /> ); export const Default: Story = { args: { children: ( <> - - - + {Array.from({ length: 32 }).map((_, index) => ( + + ))} ), }, }; +export const AlignLeft: Story = { + args: { + ...Default.args, + align: 'left', + }, +}; + +export const AlignCenter: Story = { + args: { + ...Default.args, + align: 'center', + }, +}; + +export const AlignRight: Story = { + args: { + ...Default.args, + align: 'right', + }, +}; + +export const VerticalAlignTop: Story = { + args: { + ...Default.args, + alignY: 'top', + }, +}; + +export const VerticalAlignCenter: Story = { + args: { + ...Default.args, + alignY: 'center', + }, +}; + +export const VerticalAlignBottom: Story = { + args: { + ...Default.args, + alignY: 'bottom', + }, +}; + export const LargeGap: Story = { args: { ...Default.args, diff --git a/packages/canon/src/components/Inline/Inline.tsx b/packages/canon/src/components/Inline/Inline.tsx index 9d4541ef12..2d1c649e29 100644 --- a/packages/canon/src/components/Inline/Inline.tsx +++ b/packages/canon/src/components/Inline/Inline.tsx @@ -14,45 +14,50 @@ * limitations under the License. */ -import React from 'react'; -import { Box } from '../Box/Box'; -import type { BoxProps } from '../Box/types'; +import { createElement } from 'react'; +import { inlineSprinkles } from './sprinkles.css'; +import type { InlineProps } from './types'; -export const validInlineComponents = [ - 'div', - 'span', - 'p', - 'nav', - 'ul', - 'ol', - 'li', -] as const; +const alignYToFlexAlign = (alignY: InlineProps['alignY']) => { + if (alignY === 'top') return 'flex-start'; + if (alignY === 'center') return 'center'; + if (alignY === 'bottom') return 'flex-end'; + return undefined; +}; -export interface InlineProps extends Omit { - as?: (typeof validInlineComponents)[number]; - children: React.ReactNode; - align?: 'left' | 'center' | 'right'; - gap?: BoxProps['gap']; -} +const alignToFlexAlignY = (align: InlineProps['align']) => { + if (align === 'left') return 'flex-start'; + if (align === 'center') return 'center'; + if (align === 'right') return 'flex-end'; + return undefined; +}; export const Inline = ({ - align, as = 'div', children, + align = 'left', + alignY = 'top', gap = 'xs', + className, + style, ...restProps }: InlineProps) => { - return ( - - {children} - - ); + // Generate the list of class names + const sprinklesClassName = inlineSprinkles({ + ...restProps, + gap, + alignItems: alignYToFlexAlign(alignY), + justifyContent: alignToFlexAlignY(align), + }); + + // Combine the base class name, the sprinkles class name, and any additional class names + const classNames = ['inline', sprinklesClassName, className] + .filter(Boolean) + .join(' '); + + return createElement(as, { + className: classNames, + style, + children, + }); }; diff --git a/packages/canon/src/components/Inline/sprinkles.css.ts b/packages/canon/src/components/Inline/sprinkles.css.ts new file mode 100644 index 0000000000..1d7e95da00 --- /dev/null +++ b/packages/canon/src/components/Inline/sprinkles.css.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { defineProperties, createSprinkles } from '@vanilla-extract/sprinkles'; +import { breakpoints } from '../../layout/properties'; +import { colorProperties, spacingProperties } from '../../layout/sprinkles.css'; + +const inlineProperties = defineProperties({ + conditions: breakpoints, + defaultCondition: 'xs', + properties: { + alignItems: ['flex-start', 'center', 'flex-end'], + justifyContent: ['flex-start', 'center', 'flex-end'], + }, +}); + +export const inlineSprinkles = createSprinkles( + spacingProperties, + colorProperties, + inlineProperties, +); diff --git a/packages/canon/src/components/Inline/styles.css b/packages/canon/src/components/Inline/styles.css new file mode 100644 index 0000000000..fb9b1c3825 --- /dev/null +++ b/packages/canon/src/components/Inline/styles.css @@ -0,0 +1,4 @@ +.inline { + display: flex; + flex-wrap: wrap; +} diff --git a/packages/canon/src/components/Inline/types.ts b/packages/canon/src/components/Inline/types.ts new file mode 100644 index 0000000000..413f2fbbb0 --- /dev/null +++ b/packages/canon/src/components/Inline/types.ts @@ -0,0 +1,35 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AsProps, Breakpoint, ColorProps } from '../../layout/types'; +import { SpaceProps } from '../../layout/types'; + +export interface InlineProps extends SpaceProps, ColorProps { + children: React.ReactNode; + as?: AsProps; + align?: + | 'left' + | 'center' + | 'right' + | Partial>; + alignY?: + | 'top' + | 'center' + | 'bottom' + | Partial>; + className?: string; + style?: React.CSSProperties; +} diff --git a/packages/canon/src/components/Stack/Stack.stories.tsx b/packages/canon/src/components/Stack/Stack.stories.tsx index f20677c12c..601f6b847f 100644 --- a/packages/canon/src/components/Stack/Stack.stories.tsx +++ b/packages/canon/src/components/Stack/Stack.stories.tsx @@ -18,8 +18,7 @@ import React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; import { Stack } from './Stack'; import { Box } from '../Box/Box'; -import { argTypesSpacing } from '../../../docs/utils/argTypes'; -import { argTypesColor } from '../../../docs/utils/argTypes'; +import { argTypesSpacing, argTypesColor } from '../../../docs/utils/argTypes'; const meta = { title: 'Components/Stack', diff --git a/packages/canon/src/components/Stack/types.ts b/packages/canon/src/components/Stack/types.ts index 7390e13666..81abea9999 100644 --- a/packages/canon/src/components/Stack/types.ts +++ b/packages/canon/src/components/Stack/types.ts @@ -16,17 +16,14 @@ import { AsProps, Breakpoint, ColorProps } from '../../layout/types'; import { SpaceProps } from '../../layout/types'; -/** @public */ -export type AlignProps = - | 'left' - | 'center' - | 'right' - | Partial>; - export interface StackProps extends SpaceProps, ColorProps { children: React.ReactNode; as?: AsProps; - align?: AlignProps; + align?: + | 'left' + | 'center' + | 'right' + | Partial>; className?: string; style?: React.CSSProperties; } diff --git a/packages/canon/src/theme/styles.css b/packages/canon/src/theme/styles.css index 001b8abf10..4a31340575 100644 --- a/packages/canon/src/theme/styles.css +++ b/packages/canon/src/theme/styles.css @@ -24,3 +24,4 @@ /* Components */ @import '../components/Button/styles.css'; @import '../components/Stack/styles.css'; +@import '../components/Inline/styles.css';