tailwind-styled-v4 5.1.32 → 5.1.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -12,9 +12,15 @@ type HtmlTagName = keyof HTMLElementTagNameMap;
12
12
  type VariantLiterals = string | number | boolean;
13
13
  /** Sizes sugar syntax — shorthand untuk variants.size */
14
14
  type SizesConfig = Record<string, string>;
15
- type InferVariantProps<T extends ComponentConfig> = {
16
- [K in keyof T["variants"]]?: T["variants"][K] extends Record<infer Key, any> ? Key extends "true" | "false" ? boolean : Key extends number ? Key : Key extends `${infer N extends number}` ? N : Key : never;
15
+ /**
16
+ * Shared literal-narrowing logic dipakai baik oleh `InferVariantProps` (top-level
17
+ * component variants) maupun `InferSubVariantsFromConfig` (sub-component variants) —
18
+ * supaya kedua tempat itu tidak duplikasi & selalu konsisten.
19
+ */
20
+ type InferVariantPropsFromVariantsMap<V> = {
21
+ [K in keyof V]?: V[K] extends Record<infer Key, any> ? Key extends "true" | "false" ? boolean : Key extends number ? Key : Key extends `${infer N extends number}` ? N : Key : never;
17
22
  };
23
+ type InferVariantProps<T extends ComponentConfig> = InferVariantPropsFromVariantsMap<T["variants"]>;
18
24
  type InferSizeProps<T extends ComponentConfig> = T["sizes"] extends Record<string, string> ? {
19
25
  size?: keyof T["sizes"];
20
26
  } : Record<never, never>;
@@ -52,22 +58,8 @@ interface SubComponentConfig {
52
58
  class: string;
53
59
  [key: string]: string;
54
60
  }>;
55
- /**
56
- * Override HTML tag untuk direct sub-component (bare key + base/variants).
57
- * Default: "div" kalau tidak diset (backward-compatible).
58
- * @example canvas: { tag: "section", base: "...", variants: {...} }
59
- */
60
- tag?: HtmlTagName;
61
61
  }
62
62
  type SubValue = string | SubComponentConfig | Record<string, string | SubComponentConfig>;
63
- /**
64
- * Mirror dari disambiguation logic runtime di createComponent.ts (registerSubComponents):
65
- * `"base" in value || "variants" in value`
66
- * Kalau bare-key punya property "base"/"variants" langsung, value itu adalah
67
- * SubComponentConfig untuk key itu sendiri — bukan map { namaSubkomponen: classes }.
68
- * Contoh: `canvas: { base: "...", variants: {...} }` → key "canvas" ITU sendiri nama sub-component.
69
- */
70
- type IsDirectSubConfig<T> = T extends object ? ("base" extends keyof T ? true : "variants" extends keyof T ? true : false) : false;
71
63
  /**
72
64
  * Boolean props yang di-resolve via bitmask lookup table (pre-generated di build time).
73
65
  * Berbeda dari `state` (CSS data-attribute driven) — ini adalah React props boolean.
@@ -153,16 +145,29 @@ interface ComponentConfig {
153
145
  * "header" → "header" (tidak berubah)
154
146
  */
155
147
  type ExtractSubName<K extends string> = K extends `${string}:${infer Name}` ? Name : K;
148
+ /**
149
+ * True kalau S[K] adalah SubComponentConfig LANGSUNG (satu sub-component dengan
150
+ * `base`/`variants` sendiri, mis. `canvas: { base: "...", variants: {...} }`) —
151
+ * bukan nested named-group (mis. `header: { topBar: "...", nav: "..." }`).
152
+ *
153
+ * HARUS identik dengan discriminant runtime di createComponent.ts:
154
+ * `"base" in value || "variants" in value`. Kedua bentuk sama-sama tampak sebagai
155
+ * `Record<string, ...>` secara struktural, jadi tidak bisa dibedakan cuma lewat
156
+ * `extends Record<string, string>` — perlu cek keberadaan key `base`/`variants`
157
+ * secara eksplisit seperti runtime-nya.
158
+ */
159
+ type IsDirectSubConfig<V> = V extends string ? false : "variants" extends keyof V ? true : "base" extends keyof V ? true : false;
156
160
  /**
157
161
  * Infer semua sub-component names dari config.sub:
158
- * - string value plain → key langsung: { icon: "..." } → "icon"
159
- * - string value tag:name → strip tag: { "div:action": "..." } → "action"
160
- * - nested object nested keys: { h2: { title: "..." } } → "title"
162
+ * - string value plain → key langsung: { icon: "..." } → "icon"
163
+ * - string value tag:name → strip tag: { "div:action": "..." } → "action"
164
+ * - direct SubComponentConfig key langsung (support "tag:name" juga): { canvas: {base, variants} } → "canvas"
165
+ * - nested named-group → nested keys: { h2: { title: "..." } } → "title"
161
166
  */
162
167
  type InferSubFromConfig<C extends ComponentConfig> = C extends {
163
168
  sub: infer S extends Record<string, SubValue>;
164
169
  } ? {
165
- [K in keyof S]: S[K] extends string ? K extends string ? ExtractSubName<K> : never : IsDirectSubConfig<S[K]> extends true ? K : S[K] extends Record<infer N extends string, string | SubComponentConfig> ? N : never;
170
+ [K in keyof S]: S[K] extends string ? K extends string ? ExtractSubName<K> : never : IsDirectSubConfig<S[K]> extends true ? K extends string ? ExtractSubName<K> : never : S[K] extends Record<infer N extends string, string> ? N : never;
166
171
  }[keyof S] : never;
167
172
  /**
168
173
  * HTML tags yang otomatis dikenali sebagai tag dari bare sub-key (tanpa "tag:name" syntax).
@@ -197,15 +202,30 @@ type InferSubTagsFromConfig<C extends ComponentConfig> = C extends {
197
202
  [K in keyof S]: K extends string ? S[K] extends string ? {
198
203
  [N in ExtractSubName<K>]: ResolveSubTag<K>;
199
204
  } : IsDirectSubConfig<S[K]> extends true ? {
200
- [N in K]: S[K] extends {
201
- tag: infer T extends HtmlTagName;
202
- } ? T : "div";
203
- } : S[K] extends Record<string, string | SubComponentConfig> ? {
204
- [N in keyof S[K]]: S[K][N] extends {
205
- tag: infer T extends HtmlTagName;
206
- } ? T : K extends HtmlTagName ? K : "span";
205
+ [N in ExtractSubName<K>]: ResolveSubTag<K>;
206
+ } : S[K] extends Record<string, string> ? {
207
+ [N in keyof S[K]]: K extends HtmlTagName ? K : "span";
207
208
  } : never : never;
208
209
  }[keyof S]> : Record<string, never>;
210
+ /**
211
+ * Infer mapping { subComponentName: variantProps } dari config.sub — dipakai supaya
212
+ * sub-component yang punya `variants` sendiri (mis. `canvas: { base, variants: { layout: {...} } }`)
213
+ * ikut ke-expose propnya (`layout`) di accessor-nya (`PlaygroundWrap.canvas`), bukan cuma
214
+ * native HTML attributes dari tag-nya.
215
+ *
216
+ * @example
217
+ * sub: { canvas: { variants: { layout: { wrap: "...", column: "..." } } } }
218
+ * → { canvas: { layout?: "wrap" | "column" } }
219
+ */
220
+ type InferSubVariantsFromConfig<C extends ComponentConfig> = C extends {
221
+ sub: infer S extends Record<string, SubValue>;
222
+ } ? UnionToIntersection<{
223
+ [K in keyof S]: K extends string ? IsDirectSubConfig<S[K]> extends true ? S[K] extends {
224
+ variants?: infer V;
225
+ } ? {
226
+ [N in ExtractSubName<K>]: InferVariantPropsFromVariantsMap<V>;
227
+ } : Record<never, never> : Record<never, never> : Record<never, never>;
228
+ }[keyof S]> : Record<never, never>;
209
229
  interface ContainerConfig {
210
230
  base?: string;
211
231
  queries?: Record<string, string>;
@@ -228,7 +248,7 @@ interface StyledComponentProps {
228
248
  children?: React.ReactNode;
229
249
  }
230
250
  type SubComponentMap = Record<string, unknown>;
231
- type TwSubComponentAccessor<Tag extends HtmlTagName = "span"> = React.FC<Omit<React.ComponentPropsWithoutRef<Tag>, "ref"> & {
251
+ type TwSubComponentAccessor<Tag extends HtmlTagName = "span", ExtraProps extends Record<string, unknown> = Record<never, never>> = React.FC<Omit<React.ComponentPropsWithoutRef<Tag>, "ref"> & ExtraProps & {
232
252
  children?: React.ReactNode;
233
253
  className?: string;
234
254
  }>;
@@ -240,22 +260,22 @@ type TrimRight<S extends string> = S extends `${infer L} ` | `${infer L}
240
260
  ` ? TrimRight<L> : S;
241
261
  type Trim<S extends string> = TrimLeft<TrimRight<S>>;
242
262
  type ExtractSubNames<T extends string> = T extends `${string}[${infer Name}]${string}{${string}}${infer Rest}` ? Trim<Name> | ExtractSubNames<Rest> : T extends `${string}\n${infer Name}{${string}}${infer Rest}` ? (Trim<Name> extends "" ? never : Trim<Name>) | ExtractSubNames<Rest> : never;
243
- type SubComponentKeys<S extends string, TagMap extends Record<string, string> = Record<string, never>> = {
244
- [K in S]: TwSubComponentAccessor<K extends keyof TagMap ? (TagMap[K] extends HtmlTagName ? TagMap[K] : "span") : "span">;
263
+ type SubComponentKeys<S extends string, TagMap extends Record<string, string> = Record<string, never>, SubVariantsMap extends Record<string, Record<string, unknown>> = Record<string, never>> = {
264
+ [K in S]: TwSubComponentAccessor<K extends keyof TagMap ? (TagMap[K] extends HtmlTagName ? TagMap[K] : "span") : "span", K extends keyof SubVariantsMap ? SubVariantsMap[K] : Record<never, never>>;
245
265
  };
246
- type TwStyledComponent<Config extends ComponentConfig = ComponentConfig, S extends string = string, TagMap extends Record<string, string> = Record<string, never>, Tag extends HtmlTagName = HtmlTagName> = {
266
+ type TwStyledComponent<Config extends ComponentConfig = ComponentConfig, S extends string = string, TagMap extends Record<string, string> = Record<string, never>, Tag extends HtmlTagName = HtmlTagName, SubVariantsMap extends Record<string, Record<string, unknown>> = Record<string, never>> = {
247
267
  (props: React.ComponentPropsWithoutRef<Tag> & StyledComponentProps & InferVariantProps<Config> & InferSizeProps<Config> & InferStatesProps<Config>): React.ReactElement | null;
248
268
  displayName?: string;
249
269
  extend: {
250
- (strings: TemplateStringsArray, ...exprs: unknown[]): TwStyledComponent<Config, S, TagMap, Tag>;
270
+ (strings: TemplateStringsArray, ...exprs: unknown[]): TwStyledComponent<Config, S, TagMap, Tag, SubVariantsMap>;
251
271
  (config: {
252
272
  classes?: string;
253
273
  variants?: ComponentConfig["variants"];
254
274
  defaultVariants?: ComponentConfig["defaultVariants"];
255
275
  compoundVariants?: ComponentConfig["compoundVariants"];
256
- }): TwStyledComponent<Config, S, TagMap, Tag>;
276
+ }): TwStyledComponent<Config, S, TagMap, Tag, SubVariantsMap>;
257
277
  };
258
- withVariants: (config: Partial<Config>) => TwStyledComponent<Config, S, TagMap, Tag>;
278
+ withVariants: (config: Partial<Config>) => TwStyledComponent<Config, S, TagMap, Tag, SubVariantsMap>;
259
279
  /**
260
280
  * Declare sub-component names secara eksplisit untuk autocomplete + type safety.
261
281
  *
@@ -269,14 +289,14 @@ type TwStyledComponent<Config extends ComponentConfig = ComponentConfig, S exten
269
289
  * Button.footer // ✅ autocomplete
270
290
  * Button.xyz // ❌ TypeScript error
271
291
  */
272
- withSub<NewS extends string>(): TwStyledComponent<Config, NewS, TagMap, Tag>;
273
- } & SubComponentKeys<S, TagMap>;
292
+ withSub<NewS extends string>(): TwStyledComponent<Config, NewS, TagMap, Tag, SubVariantsMap>;
293
+ } & SubComponentKeys<S, TagMap, SubVariantsMap>;
274
294
  interface TwSubComponent<P = unknown> {
275
295
  (props: P): React.ReactElement | null;
276
296
  displayName?: string;
277
297
  }
278
298
  interface TwTemplateFactory<Config extends ComponentConfig = ComponentConfig, Tag extends HtmlTagName = HtmlTagName> {
279
- <C extends ComponentConfig>(config: C): TwStyledComponent<C, InferSubFromConfig<C>, InferSubTagsFromConfig<C> extends Record<string, string> ? InferSubTagsFromConfig<C> : Record<string, never>, Tag>;
299
+ <C extends ComponentConfig>(config: C): TwStyledComponent<C, InferSubFromConfig<C>, InferSubTagsFromConfig<C> extends Record<string, string> ? InferSubTagsFromConfig<C> : Record<string, never>, Tag, InferSubVariantsFromConfig<C> extends Record<string, Record<string, unknown>> ? InferSubVariantsFromConfig<C> : Record<string, never>>;
280
300
  <const T extends string>(strings: readonly [T], ...exprs: []): TwStyledComponent<Config, ExtractSubNames<T>, Record<string, never>, Tag>;
281
301
  (strings: TemplateStringsArray, ...exprs: unknown[]): TwStyledComponent<Config, string, Record<string, never>, Tag>;
282
302
  }
package/dist/index.d.ts CHANGED
@@ -12,9 +12,15 @@ type HtmlTagName = keyof HTMLElementTagNameMap;
12
12
  type VariantLiterals = string | number | boolean;
13
13
  /** Sizes sugar syntax — shorthand untuk variants.size */
14
14
  type SizesConfig = Record<string, string>;
15
- type InferVariantProps<T extends ComponentConfig> = {
16
- [K in keyof T["variants"]]?: T["variants"][K] extends Record<infer Key, any> ? Key extends "true" | "false" ? boolean : Key extends number ? Key : Key extends `${infer N extends number}` ? N : Key : never;
15
+ /**
16
+ * Shared literal-narrowing logic dipakai baik oleh `InferVariantProps` (top-level
17
+ * component variants) maupun `InferSubVariantsFromConfig` (sub-component variants) —
18
+ * supaya kedua tempat itu tidak duplikasi & selalu konsisten.
19
+ */
20
+ type InferVariantPropsFromVariantsMap<V> = {
21
+ [K in keyof V]?: V[K] extends Record<infer Key, any> ? Key extends "true" | "false" ? boolean : Key extends number ? Key : Key extends `${infer N extends number}` ? N : Key : never;
17
22
  };
23
+ type InferVariantProps<T extends ComponentConfig> = InferVariantPropsFromVariantsMap<T["variants"]>;
18
24
  type InferSizeProps<T extends ComponentConfig> = T["sizes"] extends Record<string, string> ? {
19
25
  size?: keyof T["sizes"];
20
26
  } : Record<never, never>;
@@ -52,22 +58,8 @@ interface SubComponentConfig {
52
58
  class: string;
53
59
  [key: string]: string;
54
60
  }>;
55
- /**
56
- * Override HTML tag untuk direct sub-component (bare key + base/variants).
57
- * Default: "div" kalau tidak diset (backward-compatible).
58
- * @example canvas: { tag: "section", base: "...", variants: {...} }
59
- */
60
- tag?: HtmlTagName;
61
61
  }
62
62
  type SubValue = string | SubComponentConfig | Record<string, string | SubComponentConfig>;
63
- /**
64
- * Mirror dari disambiguation logic runtime di createComponent.ts (registerSubComponents):
65
- * `"base" in value || "variants" in value`
66
- * Kalau bare-key punya property "base"/"variants" langsung, value itu adalah
67
- * SubComponentConfig untuk key itu sendiri — bukan map { namaSubkomponen: classes }.
68
- * Contoh: `canvas: { base: "...", variants: {...} }` → key "canvas" ITU sendiri nama sub-component.
69
- */
70
- type IsDirectSubConfig<T> = T extends object ? ("base" extends keyof T ? true : "variants" extends keyof T ? true : false) : false;
71
63
  /**
72
64
  * Boolean props yang di-resolve via bitmask lookup table (pre-generated di build time).
73
65
  * Berbeda dari `state` (CSS data-attribute driven) — ini adalah React props boolean.
@@ -153,16 +145,29 @@ interface ComponentConfig {
153
145
  * "header" → "header" (tidak berubah)
154
146
  */
155
147
  type ExtractSubName<K extends string> = K extends `${string}:${infer Name}` ? Name : K;
148
+ /**
149
+ * True kalau S[K] adalah SubComponentConfig LANGSUNG (satu sub-component dengan
150
+ * `base`/`variants` sendiri, mis. `canvas: { base: "...", variants: {...} }`) —
151
+ * bukan nested named-group (mis. `header: { topBar: "...", nav: "..." }`).
152
+ *
153
+ * HARUS identik dengan discriminant runtime di createComponent.ts:
154
+ * `"base" in value || "variants" in value`. Kedua bentuk sama-sama tampak sebagai
155
+ * `Record<string, ...>` secara struktural, jadi tidak bisa dibedakan cuma lewat
156
+ * `extends Record<string, string>` — perlu cek keberadaan key `base`/`variants`
157
+ * secara eksplisit seperti runtime-nya.
158
+ */
159
+ type IsDirectSubConfig<V> = V extends string ? false : "variants" extends keyof V ? true : "base" extends keyof V ? true : false;
156
160
  /**
157
161
  * Infer semua sub-component names dari config.sub:
158
- * - string value plain → key langsung: { icon: "..." } → "icon"
159
- * - string value tag:name → strip tag: { "div:action": "..." } → "action"
160
- * - nested object nested keys: { h2: { title: "..." } } → "title"
162
+ * - string value plain → key langsung: { icon: "..." } → "icon"
163
+ * - string value tag:name → strip tag: { "div:action": "..." } → "action"
164
+ * - direct SubComponentConfig key langsung (support "tag:name" juga): { canvas: {base, variants} } → "canvas"
165
+ * - nested named-group → nested keys: { h2: { title: "..." } } → "title"
161
166
  */
162
167
  type InferSubFromConfig<C extends ComponentConfig> = C extends {
163
168
  sub: infer S extends Record<string, SubValue>;
164
169
  } ? {
165
- [K in keyof S]: S[K] extends string ? K extends string ? ExtractSubName<K> : never : IsDirectSubConfig<S[K]> extends true ? K : S[K] extends Record<infer N extends string, string | SubComponentConfig> ? N : never;
170
+ [K in keyof S]: S[K] extends string ? K extends string ? ExtractSubName<K> : never : IsDirectSubConfig<S[K]> extends true ? K extends string ? ExtractSubName<K> : never : S[K] extends Record<infer N extends string, string> ? N : never;
166
171
  }[keyof S] : never;
167
172
  /**
168
173
  * HTML tags yang otomatis dikenali sebagai tag dari bare sub-key (tanpa "tag:name" syntax).
@@ -197,15 +202,30 @@ type InferSubTagsFromConfig<C extends ComponentConfig> = C extends {
197
202
  [K in keyof S]: K extends string ? S[K] extends string ? {
198
203
  [N in ExtractSubName<K>]: ResolveSubTag<K>;
199
204
  } : IsDirectSubConfig<S[K]> extends true ? {
200
- [N in K]: S[K] extends {
201
- tag: infer T extends HtmlTagName;
202
- } ? T : "div";
203
- } : S[K] extends Record<string, string | SubComponentConfig> ? {
204
- [N in keyof S[K]]: S[K][N] extends {
205
- tag: infer T extends HtmlTagName;
206
- } ? T : K extends HtmlTagName ? K : "span";
205
+ [N in ExtractSubName<K>]: ResolveSubTag<K>;
206
+ } : S[K] extends Record<string, string> ? {
207
+ [N in keyof S[K]]: K extends HtmlTagName ? K : "span";
207
208
  } : never : never;
208
209
  }[keyof S]> : Record<string, never>;
210
+ /**
211
+ * Infer mapping { subComponentName: variantProps } dari config.sub — dipakai supaya
212
+ * sub-component yang punya `variants` sendiri (mis. `canvas: { base, variants: { layout: {...} } }`)
213
+ * ikut ke-expose propnya (`layout`) di accessor-nya (`PlaygroundWrap.canvas`), bukan cuma
214
+ * native HTML attributes dari tag-nya.
215
+ *
216
+ * @example
217
+ * sub: { canvas: { variants: { layout: { wrap: "...", column: "..." } } } }
218
+ * → { canvas: { layout?: "wrap" | "column" } }
219
+ */
220
+ type InferSubVariantsFromConfig<C extends ComponentConfig> = C extends {
221
+ sub: infer S extends Record<string, SubValue>;
222
+ } ? UnionToIntersection<{
223
+ [K in keyof S]: K extends string ? IsDirectSubConfig<S[K]> extends true ? S[K] extends {
224
+ variants?: infer V;
225
+ } ? {
226
+ [N in ExtractSubName<K>]: InferVariantPropsFromVariantsMap<V>;
227
+ } : Record<never, never> : Record<never, never> : Record<never, never>;
228
+ }[keyof S]> : Record<never, never>;
209
229
  interface ContainerConfig {
210
230
  base?: string;
211
231
  queries?: Record<string, string>;
@@ -228,7 +248,7 @@ interface StyledComponentProps {
228
248
  children?: React.ReactNode;
229
249
  }
230
250
  type SubComponentMap = Record<string, unknown>;
231
- type TwSubComponentAccessor<Tag extends HtmlTagName = "span"> = React.FC<Omit<React.ComponentPropsWithoutRef<Tag>, "ref"> & {
251
+ type TwSubComponentAccessor<Tag extends HtmlTagName = "span", ExtraProps extends Record<string, unknown> = Record<never, never>> = React.FC<Omit<React.ComponentPropsWithoutRef<Tag>, "ref"> & ExtraProps & {
232
252
  children?: React.ReactNode;
233
253
  className?: string;
234
254
  }>;
@@ -240,22 +260,22 @@ type TrimRight<S extends string> = S extends `${infer L} ` | `${infer L}
240
260
  ` ? TrimRight<L> : S;
241
261
  type Trim<S extends string> = TrimLeft<TrimRight<S>>;
242
262
  type ExtractSubNames<T extends string> = T extends `${string}[${infer Name}]${string}{${string}}${infer Rest}` ? Trim<Name> | ExtractSubNames<Rest> : T extends `${string}\n${infer Name}{${string}}${infer Rest}` ? (Trim<Name> extends "" ? never : Trim<Name>) | ExtractSubNames<Rest> : never;
243
- type SubComponentKeys<S extends string, TagMap extends Record<string, string> = Record<string, never>> = {
244
- [K in S]: TwSubComponentAccessor<K extends keyof TagMap ? (TagMap[K] extends HtmlTagName ? TagMap[K] : "span") : "span">;
263
+ type SubComponentKeys<S extends string, TagMap extends Record<string, string> = Record<string, never>, SubVariantsMap extends Record<string, Record<string, unknown>> = Record<string, never>> = {
264
+ [K in S]: TwSubComponentAccessor<K extends keyof TagMap ? (TagMap[K] extends HtmlTagName ? TagMap[K] : "span") : "span", K extends keyof SubVariantsMap ? SubVariantsMap[K] : Record<never, never>>;
245
265
  };
246
- type TwStyledComponent<Config extends ComponentConfig = ComponentConfig, S extends string = string, TagMap extends Record<string, string> = Record<string, never>, Tag extends HtmlTagName = HtmlTagName> = {
266
+ type TwStyledComponent<Config extends ComponentConfig = ComponentConfig, S extends string = string, TagMap extends Record<string, string> = Record<string, never>, Tag extends HtmlTagName = HtmlTagName, SubVariantsMap extends Record<string, Record<string, unknown>> = Record<string, never>> = {
247
267
  (props: React.ComponentPropsWithoutRef<Tag> & StyledComponentProps & InferVariantProps<Config> & InferSizeProps<Config> & InferStatesProps<Config>): React.ReactElement | null;
248
268
  displayName?: string;
249
269
  extend: {
250
- (strings: TemplateStringsArray, ...exprs: unknown[]): TwStyledComponent<Config, S, TagMap, Tag>;
270
+ (strings: TemplateStringsArray, ...exprs: unknown[]): TwStyledComponent<Config, S, TagMap, Tag, SubVariantsMap>;
251
271
  (config: {
252
272
  classes?: string;
253
273
  variants?: ComponentConfig["variants"];
254
274
  defaultVariants?: ComponentConfig["defaultVariants"];
255
275
  compoundVariants?: ComponentConfig["compoundVariants"];
256
- }): TwStyledComponent<Config, S, TagMap, Tag>;
276
+ }): TwStyledComponent<Config, S, TagMap, Tag, SubVariantsMap>;
257
277
  };
258
- withVariants: (config: Partial<Config>) => TwStyledComponent<Config, S, TagMap, Tag>;
278
+ withVariants: (config: Partial<Config>) => TwStyledComponent<Config, S, TagMap, Tag, SubVariantsMap>;
259
279
  /**
260
280
  * Declare sub-component names secara eksplisit untuk autocomplete + type safety.
261
281
  *
@@ -269,14 +289,14 @@ type TwStyledComponent<Config extends ComponentConfig = ComponentConfig, S exten
269
289
  * Button.footer // ✅ autocomplete
270
290
  * Button.xyz // ❌ TypeScript error
271
291
  */
272
- withSub<NewS extends string>(): TwStyledComponent<Config, NewS, TagMap, Tag>;
273
- } & SubComponentKeys<S, TagMap>;
292
+ withSub<NewS extends string>(): TwStyledComponent<Config, NewS, TagMap, Tag, SubVariantsMap>;
293
+ } & SubComponentKeys<S, TagMap, SubVariantsMap>;
274
294
  interface TwSubComponent<P = unknown> {
275
295
  (props: P): React.ReactElement | null;
276
296
  displayName?: string;
277
297
  }
278
298
  interface TwTemplateFactory<Config extends ComponentConfig = ComponentConfig, Tag extends HtmlTagName = HtmlTagName> {
279
- <C extends ComponentConfig>(config: C): TwStyledComponent<C, InferSubFromConfig<C>, InferSubTagsFromConfig<C> extends Record<string, string> ? InferSubTagsFromConfig<C> : Record<string, never>, Tag>;
299
+ <C extends ComponentConfig>(config: C): TwStyledComponent<C, InferSubFromConfig<C>, InferSubTagsFromConfig<C> extends Record<string, string> ? InferSubTagsFromConfig<C> : Record<string, never>, Tag, InferSubVariantsFromConfig<C> extends Record<string, Record<string, unknown>> ? InferSubVariantsFromConfig<C> : Record<string, never>>;
280
300
  <const T extends string>(strings: readonly [T], ...exprs: []): TwStyledComponent<Config, ExtractSubNames<T>, Record<string, never>, Tag>;
281
301
  (strings: TemplateStringsArray, ...exprs: unknown[]): TwStyledComponent<Config, string, Record<string, never>, Tag>;
282
302
  }
package/dist/index.js CHANGED
@@ -913,8 +913,7 @@ function registerSubComponents(component, template, configSub) {
913
913
  tag
914
914
  );
915
915
  } else if ("base" in value || "variants" in value) {
916
- const explicitTag = value.tag ?? "div";
917
- map[key] = createComponent(explicitTag, value);
916
+ map[key] = createComponent("div", value);
918
917
  } else {
919
918
  const tag = key;
920
919
  for (const [componentName, classesOrConfig] of Object.entries(value)) {
@@ -926,8 +925,7 @@ function registerSubComponents(component, template, configSub) {
926
925
  tag
927
926
  );
928
927
  } else {
929
- const nestedTag = classesOrConfig.tag ?? tag;
930
- map[componentName] = createComponent(nestedTag, classesOrConfig);
928
+ map[componentName] = createComponent(tag, classesOrConfig);
931
929
  }
932
930
  }
933
931
  }