@bug-on/m3-expressive 1.3.4 → 1.3.6
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/CHANGELOG.md +19 -0
- package/README.md +31 -7
- package/dist/assets/material-symbols-cdn.css +17 -23
- package/dist/buttons.js +129 -35
- package/dist/buttons.js.map +1 -1
- package/dist/buttons.mjs +129 -35
- package/dist/buttons.mjs.map +1 -1
- package/dist/{core-COvZHQ_k.d.ts → core-Cckt8qEm.d.ts} +10 -4
- package/dist/{core-CRkixy1y.d.mts → core-DDfG4pym.d.mts} +10 -4
- package/dist/core.d.mts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +6 -5
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +6 -5
- package/dist/core.mjs.map +1 -1
- package/dist/fading-blur-mask--uZbBKLj.d.mts +77 -0
- package/dist/fading-blur-mask--uZbBKLj.d.ts +77 -0
- package/dist/feedback.js +1 -1
- package/dist/feedback.js.map +1 -1
- package/dist/feedback.mjs +1 -1
- package/dist/feedback.mjs.map +1 -1
- package/dist/forms.d.mts +2 -2
- package/dist/forms.d.ts +2 -2
- package/dist/forms.js +17 -7
- package/dist/forms.js.map +1 -1
- package/dist/forms.mjs +17 -7
- package/dist/forms.mjs.map +1 -1
- package/dist/index.d.mts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +988 -309
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +984 -310
- package/dist/index.mjs.map +1 -1
- package/dist/layout.d.mts +5 -3
- package/dist/layout.d.ts +5 -3
- package/dist/layout.js +61 -6
- package/dist/layout.js.map +1 -1
- package/dist/layout.mjs +61 -7
- package/dist/layout.mjs.map +1 -1
- package/dist/material-symbols-cdn.css +17 -23
- package/dist/{md3-expressive-shapes-CPcfl_Hf.d.mts → md3-expressive-shapes-wk_98LJh.d.mts} +20 -1
- package/dist/{md3-expressive-shapes-CPcfl_Hf.d.ts → md3-expressive-shapes-wk_98LJh.d.ts} +20 -1
- package/dist/navigation.d.mts +26 -84
- package/dist/navigation.d.ts +26 -84
- package/dist/navigation.js +95 -29
- package/dist/navigation.js.map +1 -1
- package/dist/navigation.mjs +95 -29
- package/dist/navigation.mjs.map +1 -1
- package/dist/overlays.d.mts +4 -2
- package/dist/overlays.d.ts +4 -2
- package/dist/overlays.js +85 -44
- package/dist/overlays.js.map +1 -1
- package/dist/overlays.mjs +85 -44
- package/dist/overlays.mjs.map +1 -1
- package/dist/pickers.d.mts +12 -0
- package/dist/pickers.d.ts +12 -0
- package/dist/pickers.js +186 -120
- package/dist/pickers.js.map +1 -1
- package/dist/pickers.mjs +186 -120
- package/dist/pickers.mjs.map +1 -1
- package/dist/shapes.d.mts +141 -15
- package/dist/shapes.d.ts +141 -15
- package/dist/shapes.js +618 -126
- package/dist/shapes.js.map +1 -1
- package/dist/shapes.mjs +614 -127
- package/dist/shapes.mjs.map +1 -1
- package/dist/{side-sheet-modal-64FGhDxL.d.mts → side-sheet-modal-BycxrabB.d.mts} +70 -0
- package/dist/{side-sheet-modal-Bd5Qqvp9.d.ts → side-sheet-modal-Cw4vemKx.d.ts} +70 -0
- package/dist/{text-field-4OlT9o8s.d.mts → text-field-B1fLh5Sh.d.mts} +22 -3
- package/dist/{text-field-DARNdj14.d.ts → text-field-C0VQLp8Y.d.ts} +22 -3
- package/dist/{typography-339RV6v7.d.mts → typography-CKTjvlZ4.d.mts} +25 -0
- package/dist/{typography-339RV6v7.d.ts → typography-CKTjvlZ4.d.ts} +25 -0
- package/dist/typography.css +1 -1
- package/llms-full.txt +24 -13
- package/llms.txt +11 -6
- package/package.json +3 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as RadixDialog from '@radix-ui/react-dialog';
|
|
3
3
|
import * as React$1 from 'react';
|
|
4
|
+
import { B as BaseIconButtonProps } from './icon-button-CxyJv7UV.mjs';
|
|
4
5
|
import { MotionStyle, useMotionValue, useTransform } from 'motion/react';
|
|
5
6
|
import { b as ScrollAreaProps } from './scroll-area-CVS6HyLl.mjs';
|
|
6
7
|
|
|
@@ -43,6 +44,49 @@ interface DialogProps {
|
|
|
43
44
|
interface DialogContentProps extends React$1.ComponentPropsWithoutRef<typeof RadixDialog.Content> {
|
|
44
45
|
/** Hides the top-right close (X) button. @default false */
|
|
45
46
|
hideCloseButton?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Override any `IconButton` prop on the default close button.
|
|
49
|
+
*
|
|
50
|
+
* Common use cases:
|
|
51
|
+
* - `disabled` — prevent closing during form submission.
|
|
52
|
+
* - `aria-label` — i18n label (e.g. `"Đóng"`).
|
|
53
|
+
* - `colorStyle` — change visual style (`"filled"` restores original look).
|
|
54
|
+
* - `className` — reposition or override the default `absolute right-4 top-4`.
|
|
55
|
+
*
|
|
56
|
+
* These props are **merged** with the library defaults — you only need to specify overrides.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```tsx
|
|
60
|
+
* // Disable during form submission
|
|
61
|
+
* <DialogContent closeButtonProps={{ disabled: isSubmitting, "aria-label": "Đóng" }}>
|
|
62
|
+
*
|
|
63
|
+
* // Restore the original filled style
|
|
64
|
+
* <DialogContent closeButtonProps={{ colorStyle: "filled" }}>
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
closeButtonProps?: Partial<BaseIconButtonProps>;
|
|
68
|
+
/**
|
|
69
|
+
* Fully replace the close button with a custom React node.
|
|
70
|
+
* The node is automatically wrapped in `RadixDialog.Close asChild`.
|
|
71
|
+
*
|
|
72
|
+
* When provided, `hideCloseButton` and `closeButtonProps` are ignored —
|
|
73
|
+
* this slot takes full ownership of the close action.
|
|
74
|
+
*
|
|
75
|
+
* Use when `closeButtonProps` is insufficient (e.g. completely different element
|
|
76
|
+
* or button placed inside a custom flex header).
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```tsx
|
|
80
|
+
* <DialogContent
|
|
81
|
+
* closeButton={
|
|
82
|
+
* <IconButton disabled={isSubmitting} aria-label="Đóng" className="absolute right-4 top-4">
|
|
83
|
+
* <Icon name="close" />
|
|
84
|
+
* </IconButton>
|
|
85
|
+
* }
|
|
86
|
+
* >
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
closeButton?: React$1.ReactNode;
|
|
46
90
|
className?: string;
|
|
47
91
|
}
|
|
48
92
|
/**
|
|
@@ -62,6 +106,32 @@ interface DialogFullScreenContentProps extends React$1.ComponentPropsWithoutRef<
|
|
|
62
106
|
actionLabel?: string;
|
|
63
107
|
/** Handler invoked when pressing the primary action button. */
|
|
64
108
|
onAction?: () => void;
|
|
109
|
+
/**
|
|
110
|
+
* Override any native `<button>` attribute on the top-bar action button.
|
|
111
|
+
*
|
|
112
|
+
* Common use case: `disabled` during form submission.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```tsx
|
|
116
|
+
* <DialogFullScreenContent
|
|
117
|
+
* actionLabel="Lưu"
|
|
118
|
+
* onAction={handleSave}
|
|
119
|
+
* actionButtonProps={{ disabled: isSubmitting }}
|
|
120
|
+
* >
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
actionButtonProps?: React$1.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
124
|
+
/**
|
|
125
|
+
* Override any `IconButton` prop on the top-bar close button.
|
|
126
|
+
*
|
|
127
|
+
* Common use cases: `disabled` during submission, `aria-label` for i18n.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```tsx
|
|
131
|
+
* <DialogFullScreenContent closeButtonProps={{ disabled: isSubmitting, "aria-label": "Đóng" }}>
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
closeButtonProps?: Partial<BaseIconButtonProps>;
|
|
65
135
|
/** Renders a divider separating Top App Bar from scrollable body content. @default false */
|
|
66
136
|
showDivider?: boolean;
|
|
67
137
|
className?: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as RadixDialog from '@radix-ui/react-dialog';
|
|
3
3
|
import * as React$1 from 'react';
|
|
4
|
+
import { B as BaseIconButtonProps } from './icon-button-Di8VX6ou.js';
|
|
4
5
|
import { MotionStyle, useMotionValue, useTransform } from 'motion/react';
|
|
5
6
|
import { b as ScrollAreaProps } from './scroll-area-CVS6HyLl.js';
|
|
6
7
|
|
|
@@ -43,6 +44,49 @@ interface DialogProps {
|
|
|
43
44
|
interface DialogContentProps extends React$1.ComponentPropsWithoutRef<typeof RadixDialog.Content> {
|
|
44
45
|
/** Hides the top-right close (X) button. @default false */
|
|
45
46
|
hideCloseButton?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Override any `IconButton` prop on the default close button.
|
|
49
|
+
*
|
|
50
|
+
* Common use cases:
|
|
51
|
+
* - `disabled` — prevent closing during form submission.
|
|
52
|
+
* - `aria-label` — i18n label (e.g. `"Đóng"`).
|
|
53
|
+
* - `colorStyle` — change visual style (`"filled"` restores original look).
|
|
54
|
+
* - `className` — reposition or override the default `absolute right-4 top-4`.
|
|
55
|
+
*
|
|
56
|
+
* These props are **merged** with the library defaults — you only need to specify overrides.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```tsx
|
|
60
|
+
* // Disable during form submission
|
|
61
|
+
* <DialogContent closeButtonProps={{ disabled: isSubmitting, "aria-label": "Đóng" }}>
|
|
62
|
+
*
|
|
63
|
+
* // Restore the original filled style
|
|
64
|
+
* <DialogContent closeButtonProps={{ colorStyle: "filled" }}>
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
closeButtonProps?: Partial<BaseIconButtonProps>;
|
|
68
|
+
/**
|
|
69
|
+
* Fully replace the close button with a custom React node.
|
|
70
|
+
* The node is automatically wrapped in `RadixDialog.Close asChild`.
|
|
71
|
+
*
|
|
72
|
+
* When provided, `hideCloseButton` and `closeButtonProps` are ignored —
|
|
73
|
+
* this slot takes full ownership of the close action.
|
|
74
|
+
*
|
|
75
|
+
* Use when `closeButtonProps` is insufficient (e.g. completely different element
|
|
76
|
+
* or button placed inside a custom flex header).
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```tsx
|
|
80
|
+
* <DialogContent
|
|
81
|
+
* closeButton={
|
|
82
|
+
* <IconButton disabled={isSubmitting} aria-label="Đóng" className="absolute right-4 top-4">
|
|
83
|
+
* <Icon name="close" />
|
|
84
|
+
* </IconButton>
|
|
85
|
+
* }
|
|
86
|
+
* >
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
closeButton?: React$1.ReactNode;
|
|
46
90
|
className?: string;
|
|
47
91
|
}
|
|
48
92
|
/**
|
|
@@ -62,6 +106,32 @@ interface DialogFullScreenContentProps extends React$1.ComponentPropsWithoutRef<
|
|
|
62
106
|
actionLabel?: string;
|
|
63
107
|
/** Handler invoked when pressing the primary action button. */
|
|
64
108
|
onAction?: () => void;
|
|
109
|
+
/**
|
|
110
|
+
* Override any native `<button>` attribute on the top-bar action button.
|
|
111
|
+
*
|
|
112
|
+
* Common use case: `disabled` during form submission.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```tsx
|
|
116
|
+
* <DialogFullScreenContent
|
|
117
|
+
* actionLabel="Lưu"
|
|
118
|
+
* onAction={handleSave}
|
|
119
|
+
* actionButtonProps={{ disabled: isSubmitting }}
|
|
120
|
+
* >
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
actionButtonProps?: React$1.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
124
|
+
/**
|
|
125
|
+
* Override any `IconButton` prop on the top-bar close button.
|
|
126
|
+
*
|
|
127
|
+
* Common use cases: `disabled` during submission, `aria-label` for i18n.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```tsx
|
|
131
|
+
* <DialogFullScreenContent closeButtonProps={{ disabled: isSubmitting, "aria-label": "Đóng" }}>
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
closeButtonProps?: Partial<BaseIconButtonProps>;
|
|
65
135
|
/** Renders a divider separating Top App Bar from scrollable body content. @default false */
|
|
66
136
|
showDivider?: boolean;
|
|
67
137
|
className?: string;
|
|
@@ -473,11 +473,30 @@ interface SelectProps extends Omit<TextFieldProps, "value" | "onChange" | "defau
|
|
|
473
473
|
/** Callback fired when selection changes */
|
|
474
474
|
onChange?: (value: string, option?: SelectOption) => void;
|
|
475
475
|
/**
|
|
476
|
-
* Callback fired when search query changes
|
|
477
|
-
*
|
|
476
|
+
* Callback fired when the search query changes.
|
|
477
|
+
*
|
|
478
|
+
* ⚠️ **Requires `searchable={true}`** — without it, typing is disabled and this callback is never called.
|
|
479
|
+
*
|
|
480
|
+
* When provided, INTERNAL filtering is disabled — you control `options` externally
|
|
481
|
+
* (ideal for server-side / async search with large datasets).
|
|
482
|
+
*
|
|
483
|
+
* @example
|
|
484
|
+
* // Server-side search: fetch results as user types
|
|
485
|
+
* <Select
|
|
486
|
+
* searchable
|
|
487
|
+
* loading={isLoading}
|
|
488
|
+
* options={serverResults}
|
|
489
|
+
* onSearchChange={(query) => fetchOptions(query)}
|
|
490
|
+
* onChange={(val) => setSelected(val)}
|
|
491
|
+
* />
|
|
478
492
|
*/
|
|
479
493
|
onSearchChange?: (query: string) => void;
|
|
480
|
-
/**
|
|
494
|
+
/**
|
|
495
|
+
* Enable autocomplete/search mode — renders the trigger as an editable text input.
|
|
496
|
+
*
|
|
497
|
+
* - When `false` (default): read-only dropdown, no typing allowed.
|
|
498
|
+
* - When `true`: user can type to filter options. Combine with `onSearchChange` for server-side search.
|
|
499
|
+
*/
|
|
481
500
|
searchable?: boolean;
|
|
482
501
|
/** Whether data is loading (displays a spinner inside the dropdown) */
|
|
483
502
|
loading?: boolean;
|
|
@@ -473,11 +473,30 @@ interface SelectProps extends Omit<TextFieldProps, "value" | "onChange" | "defau
|
|
|
473
473
|
/** Callback fired when selection changes */
|
|
474
474
|
onChange?: (value: string, option?: SelectOption) => void;
|
|
475
475
|
/**
|
|
476
|
-
* Callback fired when search query changes
|
|
477
|
-
*
|
|
476
|
+
* Callback fired when the search query changes.
|
|
477
|
+
*
|
|
478
|
+
* ⚠️ **Requires `searchable={true}`** — without it, typing is disabled and this callback is never called.
|
|
479
|
+
*
|
|
480
|
+
* When provided, INTERNAL filtering is disabled — you control `options` externally
|
|
481
|
+
* (ideal for server-side / async search with large datasets).
|
|
482
|
+
*
|
|
483
|
+
* @example
|
|
484
|
+
* // Server-side search: fetch results as user types
|
|
485
|
+
* <Select
|
|
486
|
+
* searchable
|
|
487
|
+
* loading={isLoading}
|
|
488
|
+
* options={serverResults}
|
|
489
|
+
* onSearchChange={(query) => fetchOptions(query)}
|
|
490
|
+
* onChange={(val) => setSelected(val)}
|
|
491
|
+
* />
|
|
478
492
|
*/
|
|
479
493
|
onSearchChange?: (query: string) => void;
|
|
480
|
-
/**
|
|
494
|
+
/**
|
|
495
|
+
* Enable autocomplete/search mode — renders the trigger as an editable text input.
|
|
496
|
+
*
|
|
497
|
+
* - When `false` (default): read-only dropdown, no typing allowed.
|
|
498
|
+
* - When `true`: user can type to filter options. Combine with `onSearchChange` for server-side search.
|
|
499
|
+
*/
|
|
481
500
|
searchable?: boolean;
|
|
482
501
|
/** Whether data is loading (displays a spinner inside the dropdown) */
|
|
483
502
|
loading?: boolean;
|
|
@@ -97,14 +97,39 @@ interface FontVariationAxes {
|
|
|
97
97
|
ROND?: number;
|
|
98
98
|
/**
|
|
99
99
|
* Weight axis. Overrides `font-weight` via variation settings.
|
|
100
|
+
* Range: `100` (thin) – `1000` (extra black).
|
|
100
101
|
* @default font default
|
|
101
102
|
*/
|
|
102
103
|
wght?: number;
|
|
103
104
|
/**
|
|
104
105
|
* Width axis. Controls glyph condensation/expansion.
|
|
106
|
+
* Range: `75` (condensed) – `125` (expanded).
|
|
105
107
|
* @default font default
|
|
106
108
|
*/
|
|
107
109
|
wdth?: number;
|
|
110
|
+
/**
|
|
111
|
+
* Optical Size axis. Adjusts stroke thickness, proportions, and spacing
|
|
112
|
+
* for optimal readability at different text sizes.
|
|
113
|
+
* Range: `6` (caption/fine print) – `144` (display/banner).
|
|
114
|
+
*
|
|
115
|
+
* Note: Browsers normally handle optical sizing automatically via `font-optical-sizing: auto`.
|
|
116
|
+
* When manually overriding `opsz` in CSS, set `font-optical-sizing: none` to prevent conflicts.
|
|
117
|
+
* @default font default
|
|
118
|
+
*/
|
|
119
|
+
opsz?: number;
|
|
120
|
+
/**
|
|
121
|
+
* Grade axis. Modifies stroke weight/density without changing layout, line wrapping, or glyph advance widths.
|
|
122
|
+
* Ideal for dark mode adjustments or subtle hover/emphasis states.
|
|
123
|
+
* Range: `-200` (light grade) – `150` (heavy grade).
|
|
124
|
+
* @default 0
|
|
125
|
+
*/
|
|
126
|
+
GRAD?: number;
|
|
127
|
+
/**
|
|
128
|
+
* Slant axis. Applies font-designed slant angle in degrees.
|
|
129
|
+
* Range: `-15` (15-degree forward slant) – `0` (upright).
|
|
130
|
+
* @default 0
|
|
131
|
+
*/
|
|
132
|
+
slnt?: number;
|
|
108
133
|
/** Any additional named variation axis supported by the font. */
|
|
109
134
|
[axis: string]: number | undefined;
|
|
110
135
|
}
|
|
@@ -97,14 +97,39 @@ interface FontVariationAxes {
|
|
|
97
97
|
ROND?: number;
|
|
98
98
|
/**
|
|
99
99
|
* Weight axis. Overrides `font-weight` via variation settings.
|
|
100
|
+
* Range: `100` (thin) – `1000` (extra black).
|
|
100
101
|
* @default font default
|
|
101
102
|
*/
|
|
102
103
|
wght?: number;
|
|
103
104
|
/**
|
|
104
105
|
* Width axis. Controls glyph condensation/expansion.
|
|
106
|
+
* Range: `75` (condensed) – `125` (expanded).
|
|
105
107
|
* @default font default
|
|
106
108
|
*/
|
|
107
109
|
wdth?: number;
|
|
110
|
+
/**
|
|
111
|
+
* Optical Size axis. Adjusts stroke thickness, proportions, and spacing
|
|
112
|
+
* for optimal readability at different text sizes.
|
|
113
|
+
* Range: `6` (caption/fine print) – `144` (display/banner).
|
|
114
|
+
*
|
|
115
|
+
* Note: Browsers normally handle optical sizing automatically via `font-optical-sizing: auto`.
|
|
116
|
+
* When manually overriding `opsz` in CSS, set `font-optical-sizing: none` to prevent conflicts.
|
|
117
|
+
* @default font default
|
|
118
|
+
*/
|
|
119
|
+
opsz?: number;
|
|
120
|
+
/**
|
|
121
|
+
* Grade axis. Modifies stroke weight/density without changing layout, line wrapping, or glyph advance widths.
|
|
122
|
+
* Ideal for dark mode adjustments or subtle hover/emphasis states.
|
|
123
|
+
* Range: `-200` (light grade) – `150` (heavy grade).
|
|
124
|
+
* @default 0
|
|
125
|
+
*/
|
|
126
|
+
GRAD?: number;
|
|
127
|
+
/**
|
|
128
|
+
* Slant axis. Applies font-designed slant angle in degrees.
|
|
129
|
+
* Range: `-15` (15-degree forward slant) – `0` (upright).
|
|
130
|
+
* @default 0
|
|
131
|
+
*/
|
|
132
|
+
slnt?: number;
|
|
108
133
|
/** Any additional named variation axis supported by the font. */
|
|
109
134
|
[axis: string]: number | undefined;
|
|
110
135
|
}
|
package/dist/typography.css
CHANGED
package/llms-full.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# @bug-on/m3-expressive — Full AI Documentation (
|
|
1
|
+
# @bug-on/m3-expressive — Full AI Documentation & API Specification (Latest Stable Release)
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
This document provides complete, canonical context for the `@bug-on/m3-expressive` ecosystem (React 19 + Tailwind CSS v4 + Motion for React), including core principles, multi-package architecture, styling guides, component references, subpath exports, and AI gotchas.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -113,7 +113,10 @@ Icons use **Material Symbols** (Variable Font).
|
|
|
113
113
|
<Icon name="search" weight={500} size={24} />
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
- Standard CDN
|
|
116
|
+
- Standard CDN setup:
|
|
117
|
+
- Base styles: `@import "@bug-on/m3-expressive/material-symbols-cdn.css";` and `@import "@bug-on/m3-expressive/typography.css";` in root CSS.
|
|
118
|
+
- React + Vite: Add `<link rel="preconnect" ...>` and `<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block" />` to `index.html` inside `<head>`.
|
|
119
|
+
- Next.js (App Router): Add `<MaterialSymbolsPreconnect variants={["rounded"]} display="block" />` in `app/layout.tsx` inside `<head>`.
|
|
117
120
|
- Offline / Self-hosted imports: `pnpm add @bug-on/m3-fonts`, then `@import "@bug-on/m3-fonts/typography.css";` and `@import "@bug-on/m3-fonts/material-symbols.css";`
|
|
118
121
|
|
|
119
122
|
---
|
|
@@ -123,6 +126,8 @@ Icons use **Material Symbols** (Variable Font).
|
|
|
123
126
|
### 7.1 Compound Components & Responsive Layout Groups
|
|
124
127
|
Complex components use a structured compound pattern:
|
|
125
128
|
- **Dialog & Drawer**: `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogTitle`, `DialogBody`, `DialogFooter`, `DialogClose`.
|
|
129
|
+
- `DialogContent` has `closeButtonProps?: Partial<IconButtonProps>` to override the default close button (use `disabled`, `aria-label`, `colorStyle`, `className`) and `closeButton?: React.ReactNode` for full slot replacement (auto-wrapped in `DialogClose`).
|
|
130
|
+
- `DialogFullScreenContent` has `closeButtonProps?: Partial<IconButtonProps>` and `actionButtonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>` to disable/label close and action buttons during form submission.
|
|
126
131
|
- **Tabs**: `Tabs`, `TabsList`, `Tab`, `TabsContent`.
|
|
127
132
|
- **SplitButton**: `SplitButtonLayout`, `SplitButtonLeading`, `SplitButtonTrailing` (or `SplitButtonTrailingUncheckable`).
|
|
128
133
|
- **ButtonDistribute**: `ButtonDistribute` (`mode="dynamic" | "fixed" | "mixed"`), spring-animated button layout container for responsive action bars.
|
|
@@ -222,16 +227,17 @@ import {
|
|
|
222
227
|
|
|
223
228
|
## Subpath Exports Map
|
|
224
229
|
|
|
225
|
-
- `@bug-on/m3-expressive` —
|
|
226
|
-
- `@bug-on/m3-expressive/index.css` — **REQUIRED**:
|
|
227
|
-
- `@bug-on/m3-expressive/core` —
|
|
228
|
-
- `@bug-on/m3-expressive/buttons` — Button
|
|
229
|
-
- `@bug-on/m3-expressive/forms` — Select
|
|
230
|
-
- `@bug-on/m3-expressive/
|
|
231
|
-
- `@bug-on/m3-expressive/
|
|
232
|
-
- `@bug-on/m3-expressive/
|
|
233
|
-
- `@bug-on/m3-expressive/
|
|
234
|
-
- `@bug-on/m3-expressive/
|
|
230
|
+
- `@bug-on/m3-expressive` — Complete package root exports
|
|
231
|
+
- `@bug-on/m3-expressive/index.css` — **REQUIRED**: Bundled tokens + Tailwind v4 `@theme` + resets
|
|
232
|
+
- `@bug-on/m3-expressive/core` — Base providers (`MD3ThemeProvider`), theme utilities (`createMd3ExpressiveTheme`, `generateM3Theme`, `applyTheme`, `resolveMode`), hooks (`useMediaQuery`, `useDOMRipple`, `useTheme`, `useThemeMode`, `useSnackbar`), `Icon`, `Ripple`, `MaterialSymbolsPreconnect`
|
|
233
|
+
- `@bug-on/m3-expressive/buttons` — `Button`, `IconButton`, `ButtonDistribute`, `FAB`, `ExtendedFAB`, `FABMenu`, `SplitButton`, `ButtonGroup`
|
|
234
|
+
- `@bug-on/m3-expressive/forms` — `TextField`, `Select`, `Chip`, `Checkbox`, `TriStateCheckbox`, `RadioButton`, `RadioGroup`, `Switch`, `Slider`, `RangeSlider`
|
|
235
|
+
- `@bug-on/m3-expressive/navigation` — `NavigationBar`, `NavigationBarItem`, `NavigationRail`, `NavigationRailItem`, `NavigationDrawer`, `Tabs`, `Tab`, `TabsList`, `TabsContent`, `SmallAppBar`, `MediumFlexibleAppBar`, `LargeFlexibleAppBar`, `BottomAppBar`, `DockedToolbar`, `HorizontalFloatingToolbar`, `VerticalFloatingToolbar`, `ToolbarIconButton`, `ToolbarToggleButton`, `Menu`, `ContextMenu`, `VerticalMenu`, `Search`, `SearchBar`, `SearchView`
|
|
236
|
+
- `@bug-on/m3-expressive/overlays` — `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogTitle`, `DialogBody`, `DialogFooter`, `DialogClose`, `DialogFullScreenContent`, `Drawer`, `BottomSheet`, `BottomSheetModal`, `SideSheet`, `SideSheetModal`
|
|
237
|
+
- `@bug-on/m3-expressive/feedback` — `Badge`, `BadgedBox`, `LoadingIndicator`, `ProgressIndicator`, `Snackbar`, `SnackbarProvider`, `useSnackbar`, `PlainTooltip`, `RichTooltip`
|
|
238
|
+
- `@bug-on/m3-expressive/layout` — `Card`, `Carousel`, `Divider`, `List`, `ListItem`, `ListDivider`, `ScrollArea`, `CodeBlock`, `TableOfContents`, `Text`, `Typography`, `FadingBlurMask`
|
|
239
|
+
- `@bug-on/m3-expressive/pickers` — `DatePicker`, `DatePickerDialog`, `DatePickerInput`, `DateRangePicker`, `TimePicker`, `TimePickerDialog`, `TimeInput`, `useDatePickerState`, `useDateRangePickerState`, `useTimePickerState`
|
|
240
|
+
- `@bug-on/m3-expressive/shapes` — `ShapeMedia`, `ShapeSvg`, `ShapeIcon`, `useShapeMorph`
|
|
235
241
|
|
|
236
242
|
---
|
|
237
243
|
|
|
@@ -253,3 +259,8 @@ import {
|
|
|
253
259
|
| `<ProgressIndicator max={100} />` | ProgressIndicator does not support `max` prop. Progress is mapped strictly from 0 to 100 on the `value` prop |
|
|
254
260
|
| `<ProgressIndicator>` without `aria-label` | `aria-label` is required on all progress indicators for accessibility |
|
|
255
261
|
| `<ProgressIndicator value={0} />` for indeterminate mode | Omit `value` prop entirely (or pass `undefined`) to trigger indeterminate loading. Setting `value={0}` indicates 0% determinate progress |
|
|
262
|
+
| `<DialogContent>` close button during form submission | Use `closeButtonProps={{ disabled: isSubmitting }}` — do not build a custom close button just for `disabled` support |
|
|
263
|
+
| `<DialogContent>` close button i18n label | Use `closeButtonProps={{ "aria-label": "Đóng" }}` — the `aria-label` prop is forwarded to the `IconButton` |
|
|
264
|
+
| `<DialogContent>` needing full custom close button | Use `closeButton={<YourNode />}` — library auto-wraps in `DialogClose asChild`. When provided, `hideCloseButton` and `closeButtonProps` are ignored |
|
|
265
|
+
| `<DialogFullScreenContent>` action/close disabled during submit | Use `actionButtonProps={{ disabled: isSubmitting }}` and `closeButtonProps={{ disabled: isSubmitting }}` |
|
|
266
|
+
| Building a custom header with `DialogContent` just to control close button style | Use `closeButtonProps={{ colorStyle: "standard" }}` (default) or `"filled"` to override. Only use `hideCloseButton` + custom header when layout positioning is the actual requirement |
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @bug-on/m3-expressive
|
|
2
2
|
|
|
3
|
-
> MD3 Expressive Design System for React + Tailwind v4 +
|
|
3
|
+
> MD3 Expressive Design System for React 19 + Tailwind CSS v4 + Motion for React (Current Stable Release).
|
|
4
4
|
|
|
5
5
|
> [!WARNING]
|
|
6
6
|
> Bug On MD3 Expressive only supports **Tailwind CSS v4** (peer dependency `tailwindcss: ">=4.0.0"`). **Tailwind CSS v3 is no longer supported**.
|
|
@@ -23,14 +23,19 @@ pnpm add @bug-on/m3-expressive motion
|
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
```css
|
|
26
|
-
/* globals.css — Zero Config Tailwind v4 setup */
|
|
26
|
+
/* globals.css / index.css — Zero Config Tailwind v4 setup */
|
|
27
27
|
@import "tailwindcss";
|
|
28
28
|
@import "@bug-on/m3-expressive/index.css"; /* tokens + @theme + resets (REQUIRED) */
|
|
29
29
|
@import "@bug-on/m3-tailwind"; /* optional: MD3 utilities & elevation */
|
|
30
30
|
@import "@bug-on/m3-expressive/typography.css"; /* optional: typography preset classes */
|
|
31
|
-
@import "@bug-on/m3-expressive/material-symbols-cdn.css"; /*
|
|
31
|
+
@import "@bug-on/m3-expressive/material-symbols-cdn.css"; /* base styles for .md-icon */
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
Material Symbols CDN Font Loading:
|
|
35
|
+
- **React + Vite**: Add font link tags to `index.html` inside `<head>` (use `display=block` to prevent ligature text flashing):
|
|
36
|
+
`<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=block" />`
|
|
37
|
+
- **Next.js (App Router)**: Add `<MaterialSymbolsPreconnect variants={["rounded"]} display="block" />` in `app/layout.tsx` inside `<head>`.
|
|
38
|
+
|
|
34
39
|
For offline or self-hosted fonts:
|
|
35
40
|
```bash
|
|
36
41
|
pnpm add @bug-on/m3-fonts
|
|
@@ -83,13 +88,13 @@ function Root({ children }: { children: React.ReactNode }) {
|
|
|
83
88
|
|
|
84
89
|
- `@bug-on/m3-expressive` — complete package exports
|
|
85
90
|
- `@bug-on/m3-expressive/index.css` — **REQUIRED**: bundled tokens + Tailwind `@theme` + resets
|
|
86
|
-
- `@bug-on/m3-expressive/core` — base providers (`MD3ThemeProvider`), hooks (`useTheme`, `useThemeMode`, `useSnackbar`), `Icon`, `Ripple`
|
|
91
|
+
- `@bug-on/m3-expressive/core` — base providers (`MD3ThemeProvider`), theme utilities (`createMd3ExpressiveTheme`, `generateM3Theme`, `applyTheme`, `resolveMode`), hooks (`useTheme`, `useThemeMode`, `useSnackbar`, `useMediaQuery`, `useDOMRipple`), `Icon`, `Ripple`, `MaterialSymbolsPreconnect`
|
|
87
92
|
- `@bug-on/m3-expressive/buttons` — Button, IconButton, ButtonDistribute, FAB, ExtendedFAB, FABMenu, SplitButton, ButtonGroup
|
|
88
|
-
- `@bug-on/m3-expressive/forms` — TextField, Chip, Checkbox, TriStateCheckbox, RadioButton, RadioGroup, Switch, Slider, RangeSlider, Select
|
|
93
|
+
- `@bug-on/m3-expressive/forms` — TextField, Chip, Checkbox, TriStateCheckbox, RadioButton, RadioGroup, Switch, Slider, RangeSlider, Select
|
|
89
94
|
- `@bug-on/m3-expressive/feedback` — Snackbar, SnackbarProvider, useSnackbar, ProgressIndicator (linear, circular, wavy), LoadingIndicator, Badge, BadgedBox, PlainTooltip, RichTooltip
|
|
90
95
|
- `@bug-on/m3-expressive/navigation` — NavigationBar, NavigationRail, NavigationDrawer, Tabs, Tab, SmallAppBar, MediumFlexibleAppBar, LargeFlexibleAppBar, BottomAppBar, DockedToolbar, HorizontalFloatingToolbar, VerticalFloatingToolbar, Menu, ContextMenu, VerticalMenu, Search
|
|
91
96
|
- `@bug-on/m3-expressive/overlays` — Dialog, DialogFullScreenContent, Drawer, BottomSheet, BottomSheetModal, SideSheet, SideSheetModal
|
|
92
|
-
- `@bug-on/m3-expressive/layout` — Card, Carousel, Divider, List, ListItem, ListDivider, ScrollArea, CodeBlock, TableOfContents, Text, Typography
|
|
97
|
+
- `@bug-on/m3-expressive/layout` — Card, Carousel, Divider, List, ListItem, ListDivider, ScrollArea, CodeBlock, TableOfContents, Text, Typography, FadingBlurMask
|
|
93
98
|
- `@bug-on/m3-expressive/pickers` — DatePicker, DatePickerDialog, DatePickerInput, DateRangePicker, TimePicker, TimePickerDialog, TimeInput, state hooks
|
|
94
99
|
- `@bug-on/m3-expressive/shapes` — ShapeMedia, ShapeSvg, ShapeIcon, useShapeMorph
|
|
95
100
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bug-on/m3-expressive",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.6",
|
|
4
4
|
"description": "Material Design 3 Expressive React components",
|
|
5
5
|
"author": "Bug On",
|
|
6
6
|
"license": "MIT",
|
|
@@ -183,8 +183,8 @@
|
|
|
183
183
|
"class-variance-authority": "^0.7.1",
|
|
184
184
|
"clsx": "^2.1.1",
|
|
185
185
|
"tailwind-merge": "^3.6.0",
|
|
186
|
-
"@bug-on/m3-
|
|
187
|
-
"@bug-on/m3-
|
|
186
|
+
"@bug-on/m3-tailwind": "1.2.3",
|
|
187
|
+
"@bug-on/m3-tokens": "1.2.2"
|
|
188
188
|
},
|
|
189
189
|
"devDependencies": {
|
|
190
190
|
"@testing-library/jest-dom": "^6.9.1",
|