bestax-migrate 2.4.0 → 2.5.0
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/sources/bulma-classes/class-map.d.ts +25 -4
- package/dist/sources/bulma-classes/class-map.d.ts.map +1 -1
- package/dist/sources/bulma-classes/class-map.js +127 -42
- package/dist/sources/bulma-classes/plan.d.ts +6 -0
- package/dist/sources/bulma-classes/plan.d.ts.map +1 -1
- package/dist/sources/bulma-classes/plan.js +11 -1
- package/dist/sources/bulma-classes/transform.d.ts +3 -2
- package/dist/sources/bulma-classes/transform.d.ts.map +1 -1
- package/dist/sources/bulma-classes/transform.js +53 -13
- package/package.json +1 -1
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* it: each root, modifier and helper here is rendered through the built
|
|
9
9
|
* library and compared with the raw markup it replaces.
|
|
10
10
|
*
|
|
11
|
-
* Data only
|
|
12
|
-
*
|
|
13
|
-
* imports only
|
|
11
|
+
* Data only: `scripts/gen-mcp-index.mjs` imports it directly for the MCP
|
|
12
|
+
* server's `lookup_bulma_classes`, so nothing Node cannot strip (no enums, no
|
|
13
|
+
* namespaces, type imports only), and a change to it wants `pnpm gen:mcp`.
|
|
14
14
|
*/
|
|
15
15
|
export interface PropWrite {
|
|
16
16
|
readonly prop: string;
|
|
@@ -37,7 +37,10 @@ export interface Modifier {
|
|
|
37
37
|
export type RootStatus = 'mapped' | 'todo' | 'plain';
|
|
38
38
|
export interface RootEntry {
|
|
39
39
|
readonly status: RootStatus;
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* bestax JSX name, dotted for a part (`Hero.Body`). On a `todo` family, the
|
|
42
|
+
* component a person converts the family to by hand.
|
|
43
|
+
*/
|
|
41
44
|
readonly target?: string;
|
|
42
45
|
/** The tag the target renders with no `as`. */
|
|
43
46
|
readonly tag?: string;
|
|
@@ -60,6 +63,17 @@ export interface RootEntry {
|
|
|
60
63
|
readonly untypedAttrs?: readonly string[];
|
|
61
64
|
/** The target's props type requires children. */
|
|
62
65
|
readonly requiresChildren?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* The target renders its children inside an element of its own (`Card`
|
|
68
|
+
* inside `.card-content`) unless one of them is one of these parts, so the
|
|
69
|
+
* element converts only beside a direct child that converts to one.
|
|
70
|
+
* `whenEmpty`: it renders that element with no children too.
|
|
71
|
+
*/
|
|
72
|
+
readonly wrapsChildren?: {
|
|
73
|
+
readonly in: string;
|
|
74
|
+
readonly unless: readonly string[];
|
|
75
|
+
readonly whenEmpty?: boolean;
|
|
76
|
+
};
|
|
63
77
|
/**
|
|
64
78
|
* Attributes the target types as numbers. A numeric string (`value="40"`)
|
|
65
79
|
* becomes a number, which renders the same; any other string refuses.
|
|
@@ -78,6 +92,13 @@ export interface RootEntry {
|
|
|
78
92
|
readonly part?: boolean;
|
|
79
93
|
/** Why a `todo` or `plain` root is what it is; `todo` messages quote it. */
|
|
80
94
|
readonly why?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Modifiers left out of `modifiers` on purpose, because the prop that
|
|
97
|
+
* renders the class renders more than the class. They stay in `className`;
|
|
98
|
+
* the reason is for the MCP lookup, which would otherwise say bestax has
|
|
99
|
+
* no prop for them.
|
|
100
|
+
*/
|
|
101
|
+
readonly omits?: Readonly<Record<string, string>>;
|
|
81
102
|
}
|
|
82
103
|
export declare const COLORS: readonly ["primary", "link", "info", "success", "warning", "danger", "black", "black-bis", "black-ter", "grey-darker", "grey-dark", "grey", "grey-light", "grey-lighter", "white", "white-bis", "white-ter", "light", "dark"];
|
|
83
104
|
export declare const SIZES: readonly ["0", "1", "2", "3", "4", "5", "6", "auto"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class-map.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/class-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,MAAM,GAChB;IAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAE9E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B
|
|
1
|
+
{"version":3,"file":"class-map.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/class-map.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* it: each root, modifier and helper here is rendered through the built
|
|
9
9
|
* library and compared with the raw markup it replaces.
|
|
10
10
|
*
|
|
11
|
-
* Data only
|
|
12
|
-
*
|
|
13
|
-
* imports only
|
|
11
|
+
* Data only: `scripts/gen-mcp-index.mjs` imports it directly for the MCP
|
|
12
|
+
* server's `lookup_bulma_classes`, so nothing Node cannot strip (no enums, no
|
|
13
|
+
* namespaces, type imports only), and a change to it wants `pnpm gen:mcp`.
|
|
14
14
|
*/
|
|
15
15
|
export function inTagSet(set, tag) {
|
|
16
16
|
return 'on' in set ? set.on.includes(tag) : !set.except.includes(tag);
|
|
@@ -246,7 +246,9 @@ export const ROOTS = {
|
|
|
246
246
|
'is-active': 'isActive',
|
|
247
247
|
'is-hovered': 'isHovered',
|
|
248
248
|
}),
|
|
249
|
-
|
|
249
|
+
},
|
|
250
|
+
omits: {
|
|
251
|
+
'is-disabled': 'bestax `Button` renders it through `isDisabled`, which also disables the element (`disabled`, or `aria-disabled` on a link)',
|
|
250
252
|
},
|
|
251
253
|
dropsAttr: {
|
|
252
254
|
// Kept only on the elements `disabled` means something on.
|
|
@@ -318,6 +320,86 @@ export const ROOTS = {
|
|
|
318
320
|
'size',
|
|
319
321
|
],
|
|
320
322
|
},
|
|
323
|
+
// `Card` checks its children for a part (`hasCompoundComponents` in
|
|
324
|
+
// bulma-ui's Card.tsx), and `Card.Header` for a `Card.Header.Title`
|
|
325
|
+
// (`hasHeaderTitle`), and wraps them when there is none.
|
|
326
|
+
card: {
|
|
327
|
+
...BASE,
|
|
328
|
+
target: 'Card',
|
|
329
|
+
tag: 'div',
|
|
330
|
+
wrapsChildren: {
|
|
331
|
+
in: 'card-content',
|
|
332
|
+
unless: [
|
|
333
|
+
'Card.Header',
|
|
334
|
+
'Card.Header.Icon',
|
|
335
|
+
'Card.Image',
|
|
336
|
+
'Card.Content',
|
|
337
|
+
'Card.Footer',
|
|
338
|
+
'Card.FooterItem',
|
|
339
|
+
],
|
|
340
|
+
},
|
|
341
|
+
ownProps: [
|
|
342
|
+
'textColor',
|
|
343
|
+
'color',
|
|
344
|
+
'bgColor',
|
|
345
|
+
'hasShadow',
|
|
346
|
+
'header',
|
|
347
|
+
'headerCentered',
|
|
348
|
+
'headerIcon',
|
|
349
|
+
'footer',
|
|
350
|
+
'image',
|
|
351
|
+
'imageAlt',
|
|
352
|
+
],
|
|
353
|
+
},
|
|
354
|
+
'card-header': {
|
|
355
|
+
...BASE,
|
|
356
|
+
target: 'Card.Header',
|
|
357
|
+
tag: 'header',
|
|
358
|
+
wrapsChildren: {
|
|
359
|
+
in: 'card-header-title',
|
|
360
|
+
unless: ['Card.Header.Title'],
|
|
361
|
+
whenEmpty: true,
|
|
362
|
+
},
|
|
363
|
+
ownProps: ['color', 'bgColor', 'textColor', 'centered'],
|
|
364
|
+
},
|
|
365
|
+
'card-header-title': {
|
|
366
|
+
...BASE,
|
|
367
|
+
target: 'Card.Header.Title',
|
|
368
|
+
tag: 'div',
|
|
369
|
+
modifiers: flags({ 'is-centered': 'centered' }),
|
|
370
|
+
ownProps: ['color', 'bgColor', 'textColor', 'centered'],
|
|
371
|
+
},
|
|
372
|
+
'card-header-icon': {
|
|
373
|
+
...BASE,
|
|
374
|
+
target: 'Card.Header.Icon',
|
|
375
|
+
tag: 'button',
|
|
376
|
+
defaults: { 'aria-label': 'more options' },
|
|
377
|
+
ownProps: ['color', 'bgColor', 'textColor'],
|
|
378
|
+
},
|
|
379
|
+
'card-image': {
|
|
380
|
+
...BASE,
|
|
381
|
+
target: 'Card.Image',
|
|
382
|
+
tag: 'div',
|
|
383
|
+
ownProps: ['color', 'bgColor', 'textColor'],
|
|
384
|
+
},
|
|
385
|
+
'card-content': {
|
|
386
|
+
...BASE,
|
|
387
|
+
target: 'Card.Content',
|
|
388
|
+
tag: 'div',
|
|
389
|
+
ownProps: ['color', 'bgColor', 'textColor'],
|
|
390
|
+
},
|
|
391
|
+
'card-footer': {
|
|
392
|
+
...BASE,
|
|
393
|
+
target: 'Card.Footer',
|
|
394
|
+
tag: 'footer',
|
|
395
|
+
ownProps: ['color', 'bgColor', 'textColor'],
|
|
396
|
+
},
|
|
397
|
+
'card-footer-item': {
|
|
398
|
+
...BASE,
|
|
399
|
+
target: 'Card.FooterItem',
|
|
400
|
+
tag: 'span',
|
|
401
|
+
ownProps: ['color', 'bgColor', 'textColor'],
|
|
402
|
+
},
|
|
321
403
|
columns: {
|
|
322
404
|
...BASE,
|
|
323
405
|
target: 'Columns',
|
|
@@ -656,7 +738,9 @@ export const ROOTS = {
|
|
|
656
738
|
'is-rounded': 'isRounded',
|
|
657
739
|
'is-hoverable': 'isHoverable',
|
|
658
740
|
}),
|
|
659
|
-
|
|
741
|
+
},
|
|
742
|
+
omits: {
|
|
743
|
+
'is-delete': 'bestax `Tag` renders it through `isDelete`, which also turns the tag into a <button>',
|
|
660
744
|
},
|
|
661
745
|
ownProps: [
|
|
662
746
|
'color',
|
|
@@ -698,51 +782,43 @@ export const ROOTS = {
|
|
|
698
782
|
ownProps: ['size', 'isSpaced', 'as', 'hasSkeleton', 'textColor', 'bgColor'],
|
|
699
783
|
},
|
|
700
784
|
// ---- Families bestax has but that do not map element by element yet ------
|
|
701
|
-
breadcrumb: todo('bestax `Breadcrumb` renders the `<ul>` itself and adds an `aria-label`'),
|
|
702
|
-
|
|
703
|
-
'
|
|
704
|
-
'
|
|
705
|
-
'
|
|
706
|
-
'
|
|
707
|
-
'
|
|
708
|
-
'
|
|
709
|
-
'
|
|
710
|
-
cell: todo('this source leaves Grid markup as written; convert it to bestax `Grid` and `Cell` by hand (`Grid isFixed` renders the `.fixed-grid` wrapper itself)'),
|
|
711
|
-
grid: todo('this source leaves Grid markup as written; convert it to bestax `Grid` and `Cell` by hand (`Grid isFixed` renders the `.fixed-grid` wrapper itself)'),
|
|
712
|
-
'fixed-grid': todo('this source leaves Grid markup as written; convert it to bestax `Grid` and `Cell` by hand (`Grid isFixed` renders the `.fixed-grid` wrapper itself)'),
|
|
713
|
-
checkbox: todo("bestax `Checkbox` renders its own styled markup, not Bulma's"),
|
|
714
|
-
checkboxes: todo('bestax `Checkboxes` renders its own `.field` and `.control` wrappers'),
|
|
715
|
-
radio: todo("bestax `Radio` renders its own styled markup, not Bulma's"),
|
|
716
|
-
radios: todo('bestax `Radios` renders its own `.field` and `.control` wrappers'),
|
|
717
|
-
field: todo('bestax form controls render their own `.field` and `.control` wrappers; see the unmappables reference'),
|
|
785
|
+
breadcrumb: todo('Breadcrumb', 'bestax `Breadcrumb` renders the `<ul>` itself and adds an `aria-label`'),
|
|
786
|
+
cell: todo('Cell', 'this source leaves Grid markup as written; convert it to bestax `Grid` and `Cell` by hand (`Grid isFixed` renders the `.fixed-grid` wrapper itself)'),
|
|
787
|
+
grid: todo('Grid', 'this source leaves Grid markup as written; convert it to bestax `Grid` and `Cell` by hand (`Grid isFixed` renders the `.fixed-grid` wrapper itself)'),
|
|
788
|
+
'fixed-grid': todo('Grid', 'this source leaves Grid markup as written; convert it to bestax `Grid` and `Cell` by hand (`Grid isFixed` renders the `.fixed-grid` wrapper itself)'),
|
|
789
|
+
checkbox: todo('Checkbox', "bestax `Checkbox` renders its own styled markup, not Bulma's"),
|
|
790
|
+
checkboxes: todo('Checkboxes', 'bestax `Checkboxes` renders its own `.field` and `.control` wrappers'),
|
|
791
|
+
radio: todo('Radio', "bestax `Radio` renders its own styled markup, not Bulma's"),
|
|
792
|
+
radios: todo('Radios', 'bestax `Radios` renders its own `.field` and `.control` wrappers'),
|
|
793
|
+
field: todo('Field', 'bestax form controls render their own `.field` and `.control` wrappers; see the unmappables reference'),
|
|
718
794
|
'field-label': part(),
|
|
719
795
|
'field-body': part(),
|
|
720
796
|
control: part(),
|
|
721
|
-
input: todo('bestax `Input` renders its own `.field` and `.control` wrappers'),
|
|
722
|
-
textarea: todo('bestax `TextArea` renders its own `.field` and `.control` wrappers'),
|
|
723
|
-
select: todo('bestax `Select` renders the `.select` wrapper and the `<select>` together'),
|
|
724
|
-
file: todo('bestax `File` renders the whole `.file-label` tree itself'),
|
|
797
|
+
input: todo('Input', 'bestax `Input` renders its own `.field` and `.control` wrappers'),
|
|
798
|
+
textarea: todo('TextArea', 'bestax `TextArea` renders its own `.field` and `.control` wrappers'),
|
|
799
|
+
select: todo('Select', 'bestax `Select` renders the `.select` wrapper and the `<select>` together'),
|
|
800
|
+
file: todo('File', 'bestax `File` renders the whole `.file-label` tree itself'),
|
|
725
801
|
'file-label': part(),
|
|
726
802
|
'file-input': part(),
|
|
727
803
|
'file-cta': part(),
|
|
728
804
|
'file-icon': part(),
|
|
729
805
|
'file-name': part(),
|
|
730
|
-
dropdown: todo('bestax `Dropdown` renders its own trigger and menu from props'),
|
|
806
|
+
dropdown: todo('Dropdown', 'bestax `Dropdown` renders its own trigger and menu from props'),
|
|
731
807
|
'dropdown-menu': part(),
|
|
732
808
|
'dropdown-content': part(),
|
|
733
809
|
'dropdown-item': part(),
|
|
734
810
|
'dropdown-divider': part(),
|
|
735
|
-
icon: todo('bestax `Icon` renders its own `<i>` and adds an `aria-label`'),
|
|
736
|
-
'icon-text': todo('bestax `IconText` pairs with `Icon`, which renders its own `<i>`'),
|
|
737
|
-
image: todo('bestax `Image` renders its own `<img>`'),
|
|
738
|
-
menu: todo('bestax `Menu.Item` renders the `<li>` and the `<a>` together'),
|
|
811
|
+
icon: todo('Icon', 'bestax `Icon` renders its own `<i>` and adds an `aria-label`'),
|
|
812
|
+
'icon-text': todo('IconText', 'bestax `IconText` pairs with `Icon`, which renders its own `<i>`'),
|
|
813
|
+
image: todo('Image', 'bestax `Image` renders its own `<img>`'),
|
|
814
|
+
menu: todo('Menu', 'bestax `Menu.Item` renders the `<li>` and the `<a>` together'),
|
|
739
815
|
'menu-label': part(),
|
|
740
816
|
'menu-list': part(),
|
|
741
817
|
'menu-item': part(),
|
|
742
|
-
message: todo('bestax `Message` always wraps its children in `.message-body`'),
|
|
818
|
+
message: todo('Message', 'bestax `Message` always wraps its children in `.message-body`'),
|
|
743
819
|
'message-header': part(),
|
|
744
820
|
'message-body': part(),
|
|
745
|
-
modal: todo('bestax `Modal` renders its own background and content parts, and adds dialog attributes'),
|
|
821
|
+
modal: todo('Modal', 'bestax `Modal` renders its own background and content parts, and adds dialog attributes'),
|
|
746
822
|
'modal-background': part(),
|
|
747
823
|
'modal-content': part(),
|
|
748
824
|
'modal-card': part(),
|
|
@@ -751,7 +827,7 @@ export const ROOTS = {
|
|
|
751
827
|
'modal-card-body': part(),
|
|
752
828
|
'modal-card-foot': part(),
|
|
753
829
|
'modal-close': part(),
|
|
754
|
-
navbar: todo('bestax `Navbar` adds navigation roles, and its burger renders its own spans'),
|
|
830
|
+
navbar: todo('Navbar', 'bestax `Navbar` adds navigation roles, and its burger renders its own spans'),
|
|
755
831
|
'navbar-brand': part(),
|
|
756
832
|
'navbar-burger': part(),
|
|
757
833
|
'navbar-menu': part(),
|
|
@@ -763,22 +839,22 @@ export const ROOTS = {
|
|
|
763
839
|
'navbar-divider': part(),
|
|
764
840
|
'navbar-content': part(),
|
|
765
841
|
'navbar-tabs': part(),
|
|
766
|
-
pagination: todo('bestax `Pagination` renders its own list items and adds navigation roles'),
|
|
842
|
+
pagination: todo('Pagination', 'bestax `Pagination` renders its own list items and adds navigation roles'),
|
|
767
843
|
'pagination-list': part(),
|
|
768
844
|
'pagination-link': part(),
|
|
769
845
|
'pagination-ellipsis': part(),
|
|
770
846
|
'pagination-previous': part(),
|
|
771
847
|
'pagination-next': part(),
|
|
772
|
-
panel: todo('bestax `Panel` parts render their own tags and attributes (`Panel.Block` is an `<a>`, `Panel.Icon` adds an `aria-label`)'),
|
|
848
|
+
panel: todo('Panel', 'bestax `Panel` parts render their own tags and attributes (`Panel.Block` is an `<a>`, `Panel.Icon` adds an `aria-label`)'),
|
|
773
849
|
'panel-heading': part(),
|
|
774
850
|
'panel-tabs': part(),
|
|
775
851
|
'panel-block': part(),
|
|
776
852
|
'panel-icon': part(),
|
|
777
853
|
'panel-list': part(),
|
|
778
|
-
tabs: todo("bestax `Tabs` renders each tab's `<li>` and `<a>` together, with tab roles"),
|
|
779
|
-
'table-container': todo('bestax renders `.table-container` from `Table isResponsive`'),
|
|
780
|
-
'skeleton-block': todo('bestax `Skeleton` renders its own markup'),
|
|
781
|
-
'skeleton-lines': todo('bestax `Skeleton` renders its own markup'),
|
|
854
|
+
tabs: todo('Tabs', "bestax `Tabs` renders each tab's `<li>` and `<a>` together, with tab roles"),
|
|
855
|
+
'table-container': todo('Table', 'bestax renders `.table-container` from `Table isResponsive`'),
|
|
856
|
+
'skeleton-block': todo('Skeleton', 'bestax `Skeleton` renders its own markup'),
|
|
857
|
+
'skeleton-lines': todo('Skeleton', 'bestax `Skeleton` renders its own markup'),
|
|
782
858
|
// ---- Valid Bulma, nothing to convert to --------------------------------------
|
|
783
859
|
// The other sources emit these on purpose where bestax has no component.
|
|
784
860
|
help: plain('bestax renders `.help` only inside its form controls'),
|
|
@@ -792,8 +868,8 @@ export const ROOTS = {
|
|
|
792
868
|
marginless: plain('a Bulma helper with no bestax prop'),
|
|
793
869
|
paddingless: plain('a Bulma helper with no bestax prop'),
|
|
794
870
|
};
|
|
795
|
-
function todo(why) {
|
|
796
|
-
return { status: 'todo', why };
|
|
871
|
+
function todo(target, why) {
|
|
872
|
+
return { status: 'todo', target, why };
|
|
797
873
|
}
|
|
798
874
|
function part() {
|
|
799
875
|
return { status: 'todo', part: true };
|
|
@@ -824,6 +900,15 @@ export const PRECEDENCE = [
|
|
|
824
900
|
'media-left',
|
|
825
901
|
'media-content',
|
|
826
902
|
'media-right',
|
|
903
|
+
// A part before a surface class, so the card around it still sees a part.
|
|
904
|
+
'card',
|
|
905
|
+
'card-header',
|
|
906
|
+
'card-header-title',
|
|
907
|
+
'card-header-icon',
|
|
908
|
+
'card-image',
|
|
909
|
+
'card-content',
|
|
910
|
+
'card-footer',
|
|
911
|
+
'card-footer-item',
|
|
827
912
|
'buttons',
|
|
828
913
|
'tags',
|
|
829
914
|
'button',
|
|
@@ -22,6 +22,12 @@ export interface ElementFacts {
|
|
|
22
22
|
hasRef: boolean;
|
|
23
23
|
/** Whether the element has children (JSX text, elements or expressions). */
|
|
24
24
|
hasChildren: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* The bestax components the element's child elements are, or convert to
|
|
27
|
+
* (`Card.Content`). Only a child written directly inside the element
|
|
28
|
+
* counts: one in an expression may not render.
|
|
29
|
+
*/
|
|
30
|
+
childTargets?: readonly string[];
|
|
25
31
|
/**
|
|
26
32
|
* The component this element is the only child of, if any (`Link` for
|
|
27
33
|
* `<Link href="/x"><a className="button">`), since that component can
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiBH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IACtD,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,4EAA4E;IAC5E,WAAW,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IACnD,4DAA4D;IAC5D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mEAAmE;IACnE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,8DAA8D;IAC9D,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,IAAI;IACnB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AA+BD,wBAAgB,IAAI,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiBH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IACtD,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,4EAA4E;IAC5E,WAAW,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IACnD,4DAA4D;IAC5D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mEAAmE;IACnE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,8DAA8D;IAC9D,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,IAAI;IACnB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AA+BD,wBAAgB,IAAI,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAiQ9C"}
|
|
@@ -48,7 +48,7 @@ export function plan(facts) {
|
|
|
48
48
|
todos.push({ rule: ruleId('legacy', token), message: hint });
|
|
49
49
|
}
|
|
50
50
|
// A family this source leaves as markup keeps its element as markup, even
|
|
51
|
-
// beside a class it would convert (`
|
|
51
|
+
// beside a class it would convert (`navbar box`): the family's parts carry no
|
|
52
52
|
// TODO of their own, so its outermost class is the one place it is flagged.
|
|
53
53
|
const family = tokens.find(token => {
|
|
54
54
|
const found = rootFor(token);
|
|
@@ -128,6 +128,16 @@ export function plan(facts) {
|
|
|
128
128
|
if (entry.requiresChildren && !facts.hasChildren) {
|
|
129
129
|
return refuse('children', target, `bestax \`${target}\` requires children, and this element has none; keep it as markup`);
|
|
130
130
|
}
|
|
131
|
+
const wraps = entry.wrapsChildren;
|
|
132
|
+
if (wraps &&
|
|
133
|
+
(facts.hasChildren || wraps.whenEmpty) &&
|
|
134
|
+
!facts.childTargets?.some(child => wraps.unless.includes(child))) {
|
|
135
|
+
const parts = wraps.unless.map(part => `\`${part}\``);
|
|
136
|
+
const list = parts.length > 1
|
|
137
|
+
? `${parts.slice(0, -1).join(', ')} or ${parts[parts.length - 1]}`
|
|
138
|
+
: parts[0];
|
|
139
|
+
return refuse('children', target, `bestax \`${target}\` renders its children inside a \`.${wraps.in}\` of its own unless one of them is a ${list}, so this element stays markup`);
|
|
140
|
+
}
|
|
131
141
|
if (missing.length > 0) {
|
|
132
142
|
const list = missing.map(([name, value]) => `\`${name}="${value}"\``);
|
|
133
143
|
return refuse('defaults', target, `bestax \`${target}\` renders ${list.join(' and ')} when the element does not set ${missing.length === 1 ? 'it' : 'them'}; add ${missing.length === 1 ? 'it' : 'them'} here if that is what you want, then re-run`);
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Passes, in order:
|
|
10
10
|
* 1. the shared stylesheet-import pass (a no-op under the default `keep`)
|
|
11
|
-
* 2. plan every element in scope; a computed
|
|
12
|
-
* strings in it and becomes a TODO, never
|
|
11
|
+
* 2. plan every element in scope, children before parents; a computed
|
|
12
|
+
* className is planned from the strings in it and becomes a TODO, never
|
|
13
|
+
* a conversion
|
|
13
14
|
* 3. file-level gates: a non-React JSX runtime, CommonJS, styled-jsx, and a
|
|
14
15
|
* Next.js server component (bestax's components are client components)
|
|
15
16
|
* 4. TODOs in reading order; conversions innermost first
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/transform.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAmSvD,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CA2SpB"}
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Passes, in order:
|
|
10
10
|
* 1. the shared stylesheet-import pass (a no-op under the default `keep`)
|
|
11
|
-
* 2. plan every element in scope; a computed
|
|
12
|
-
* strings in it and becomes a TODO, never
|
|
11
|
+
* 2. plan every element in scope, children before parents; a computed
|
|
12
|
+
* className is planned from the strings in it and becomes a TODO, never
|
|
13
|
+
* a conversion
|
|
13
14
|
* 3. file-level gates: a non-React JSX runtime, CommonJS, styled-jsx, and a
|
|
14
15
|
* Next.js server component (bestax's components are client components)
|
|
15
16
|
* 4. TODOs in reading order; conversions innermost first
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
*/
|
|
18
19
|
import path from 'node:path';
|
|
19
20
|
import { addTodo, findAttr, forgetJsxParens, jsxNameParts, literalValueOf, makeAttr, renameElement, reprintDirectives, } from '../_shared/jsx-utils.js';
|
|
20
|
-
import { collectBoundNames, makeReserve, prefersTabs, } from '../_shared/imports.js';
|
|
21
|
+
import { collectBoundNames, makeReserve, prefersTabs, resolvesToBinding, } from '../_shared/imports.js';
|
|
21
22
|
import { rewriteStylesheetImports } from '../_shared/css-imports.js';
|
|
22
23
|
import { BESTAX, buildBestaxImport, placeBestaxImport, seedBestaxImport, } from '../_shared/bestax-import.js';
|
|
23
24
|
import { plan } from './plan.js';
|
|
@@ -217,6 +218,17 @@ function isContent(child) {
|
|
|
217
218
|
}
|
|
218
219
|
return true;
|
|
219
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* Whether a JSX child reaches React at all. JSX drops a comment, and text
|
|
223
|
+
* made only of spaces and tabs split by a line break; it keeps the rest.
|
|
224
|
+
* `<div> </div>` has a child, which `Card` would wrap, and so does an
|
|
225
|
+
* ` ` on its own line: `trim()` would drop it, and JSX does not.
|
|
226
|
+
*/
|
|
227
|
+
function reachesReact(child) {
|
|
228
|
+
if (child.type !== 'JSXText')
|
|
229
|
+
return isContent(child);
|
|
230
|
+
return /[^ \t\r\n]/.test(child.value) || !/[\r\n]/.test(child.value);
|
|
231
|
+
}
|
|
220
232
|
function insideForeignContent(elementPath) {
|
|
221
233
|
let current = elementPath.parent;
|
|
222
234
|
while (current) {
|
|
@@ -278,29 +290,55 @@ export default function transform(fileInfo, api, options = {}) {
|
|
|
278
290
|
// every class a converted element renders.
|
|
279
291
|
rewriteStylesheetImports(ctx, root, options.cssMode ?? 'keep');
|
|
280
292
|
// ---- 2. Plan the elements in scope ----------------------------------------
|
|
281
|
-
|
|
293
|
+
// Each local bestax name, with the component path it stands for: `Card`
|
|
294
|
+
// for `import { Card as C }`, nothing for a namespace (`B.Card`).
|
|
295
|
+
const bestaxNames = new Map();
|
|
282
296
|
root
|
|
283
297
|
.find(j.ImportDeclaration, { source: { value: BESTAX } })
|
|
284
298
|
.forEach((importPath) => {
|
|
285
299
|
for (const spec of importPath.node.specifiers ?? []) {
|
|
286
|
-
if (spec.local)
|
|
287
|
-
|
|
300
|
+
if (!spec.local)
|
|
301
|
+
continue;
|
|
302
|
+
bestaxNames.set(spec.local.name, spec.type === 'ImportSpecifier' ? [spec.imported.name] : []);
|
|
288
303
|
}
|
|
289
304
|
});
|
|
305
|
+
const bestaxLocals = new Set(bestaxNames.keys());
|
|
306
|
+
// Children are planned before their parents (reverse document order), so
|
|
307
|
+
// a parent can see what its children become: `Card` converts only beside
|
|
308
|
+
// a child that is one of its parts.
|
|
309
|
+
const planned = new Map();
|
|
310
|
+
const programScope = root.find(j.Program).paths()[0]?.scope;
|
|
311
|
+
const childTargets = (elementPath) => (elementPath.node.children ?? []).flatMap((child) => {
|
|
312
|
+
if (child.type !== 'JSXElement')
|
|
313
|
+
return [];
|
|
314
|
+
const target = planned.get(child)?.conversion?.target;
|
|
315
|
+
if (target)
|
|
316
|
+
return [target];
|
|
317
|
+
// A part the file already uses counts when its name is the bestax
|
|
318
|
+
// import, not a local that shadows it. A direct child is looked up in
|
|
319
|
+
// the element's own scope, which is the child's.
|
|
320
|
+
const parts = jsxNameParts(child.openingElement.name);
|
|
321
|
+
const owner = parts && bestaxNames.get(parts[0]);
|
|
322
|
+
if (!owner || !resolvesToBinding(elementPath, parts[0], programScope)) {
|
|
323
|
+
return [];
|
|
324
|
+
}
|
|
325
|
+
return [[...owner, ...parts.slice(1)].join('.')];
|
|
326
|
+
});
|
|
290
327
|
// `converts` is whether the element would become a component with its
|
|
291
328
|
// classes written out, so it holds for a computed className too.
|
|
292
329
|
const elements = [];
|
|
293
|
-
root.find(j.JSXElement).
|
|
330
|
+
const candidates = root.find(j.JSXElement).paths();
|
|
331
|
+
for (const elementPath of [...candidates].reverse()) {
|
|
294
332
|
const element = elementPath.node;
|
|
295
333
|
const name = element.openingElement.name;
|
|
296
334
|
if (name.type !== 'JSXIdentifier' || !INTRINSIC.test(name.name))
|
|
297
|
-
|
|
335
|
+
continue;
|
|
298
336
|
if (FOREIGN_ROOTS.has(name.name) || insideForeignContent(elementPath)) {
|
|
299
|
-
|
|
337
|
+
continue;
|
|
300
338
|
}
|
|
301
339
|
const classAttr = findAttr(element, 'className');
|
|
302
340
|
if (!classAttr)
|
|
303
|
-
|
|
341
|
+
continue;
|
|
304
342
|
const attributes = new Map();
|
|
305
343
|
for (const attr of element.openingElement.attributes ?? []) {
|
|
306
344
|
if (attr.type !== 'JSXAttribute' || attr === classAttr)
|
|
@@ -316,7 +354,8 @@ export default function transform(fileInfo, api, options = {}) {
|
|
|
316
354
|
attributes,
|
|
317
355
|
hasSpread: (element.openingElement.attributes ?? []).some((attr) => attr.type === 'JSXSpreadAttribute'),
|
|
318
356
|
hasRef: attributes.has('ref'),
|
|
319
|
-
hasChildren: (element.children ?? []).some(
|
|
357
|
+
hasChildren: (element.children ?? []).some(reachesReact),
|
|
358
|
+
childTargets: childTargets(elementPath),
|
|
320
359
|
onlyChildOf: onlyChildOf(elementPath, bestaxLocals),
|
|
321
360
|
};
|
|
322
361
|
let result = plan(facts);
|
|
@@ -336,10 +375,11 @@ export default function transform(fileInfo, api, options = {}) {
|
|
|
336
375
|
],
|
|
337
376
|
};
|
|
338
377
|
}
|
|
378
|
+
planned.set(element, result);
|
|
339
379
|
if (result.conversion || result.todos.length > 0) {
|
|
340
|
-
elements.
|
|
380
|
+
elements.unshift({ path: elementPath, plan: result, converts });
|
|
341
381
|
}
|
|
342
|
-
}
|
|
382
|
+
}
|
|
343
383
|
if (elements.length === 0)
|
|
344
384
|
return print();
|
|
345
385
|
// ---- 3. File-level gates ------------------------------------------------------
|