@allxsmith/bestax-bulma 5.15.1 → 5.15.2
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.cjs.js +104 -29
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +104 -29
- package/dist/index.esm.js.map +1 -1
- package/dist/types/components/Dropdown.d.ts +35 -6
- package/dist/types/components/Panel.d.ts +2 -2
- package/dist/types/elements/Icon.d.ts +44 -5
- package/dist/types/elements/iconProps.d.ts +30 -0
- package/dist/types/helpers/polymorphic.d.ts +37 -4
- package/dist/types/index.d.ts +1 -1
- package/package.json +2 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BulmaClassesProps } from '../helpers/useBulmaClasses';
|
|
3
|
+
import type { ConstrainedPolymorphicComponentWithoutRef } from '../helpers/polymorphic';
|
|
3
4
|
/**
|
|
4
5
|
* Checks if code is running in a browser environment.
|
|
5
6
|
* @param win - Window object.
|
|
@@ -38,20 +39,48 @@ export interface DropdownProps extends Omit<React.HTMLAttributes<HTMLDivElement>
|
|
|
38
39
|
id?: string;
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
41
|
-
*
|
|
42
|
+
* The elements a dropdown item may render as. Bulma's dropdown markup names
|
|
43
|
+
* these three and no others, so `as` is a closed set rather than an open
|
|
44
|
+
* `React.ElementType`.
|
|
42
45
|
*/
|
|
43
|
-
export
|
|
46
|
+
export type DropdownItemElement = 'a' | 'div' | 'button';
|
|
47
|
+
/**
|
|
48
|
+
* The DropdownItem component's own props.
|
|
49
|
+
*/
|
|
50
|
+
export interface DropdownItemOwnProps extends BulmaClassesProps {
|
|
44
51
|
/** Whether the item is active. */
|
|
45
52
|
active?: boolean;
|
|
46
53
|
/** Additional CSS classes. */
|
|
47
54
|
className?: string;
|
|
48
|
-
/** The element type to render. */
|
|
49
|
-
as?: 'a' | 'div' | 'button';
|
|
50
55
|
/** Marks the item as disabled; disabled items are skipped during keyboard navigation. Use with `as="button"` for a native disabled control, or pair with `aria-disabled` on a link. */
|
|
51
56
|
disabled?: boolean;
|
|
52
57
|
/** Item content. */
|
|
53
58
|
children?: React.ReactNode;
|
|
54
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Props for the DropdownItem component. Everything the item does not own
|
|
62
|
+
* follows `as`: `href`, `target` and `rel` under the default `'a'`, `type` and
|
|
63
|
+
* `form` under `'button'`, and the shared HTML attributes under any of them.
|
|
64
|
+
*
|
|
65
|
+
* Pinning these to `React.HTMLAttributes<HTMLElement>` instead — which is what
|
|
66
|
+
* this type did before — rejected `href` on an anchor and `type` on a button,
|
|
67
|
+
* both of which have always worked at runtime. Same defect as #641, in the
|
|
68
|
+
* narrower shape a constrained `as` takes.
|
|
69
|
+
*
|
|
70
|
+
* **Name the tag you mean.** The type parameter defaults to the whole union, not
|
|
71
|
+
* to the rendered element, so bare `DropdownItemProps` keeps accepting
|
|
72
|
+
* `{ as: 'div' }` the way it always has. The cost is that it is not
|
|
73
|
+
* distributive: `Omit` over a union keeps only the shared keys, so the bare
|
|
74
|
+
* alias carries no `href` even though the component takes one under `as="a"`.
|
|
75
|
+
* Write `DropdownItemProps<'a'>` for the anchor's props. That is the #667 alias
|
|
76
|
+
* limitation Button carries, labelled next-major because closing it is
|
|
77
|
+
* source-breaking, and pinned for this component in
|
|
78
|
+
* `__typetests__/polymorphic.tsx`; the component itself is unaffected.
|
|
79
|
+
*/
|
|
80
|
+
export type DropdownItemProps<T extends DropdownItemElement = DropdownItemElement> = DropdownItemOwnProps & Omit<React.ComponentPropsWithoutRef<T>, keyof DropdownItemOwnProps | 'as'> & {
|
|
81
|
+
/** The element type to render. */
|
|
82
|
+
as?: T;
|
|
83
|
+
};
|
|
55
84
|
/**
|
|
56
85
|
* Bulma Dropdown item.
|
|
57
86
|
*
|
|
@@ -59,7 +88,7 @@ export interface DropdownItemProps extends Omit<React.HTMLAttributes<HTMLElement
|
|
|
59
88
|
* @param {DropdownItemProps} props - Props for the DropdownItem component.
|
|
60
89
|
* @returns {JSX.Element} The rendered dropdown item.
|
|
61
90
|
*/
|
|
62
|
-
export declare const DropdownItem:
|
|
91
|
+
export declare const DropdownItem: ConstrainedPolymorphicComponentWithoutRef<DropdownItemOwnProps, DropdownItemElement, "a">;
|
|
63
92
|
/**
|
|
64
93
|
* Bulma Dropdown divider.
|
|
65
94
|
*
|
|
@@ -69,7 +98,7 @@ export declare const DropdownItem: React.FC<DropdownItemProps>;
|
|
|
69
98
|
export declare const DropdownDivider: React.FC;
|
|
70
99
|
/** Bulma Dropdown component with Item and Divider sub-components. */
|
|
71
100
|
export declare const Dropdown: React.ForwardRefExoticComponent<DropdownProps & React.RefAttributes<HTMLDivElement>> & {
|
|
72
|
-
Item:
|
|
101
|
+
Item: ConstrainedPolymorphicComponentWithoutRef<DropdownItemOwnProps, DropdownItemElement, "a">;
|
|
73
102
|
Divider: React.FC<{}>;
|
|
74
103
|
};
|
|
75
104
|
export default Dropdown;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { BulmaClassesProps } from '../helpers/useBulmaClasses';
|
|
3
|
-
import { IconChildrenProps, IconNameProps } from '../elements/Icon';
|
|
3
|
+
import { IconChildrenProps, IconDeprecatedProps, IconNameProps } from '../elements/Icon';
|
|
4
4
|
/**
|
|
5
5
|
* Props for the Panel component.
|
|
6
6
|
*/
|
|
@@ -45,7 +45,7 @@ export interface PanelBlockProps extends React.AnchorHTMLAttributes<HTMLAnchorEl
|
|
|
45
45
|
* Props for the PanelIcon component.
|
|
46
46
|
* Extends IconProps but uses 'panel-icon' as the container class.
|
|
47
47
|
*/
|
|
48
|
-
export type PanelIconProps = Omit<IconNameProps, 'containerClassName'> | Omit<IconChildrenProps, 'containerClassName'>;
|
|
48
|
+
export type PanelIconProps = Omit<IconNameProps, 'containerClassName'> | Omit<IconChildrenProps, 'containerClassName'> | Omit<IconDeprecatedProps, 'containerClassName'>;
|
|
49
49
|
/**
|
|
50
50
|
* Props for the PanelInputBlock component.
|
|
51
51
|
*/
|
|
@@ -33,7 +33,14 @@ interface IconBaseProps extends React.HTMLAttributes<HTMLSpanElement>, BulmaClas
|
|
|
33
33
|
color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';
|
|
34
34
|
/** Background color helper. */
|
|
35
35
|
bgColor?: (typeof validColors)[number] | 'inherit' | 'current';
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Legacy icon class string (e.g. `'fas fa-star'`). Only its last segment is read, as the
|
|
38
|
+
* glyph name; the library still comes from `library` or `ConfigProvider`, so
|
|
39
|
+
* `'mdi mdi-rocket'` renders an `fa` class unless the effective library is already `mdi` —
|
|
40
|
+
* set it here or on the provider.
|
|
41
|
+
*
|
|
42
|
+
* @deprecated Use `name` instead.
|
|
43
|
+
*/
|
|
37
44
|
icon?: string;
|
|
38
45
|
/**
|
|
39
46
|
* The icon library to use ('fa' = Font Awesome, 'mdi' = Material Design Icons, 'ion' = Ionicons Web Components, 'material-icons' = Google Material Icons, 'material-symbols' = Google Material Symbols). Defaults to the value set in ConfigProvider or 'fa' if not configured. Ignored when `children` supplies the glyph instead of `name`.
|
|
@@ -44,7 +51,11 @@ interface IconBaseProps extends React.HTMLAttributes<HTMLSpanElement>, BulmaClas
|
|
|
44
51
|
variant?: string;
|
|
45
52
|
/** Additional modifiers (e.g. `'fa-lg'`, `'fa-spin'`, `'is-size-1'`). Ignored when `children` supplies the glyph instead of `name`. */
|
|
46
53
|
features?: string | string[];
|
|
47
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* Additional modifiers in the older combined form, parsed into `variant` and `features`.
|
|
56
|
+
*
|
|
57
|
+
* @deprecated Use `variant` and `features` instead.
|
|
58
|
+
*/
|
|
48
59
|
libraryFeatures?: string | string[];
|
|
49
60
|
/** Size modifier for the icon container. */
|
|
50
61
|
size?: 'small' | 'medium' | 'large';
|
|
@@ -83,10 +94,38 @@ export interface IconChildrenProps extends IconBaseProps {
|
|
|
83
94
|
children: Exclude<React.ReactNode, undefined>;
|
|
84
95
|
}
|
|
85
96
|
/**
|
|
86
|
-
* Props for
|
|
87
|
-
*
|
|
97
|
+
* Props for `Icon` naming its glyph through the deprecated `icon` prop instead of `name`.
|
|
98
|
+
*
|
|
99
|
+
* The runtime has always accepted `icon` on its own — it strips a leading library prefix off
|
|
100
|
+
* the class string and falls through to the `name` path — but the type offered no member without
|
|
101
|
+
* a `name` or `children`, so every caller still on the deprecated prop got an error the
|
|
102
|
+
* package could not see — until #663 nothing here type-checked a test or a story, so the
|
|
103
|
+
* three `Icon.test.tsx` cases exercising this path proved the runtime and said nothing about
|
|
104
|
+
* the type. Declaring the path is the honest resolution: it is deprecated, not removed, and a
|
|
105
|
+
* deprecation that does not type-check is a removal announced only to whoever tries it.
|
|
106
|
+
*
|
|
107
|
+
* @deprecated Pass `name` instead. This member goes when `icon` does.
|
|
108
|
+
*/
|
|
109
|
+
export interface IconDeprecatedProps extends IconBaseProps {
|
|
110
|
+
/**
|
|
111
|
+
* Legacy icon class string (e.g. `'fas fa-star'`). Only its last segment is read, as the
|
|
112
|
+
* glyph name; the library still comes from `library` or `ConfigProvider`, so
|
|
113
|
+
* `'mdi mdi-rocket'` renders an `fa` class unless the effective library is already `mdi` —
|
|
114
|
+
* set it here or on the provider.
|
|
115
|
+
*
|
|
116
|
+
* @deprecated Use `name` instead.
|
|
117
|
+
*/
|
|
118
|
+
icon: string;
|
|
119
|
+
/** The icon name. Absent on this path — `icon` supplies the glyph. */
|
|
120
|
+
name?: undefined;
|
|
121
|
+
/** A custom node. Mutually exclusive with `icon`. */
|
|
122
|
+
children?: never;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Props for the Icon component — a discriminated union of a class-based `name`, a custom
|
|
126
|
+
* `children` node, and the deprecated `icon` class string.
|
|
88
127
|
*/
|
|
89
|
-
export type IconProps = IconNameProps | IconChildrenProps;
|
|
128
|
+
export type IconProps = IconNameProps | IconChildrenProps | IconDeprecatedProps;
|
|
90
129
|
/**
|
|
91
130
|
* The `Icon` component is a Bulma-styled wrapper for displaying icons from various libraries (Font Awesome, Material Design Icons, Ionicons, Google Material Icons, Material Symbols, etc.).
|
|
92
131
|
*
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { IconProps } from './Icon';
|
|
3
|
+
/**
|
|
4
|
+
* Distinguishes an `IconProps` object from a plain custom node (an inline SVG, a
|
|
5
|
+
* `react-icons` component, …) in a slot that accepts either — `Control`'s
|
|
6
|
+
* `iconLeft`/`iconRight`, `IconText`'s `iconProps`.
|
|
7
|
+
*
|
|
8
|
+
* One copy, imported by both consumers: two hand-maintained copies, one per
|
|
9
|
+
* consumer, is how the deprecated `icon` path came to crash both (#663).
|
|
10
|
+
*
|
|
11
|
+
* Its own module rather than `Icon.tsx` because `src/index.ts` wildcard-exports
|
|
12
|
+
* that file, and everything published there is public forever. `polymorphic.ts`
|
|
13
|
+
* makes the same call for `isCustomElement`: an internal discriminator is not
|
|
14
|
+
* something to support for the life of the package.
|
|
15
|
+
*
|
|
16
|
+
* It tests each member's VALUE, not merely its key, and only after everything
|
|
17
|
+
* React owns is out of the way. `'icon' in value` was enough
|
|
18
|
+
* to claim a Font Awesome `IconDefinition` — `{ prefix, iconName, icon: [w, h, …,
|
|
19
|
+
* path] }` — whose `icon` is a path array rather than a class string. That object
|
|
20
|
+
* is not a renderable node either, so the honest outcome is the one this slot has
|
|
21
|
+
* always had for it: the node branch, and React's own "Objects are not valid as a
|
|
22
|
+
* React child". Claiming it here instead rendered a blank container that still
|
|
23
|
+
* reserved layout.
|
|
24
|
+
*
|
|
25
|
+
* A member added to `IconProps` needs a line here, and a missed one is a crash
|
|
26
|
+
* rather than a fallthrough. That is the cost of a slot taking either a props
|
|
27
|
+
* object or a node; keeping the guard in one place is what keeps the cost to a
|
|
28
|
+
* single line.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isIconProps(value: IconProps | React.ReactNode): value is IconProps;
|
|
@@ -73,10 +73,14 @@ export type PolymorphicProps<T extends React.ElementType, Own> = T extends unkno
|
|
|
73
73
|
* **A wrapping HOC erases the genericity.** `React.memo(Button)`,
|
|
74
74
|
* `React.lazy`, a `styled()` wrapper — anything that infers its props through
|
|
75
75
|
* `ComponentProps<T>` — instantiates the type parameter once and hands back a
|
|
76
|
-
* component with a single
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
76
|
+
* component with a single prop type. It takes the LAST call signature, which is
|
|
77
|
+
* the derivation overload, so the wrapper is pinned to the DEFAULT element:
|
|
78
|
+
* `React.memo(Button)` rejects `as="div"` outright, and `React.memo(Dropdown.Item)`
|
|
79
|
+
* renders neither a `<div>` nor a `<button>`, though both components accept those
|
|
80
|
+
* directly. Stricter, not looser — the checks do not stop, they collapse onto one
|
|
81
|
+
* element, and a `Dropdown.Item` memoized for a long menu list is the case that
|
|
82
|
+
* meets it. This is inherent to polymorphic components in TypeScript, not
|
|
83
|
+
* something this library can fix. Re-assert the type to get the rest back:
|
|
80
84
|
*
|
|
81
85
|
* ```tsx
|
|
82
86
|
* const MemoButton = React.memo(Button) as typeof Button;
|
|
@@ -103,3 +107,32 @@ export interface PolymorphicComponentWithoutRef<Own, Default extends React.Eleme
|
|
|
103
107
|
(props: PolymorphicProps<Default, Own>): React.ReactElement | null;
|
|
104
108
|
displayName?: string;
|
|
105
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* A component whose props follow `as`, where `as` is a closed set of tags.
|
|
112
|
+
*
|
|
113
|
+
* `PolymorphicComponentWithoutRef` lets `as` name anything; this narrows it to
|
|
114
|
+
* `Allowed`. Bulma pins some elements by its own markup contract — a dropdown
|
|
115
|
+
* item is an `<a>`, a `<div>` or a `<button>` and nothing else — and the
|
|
116
|
+
* constraint keeps that promise while still deriving props from whichever of
|
|
117
|
+
* the three a caller picks.
|
|
118
|
+
*
|
|
119
|
+
* Genericity is what makes the derivation exact for a LITERAL `as`, and it is
|
|
120
|
+
* worth the extra type parameter. Typing such a component as `React.FC<Union>`
|
|
121
|
+
* instead — a union of the three prop shapes — reads as equivalent but is not:
|
|
122
|
+
* against a union target, an object literal's excess-property check passes if
|
|
123
|
+
* the property exists in ANY member, so `<Item as="div" href="/x" />` slips
|
|
124
|
+
* through. Inferring `T` from the literal checks against that one member.
|
|
125
|
+
*
|
|
126
|
+
* A UNION-typed `as` — a ternary, or a variable typed as the whole set — infers
|
|
127
|
+
* `T` as the union and lands back in that same permissive check, so
|
|
128
|
+
* `<Item as={tag} href="/x" />` compiles whatever `tag` turns out to be. That is
|
|
129
|
+
* the open `as` behaviour too, and deliberate there: `PolymorphicProps`
|
|
130
|
+
* distributes precisely so a union-typed `as` KEEPS each member's props rather
|
|
131
|
+
* than losing every prop the members do not share. Narrowing it is not a
|
|
132
|
+
* constrained-component question; it would have to change for `Button` first.
|
|
133
|
+
*/
|
|
134
|
+
export interface ConstrainedPolymorphicComponentWithoutRef<Own, Allowed extends React.ElementType, Default extends Allowed> {
|
|
135
|
+
<T extends Allowed = Default>(props: PolymorphicProps<T, Own>): React.ReactElement | null;
|
|
136
|
+
(props: PolymorphicProps<Default, Own>): React.ReactElement | null;
|
|
137
|
+
displayName?: string;
|
|
138
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -100,7 +100,7 @@ export type { FormFieldProps } from './form/fieldProps';
|
|
|
100
100
|
export * from './grid/Cell';
|
|
101
101
|
export * from './grid/Grid';
|
|
102
102
|
export * from './helpers/classNames';
|
|
103
|
-
export type { PolymorphicComponent, PolymorphicComponentWithoutRef, PolymorphicProps, PolymorphicRef, } from './helpers/polymorphic';
|
|
103
|
+
export type { ConstrainedPolymorphicComponentWithoutRef, PolymorphicComponent, PolymorphicComponentWithoutRef, PolymorphicProps, PolymorphicRef, } from './helpers/polymorphic';
|
|
104
104
|
export * from './helpers/mergeBulmaStyles';
|
|
105
105
|
export * from './helpers/useBulmaClasses';
|
|
106
106
|
export * from './helpers/Theme';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allxsmith/bestax-bulma",
|
|
3
|
-
"version": "5.15.
|
|
3
|
+
"version": "5.15.2",
|
|
4
4
|
"description": "A fully-typed React component library for the Bulma CSS framework. Build modern UIs quickly with reusable, accessible, and customizable Bulma-based React components.",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -190,6 +190,7 @@
|
|
|
190
190
|
"bundle:stats": "rollup -c --configPlugin visualizer",
|
|
191
191
|
"lint": "eslint src",
|
|
192
192
|
"typecheck": "tsc --noEmit",
|
|
193
|
+
"typecheck:tests": "tsc -p tsconfig.test.json --noEmit",
|
|
193
194
|
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
194
195
|
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
|
195
196
|
"clean": "rimraf dist",
|