bestax-migrate 2.2.2 → 2.3.1
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/README.md +12 -10
- package/dist/sources/_shared/imports.d.ts +28 -0
- package/dist/sources/_shared/imports.d.ts.map +1 -1
- package/dist/sources/_shared/imports.js +62 -0
- package/dist/sources/_shared/jsx-utils.d.ts +17 -0
- package/dist/sources/_shared/jsx-utils.d.ts.map +1 -1
- package/dist/sources/_shared/jsx-utils.js +49 -1
- package/dist/sources/_shared/props.d.ts +17 -0
- package/dist/sources/_shared/props.d.ts.map +1 -1
- package/dist/sources/_shared/props.js +72 -3
- package/dist/sources/_shared/specials-utils.d.ts +49 -3
- package/dist/sources/_shared/specials-utils.d.ts.map +1 -1
- package/dist/sources/_shared/specials-utils.js +165 -5
- package/dist/sources/_shared/viewports.d.ts +17 -0
- package/dist/sources/_shared/viewports.d.ts.map +1 -0
- package/dist/sources/_shared/viewports.js +32 -0
- package/dist/sources/bloomer/deps.d.ts +17 -0
- package/dist/sources/bloomer/deps.d.ts.map +1 -0
- package/dist/sources/bloomer/deps.js +119 -0
- package/dist/sources/bloomer/index.d.ts +3 -0
- package/dist/sources/bloomer/index.d.ts.map +1 -0
- package/dist/sources/bloomer/index.js +10 -0
- package/dist/sources/bloomer/mapping.d.ts +84 -0
- package/dist/sources/bloomer/mapping.d.ts.map +1 -0
- package/dist/sources/bloomer/mapping.js +988 -0
- package/dist/sources/bloomer/responsive.d.ts +39 -0
- package/dist/sources/bloomer/responsive.d.ts.map +1 -0
- package/dist/sources/bloomer/responsive.js +259 -0
- package/dist/sources/bloomer/specials.d.ts +19 -0
- package/dist/sources/bloomer/specials.d.ts.map +1 -0
- package/dist/sources/bloomer/specials.js +774 -0
- package/dist/sources/bloomer/styles.d.ts +13 -0
- package/dist/sources/bloomer/styles.d.ts.map +1 -0
- package/dist/sources/bloomer/styles.js +17 -0
- package/dist/sources/bloomer/transform.d.ts +27 -0
- package/dist/sources/bloomer/transform.d.ts.map +1 -0
- package/dist/sources/bloomer/transform.js +826 -0
- package/dist/sources/rbx/responsive.d.ts.map +1 -1
- package/dist/sources/rbx/responsive.js +1 -31
- package/dist/sources/rbx/specials.d.ts.map +1 -1
- package/dist/sources/rbx/specials.js +14 -91
- package/dist/sources/rbx/transform.d.ts.map +1 -1
- package/dist/sources/rbx/transform.js +168 -78
- package/dist/sources/react-bulma-components/responsive.d.ts.map +1 -1
- package/dist/sources/react-bulma-components/responsive.js +2 -14
- package/dist/sources/react-bulma-components/specials.d.ts.map +1 -1
- package/dist/sources/react-bulma-components/specials.js +33 -17
- package/dist/sources/react-bulma-components/transform.d.ts.map +1 -1
- package/dist/sources/react-bulma-components/transform.js +168 -78
- package/dist/sources/registry.d.ts.map +1 -1
- package/dist/sources/registry.js +2 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -5
|
@@ -0,0 +1,988 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bloomer (0.6) → @allxsmith/bestax-bulma mapping tables.
|
|
3
|
+
*
|
|
4
|
+
* Data only — no AST work. `MAPPING` is the single source of truth for what
|
|
5
|
+
* the transform does with each bloomer export; `BLOOMER_EXPORTS` vendors
|
|
6
|
+
* bloomer's public surface so `mapping-coverage.test.ts` can close it in both
|
|
7
|
+
* directions.
|
|
8
|
+
*
|
|
9
|
+
* bloomer's shape is the reverse of rbx's: every export is a FLAT name
|
|
10
|
+
* (`CardHeaderTitle`, `NavbarItem`), while bestax groups the same components
|
|
11
|
+
* into dotted compounds (`Card.Header.Title`, `Navbar.Item`). So most rows
|
|
12
|
+
* here rename a flat identifier onto a dotted target — a shape the rename and
|
|
13
|
+
* value-reference passes already build, since the first segment of a dotted
|
|
14
|
+
* target is what gets imported.
|
|
15
|
+
*
|
|
16
|
+
* Its modifier vocabulary is already bestax's for the booleans (`isActive`,
|
|
17
|
+
* `isLoading`, `isOutlined`, …) — those are `{}` entries, present so the
|
|
18
|
+
* universal pass never sees them. What differs is the value-carrying props:
|
|
19
|
+
* `isColor` → `color`, `isSize` → `size` (claimed per component, because its
|
|
20
|
+
* type differs per component: numeric on Title/Subtitle, sizes-or-fractions on
|
|
21
|
+
* Column, `'128x128'` on Image, `'large'` elsewhere), `isAlign` → whatever
|
|
22
|
+
* the target calls it, and `tag` → `as` where bestax declares one.
|
|
23
|
+
*/
|
|
24
|
+
const DOCS = 'https://bestax.io/docs';
|
|
25
|
+
/**
|
|
26
|
+
* The two Bulma 0.6 shades bestax's `validColors` does not carry. Every other
|
|
27
|
+
* colour and shade name of that era exists in bestax verbatim.
|
|
28
|
+
*/
|
|
29
|
+
const SHADE_TODO = {
|
|
30
|
+
'white-ter': `\`white-ter\` is not a bestax colour; use \`white\` or a custom class (${DOCS}/api/helpers/usebulmaclasses)`,
|
|
31
|
+
'white-bis': `\`white-bis\` is not a bestax colour; use \`white\` or a custom class (${DOCS}/api/helpers/usebulmaclasses)`,
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* `tag` is on nearly every bloomer component (`Bulma.Tag`, rendered through
|
|
35
|
+
* `React.createElement(tag, …)`), but bestax declares `as` on only some
|
|
36
|
+
* components, several of them constrained to a literal union (`Footer` is
|
|
37
|
+
* `'footer' | 'div'`). So the default is a TODO, and the components whose
|
|
38
|
+
* bestax counterpart really does accept `as` opt in with `TAG_AS` in their
|
|
39
|
+
* own prop map, which runs first and wins. A literal outside the target's
|
|
40
|
+
* union still surfaces — as a type error the user can see, not a rewrite.
|
|
41
|
+
*/
|
|
42
|
+
const TAG_TODO = {
|
|
43
|
+
todo: `bloomer's \`tag\` renders a different HTML element; bestax declares \`as\` on only some components, and this is not one of them — render the tag directly or restructure (${DOCS}/api)`,
|
|
44
|
+
};
|
|
45
|
+
const TAG_AS = { rename: 'as' };
|
|
46
|
+
/**
|
|
47
|
+
* `render` (`Bulma.Render`) let a component hand its computed props to a
|
|
48
|
+
* custom renderer. bestax has no render-prop escape hatch, and there is no
|
|
49
|
+
* way to rewrite a function value into markup, so it is always a TODO.
|
|
50
|
+
*/
|
|
51
|
+
export const RENDER_TODO = {
|
|
52
|
+
todo: `bloomer's \`render\` prop injected the computed props into your own renderer; bestax has no render-prop escape hatch — render the markup directly (\`useBulmaClasses\` yields the helper classes) or wrap the component (${DOCS}/api/helpers/usebulmaclasses)`,
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* `isFullWidth` is universal in bloomer (via `withHelpersModifiers`), but
|
|
56
|
+
* Bulma's `is-fullwidth` only means something on a handful of elements, and
|
|
57
|
+
* bestax declares `isFullWidth` on exactly those: Button, Select, Table and
|
|
58
|
+
* Tabs opt in with `FULLWIDTH_OK`.
|
|
59
|
+
*/
|
|
60
|
+
const FULLWIDTH_TODO = {
|
|
61
|
+
todo: 'Bulma defines `is-fullwidth` only on buttons, files, images, inputs, textareas, selects, tables and tabs, and this is none of them — drop it, or add className="is-fullwidth" if your own CSS styled the class',
|
|
62
|
+
};
|
|
63
|
+
/** Bulma styles `is-fullwidth` here, but bestax declares no prop for it. */
|
|
64
|
+
const FULLWIDTH_CLASS = { toClass: 'is-fullwidth' };
|
|
65
|
+
const FULLWIDTH_OK = {};
|
|
66
|
+
/**
|
|
67
|
+
* `textColor` is not part of `BulmaClassesProps` — each component declares it
|
|
68
|
+
* by hand, and many do not. So it is claimed per component, like `isSize`;
|
|
69
|
+
* everywhere else bloomer's `hasTextColor` becomes the Bulma class it stood
|
|
70
|
+
* for, which every element takes.
|
|
71
|
+
*/
|
|
72
|
+
const TEXT_COLOR_OK = {
|
|
73
|
+
rename: 'textColor',
|
|
74
|
+
valueTodo: SHADE_TODO,
|
|
75
|
+
};
|
|
76
|
+
const size = { rename: 'size' };
|
|
77
|
+
const color = { rename: 'color' };
|
|
78
|
+
const active = { rename: 'active' };
|
|
79
|
+
const NAV_TODO = (name) => ({
|
|
80
|
+
status: 'todo',
|
|
81
|
+
todo: `\`${name}\` is Bulma 0.4's \`.nav\`, which Bulma removed in 0.5 (bloomer kept the component); rebuild it with bestax's \`Navbar\` — \`Nav\` → \`Navbar\`, \`NavLeft\`/\`NavRight\` → \`Navbar.Start\`/\`Navbar.End\`, \`NavItem\` → \`Navbar.Item\`, \`NavToggle\` → \`Navbar.Burger\` (${DOCS}/api/components/navbar)`,
|
|
82
|
+
});
|
|
83
|
+
/**
|
|
84
|
+
* bestax's `Message.color` is the six semantic colours; bloomer's `isColor`
|
|
85
|
+
* is any string. The Bulma 0.6 colours outside that union are named so they
|
|
86
|
+
* become a TODO instead of a silent type error.
|
|
87
|
+
*/
|
|
88
|
+
const MESSAGE_COLOR_TODO = Object.fromEntries(['white', 'black', 'light', 'dark'].map(c => [
|
|
89
|
+
c,
|
|
90
|
+
`bestax \`Message\` takes only the semantic colours (primary … danger); use \`bgColor="${c}"\` or a custom class`,
|
|
91
|
+
]));
|
|
92
|
+
/**
|
|
93
|
+
* Helper props `withHelpersModifiers` mixes into EVERY bloomer component.
|
|
94
|
+
* Applied after each component's own prop map, to whatever attributes are
|
|
95
|
+
* left.
|
|
96
|
+
*
|
|
97
|
+
* `isDisplay` and `isHidden` are deliberately absent: they are consumed
|
|
98
|
+
* structurally by responsive.ts before this pass runs (their values are
|
|
99
|
+
* strings, arrays or objects that flatten to several bestax props), and
|
|
100
|
+
* bestax has no prop of either name, so a leftover would be an
|
|
101
|
+
* excess-property type error rather than a TODO.
|
|
102
|
+
*/
|
|
103
|
+
export const UNIVERSAL_PROPS = {
|
|
104
|
+
// --- typography ----------------------------------------------------------
|
|
105
|
+
hasTextAlign: { rename: 'textAlign' }, // left | right | centered — same union
|
|
106
|
+
// Per-component maps override this wherever the target declares `textColor`.
|
|
107
|
+
hasTextColor: { toClassPrefix: 'has-text-' },
|
|
108
|
+
// --- float / overlay -----------------------------------------------------
|
|
109
|
+
isPulled: { rename: 'float' }, // left | right — same union
|
|
110
|
+
isClearfix: { booleanToProp: { name: 'clearfix' } },
|
|
111
|
+
isOverlay: { booleanToProp: { name: 'overlay' } },
|
|
112
|
+
isUnselectable: {
|
|
113
|
+
booleanToProp: { name: 'interaction', value: 'unselectable' },
|
|
114
|
+
},
|
|
115
|
+
// --- spacing: bestax expresses the `is-*less` helpers as `m`/`p` --------
|
|
116
|
+
isMarginless: { booleanToProp: { name: 'm', value: '0' } },
|
|
117
|
+
isPaddingless: { booleanToProp: { name: 'p', value: '0' } },
|
|
118
|
+
// Per-component maps override these where bestax has the prop.
|
|
119
|
+
isFullWidth: FULLWIDTH_TODO,
|
|
120
|
+
tag: TAG_TODO,
|
|
121
|
+
render: RENDER_TODO,
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* The helper props responsive.ts consumes. Named here so the plain-element
|
|
125
|
+
* path can strip them from an element that is becoming intrinsic HTML: the
|
|
126
|
+
* structural pass runs before the rename step, which a `replaced: true`
|
|
127
|
+
* special skips.
|
|
128
|
+
*/
|
|
129
|
+
export const RESPONSIVE_PROPS = {
|
|
130
|
+
isDisplay: null,
|
|
131
|
+
isHidden: null,
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* bestax targets that extend only React's HTML attributes — no
|
|
135
|
+
* `BulmaClassesProps` — so bloomer's universal helpers have no prop to land
|
|
136
|
+
* on. The transform turns each into a TODO naming the Bulma class instead of
|
|
137
|
+
* emitting an excess-property type error.
|
|
138
|
+
*/
|
|
139
|
+
/**
|
|
140
|
+
* Targets whose `className` cannot be used: `Navbar.Divider` and
|
|
141
|
+
* `Pagination.Ellipsis` spread `{...props}` AFTER their own className (so one
|
|
142
|
+
* written here replaces the class that makes them work), and
|
|
143
|
+
* `Dropdown.Divider` is a bare `React.FC` that declares no props at all and
|
|
144
|
+
* renders its own `<hr>` regardless. A helper on one of these is named, never
|
|
145
|
+
* converted.
|
|
146
|
+
*/
|
|
147
|
+
export const NO_CLASSNAME_TARGETS = new Set([
|
|
148
|
+
'Navbar.Divider',
|
|
149
|
+
'Pagination.Ellipsis',
|
|
150
|
+
'Dropdown.Divider',
|
|
151
|
+
]);
|
|
152
|
+
export const HELPERLESS_TARGETS = new Set([
|
|
153
|
+
'Pagination.Previous',
|
|
154
|
+
'Pagination.Next',
|
|
155
|
+
'Navbar.Dropdown',
|
|
156
|
+
'Navbar.DropdownMenu',
|
|
157
|
+
'Dropdown.Divider',
|
|
158
|
+
'Panel.Heading',
|
|
159
|
+
'Panel.Tabs',
|
|
160
|
+
'Panel.Block',
|
|
161
|
+
'Tabs.List',
|
|
162
|
+
'Tabs.Item',
|
|
163
|
+
'Message.Header',
|
|
164
|
+
'Message.Body',
|
|
165
|
+
'Modal.Background',
|
|
166
|
+
'Modal.Content',
|
|
167
|
+
'Modal.Card',
|
|
168
|
+
'Modal.Card.Head',
|
|
169
|
+
'Modal.Card.Title',
|
|
170
|
+
'Modal.Card.Body',
|
|
171
|
+
'Modal.Card.Foot',
|
|
172
|
+
'Modal.Close',
|
|
173
|
+
]);
|
|
174
|
+
/** The Bulma class a helper prop stood for, for the hint on those targets. */
|
|
175
|
+
export function helperClassHint(name, value) {
|
|
176
|
+
const v = typeof value === 'string' ? value : undefined;
|
|
177
|
+
switch (name) {
|
|
178
|
+
case 'hasTextAlign':
|
|
179
|
+
return `has-text-${v ?? '<alignment>'}`;
|
|
180
|
+
case 'hasTextColor':
|
|
181
|
+
return `has-text-${v ?? '<colour>'}`;
|
|
182
|
+
case 'isPulled':
|
|
183
|
+
return `is-pulled-${v ?? '<side>'}`;
|
|
184
|
+
case 'isClearfix':
|
|
185
|
+
return 'is-clearfix';
|
|
186
|
+
case 'isOverlay':
|
|
187
|
+
return 'is-overlay';
|
|
188
|
+
case 'isUnselectable':
|
|
189
|
+
return 'is-unselectable';
|
|
190
|
+
case 'isMarginless':
|
|
191
|
+
return 'm-0';
|
|
192
|
+
case 'isPaddingless':
|
|
193
|
+
return 'p-0';
|
|
194
|
+
case 'isDisplay':
|
|
195
|
+
return `is-${v ?? '<display>[-<viewport>]'}`;
|
|
196
|
+
case 'isHidden':
|
|
197
|
+
return v ? `is-hidden-${v}` : 'is-hidden';
|
|
198
|
+
default:
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/** Bloomer's fraction and width spellings → bestax's `BulmaColumnSize` names. */
|
|
203
|
+
export const COLUMN_SIZE_MAP = {
|
|
204
|
+
'1/2': 'half',
|
|
205
|
+
'1/3': 'one-third',
|
|
206
|
+
'1/4': 'one-quarter',
|
|
207
|
+
'2/3': 'two-thirds',
|
|
208
|
+
'3/4': 'three-quarters',
|
|
209
|
+
full: 'full',
|
|
210
|
+
};
|
|
211
|
+
export const MAPPING = {
|
|
212
|
+
// ---- grid ---------------------------------------------------------------
|
|
213
|
+
Columns: {
|
|
214
|
+
status: 'mapped',
|
|
215
|
+
target: 'Columns',
|
|
216
|
+
props: {
|
|
217
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
218
|
+
isMobile: {},
|
|
219
|
+
isDesktop: {},
|
|
220
|
+
isGapless: {},
|
|
221
|
+
isMultiline: {},
|
|
222
|
+
isVCentered: {},
|
|
223
|
+
isCentered: {},
|
|
224
|
+
isGrid: {
|
|
225
|
+
todo: 'Bulma removed `columns.is-grid` in 0.5; bestax `Columns` has no equivalent — use `isMultiline` with sized Columns, or the Grid component',
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
// `isSize` / `isOffset` (numbers, fractions, or a per-breakpoint object)
|
|
230
|
+
// are flattened by responsive.ts, which the `column` special opts into.
|
|
231
|
+
Column: {
|
|
232
|
+
status: 'mapped',
|
|
233
|
+
target: 'Column',
|
|
234
|
+
special: 'column',
|
|
235
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
236
|
+
},
|
|
237
|
+
Tile: {
|
|
238
|
+
status: 'todo',
|
|
239
|
+
todo: `Bulma v1 replaced tiles with the Grid/Cell components — see ${DOCS}/api/grid and the migration guide ${DOCS}/guides/getting-started/migration/bulma-0-9-to-1`,
|
|
240
|
+
},
|
|
241
|
+
// ---- elements -----------------------------------------------------------
|
|
242
|
+
Box: {
|
|
243
|
+
status: 'mapped',
|
|
244
|
+
target: 'Box',
|
|
245
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
246
|
+
},
|
|
247
|
+
Button: {
|
|
248
|
+
status: 'mapped',
|
|
249
|
+
target: 'Button',
|
|
250
|
+
// `isLink` and `href` are handled by the special: the first is a colour
|
|
251
|
+
// that may collide with `isColor`, the second selects the anchor form.
|
|
252
|
+
special: 'button',
|
|
253
|
+
props: {
|
|
254
|
+
isColor: color,
|
|
255
|
+
isSize: size,
|
|
256
|
+
isOutlined: {},
|
|
257
|
+
isInverted: {},
|
|
258
|
+
isStatic: {},
|
|
259
|
+
isActive: {},
|
|
260
|
+
isHovered: {},
|
|
261
|
+
isFocused: {},
|
|
262
|
+
isLoading: {},
|
|
263
|
+
isFullWidth: FULLWIDTH_OK,
|
|
264
|
+
tag: TAG_AS,
|
|
265
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
Content: {
|
|
269
|
+
status: 'mapped',
|
|
270
|
+
target: 'Content',
|
|
271
|
+
props: { hasTextColor: TEXT_COLOR_OK, isSize: size },
|
|
272
|
+
},
|
|
273
|
+
Delete: {
|
|
274
|
+
status: 'mapped',
|
|
275
|
+
target: 'Delete',
|
|
276
|
+
props: {
|
|
277
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
278
|
+
isSize: size,
|
|
279
|
+
href: {
|
|
280
|
+
todo: 'bestax `Delete` renders a <button> and has no anchor form; wrap it in an <a>, or handle the navigation in `onClick`',
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
Icon: {
|
|
285
|
+
status: 'partial',
|
|
286
|
+
target: 'Icon',
|
|
287
|
+
special: 'icon',
|
|
288
|
+
props: { isSize: size },
|
|
289
|
+
},
|
|
290
|
+
Image: {
|
|
291
|
+
status: 'mapped',
|
|
292
|
+
target: 'Image',
|
|
293
|
+
special: 'image',
|
|
294
|
+
props: {
|
|
295
|
+
tag: TAG_AS,
|
|
296
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
297
|
+
isFullWidth: FULLWIDTH_CLASS,
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
Notification: {
|
|
301
|
+
status: 'mapped',
|
|
302
|
+
target: 'Notification',
|
|
303
|
+
props: { hasTextColor: TEXT_COLOR_OK, isColor: color },
|
|
304
|
+
},
|
|
305
|
+
Progress: {
|
|
306
|
+
status: 'mapped',
|
|
307
|
+
target: 'Progress',
|
|
308
|
+
props: { isColor: color, isSize: size },
|
|
309
|
+
},
|
|
310
|
+
Table: {
|
|
311
|
+
status: 'mapped',
|
|
312
|
+
target: 'Table',
|
|
313
|
+
props: {
|
|
314
|
+
isBordered: {},
|
|
315
|
+
isStriped: {},
|
|
316
|
+
isNarrow: {},
|
|
317
|
+
isFullWidth: FULLWIDTH_OK,
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
Tag: {
|
|
321
|
+
status: 'mapped',
|
|
322
|
+
target: 'Tag',
|
|
323
|
+
props: { isColor: color, isSize: size },
|
|
324
|
+
},
|
|
325
|
+
// bestax's `Title.size` accepts the numbers 1–6 as well as their string
|
|
326
|
+
// forms, so bloomer's numeric `isSize` carries over untouched.
|
|
327
|
+
Title: {
|
|
328
|
+
status: 'mapped',
|
|
329
|
+
target: 'Title',
|
|
330
|
+
props: {
|
|
331
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
332
|
+
isSize: size,
|
|
333
|
+
isSpaced: {},
|
|
334
|
+
tag: TAG_AS,
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
Subtitle: {
|
|
338
|
+
status: 'mapped',
|
|
339
|
+
target: 'SubTitle',
|
|
340
|
+
special: 'subtitle',
|
|
341
|
+
props: {
|
|
342
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
343
|
+
isSize: size,
|
|
344
|
+
isSpaced: { toClass: 'is-spaced' },
|
|
345
|
+
tag: TAG_AS,
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
// bloomer's Heading is Bulma's `.heading` label, whose styles Bulma v1 no
|
|
349
|
+
// longer ships — bestax has no component for it.
|
|
350
|
+
Heading: { status: 'partial', special: 'heading' },
|
|
351
|
+
// ---- form ---------------------------------------------------------------
|
|
352
|
+
Checkbox: {
|
|
353
|
+
status: 'mapped',
|
|
354
|
+
target: 'Checkbox',
|
|
355
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
356
|
+
},
|
|
357
|
+
Radio: {
|
|
358
|
+
status: 'mapped',
|
|
359
|
+
target: 'Radio',
|
|
360
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
361
|
+
},
|
|
362
|
+
Control: {
|
|
363
|
+
status: 'mapped',
|
|
364
|
+
target: 'Control',
|
|
365
|
+
special: 'control-icons',
|
|
366
|
+
props: {
|
|
367
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
368
|
+
isExpanded: {},
|
|
369
|
+
isLoading: {},
|
|
370
|
+
tag: TAG_AS,
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
Help: { status: 'mapped', special: 'help' },
|
|
374
|
+
// bloomer's form elements were bare <input>/<select>/<textarea>s; bestax's
|
|
375
|
+
// Input/Select/TextArea wrap themselves in Field and Control when not
|
|
376
|
+
// already inside one, which a bare element in a table cell or beside an
|
|
377
|
+
// icon did not do. The *Base exports are the bare elements.
|
|
378
|
+
Input: {
|
|
379
|
+
status: 'mapped',
|
|
380
|
+
target: 'InputBase',
|
|
381
|
+
props: {
|
|
382
|
+
isFullWidth: FULLWIDTH_CLASS,
|
|
383
|
+
isColor: color,
|
|
384
|
+
isSize: size,
|
|
385
|
+
isHovered: {},
|
|
386
|
+
isFocused: {},
|
|
387
|
+
isActive: { toClass: 'is-active' },
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
Label: { status: 'mapped', special: 'label' },
|
|
391
|
+
Select: {
|
|
392
|
+
status: 'mapped',
|
|
393
|
+
target: 'SelectBase',
|
|
394
|
+
props: {
|
|
395
|
+
isColor: color,
|
|
396
|
+
isSize: size,
|
|
397
|
+
isLoading: {},
|
|
398
|
+
isFullWidth: FULLWIDTH_OK,
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
TextArea: {
|
|
402
|
+
status: 'mapped',
|
|
403
|
+
target: 'TextAreaBase',
|
|
404
|
+
props: {
|
|
405
|
+
isFullWidth: FULLWIDTH_CLASS,
|
|
406
|
+
isSize: size,
|
|
407
|
+
isActive: {},
|
|
408
|
+
isHovered: {},
|
|
409
|
+
isFocused: {},
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
Field: {
|
|
413
|
+
status: 'mapped',
|
|
414
|
+
target: 'Field',
|
|
415
|
+
props: {
|
|
416
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
417
|
+
// `boolean | 'right' | 'centered'` on both sides.
|
|
418
|
+
isGrouped: { rename: 'grouped' },
|
|
419
|
+
hasAddons: {
|
|
420
|
+
valueTodo: {
|
|
421
|
+
fullwidth: 'bestax `Field.hasAddons` takes `true`, "centered" or "right"; Bulma v1 keeps `has-addons-fullwidth`, so use `hasAddons` plus className="has-addons-fullwidth"',
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
isHorizontal: { rename: 'horizontal' },
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
FieldBody: {
|
|
428
|
+
status: 'mapped',
|
|
429
|
+
target: 'Field.Body',
|
|
430
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
431
|
+
},
|
|
432
|
+
FieldLabel: {
|
|
433
|
+
status: 'mapped',
|
|
434
|
+
target: 'Field.Label',
|
|
435
|
+
props: {
|
|
436
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
437
|
+
isSize: size,
|
|
438
|
+
isNormal: { booleanToProp: { name: 'size', value: 'normal' } },
|
|
439
|
+
},
|
|
440
|
+
},
|
|
441
|
+
// ---- breadcrumb ---------------------------------------------------------
|
|
442
|
+
// bestax's Breadcrumb renders its own <ul>; bloomer's was the bare <nav>
|
|
443
|
+
// and its docs wrote the <ul>, which the special folds away.
|
|
444
|
+
Breadcrumb: {
|
|
445
|
+
status: 'mapped',
|
|
446
|
+
target: 'Breadcrumb',
|
|
447
|
+
special: 'breadcrumb',
|
|
448
|
+
props: {
|
|
449
|
+
hasSeparator: { rename: 'separator' },
|
|
450
|
+
isAlign: { rename: 'alignment' }, // centered | right — same union
|
|
451
|
+
isSize: size,
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
// bestax's Breadcrumb renders the <ul> and takes plain <li> children.
|
|
455
|
+
BreadcrumbItem: { status: 'mapped', special: 'breadcrumb-item' },
|
|
456
|
+
// ---- card ---------------------------------------------------------------
|
|
457
|
+
Card: {
|
|
458
|
+
status: 'mapped',
|
|
459
|
+
target: 'Card',
|
|
460
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
461
|
+
},
|
|
462
|
+
CardImage: {
|
|
463
|
+
status: 'mapped',
|
|
464
|
+
target: 'Card.Image',
|
|
465
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
466
|
+
},
|
|
467
|
+
CardContent: {
|
|
468
|
+
status: 'mapped',
|
|
469
|
+
target: 'Card.Content',
|
|
470
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
471
|
+
},
|
|
472
|
+
CardHeader: {
|
|
473
|
+
status: 'mapped',
|
|
474
|
+
target: 'Card.Header',
|
|
475
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
476
|
+
},
|
|
477
|
+
CardHeaderTitle: {
|
|
478
|
+
status: 'mapped',
|
|
479
|
+
target: 'Card.Header.Title',
|
|
480
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
481
|
+
},
|
|
482
|
+
CardHeaderIcon: {
|
|
483
|
+
status: 'mapped',
|
|
484
|
+
target: 'Card.Header.Icon',
|
|
485
|
+
props: {
|
|
486
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
487
|
+
href: {
|
|
488
|
+
todo: 'bestax `Card.Header.Icon` renders a <button>; put an <a> inside it, or handle the navigation in `onClick`',
|
|
489
|
+
},
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
CardFooter: {
|
|
493
|
+
status: 'mapped',
|
|
494
|
+
target: 'Card.Footer',
|
|
495
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
496
|
+
},
|
|
497
|
+
CardFooterItem: {
|
|
498
|
+
status: 'mapped',
|
|
499
|
+
target: 'Card.FooterItem',
|
|
500
|
+
props: {
|
|
501
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
502
|
+
href: {
|
|
503
|
+
todo: 'bestax `Card.FooterItem` renders a <span> with no anchor form; put an <a> inside it',
|
|
504
|
+
},
|
|
505
|
+
},
|
|
506
|
+
},
|
|
507
|
+
// ---- dropdown -----------------------------------------------------------
|
|
508
|
+
// bestax's Dropdown takes a `label` and renders its own trigger and menu, so
|
|
509
|
+
// bloomer's trigger/menu/content wrappers have nothing to become.
|
|
510
|
+
Dropdown: {
|
|
511
|
+
status: 'partial',
|
|
512
|
+
target: 'Dropdown',
|
|
513
|
+
special: 'dropdown',
|
|
514
|
+
props: {
|
|
515
|
+
isActive: active,
|
|
516
|
+
isHoverable: { rename: 'hoverable' },
|
|
517
|
+
isAlign: { valueMap: { right: 'right' }, valueToProp: true },
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
DropdownTrigger: {
|
|
521
|
+
status: 'todo',
|
|
522
|
+
todo: 'bestax `Dropdown` renders its own trigger; move this content into its `label` prop and drop the wrapper',
|
|
523
|
+
},
|
|
524
|
+
DropdownMenu: {
|
|
525
|
+
status: 'todo',
|
|
526
|
+
todo: 'bestax `Dropdown` renders its own menu; drop this wrapper and keep the `<Dropdown.Item>`s as direct children',
|
|
527
|
+
},
|
|
528
|
+
DropdownContent: {
|
|
529
|
+
status: 'todo',
|
|
530
|
+
todo: 'bestax `Dropdown` renders its own menu content; drop this wrapper and keep the `<Dropdown.Item>`s as direct children',
|
|
531
|
+
},
|
|
532
|
+
DropdownItem: {
|
|
533
|
+
status: 'mapped',
|
|
534
|
+
target: 'Dropdown.Item',
|
|
535
|
+
special: 'dropdown-item',
|
|
536
|
+
props: {
|
|
537
|
+
isActive: active,
|
|
538
|
+
tag: TAG_AS,
|
|
539
|
+
href: {
|
|
540
|
+
todo: 'bestax `Dropdown.Item` declares no `href`; navigate in `onClick`, or put an <a> inside the item',
|
|
541
|
+
},
|
|
542
|
+
},
|
|
543
|
+
},
|
|
544
|
+
DropdownDivider: { status: 'mapped', target: 'Dropdown.Divider' },
|
|
545
|
+
// ---- level / media / menu / message ------------------------------------
|
|
546
|
+
Level: {
|
|
547
|
+
status: 'mapped',
|
|
548
|
+
target: 'Level',
|
|
549
|
+
props: { hasTextColor: TEXT_COLOR_OK, isMobile: {} },
|
|
550
|
+
},
|
|
551
|
+
LevelItem: {
|
|
552
|
+
status: 'mapped',
|
|
553
|
+
target: 'Level.Item',
|
|
554
|
+
special: 'level-item',
|
|
555
|
+
props: {
|
|
556
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
557
|
+
isFlexible: { toClass: 'is-flexible' },
|
|
558
|
+
tag: TAG_AS,
|
|
559
|
+
},
|
|
560
|
+
},
|
|
561
|
+
LevelLeft: {
|
|
562
|
+
status: 'mapped',
|
|
563
|
+
target: 'Level.Left',
|
|
564
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
565
|
+
},
|
|
566
|
+
LevelRight: {
|
|
567
|
+
status: 'mapped',
|
|
568
|
+
target: 'Level.Right',
|
|
569
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
570
|
+
},
|
|
571
|
+
Media: {
|
|
572
|
+
status: 'mapped',
|
|
573
|
+
target: 'Media',
|
|
574
|
+
props: {
|
|
575
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
576
|
+
isSize: { toClassPrefix: 'is-' },
|
|
577
|
+
tag: TAG_AS,
|
|
578
|
+
},
|
|
579
|
+
},
|
|
580
|
+
MediaContent: {
|
|
581
|
+
status: 'mapped',
|
|
582
|
+
target: 'Media.Content',
|
|
583
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
584
|
+
},
|
|
585
|
+
MediaLeft: {
|
|
586
|
+
status: 'mapped',
|
|
587
|
+
target: 'Media.Left',
|
|
588
|
+
props: { hasTextColor: TEXT_COLOR_OK, tag: TAG_AS },
|
|
589
|
+
},
|
|
590
|
+
MediaRight: {
|
|
591
|
+
status: 'mapped',
|
|
592
|
+
target: 'Media.Right',
|
|
593
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
594
|
+
},
|
|
595
|
+
Menu: { status: 'mapped', target: 'Menu' },
|
|
596
|
+
MenuLabel: { status: 'mapped', target: 'Menu.Label' },
|
|
597
|
+
MenuList: { status: 'mapped', target: 'Menu.List' },
|
|
598
|
+
// bestax's Menu.Item renders its own <li><a>; bloomer's MenuLink was the
|
|
599
|
+
// <a>, wrapped in a literal <li> by convention (its docs do), which the
|
|
600
|
+
// special folds away.
|
|
601
|
+
MenuLink: {
|
|
602
|
+
status: 'mapped',
|
|
603
|
+
target: 'Menu.Item',
|
|
604
|
+
special: 'menu-link',
|
|
605
|
+
props: { isActive: active, tag: TAG_AS },
|
|
606
|
+
},
|
|
607
|
+
Message: {
|
|
608
|
+
status: 'mapped',
|
|
609
|
+
target: 'Message',
|
|
610
|
+
props: {
|
|
611
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
612
|
+
isColor: { rename: 'color', valueTodo: MESSAGE_COLOR_TODO },
|
|
613
|
+
},
|
|
614
|
+
},
|
|
615
|
+
MessageHeader: { status: 'mapped', target: 'Message.Header' },
|
|
616
|
+
MessageBody: { status: 'mapped', target: 'Message.Body' },
|
|
617
|
+
// ---- modal --------------------------------------------------------------
|
|
618
|
+
Modal: {
|
|
619
|
+
status: 'partial',
|
|
620
|
+
target: 'Modal',
|
|
621
|
+
special: 'modal',
|
|
622
|
+
props: { hasTextColor: TEXT_COLOR_OK, isActive: active },
|
|
623
|
+
},
|
|
624
|
+
ModalBackground: { status: 'mapped', target: 'Modal.Background' },
|
|
625
|
+
ModalContent: { status: 'mapped', target: 'Modal.Content' },
|
|
626
|
+
// bestax's Modal.Close defaults to `variant="delete"` (the small X for a
|
|
627
|
+
// card header) and honours `size` only on the floating variant; bloomer's
|
|
628
|
+
// ModalClose was always Bulma's `.modal-close` overlay button.
|
|
629
|
+
ModalClose: {
|
|
630
|
+
status: 'mapped',
|
|
631
|
+
target: 'Modal.Close',
|
|
632
|
+
special: 'modal-close',
|
|
633
|
+
props: { isSize: size },
|
|
634
|
+
},
|
|
635
|
+
ModalCard: { status: 'mapped', target: 'Modal.Card' },
|
|
636
|
+
ModalCardHeader: { status: 'mapped', target: 'Modal.Card.Head' },
|
|
637
|
+
ModalCardTitle: { status: 'mapped', target: 'Modal.Card.Title' },
|
|
638
|
+
ModalCardBody: { status: 'mapped', target: 'Modal.Card.Body' },
|
|
639
|
+
ModalCardFooter: { status: 'mapped', target: 'Modal.Card.Foot' },
|
|
640
|
+
// ---- nav (Bulma 0.4) ----------------------------------------------------
|
|
641
|
+
Nav: NAV_TODO('Nav'),
|
|
642
|
+
NavLeft: NAV_TODO('NavLeft'),
|
|
643
|
+
NavCenter: NAV_TODO('NavCenter'),
|
|
644
|
+
NavRight: NAV_TODO('NavRight'),
|
|
645
|
+
NavToggle: NAV_TODO('NavToggle'),
|
|
646
|
+
NavItem: NAV_TODO('NavItem'),
|
|
647
|
+
// ---- navbar -------------------------------------------------------------
|
|
648
|
+
Navbar: {
|
|
649
|
+
status: 'mapped',
|
|
650
|
+
target: 'Navbar',
|
|
651
|
+
props: {
|
|
652
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
653
|
+
isTransparent: { rename: 'transparent' },
|
|
654
|
+
},
|
|
655
|
+
},
|
|
656
|
+
NavbarBrand: {
|
|
657
|
+
status: 'mapped',
|
|
658
|
+
target: 'Navbar.Brand',
|
|
659
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
660
|
+
},
|
|
661
|
+
NavbarBurger: {
|
|
662
|
+
status: 'mapped',
|
|
663
|
+
target: 'Navbar.Burger',
|
|
664
|
+
props: { hasTextColor: TEXT_COLOR_OK, isActive: active },
|
|
665
|
+
},
|
|
666
|
+
NavbarMenu: {
|
|
667
|
+
status: 'mapped',
|
|
668
|
+
target: 'Navbar.Menu',
|
|
669
|
+
props: { hasTextColor: TEXT_COLOR_OK, isActive: active },
|
|
670
|
+
},
|
|
671
|
+
NavbarStart: {
|
|
672
|
+
status: 'mapped',
|
|
673
|
+
target: 'Navbar.Start',
|
|
674
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
675
|
+
},
|
|
676
|
+
NavbarEnd: {
|
|
677
|
+
status: 'mapped',
|
|
678
|
+
target: 'Navbar.End',
|
|
679
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
680
|
+
},
|
|
681
|
+
// `hasDropdown` picks between Navbar.Item and the Navbar.Dropdown container.
|
|
682
|
+
NavbarItem: {
|
|
683
|
+
status: 'mapped',
|
|
684
|
+
special: 'navbar-item',
|
|
685
|
+
props: { isActive: active, tag: TAG_AS },
|
|
686
|
+
},
|
|
687
|
+
NavbarLink: {
|
|
688
|
+
status: 'mapped',
|
|
689
|
+
target: 'Navbar.Link',
|
|
690
|
+
props: {
|
|
691
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
692
|
+
isActive: { toClass: 'is-active' },
|
|
693
|
+
tag: TAG_AS,
|
|
694
|
+
},
|
|
695
|
+
},
|
|
696
|
+
NavbarDropdown: { status: 'mapped', special: 'navbar-dropdown' },
|
|
697
|
+
NavbarDivider: {
|
|
698
|
+
status: 'mapped',
|
|
699
|
+
target: 'Navbar.Divider',
|
|
700
|
+
props: {
|
|
701
|
+
isBoxed: {
|
|
702
|
+
todo: 'Bulma v1 scopes navbar `is-boxed` to `.navbar-dropdown`, so there is no `.navbar-divider.is-boxed` to keep — drop it',
|
|
703
|
+
},
|
|
704
|
+
},
|
|
705
|
+
},
|
|
706
|
+
// ---- pagination ---------------------------------------------------------
|
|
707
|
+
Pagination: {
|
|
708
|
+
status: 'mapped',
|
|
709
|
+
target: 'Pagination',
|
|
710
|
+
special: 'pagination',
|
|
711
|
+
props: { hasTextColor: TEXT_COLOR_OK, isSize: size },
|
|
712
|
+
},
|
|
713
|
+
PageControl: {
|
|
714
|
+
status: 'mapped',
|
|
715
|
+
special: 'page-control',
|
|
716
|
+
props: {
|
|
717
|
+
isActive: { toClass: 'is-active' },
|
|
718
|
+
isFocused: { toClass: 'is-focused' },
|
|
719
|
+
},
|
|
720
|
+
},
|
|
721
|
+
PageEllipsis: {
|
|
722
|
+
status: 'mapped',
|
|
723
|
+
target: 'Pagination.Ellipsis',
|
|
724
|
+
props: {
|
|
725
|
+
isActive: {
|
|
726
|
+
todo: 'bestax `Pagination.Ellipsis` spreads its props after its own className, so a class written here would replace `pagination-ellipsis`; wrap it or restyle by hand if you need `is-active`',
|
|
727
|
+
},
|
|
728
|
+
isFocused: {
|
|
729
|
+
todo: 'bestax `Pagination.Ellipsis` spreads its props after its own className, so a class written here would replace `pagination-ellipsis`; wrap it or restyle by hand if you need `is-focused`',
|
|
730
|
+
},
|
|
731
|
+
},
|
|
732
|
+
},
|
|
733
|
+
// bestax's Pagination.Link and Pagination.Ellipsis render their own <li>.
|
|
734
|
+
Page: { status: 'mapped', special: 'page' },
|
|
735
|
+
PageList: {
|
|
736
|
+
status: 'mapped',
|
|
737
|
+
target: 'Pagination.List',
|
|
738
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
739
|
+
},
|
|
740
|
+
PageLink: {
|
|
741
|
+
status: 'mapped',
|
|
742
|
+
target: 'Pagination.Link',
|
|
743
|
+
props: {
|
|
744
|
+
hasTextColor: TEXT_COLOR_OK,
|
|
745
|
+
isCurrent: active, // bestax's `active` renders Bulma's `is-current`
|
|
746
|
+
isActive: { toClass: 'is-active' },
|
|
747
|
+
isFocused: { toClass: 'is-focused' },
|
|
748
|
+
},
|
|
749
|
+
},
|
|
750
|
+
// ---- panel --------------------------------------------------------------
|
|
751
|
+
Panel: { status: 'mapped', target: 'Panel' },
|
|
752
|
+
PanelHeading: { status: 'mapped', target: 'Panel.Heading' },
|
|
753
|
+
PanelTabs: { status: 'mapped', target: 'Panel.Tabs' },
|
|
754
|
+
PanelTab: { status: 'mapped', special: 'panel-tab' },
|
|
755
|
+
PanelBlock: {
|
|
756
|
+
status: 'mapped',
|
|
757
|
+
target: 'Panel.Block',
|
|
758
|
+
special: 'panel-block',
|
|
759
|
+
props: {
|
|
760
|
+
isActive: active,
|
|
761
|
+
isWrapped: { toClass: 'is-wrapped' },
|
|
762
|
+
},
|
|
763
|
+
},
|
|
764
|
+
PanelIcon: {
|
|
765
|
+
status: 'partial',
|
|
766
|
+
target: 'Panel.Icon',
|
|
767
|
+
special: 'panel-icon',
|
|
768
|
+
},
|
|
769
|
+
// ---- tabs ---------------------------------------------------------------
|
|
770
|
+
Tabs: {
|
|
771
|
+
status: 'mapped',
|
|
772
|
+
target: 'Tabs',
|
|
773
|
+
props: {
|
|
774
|
+
isAlign: { rename: 'align' }, // left | centered | right — same union
|
|
775
|
+
isSize: size,
|
|
776
|
+
isBoxed: { rename: 'boxed' },
|
|
777
|
+
isToggle: { rename: 'toggle' },
|
|
778
|
+
isFullWidth: FULLWIDTH_OK,
|
|
779
|
+
},
|
|
780
|
+
},
|
|
781
|
+
TabList: {
|
|
782
|
+
status: 'mapped',
|
|
783
|
+
target: 'Tabs.List',
|
|
784
|
+
props: {
|
|
785
|
+
isAlign: {
|
|
786
|
+
todo: "Bulma aligns tabs on the `.tabs` container, not the list (bloomer's `is-center` on the <ul> did nothing); set `align` on the `<Tabs>` instead",
|
|
787
|
+
},
|
|
788
|
+
},
|
|
789
|
+
},
|
|
790
|
+
// bestax's `Tabs.Tab` is the controlled API and requires an `index`;
|
|
791
|
+
// `Tabs.Item` is the plain <li> that bloomer's Tab actually is.
|
|
792
|
+
Tab: { status: 'mapped', target: 'Tabs.Item', props: { isActive: active } },
|
|
793
|
+
TabLink: { status: 'mapped', special: 'tab-link' },
|
|
794
|
+
// ---- layout -------------------------------------------------------------
|
|
795
|
+
Container: {
|
|
796
|
+
status: 'mapped',
|
|
797
|
+
target: 'Container',
|
|
798
|
+
props: { hasTextColor: TEXT_COLOR_OK, isFluid: { rename: 'fluid' } },
|
|
799
|
+
},
|
|
800
|
+
Footer: {
|
|
801
|
+
status: 'mapped',
|
|
802
|
+
target: 'Footer',
|
|
803
|
+
props: { hasTextColor: TEXT_COLOR_OK, tag: TAG_AS },
|
|
804
|
+
},
|
|
805
|
+
Section: {
|
|
806
|
+
status: 'mapped',
|
|
807
|
+
target: 'Section',
|
|
808
|
+
props: { hasTextColor: TEXT_COLOR_OK, isSize: size },
|
|
809
|
+
},
|
|
810
|
+
Hero: {
|
|
811
|
+
status: 'mapped',
|
|
812
|
+
target: 'Hero',
|
|
813
|
+
props: {
|
|
814
|
+
isColor: color,
|
|
815
|
+
isSize: size,
|
|
816
|
+
isFullHeight: { booleanToProp: { name: 'size', value: 'fullheight' } },
|
|
817
|
+
isHalfHeight: { toClass: 'is-halfheight' },
|
|
818
|
+
isBold: { toClass: 'is-bold' },
|
|
819
|
+
},
|
|
820
|
+
},
|
|
821
|
+
HeroHeader: {
|
|
822
|
+
status: 'mapped',
|
|
823
|
+
target: 'Hero.Head',
|
|
824
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
825
|
+
},
|
|
826
|
+
HeroBody: {
|
|
827
|
+
status: 'mapped',
|
|
828
|
+
target: 'Hero.Body',
|
|
829
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
830
|
+
},
|
|
831
|
+
HeroVideo: { status: 'mapped', special: 'hero-video' },
|
|
832
|
+
HeroFooter: {
|
|
833
|
+
status: 'mapped',
|
|
834
|
+
target: 'Hero.Foot',
|
|
835
|
+
props: { hasTextColor: TEXT_COLOR_OK },
|
|
836
|
+
},
|
|
837
|
+
// ---- the helper HOC -----------------------------------------------------
|
|
838
|
+
withHelpersModifiers: {
|
|
839
|
+
status: 'todo',
|
|
840
|
+
todo: `\`withHelpersModifiers\` wrapped a component so it accepted bloomer's helper props; bestax components take the same helpers natively (bar the parts that extend only React's HTML attributes, which take className), and a custom component can call \`useBulmaClasses\` itself (${DOCS}/api/helpers/usebulmaclasses)`,
|
|
841
|
+
},
|
|
842
|
+
};
|
|
843
|
+
/**
|
|
844
|
+
* bloomer's public export surface, vendored from `src/index.ts` at the SHA
|
|
845
|
+
* `scripts/validate-corpus-bloomer.mjs` pins, in that file's order. Every
|
|
846
|
+
* export is flat, so no entry carries sub-paths; the shape matches the other
|
|
847
|
+
* sources' tables so the coverage and doc tests port unchanged.
|
|
848
|
+
*
|
|
849
|
+
* `mapping-coverage.test.ts` walks this against `MAPPING` in both directions,
|
|
850
|
+
* so bloomer coverage cannot silently regress and `MAPPING` cannot grow an
|
|
851
|
+
* entry for something bloomer never exported.
|
|
852
|
+
*/
|
|
853
|
+
export const BLOOMER_EXPORTS = Object.fromEntries([
|
|
854
|
+
// grid
|
|
855
|
+
'Columns',
|
|
856
|
+
'Column',
|
|
857
|
+
'Tile',
|
|
858
|
+
// elements
|
|
859
|
+
'Box',
|
|
860
|
+
'Button',
|
|
861
|
+
'Content',
|
|
862
|
+
'Delete',
|
|
863
|
+
'Icon',
|
|
864
|
+
'Image',
|
|
865
|
+
'Notification',
|
|
866
|
+
'Progress',
|
|
867
|
+
'Table',
|
|
868
|
+
'Tag',
|
|
869
|
+
'Title',
|
|
870
|
+
'Subtitle',
|
|
871
|
+
'Heading',
|
|
872
|
+
// form
|
|
873
|
+
'Checkbox',
|
|
874
|
+
'Control',
|
|
875
|
+
'Help',
|
|
876
|
+
'Input',
|
|
877
|
+
'Label',
|
|
878
|
+
'Radio',
|
|
879
|
+
'Select',
|
|
880
|
+
'TextArea',
|
|
881
|
+
'Field',
|
|
882
|
+
'FieldBody',
|
|
883
|
+
'FieldLabel',
|
|
884
|
+
// breadcrumb
|
|
885
|
+
'Breadcrumb',
|
|
886
|
+
'BreadcrumbItem',
|
|
887
|
+
// card
|
|
888
|
+
'Card',
|
|
889
|
+
'CardImage',
|
|
890
|
+
'CardContent',
|
|
891
|
+
'CardHeader',
|
|
892
|
+
'CardHeaderTitle',
|
|
893
|
+
'CardHeaderIcon',
|
|
894
|
+
'CardFooter',
|
|
895
|
+
'CardFooterItem',
|
|
896
|
+
// dropdown
|
|
897
|
+
'Dropdown',
|
|
898
|
+
'DropdownContent',
|
|
899
|
+
'DropdownDivider',
|
|
900
|
+
'DropdownItem',
|
|
901
|
+
'DropdownMenu',
|
|
902
|
+
'DropdownTrigger',
|
|
903
|
+
// level
|
|
904
|
+
'Level',
|
|
905
|
+
'LevelItem',
|
|
906
|
+
'LevelLeft',
|
|
907
|
+
'LevelRight',
|
|
908
|
+
// media
|
|
909
|
+
'Media',
|
|
910
|
+
'MediaContent',
|
|
911
|
+
'MediaLeft',
|
|
912
|
+
'MediaRight',
|
|
913
|
+
// menu
|
|
914
|
+
'Menu',
|
|
915
|
+
'MenuLabel',
|
|
916
|
+
'MenuList',
|
|
917
|
+
'MenuLink',
|
|
918
|
+
// message
|
|
919
|
+
'Message',
|
|
920
|
+
'MessageHeader',
|
|
921
|
+
'MessageBody',
|
|
922
|
+
// modal
|
|
923
|
+
'Modal',
|
|
924
|
+
'ModalBackground',
|
|
925
|
+
'ModalContent',
|
|
926
|
+
'ModalClose',
|
|
927
|
+
'ModalCard',
|
|
928
|
+
'ModalCardHeader',
|
|
929
|
+
'ModalCardTitle',
|
|
930
|
+
'ModalCardBody',
|
|
931
|
+
'ModalCardFooter',
|
|
932
|
+
// nav
|
|
933
|
+
'Nav',
|
|
934
|
+
'NavLeft',
|
|
935
|
+
'NavCenter',
|
|
936
|
+
'NavRight',
|
|
937
|
+
'NavToggle',
|
|
938
|
+
'NavItem',
|
|
939
|
+
// navbar
|
|
940
|
+
'Navbar',
|
|
941
|
+
'NavbarBrand',
|
|
942
|
+
'NavbarBurger',
|
|
943
|
+
'NavbarMenu',
|
|
944
|
+
'NavbarStart',
|
|
945
|
+
'NavbarEnd',
|
|
946
|
+
'NavbarItem',
|
|
947
|
+
'NavbarLink',
|
|
948
|
+
'NavbarDropdown',
|
|
949
|
+
'NavbarDivider',
|
|
950
|
+
// pagination
|
|
951
|
+
'Pagination',
|
|
952
|
+
'PageControl',
|
|
953
|
+
'PageEllipsis',
|
|
954
|
+
'Page',
|
|
955
|
+
'PageList',
|
|
956
|
+
'PageLink',
|
|
957
|
+
// panel
|
|
958
|
+
'Panel',
|
|
959
|
+
'PanelHeading',
|
|
960
|
+
'PanelTabs',
|
|
961
|
+
'PanelTab',
|
|
962
|
+
'PanelBlock',
|
|
963
|
+
'PanelIcon',
|
|
964
|
+
// tabs
|
|
965
|
+
'Tabs',
|
|
966
|
+
'Tab',
|
|
967
|
+
'TabList',
|
|
968
|
+
'TabLink',
|
|
969
|
+
// layout
|
|
970
|
+
'Container',
|
|
971
|
+
'Footer',
|
|
972
|
+
'Section',
|
|
973
|
+
'Hero',
|
|
974
|
+
'HeroHeader',
|
|
975
|
+
'HeroBody',
|
|
976
|
+
'HeroVideo',
|
|
977
|
+
'HeroFooter',
|
|
978
|
+
// the HOC
|
|
979
|
+
'withHelpersModifiers',
|
|
980
|
+
].map(name => [name, []]));
|
|
981
|
+
/** Walk a dotted component path through `MAPPING`. */
|
|
982
|
+
export function resolveMapping(path) {
|
|
983
|
+
let current = MAPPING[path[0]];
|
|
984
|
+
for (const segment of path.slice(1)) {
|
|
985
|
+
current = current?.subs?.[segment];
|
|
986
|
+
}
|
|
987
|
+
return current;
|
|
988
|
+
}
|