Skip to content

Commit 19b7557

Browse files
feat: init
0 parents  commit 19b7557

6 files changed

Lines changed: 5340 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist
2+
node_modules

README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Slots Component
2+
3+
## Installation
4+
5+
`npm i slots-component`
6+
7+
## How to use it?
8+
9+
```tsx
10+
import { SlotsProps, Slots, SlotsCreator } from './Slots';
11+
12+
const DEFAULT_SLOTS = {
13+
List: 'ul',
14+
Row: 'li',
15+
} satisfies Slots;
16+
17+
type SlotsConfig = SlotsCreator<typeof DEFAULT_SLOTS, {
18+
Row: [TItem];
19+
}>
20+
21+
interface TItem {
22+
id: string;
23+
name: string;
24+
}
25+
26+
interface Props {
27+
rows: TItem[];
28+
}
29+
30+
export const List = <
31+
TSlots extends SlotsConfig["Slots"],
32+
>({ rows, slots, slotProps }: Props & SlotsProps<SlotsConfig, TSlots>) => {
33+
const combinedSlots = {
34+
...DEFAULT_SLOTS,
35+
...slots,
36+
};
37+
38+
return (
39+
<combinedSlots.List {...slotProps?.list}>
40+
{rows.map((row) => (
41+
<combinedSlots.Row
42+
key={row.id}
43+
{...(typeof slotProps?.row === 'function'
44+
? slotProps?.row(row)
45+
: slotProps?.row)}
46+
>
47+
{row.name}
48+
</combinedSlots.Row>
49+
))}
50+
</combinedSlots.List>
51+
);
52+
};
53+
```

index.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { ComponentProps, JSXElementConstructor, JSX } from 'react';
2+
3+
type MaybeFunc<Value, Args extends Array<unknown>> =
4+
| Value
5+
| ((...args: Args) => Value);
6+
7+
type ReactComponent = keyof JSX.IntrinsicElements | JSXElementConstructor<any>;
8+
type Slots = Record<string, ReactComponent>;
9+
10+
type CallbacksCreator<DefaultProps extends Slots> = {
11+
[Key in keyof DefaultProps]?: Array<any>;
12+
};
13+
14+
type SlotProps<
15+
TSlots extends Slots,
16+
SlotPropsWithCallback extends CallbacksCreator<TSlots>
17+
> = {
18+
[SlotKey in keyof TSlots as SlotKey extends string
19+
? Lowercase<SlotKey>
20+
: never]: TSlots[SlotKey] extends ReactComponent
21+
? SlotPropsWithCallback[SlotKey] extends Array<any>
22+
? MaybeFunc<
23+
Partial<ComponentProps<TSlots[SlotKey]>>,
24+
SlotPropsWithCallback[SlotKey]
25+
>
26+
: Partial<ComponentProps<TSlots[SlotKey]>>
27+
: never;
28+
};
29+
30+
type SlotsCreator<
31+
TDefaultSlots extends Slots,
32+
TCallbacks extends CallbacksCreator<TDefaultSlots>
33+
> = {
34+
DefaultSlots: TDefaultSlots;
35+
Slots: { [Key in keyof TDefaultSlots]?: ReactComponent };
36+
Callbacks: TCallbacks;
37+
};
38+
39+
type SlotsProps<
40+
TSlotsConfig extends SlotsCreator<any, any>,
41+
TSlots extends TSlotsConfig['Slots']
42+
> = {
43+
slots?: TSlots;
44+
slotProps?: Partial<
45+
SlotProps<
46+
Omit<TSlotsConfig['DefaultSlots'], keyof TSlots> & TSlots,
47+
TSlotsConfig['Callbacks']
48+
>
49+
>;
50+
};
51+
52+
export type { SlotsProps, SlotsCreator, Slots };

0 commit comments

Comments
 (0)