1
- // import { Primitive } from "react-classnaming/ts-swiss.defs"
1
+ import type { Ever0 , Extends , PartDeep } from "src/ts-swiss.types"
2
+ import type { ReactClassNaming } from "../src"
2
3
import { CssModule } from "../src/definitions.types"
3
4
4
5
it ( "tree2classes" , ( ) => {
@@ -149,50 +150,106 @@ describe("upon delimiter", () => {
149
150
} )
150
151
151
152
it ( "query" , ( ) => {
153
+ // Can be used on #30
154
+
155
+ type Elements <
156
+ classes extends string ,
157
+ b extends string ,
158
+ delE extends string = "__" /*"elementDelimiter" extends keyof ReactClassNaming.BemOptions
159
+ ? ReactClassNaming.BemOptions["elementDelimiter"]
160
+ : ReactClassNaming.BemOptions["$default"]["elementDelimiter"]*/ ,
161
+ delM extends string = "modDelimiter" extends keyof ReactClassNaming . BemOptions
162
+ ? ReactClassNaming . BemOptions [ "modDelimiter" ]
163
+ : ReactClassNaming . BemOptions [ "$default" ] [ "modDelimiter" ] ,
164
+ bModKey extends string = "$" /*"blockModKey" extends keyof ReactClassNaming.BemOptions
165
+ ? ReactClassNaming.BemOptions["blockModKey"]
166
+ : ReactClassNaming.BemOptions["$default"]["blockModKey"]*/
167
+ > = classes extends `${b } ${delE } ${infer E } `
168
+ ? Strip < E , delM >
169
+ : classes extends `${b } ${delM } ${string } `
170
+ ? bModKey
171
+ : never
172
+
152
173
type BemQuery <
153
- bModKey extends string ,
154
- delE extends string ,
155
- delM extends string ,
156
174
classes extends string ,
157
- BE extends string ,
158
- Block extends string
159
- > = {
160
- [ b in Block ] ?: boolean | (
161
- {
162
- [ bmKey in bModKey ] ?: {
163
- [
164
- m in classes extends `${b } ${delM } ${infer MV } `
165
- ? MV extends `${infer M } ${delM } ${infer _ } ` ? M : MV
166
- : never
167
- ] ?: classes extends `${b } ${delM } ${m } ${delM } ${infer V } `
168
- ? false | V
169
- : boolean
175
+ delE extends string = "__" /*"elementDelimiter" extends keyof ReactClassNaming.BemOptions
176
+ ? ReactClassNaming.BemOptions["elementDelimiter"]
177
+ : ReactClassNaming.BemOptions["$default"]["elementDelimiter"]*/ ,
178
+ delM extends string = "modDelimiter" extends keyof ReactClassNaming . BemOptions
179
+ ? ReactClassNaming . BemOptions [ "modDelimiter" ]
180
+ : ReactClassNaming . BemOptions [ "$default" ] [ "modDelimiter" ] ,
181
+ bModKey extends string = "$" /*"blockModKey" extends keyof ReactClassNaming.BemOptions
182
+ ? ReactClassNaming.BemOptions["blockModKey"]
183
+ : ReactClassNaming.BemOptions["$default"]["blockModKey"]*/
184
+ > = string extends classes ? BemInGeneral : PartDeep < {
185
+ [ b in Strip < Strip < classes , delM > , delE > ] : boolean
186
+ | Exclude < MVs < classes , b , bModKey > , `${string } ${delM } ${string } `>
187
+ | (
188
+ Extends < classes , `${b } ${delE | delM } ${string } `,
189
+ {
190
+ [ e in Elements < classes , b > ] : boolean
191
+ | Exclude < MVs < classes , b , e > , `${string } ${delM } ${string } `>
192
+ | (
193
+ { [ m in Strip < MVs < classes , b , e > , delM > ] :
194
+ false | (
195
+ Ever0 <
196
+ classes extends `${b } ${
197
+ e extends bModKey ? "" : `${delE } ${e } `
198
+ } ${delM } ${m } ${delM } ${infer V } `
199
+ ? V : never ,
200
+ true
201
+ >
202
+ )
203
+ }
204
+ )
170
205
}
171
- } & {
172
- [ e in BE extends `${b } ${delE } ${infer E } ` ? E : never ] ?: boolean | {
173
- [
174
- m in classes extends `${b } ${delE } ${e } ${delM } ${infer M } ${delM } ${infer _ } `
175
- ? M
176
- : classes extends `${b } ${delE } ${e } ${delM } ${infer M } `
177
- ? M
178
- : never
179
- ] ?: classes extends `${b } ${delE } ${e } ${delM } ${m } ${delM } ${infer V } `
180
- ? false | V
181
- : boolean
182
-
206
+ >
207
+ )
208
+ } >
209
+
210
+ type MVs <
211
+ classes extends string ,
212
+ b extends string ,
213
+ e extends string ,
214
+ delE extends string = "__" /*"elementDelimiter" extends keyof ReactClassNaming.BemOptions
215
+ ? ReactClassNaming.BemOptions["elementDelimiter"]
216
+ : ReactClassNaming.BemOptions["$default"]["elementDelimiter"]*/ ,
217
+ delM extends string = "modDelimiter" extends keyof ReactClassNaming . BemOptions
218
+ ? ReactClassNaming . BemOptions [ "modDelimiter" ]
219
+ : ReactClassNaming . BemOptions [ "$default" ] [ "modDelimiter" ] ,
220
+ bModKey extends string = "$" /*"blockModKey" extends keyof ReactClassNaming.BemOptions
221
+ ? ReactClassNaming.BemOptions["blockModKey"]
222
+ : ReactClassNaming.BemOptions["$default"]["blockModKey"]*/
223
+ > = classes extends `${b } ${
224
+ e extends bModKey ? "" : `${delE } ${e } `
225
+ } ${delM } ${infer MV } ` ? MV : never
226
+
227
+ type BemInGeneral = {
228
+ [ block : string ] : undefined | boolean | string | {
229
+ [ el : string ] : undefined | boolean | string
230
+ | {
231
+ [ mod : string ] : undefined | boolean | string
183
232
}
184
- } )
185
- }
233
+ }
234
+ }
235
+
186
236
type BemQuerier <
187
237
ClassNames extends CssModule ,
188
- bModKey extends string = "$" ,
189
238
delE extends string = "__" ,
190
- delM extends string = "--"
239
+ delM extends string = "--" ,
240
+ bModKey extends string = "$" ,
191
241
> =
192
242
<
193
243
// classes extends keyof ClassNames,
194
- BE extends StripFromObj < ClassNames , delM > ,
195
- Q extends BemQuery < bModKey , delE , delM , keyof ClassNames , BE , Strip < BE , delE > >
244
+ // BE extends StripFromObj<ClassNames, delM>,
245
+ Q extends BemQuery <
246
+ keyof ClassNames ,
247
+ delE ,
248
+ delM ,
249
+ bModKey
250
+ // BE,
251
+ // Strip<BE, delE>
252
+ >
196
253
> ( arg : Q ) => { [ K in
197
254
{ [ b in keyof Q ] : Q [ b ] extends boolean ? b : never } [ keyof Q ]
198
255
// | {[b in keyof Q]: Q[b] extends Primitive ? never : `${b}${delE}${keyof Q[b]}`}[keyof Q]
@@ -211,46 +268,7 @@ describe("upon delimiter", () => {
211
268
] : boolean }
212
269
213
270
//@ts -expect-error
214
- const q : BemQuerier < ClassNames > = x => {
215
- const $result : Record < string , undefined | boolean > = { }
216
-
217
- for ( const block in x ) {
218
- const bVal = x [ block ]
219
-
220
- if ( ! bVal ) {
221
- //@ts -expect-error
222
- $result [ block ] = bVal
223
- continue
224
- }
225
-
226
- for ( const el in bVal ) {
227
- //@ts -expect-error
228
- const eVal = bVal [ el ]
229
- , be = el === "$" ? block : `${ block } __${ el } `
230
-
231
- if ( ! eVal ) {
232
- $result [ be ] = eVal
233
- continue
234
- }
235
-
236
- $result [ be ] = true
237
-
238
- for ( const mod in eVal ) {
239
- const value : string | boolean = eVal [ mod ]
240
- switch ( typeof value ) {
241
- case "boolean" :
242
- $result [ `${ be } --${ mod } ` ] = value
243
- break
244
- case "string" :
245
- $result [ `${ be } --${ mod } --${ value } ` ] = true
246
- break
247
- }
248
- }
249
- }
250
- }
251
-
252
- return $result
253
- }
271
+ const q = x => x as unknown as BemQuerier < ClassNames >
254
272
, res = q ( {
255
273
"App" : {
256
274
"Header" : false ,
@@ -272,24 +290,25 @@ describe("upon delimiter", () => {
272
290
} )
273
291
, typeCheck : Record < string , typeof res > = {
274
292
"exact" : {
293
+ //@ts -expect-error
275
294
Footer : true ,
276
295
Btn : true ,
277
296
App : true ,
278
297
}
279
298
}
280
299
281
- expect ( res ) . toStrictEqual ( {
282
- "App__Container" : true ,
283
- "App__Container--loading" : true ,
284
- "App__Container--status--error" : true ,
285
- "App__Header" : false ,
286
- "Btn" : true ,
287
- "Btn--disabled" : false ,
288
- "Btn--info--error" : true ,
289
- "Btn__Icon" : true ,
290
- "Btn__Icon--big" : true ,
291
- "Footer" : false ,
292
- } )
300
+ // expect(res).toStrictEqual({
301
+ // "App__Container": true,
302
+ // "App__Container--loading": true,
303
+ // "App__Container--status--error": true,
304
+ // "App__Header": false,
305
+ // "Btn": true,
306
+ // "Btn--disabled": false,
307
+ // "Btn--info--error": true,
308
+ // "Btn__Icon": true,
309
+ // "Btn__Icon--big": true,
310
+ // "Footer": false,
311
+ // })
293
312
expect ( typeCheck ) . toBeInstanceOf ( Object )
294
313
} )
295
314
} )
0 commit comments