11/** biome-ignore-all lint/suspicious/noExplicitAny: for arbitrary values */
2- import type { ComponentProps , ComponentType } from 'react' ;
3- import type { PropertySpec } from '../PropertySpec' ;
4-
5- export type Block <
6- Component extends ComponentType < any > = any ,
7- Props = ComponentProps < Component > ,
8- Key extends keyof Props = keyof Props ,
9- > = {
10- name : string ;
11- category ?: string ;
12- component : Component ;
13- props : {
14- [ key in Key ] : PropertySpec < Props [ key ] > ;
15- } ;
16- } ;
2+ import type { ComponentType } from 'react' ;
3+ import { Block , type BlockConfig } from '../Block' ;
174
185const blocks = new Map < string , Block > ( ) ;
196
207export const register = < Component extends ComponentType < any > > (
218 name : string ,
22- block : Omit < Block < Component > , 'name' > ,
9+ config : BlockConfig < Component > ,
2310) => {
24- for ( const spec of Object . values ( block . props ) ) {
25- const typedSpec = spec as PropertySpec < any > ;
11+ const block = new Block ( name , config ) ;
2612
27- setSpecDefault ( typedSpec ) ;
28- }
29-
30- blocks . set ( name , {
31- name,
32- ...block ,
33- } ) ;
13+ blocks . set ( name , block ) ;
3414} ;
3515
3616export const valid = ( names : string [ ] ) : boolean => {
@@ -43,10 +23,10 @@ export const missing = (names: string[]): string[] => {
4323
4424export const get = ( name : string ) => {
4525 if ( name . toLowerCase ( ) === name ) {
46- return {
26+ return new Block ( name , {
4727 component : name ,
48- props : { } as Record < string , PropertySpec < any > > ,
49- } ;
28+ props : { } ,
29+ } ) ;
5030 }
5131
5232 return blocks . get ( name ) ;
@@ -56,15 +36,11 @@ export const getAll = (query?: string) => {
5636 const blockList = Array . from ( blocks . values ( ) )
5737 . filter ( ( block ) => block . name . toLowerCase ( ) . includes ( query ?. toLowerCase ( ) ?? '' ) )
5838 . sort ( ( a , b ) => {
59- const aCategory = a . category ?? '~' ;
60- const bCategory = b . category ?? '~' ;
39+ const aCategory = a . category === Block . UNCATEGORIZED ? '~' : a . category ;
40+ const bCategory = b . category === Block . UNCATEGORIZED ? '~' : b . category ;
6141
6242 return aCategory < bCategory ? - 1 : 1 ;
63- } )
64- . map ( ( block ) => ( {
65- ...block ,
66- category : block . category ?? 'Uncategorized' ,
67- } ) ) ;
43+ } ) ;
6844
6945 const blocksByCategory = blockList . reduce (
7046 ( acc , block ) => {
@@ -88,45 +64,3 @@ export const getAll = (query?: string) => {
8864export const clear = ( ) => {
8965 blocks . clear ( ) ;
9066} ;
91-
92- const setSpecDefault = ( spec : PropertySpec < any > ) : void => {
93- spec . hasDefault = typeof spec . default !== 'undefined' ;
94-
95- switch ( spec . type ) {
96- case 'array' :
97- spec . default ??= [ ] ;
98- setSpecDefault ( spec . item ) ;
99- break ;
100- case 'boolean' :
101- spec . default ??= false ;
102- break ;
103- case 'node' :
104- spec . default ??= null ;
105- break ;
106- case 'number' :
107- spec . default ??= 0 ;
108- break ;
109- case 'object' :
110- for ( const field of Object . values ( spec . fields ) ) {
111- setSpecDefault ( field ) ;
112- }
113- spec . default ??= Object . fromEntries (
114- Object . entries ( spec . fields ) . map ( ( [ key , field ] ) => [ key , field . default ] ) ,
115- ) ;
116- break ;
117- case 'custom' :
118- break ;
119- case 'radio' :
120- spec . default ??= 'value' in spec . options [ 0 ] ? spec . options [ 0 ] . value : spec . options [ 0 ] ;
121- break ;
122- case 'select' :
123- spec . default ??= spec . options [ 0 ] ?. value ;
124- break ;
125- case 'text' :
126- case 'textarea' :
127- spec . default ??= '' ;
128- break ;
129- default :
130- throw new Error ( 'Unknown property spec' ) ;
131- }
132- } ;
0 commit comments