Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build in autosizing box #292

Merged
merged 15 commits into from
May 15, 2024
Merged
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
3 changes: 2 additions & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// ---------- atoms ------- //
export * from '@/components/atoms/AutoSizingBox';
export * from '@/components/atoms/BackDrop';
export * from '@/components/atoms/ColorIndicator';
export * from '@/components/atoms/BackDrop';
Expand Down Expand Up @@ -42,7 +43,7 @@ export * from '@/components/atoms/RawRadio';
export * from '@/components/atoms/LoadingSVGArrows';
export * from '@/components/atoms/SwitchActiveIndicator';
export * from '@/components/atoms/FancyActionWrapper';
export * from '@/components/atoms/ListDivider';
export * from '@/components/atoms/Seperator';
export * from '@/components/atoms/MenuItem';
export * from '@/components/atoms/PageNumberList';
export * from '@/components/atoms/RawLI';
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "TobiTRy"
},
"private": false,
"version": "0.4.7",
"version": "0.4.8",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
22 changes: 19 additions & 3 deletions src/Routes/ExperimentalRoute/ExperimentalRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import styled from 'styled-components';
import createMultiIntersectionObserver from '@/utils/hooks/useMiltiIntersectionObserver/multiplyIntersectionObserver';
import { FancyVirtualScroll } from '@/components/shared/FancyVirtualScroll';
import ActionItem from '@/components/molecules/ActionItem/ActionItem';
import { AutoSizingBox } from '@/components/atoms/AutoSizingBox';

const Icon = (
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
Expand Down Expand Up @@ -88,7 +89,7 @@ const CustomComponent = ({ children, test }: { children?: React.ReactNode; test?
return <span>{children}</span>;
};

const testComps = () => [
const TestComps = () => [
<>
<div>Hiii</div>
<div>Hiii</div>
Expand Down Expand Up @@ -137,12 +138,27 @@ export default function ExperimentalRoute() {
};
}, []);

const addContent = () => {
setIsLoading(!isLoading);
};

return (
<>
<DesignWrapper>
<DesignArea title="Test">
<Button sizeC={undefined}>Mooiin</Button>
<FancyNumberInput label="TTTSa" systemMessage={{ type: 'error', message: 'errroor' }} />
<AutoSizingBox adjustHeight>
<Button sizeC={undefined} onClick={addContent}>
Mooiin
</Button>
{isLoading ? (
<TestComps />
) : (
<Button sizeC={undefined} onClick={addContent}>
Mooiin
</Button>
)}
</AutoSizingBox>
<FancyNumberInput label="TTTSa" systemMessage="error" />
<Card />
<Card>
<FancyContent direction="column" justify="center">
Expand Down
13 changes: 4 additions & 9 deletions src/Routes/InputsRoute/InputsRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export default function InputsRoute() {
label="Text"
onChange={testHandler2}
value={test}
systemMessage={{ type: 'error', message: 'This is an error message' }}
systemMessage={'error'}
/>
<FancyNumberInput
decimalPlaces={4}
Expand All @@ -107,7 +107,7 @@ export default function InputsRoute() {
onChange={testHandler2}
value={test}
placeholder="test45454554"
systemMessage={{ type: 'success', message: 'This is an error message' }}
systemMessage={'success'}
/>
<FancyNumberInput
decimalPlaces={4}
Expand All @@ -116,7 +116,7 @@ export default function InputsRoute() {
onChange={testHandler2}
value={test}
placeholder="test45454554"
systemMessage={{ type: 'info', message: 'This is an error message' }}
systemMessage={'info'}
/>
</DesignArea>
<DesignArea title="Password Input111">
Expand All @@ -135,12 +135,7 @@ export default function InputsRoute() {
align="center"
placeholder="test45454554"
/>
<FancyTextInput
placeholder="Hiiii"
systemMessage={{ type: 'success', message: 'moooiin' }}
value={text}
onChange={testHandler}
/>
<FancyTextInput placeholder="Hiiii" systemMessage={'success'} value={text} onChange={testHandler} />
</DesignArea>
<DesignArea title="Number Input">
<FancyNumberInput icon={svg} label="Text" onChange={testHandler2} value={test} step={0.1} min={0} max={100} />
Expand Down
8 changes: 8 additions & 0 deletions src/components/atoms/AutoSizingBox/AutoSizingBox.style.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { styled } from 'styled-components';

export const InnerContentWrapper = styled.div`
transition:
height 0.3s ease-in-out,
width 0.3s ease-in-out;
overflow: hidden;
`;
44 changes: 44 additions & 0 deletions src/components/atoms/AutoSizingBox/AutoSizingBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useState, useRef, useEffect } from 'react';
import { InnerContentWrapper } from './AutoSizingBox.style';
import { TAutoSizingBox } from './TAutoSizingBox.model';

// --------------------------------------------------------------------------- //
// A Box thats adjusts width and height dynamicly from the childs via animation//
// --------------------------------------------------------------------------- //
export default function AutoSizingBox(props: TAutoSizingBox) {
const { children, startHeight, startWidth, adjustHeight = true, adjustWidth } = props;

// State for the height and width of the box
const [boxHeight, setBoxHeight] = useState(startHeight || 'auto');
const [boxWidth, setBoxWidth] = useState(startWidth || 'auto');

// Reference to the box element to get the scrollHeight and scrollWidth
const boxRef = useRef<HTMLDivElement>(null);

useEffect(() => {
// ResizeObserver to observe the box element
const resizeObserver = new ResizeObserver(() => {
if (boxRef.current) {
if (adjustHeight) {
setBoxHeight(boxRef.current.scrollHeight);
}
if (adjustWidth) {
setBoxWidth(boxRef.current.scrollWidth);
}
}
});

if (boxRef.current) {
// Start observing the box element for changes
resizeObserver.observe(boxRef.current);
}
// Cleanup the observer on unmount or before re-running this effect
return () => resizeObserver.disconnect();
}, [children, adjustHeight, adjustWidth]);

return (
<InnerContentWrapper style={{ height: boxHeight, width: boxWidth }}>
<div ref={boxRef}>{children}</div>
</InnerContentWrapper>
);
}
9 changes: 9 additions & 0 deletions src/components/atoms/AutoSizingBox/TAutoSizingBox.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type TAutoSizingBox = {
children?: React.ReactNode;
startHeight?: number;
startWidth?: number;
adjustHeight?: boolean;
adjustWidth?: boolean;
};

export type TAutoSizingBoxWithHTMLAttrs = TAutoSizingBox & React.HTMLAttributes<HTMLDivElement>;
40 changes: 40 additions & 0 deletions src/components/atoms/AutoSizingBox/docu/AutoSizingBox.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Meta, Controls, Title, Description, Canvas } from '@storybook/blocks';

import * as AutoSizingBox from './AutoSizingBox.stories.tsx';

<Meta of={AutoSizingBox} />

<Title />

### Brief Description

<Description />

### Setup Instructions

1. Import the `AutoSizingBox` component where you need to use it:

```javascript
import { AutoSizingBox } from 'fui-fancyui';
```

2. Make sure to import the `TAutoSizingBox` type definitions if you are using TypeScript:
```javascript
import { TAutoSizingBox } from 'fui-fancyui';
```

### Example Usage

Here's how to use the `AutoSizingBox` component in a React component:

```jsx
<AutoSizingBox startHeight="100px" startWidth="100px" adjustHeight={true} adjustWidth={true}>
<div>Dynamic Content Here</div>
</AutoSizingBox>
```

<Canvas />

### Component Properties

<Controls />
106 changes: 106 additions & 0 deletions src/components/atoms/AutoSizingBox/docu/AutoSizingBox.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import type { Meta, StoryObj } from '@storybook/react';

import AutoSizingBox from '../AutoSizingBox';
import { TAutoSizingBox } from '../TAutoSizingBox.model';
import React from 'react';
import { FancyButton } from '@/components/organisms/FancyButton';
import { FancyBox } from '@/components/atoms/FancyBox';

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
component: AutoSizingBox,
title: 'components/atoms/AutoSizingBox',
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
docs: {
description: {
component:
'The `AutoSizingBox` is a React component designed to dynamically adjust its width and height based on the size of its child elements. It uses CSS transitions for smooth animations during these adjustments.',
},
},
},
argTypes: {
children: {
description: 'This is the content of the box',
control: { type: 'object' },
table: {
category: 'Content',
},
},
startHeight: {
description: 'This is the initial height of the box',
control: { type: 'number' },
},
startWidth: {
description: 'This is the initial width of the box',
control: { type: 'number' },
table: {
defaultValue: { summary: 'number' },
},
},
adjustHeight: {
description: 'This is the flag to adjust the height of the box',
control: { type: 'boolean' },
table: {
defaultValue: { summary: 'true' },
},
},
adjustWidth: {
description: 'This is the flag to adjust the width of the box',
control: { type: 'boolean' },
table: {
defaultValue: { summary: 'false' },
},
},
},
} satisfies Meta<typeof AutoSizingBox>;

export default meta;

type Story = StoryObj<typeof meta>;

const HelperComponent = (props: TAutoSizingBox) => {
const [isopen, setIsOpen] = React.useState(false);

return (
<FancyBox
themeType="secondary"
borderRadius={'sm'}
externalStyle={{
color: 'black',
}}
>
<AutoSizingBox {...props}>
<FancyButton label={isopen ? 'close' : 'open'} onClick={() => setIsOpen((prev) => !prev)} />
{isopen ? <TestComps /> : ''}
</AutoSizingBox>
</FancyBox>
);
};

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Primary: Story = {
render: (args) => <HelperComponent {...args} />,
args: {
startHeight: 100,
startWidth: 200,
adjustHeight: true,
adjustWidth: false,
},
};

const TestComps = () => [
<>
<div>Hiii</div>
<div>Hiii</div>
<div>Hiii</div>
<div>Hiii</div>
<div>Hiii</div>
<div>Hiii</div>
<div>Hiii</div>
<div>Hiii</div>
<div>Hiii</div>
<div>Hiii</div>
<div>Hiii</div>
</>,
];
3 changes: 3 additions & 0 deletions src/components/atoms/AutoSizingBox/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default as AutoSizingBox } from './AutoSizingBox';

export type { TAutoSizingBoxWithHTMLAttrs, TAutoSizingBox } from './TAutoSizingBox.model';
2 changes: 1 addition & 1 deletion src/components/atoms/FancyBox/FancyBox.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ type TNonOutlinedFancyBoxPropsFalse = {
export type TFancyBox = TFancyBoxProps & (TOutlinedFancyBoxProps | TNonOutlinedFancyBoxPropsFalse);

export type TFancyBoxWithHTMLAttrs<T extends ElementType = 'div'> = TFancyBox &
Omit<React.DetailedHTMLProps<React.HTMLAttributes<T>, T>, 'style'>;
React.DetailedHTMLProps<React.HTMLAttributes<T>, T>;
4 changes: 2 additions & 2 deletions src/components/atoms/FancyBox/FancyBox.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export const StyledFancyBox = styled.div<IStyledFancyBox>`
margin: ${({ $margin }) => arrayToCssValues($margin, 'spacing')};

box-sizing: border-box;
${({ $themeType, theme, $layer, $outlined, $outlinedBackgroundStrength }) =>
generateThemeForCard({ $themeType, theme, $outlined, $layer, $outlinedBackgroundStrength })};
${({ $themeType, theme, $layer, $outlined, $outlinedBackgroundStrength, $outlinedRemoveBorder }) =>
generateThemeForCard({ $themeType, theme, $outlined, $layer, $outlinedBackgroundStrength, $outlinedRemoveBorder })};

${({ $externalStyle }) => $externalStyle};
`;
2 changes: 1 addition & 1 deletion src/components/atoms/FancyLine/FancyLine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default function FancyLine(props: TFancyLineWithHTMLAttributes) {
direction = 'horizontal',
thickness,
margin,
themeType,
themeType = 'accent',
layer,
length,
externalStyle,
Expand Down
Loading
Loading