Skip to content

Commit

Permalink
Merge pull request #35 from GaoNeng-wWw/feat/group
Browse files Browse the repository at this point in the history
  • Loading branch information
SnowballXueQiu authored Oct 5, 2024
2 parents aab3b2c + ab9ddfd commit 20894b4
Show file tree
Hide file tree
Showing 15 changed files with 289 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-countries-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@qwqui/group": major
---

feat: implment group component.
5 changes: 5 additions & 0 deletions doc/docs/components/layout/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,10 @@
"type": "file",
"name": "stack",
"label": "Stack"
},
{
"type": "file",
"name": "group",
"label": "Group"
}
]
31 changes: 31 additions & 0 deletions doc/docs/components/layout/group.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Group

## 基本用法

<code src="./group/basic-usage.tsx" />

## Props

| 名称 | 类型 | 介绍 | 默认值 |
| :-------: | :-----------------------: | :-------------------------------------------: | :-------: |
| gao | number | 元素之间的间隔 | 0 |
| align | GroupAlign | 元素垂直方向对齐方式, 等价于`align-items` | 'start' |
| justify | GroupJustify | 元素水平方向排列方式, 等价于`justify-content` | 'center' |
| className | string | 额外的`className` | '' |
| h | number | 容器高度 | undefined |
| style | CSSProperties | 追加的样式 | `{}` |
| grow | boolean | 子元素是否会自动占据宽度 | false |
| wrap | CSSProperties['flexWrap'] | 子元素换行策略 | 'wrap' |

## Type

```ts
export type GroupAlign = "center" | "start" | "end";
export type GroupJustify =
| "start"
| "center"
| "end"
| "space-around"
| "space-between"
| "space-evenly";
```
65 changes: 65 additions & 0 deletions doc/docs/components/layout/group/basic-usage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Group, GroupJustify } from '@qwqui/core';
import './style.scss'
import { Dispatch, SetStateAction, useState } from 'react';

function select<T extends string>(
state: T,
setState: Dispatch<SetStateAction<T>>,
id: string,
values: T[]
) {
return (
<div className={id}>
<p>{id}: {state}</p>
<div className={`${id}__wrapper`}>
{
values.map((val, idx) => {
return (
<div key={idx}>
<input
name={`${id}`}
key={idx}
type='radio'
id={`${id}-${val}`}
value={val}
onClick={() => setState(val)}
defaultChecked={val === state}
/>
<label htmlFor={`${id}-${val}`}>{val}</label>
</div>
)
})
}
</div>
</div>
)
}

export default function App() {
const [grow, setGrow] = useState(false);
const [justify, setJustify] = useState<GroupJustify>('start');
const [gap, setGap] = useState(0);
return (
<div>
<Group gap={gap} grow={grow} justify={justify}>
<div className='demo-block'>Item - 1</div>
<div className='demo-block'>Item - 2</div>
<div className='demo-block'>Item - 3</div>
</Group>

<div style={{
marginTop: '64px'
}}>
<label htmlFor="">Gap: {gap}px</label>
<input type='range' defaultValue={gap} min={0} max={32} onChange={(ev) => setGap(parseInt(ev.target.value))} />
</div>
<div>
<label htmlFor="grow">Grow: </label>
<input id='grow' type='checkbox' defaultChecked={grow} onChange={(ev) => setGrow(ev.target.checked)} />
</div>
{
select(justify, setJustify, 'Justify', ['start', 'center', 'end', 'space-around', 'space-between', 'space-evenly'] as GroupJustify[])
}
</div>
)
}
11 changes: 11 additions & 0 deletions doc/docs/components/layout/group/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.demo-block {
width: fit-content;
background: #66ccff;
color: #000;
padding: 4px 8px;
}

.Justify__wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
}
13 changes: 13 additions & 0 deletions packages/components/group/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# @qwqui/group

<!-- Description -->

## Install

```bash
pnpm add @qwqui/group
```

## License

MIT
17 changes: 17 additions & 0 deletions packages/components/group/__test__/group.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { render } from '@testing-library/react'
import { Group } from '..';
describe('group', () => {
it('should define', () => {
expect(
render(<Group></Group>)
).toBeDefined()
});
it('gap', () => {
const wrapper = render(
<Group gap={8}></Group>
)
const firstChild = wrapper.container.firstElementChild;
const gap = window.getComputedStyle(firstChild).getPropertyValue('--group-gap');
expect(gap).toBe('8px');
})
})
1 change: 1 addition & 0 deletions packages/components/group/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src/group'
29 changes: 29 additions & 0 deletions packages/components/group/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@qwqui/group",
"version": "0.0.0",
"description": "",
"scripts": {
"build": "rslib build",
"clean:dist": "rimraf dist .rslib",
"clean:deps": "rimraf node_modules"
},
"keywords": [],
"author": "",
"license": "MIT",
"types": "./dist/index.d.mts",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js",
"types": "./dist/index.d.mts"
}
},
"files": [
"dist"
],
"peerDependencies": {
"react": "18.3.1"
}
}
2 changes: 2 additions & 0 deletions packages/components/group/rslib.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { defineBuild } from '@qwqui/build';
export default defineBuild();
32 changes: 32 additions & 0 deletions packages/components/group/src/group.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.root:root {
--group-wrap: wrap;
--group-justify: flex-start;
--group-align: flex-start;
--group-gap: 0px;
--group-h: auto;
}


$group-wrap: var(--group-wrap);
$group-justify: var(--group-justify);
$group-align: var(--group-align);
$group-gap: var(--group-gap);
$group-children-width: var(--group-child-width);
$group-h: var(--group-h);

.root {
display: flex;
flex-direction: row;
flex-wrap: $group-wrap;
justify-content: $group-justify;
align-items: $group-align;
gap: $group-gap;
height: $group-h;

&[data-grow="true"] {
&>* {
flex-grow: 1;
max-width: $group-children-width;
}
}
}
60 changes: 60 additions & 0 deletions packages/components/group/src/group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { CSSProperties } from 'react';
import style from './group.module.scss';

const resolveVar = (props: Omit<GroupProps, 'children'>) => {
return {
'--group-wrap': props.wrap,
'--group-justify': props.justify,
'--group-align': props.align,
'--group-gap': `${props.gap}px`,
'--group-child-width': '',
'--group-h': props.h ? `${props.h}px` : undefined
} as CSSProperties
}

const filterChildren = (children: React.ReactNode) => React.Children.toArray(children).filter(Boolean);
const DEFAULT_PROPS: Partial<GroupProps> = {
wrap: 'wrap',
justify: 'start',
align: 'start',
gap: 0,
}
export const Group = (props: GroupProps) => {
const children = filterChildren(props.children);
const vars = resolveVar({
...DEFAULT_PROPS,
...props,
});
const childrenCount = children.length;
const childWidth = `calc(${100 / childrenCount}% - ${props.gap - props.gap / childrenCount})`
vars['--group-child-width'] = childWidth;
return (
<div
className={[style.root, props.className ?? ''].join(' ')}
style={{
...vars,
...props.style
}}
data-grow={props.grow}
>
{children}
</div>
)
}

Group.displayName = '@qwqui/layout/Group'

export type GroupAlign = 'center' | 'start' | 'end';
export type GroupJustify = 'start' | 'center' | 'end' | 'space-around' | 'space-between' | 'space-evenly';

export interface GroupProps {
gap?: number;
align?: GroupAlign;
justify?: GroupJustify;
className?: string;
children?: React.ReactNode;
h?: number;
style?: CSSProperties;
grow?: boolean;
wrap?: CSSProperties['flexWrap'];
}
10 changes: 10 additions & 0 deletions packages/components/group/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"include": [
"index.ts",
"src"
],
"exclude": [
"node_modules"
],
"extends": "../../../tsconfig.json"
}
2 changes: 2 additions & 0 deletions packages/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import './button/src/button.module.scss'
import './center/src/center.module.scss'
import './group/src/group.module.scss'
import './ripple/src/ripple.module.scss'
import './stack/src/stack.module.scss'
export * from './button/index.ts'
export * from './center/index.ts'
export * from './group/index.ts'
export * from './ripple/index.ts'
export * from './stack/index.ts'
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 20894b4

Please sign in to comment.