@bug-on/m3-expressive 1.3.5 → 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.
Files changed (43) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/forms.d.mts +2 -2
  3. package/dist/forms.d.ts +2 -2
  4. package/dist/forms.js +16 -6
  5. package/dist/forms.js.map +1 -1
  6. package/dist/forms.mjs +16 -6
  7. package/dist/forms.mjs.map +1 -1
  8. package/dist/index.d.mts +4 -4
  9. package/dist/index.d.ts +4 -4
  10. package/dist/index.js +722 -187
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +718 -188
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/{md3-expressive-shapes-CPcfl_Hf.d.mts → md3-expressive-shapes-wk_98LJh.d.mts} +20 -1
  15. package/dist/{md3-expressive-shapes-CPcfl_Hf.d.ts → md3-expressive-shapes-wk_98LJh.d.ts} +20 -1
  16. package/dist/navigation.d.mts +1 -1
  17. package/dist/navigation.d.ts +1 -1
  18. package/dist/navigation.js +73 -20
  19. package/dist/navigation.js.map +1 -1
  20. package/dist/navigation.mjs +73 -20
  21. package/dist/navigation.mjs.map +1 -1
  22. package/dist/overlays.d.mts +4 -2
  23. package/dist/overlays.d.ts +4 -2
  24. package/dist/overlays.js +84 -43
  25. package/dist/overlays.js.map +1 -1
  26. package/dist/overlays.mjs +84 -43
  27. package/dist/overlays.mjs.map +1 -1
  28. package/dist/pickers.js +88 -55
  29. package/dist/pickers.js.map +1 -1
  30. package/dist/pickers.mjs +88 -55
  31. package/dist/pickers.mjs.map +1 -1
  32. package/dist/shapes.d.mts +141 -15
  33. package/dist/shapes.d.ts +141 -15
  34. package/dist/shapes.js +618 -126
  35. package/dist/shapes.js.map +1 -1
  36. package/dist/shapes.mjs +614 -127
  37. package/dist/shapes.mjs.map +1 -1
  38. package/dist/{side-sheet-modal-64FGhDxL.d.mts → side-sheet-modal-BycxrabB.d.mts} +70 -0
  39. package/dist/{side-sheet-modal-Bd5Qqvp9.d.ts → side-sheet-modal-Cw4vemKx.d.ts} +70 -0
  40. package/dist/{text-field-4OlT9o8s.d.mts → text-field-B1fLh5Sh.d.mts} +22 -3
  41. package/dist/{text-field-DARNdj14.d.ts → text-field-C0VQLp8Y.d.ts} +22 -3
  42. package/llms-full.txt +7 -0
  43. package/package.json +1 -1
@@ -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 in searchable mode.
477
- * When provided, INTERNAL filtering is disabled — pass filtered `options` from outside (for server-side/async search).
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
- /** Enable autocomplete mode (input filtering real-time search) */
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 in searchable mode.
477
- * When provided, INTERNAL filtering is disabled — pass filtered `options` from outside (for server-side/async search).
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
- /** Enable autocomplete mode (input filtering real-time search) */
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;
package/llms-full.txt CHANGED
@@ -126,6 +126,8 @@ Icons use **Material Symbols** (Variable Font).
126
126
  ### 7.1 Compound Components & Responsive Layout Groups
127
127
  Complex components use a structured compound pattern:
128
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.
129
131
  - **Tabs**: `Tabs`, `TabsList`, `Tab`, `TabsContent`.
130
132
  - **SplitButton**: `SplitButtonLayout`, `SplitButtonLeading`, `SplitButtonTrailing` (or `SplitButtonTrailingUncheckable`).
131
133
  - **ButtonDistribute**: `ButtonDistribute` (`mode="dynamic" | "fixed" | "mixed"`), spring-animated button layout container for responsive action bars.
@@ -257,3 +259,8 @@ import {
257
259
  | `<ProgressIndicator max={100} />` | ProgressIndicator does not support `max` prop. Progress is mapped strictly from 0 to 100 on the `value` prop |
258
260
  | `<ProgressIndicator>` without `aria-label` | `aria-label` is required on all progress indicators for accessibility |
259
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bug-on/m3-expressive",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
4
4
  "description": "Material Design 3 Expressive React components",
5
5
  "author": "Bug On",
6
6
  "license": "MIT",