@mantis-core/ui 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/COMPONENTS.md +15 -142
  2. package/PRIMEREACT_MAPPING.md +6 -0
  3. package/README.md +56 -72
  4. package/dist/components/Forms/AsyncSelect.d.ts +20 -0
  5. package/dist/components/Forms/AsyncSelect.d.ts.map +1 -0
  6. package/dist/components/Forms/AsyncSelect.js +77 -0
  7. package/dist/components/Forms/AsyncSelect.js.map +1 -0
  8. package/dist/components/Forms/DirtyFormGuard.d.ts +5 -0
  9. package/dist/components/Forms/DirtyFormGuard.d.ts.map +1 -0
  10. package/dist/components/Forms/DirtyFormGuard.js +8 -0
  11. package/dist/components/Forms/DirtyFormGuard.js.map +1 -0
  12. package/dist/components/Forms/FileDropzone.d.ts +29 -0
  13. package/dist/components/Forms/FileDropzone.d.ts.map +1 -0
  14. package/dist/components/Forms/FileDropzone.js +137 -0
  15. package/dist/components/Forms/FileDropzone.js.map +1 -0
  16. package/dist/components/Forms/FormActionsBar.d.ts +26 -0
  17. package/dist/components/Forms/FormActionsBar.d.ts.map +1 -0
  18. package/dist/components/Forms/FormActionsBar.js +16 -0
  19. package/dist/components/Forms/FormActionsBar.js.map +1 -0
  20. package/dist/components/Forms/useDirtyFormGuard.d.ts +12 -0
  21. package/dist/components/Forms/useDirtyFormGuard.d.ts.map +1 -0
  22. package/dist/components/Forms/useDirtyFormGuard.js +36 -0
  23. package/dist/components/Forms/useDirtyFormGuard.js.map +1 -0
  24. package/dist/components/ui/ConfirmDialog.d.ts +19 -0
  25. package/dist/components/ui/ConfirmDialog.d.ts.map +1 -0
  26. package/dist/components/ui/ConfirmDialog.js +20 -0
  27. package/dist/components/ui/ConfirmDialog.js.map +1 -0
  28. package/dist/components/ui/DataState.d.ts +20 -0
  29. package/dist/components/ui/DataState.d.ts.map +1 -0
  30. package/dist/components/ui/DataState.js +30 -0
  31. package/dist/components/ui/DataState.js.map +1 -0
  32. package/dist/components/ui/StatusBadge.d.ts +12 -0
  33. package/dist/components/ui/StatusBadge.d.ts.map +1 -0
  34. package/dist/components/ui/StatusBadge.js +19 -0
  35. package/dist/components/ui/StatusBadge.js.map +1 -0
  36. package/dist/index.d.ts +16 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +8 -0
  39. package/dist/index.js.map +1 -1
  40. package/docs/README.md +72 -0
  41. package/docs/components/action-column.md +17 -0
  42. package/docs/components/admin-page-header.md +21 -0
  43. package/docs/components/admin-page-layout.md +29 -0
  44. package/docs/components/async-select.md +26 -0
  45. package/docs/components/button.md +25 -0
  46. package/docs/components/ckeditor-input.md +24 -0
  47. package/docs/components/confirm-dialog.md +21 -0
  48. package/docs/components/data-state.md +19 -0
  49. package/docs/components/date-input.md +22 -0
  50. package/docs/components/dirty-form-guard.md +31 -0
  51. package/docs/components/drop-down.md +28 -0
  52. package/docs/components/error-message.md +13 -0
  53. package/docs/components/file-dropzone.md +25 -0
  54. package/docs/components/filter-pannel.md +23 -0
  55. package/docs/components/form-actions-bar.md +22 -0
  56. package/docs/components/form-field-render.md +20 -0
  57. package/docs/components/form-section.md +15 -0
  58. package/docs/components/hidden-field.md +19 -0
  59. package/docs/components/index-column.md +13 -0
  60. package/docs/components/loading.md +21 -0
  61. package/docs/components/map-picker-client.md +22 -0
  62. package/docs/components/map-picker-osm.md +18 -0
  63. package/docs/components/map-picker.md +21 -0
  64. package/docs/components/menu-button.md +22 -0
  65. package/docs/components/multi-select-filter.md +20 -0
  66. package/docs/components/multi-select.md +23 -0
  67. package/docs/components/number-input.md +20 -0
  68. package/docs/components/page-title.md +13 -0
  69. package/docs/components/paginated-table.md +35 -0
  70. package/docs/components/pagination.md +27 -0
  71. package/docs/components/render-field.md +24 -0
  72. package/docs/components/rich-text-preview.md +18 -0
  73. package/docs/components/select.md +28 -0
  74. package/docs/components/status-badge.md +14 -0
  75. package/docs/components/switch.md +27 -0
  76. package/docs/components/table-filter-field.md +21 -0
  77. package/docs/components/table-toolbar.md +19 -0
  78. package/docs/components/text-area.md +20 -0
  79. package/docs/components/text-input.md +23 -0
  80. package/docs/components/time-picker.md +22 -0
  81. package/docs/components/toggle-inline-button.md +22 -0
  82. package/docs/components/toggle.md +21 -0
  83. package/docs/components/upload-files-preview.md +26 -0
  84. package/docs/contracts/controller-props.md +28 -0
  85. package/docs/contracts/dependency-map.md +57 -0
  86. package/docs/contracts/style-imports.md +27 -0
  87. package/package.json +6 -4
package/COMPONENTS.md CHANGED
@@ -1,147 +1,20 @@
1
- # @mantis-core/ui Component Catalog
1
+ # @mantis-core/ui Component Index
2
2
 
3
- This document describes what each exported UI component does, when to use it, and key integration notes.
3
+ The detailed package documentation is now split into focused files under [`docs/`](./docs/README.md).
4
4
 
5
- ## Export Groups
5
+ ## Start Here
6
6
 
7
- ## Buttons
7
+ - [Documentation index](./docs/README.md)
8
+ - [Shared contracts](./docs/contracts/controller-props.md)
9
+ - [Underlying library map](./docs/contracts/dependency-map.md)
10
+ - [Style import guide](./docs/contracts/style-imports.md)
8
11
 
9
- - `Button`
10
- - Generic action button with variant support.
11
- - Use for reusable actions, not domain-specific behavior.
12
+ ## Key component docs
12
13
 
13
- ## Loaders
14
-
15
- - `Loading`
16
- - Wrapper and spinner/loading utilities for async states.
17
-
18
- ## Forms
19
-
20
- - `CKEditorInput`
21
- - Rich text editor input built around CKEditor.
22
- - Includes content metrics type export.
23
- - `DateInput`
24
- - Date picker field.
25
- - `DropDown`
26
- - PrimeReact dropdown wrapper.
27
- - `ErrorMessage`
28
- - Standardized field error rendering.
29
- - `FormFieldRender`
30
- - Label + render prop + error wrapper for fields.
31
- - `HiddenField`
32
- - Hidden input field support.
33
- - `MultiSelect`
34
- - Multi-select control wrapper.
35
- - `NumberInput`
36
- - Numeric input control.
37
- - `RenderField`
38
- - Field renderer utility.
39
- - `Select`
40
- - Select component wrapper.
41
- - `Switch`
42
- - Boolean switch input.
43
- - `TextArea`
44
- - Multi-line text input.
45
- - `TextInput`
46
- - Standard text input.
47
- - `TimePicker`
48
- - Time selection input.
49
- - `Toggle`
50
- - Toggle control.
51
- - `ToggleInlineButton`
52
- - Inline toggle button.
53
- - `UploadFilesPreview`
54
- - Upload preview component with item/copy types.
55
- - `ControllerProps` (type)
56
- - Shared control typing contract.
57
-
58
- ## Tables
59
-
60
- - `TableToolbar`
61
- - Header area for title, meta, and actions.
62
- - `TableFilterField`
63
- - Wrapper for consistent table filter controls.
64
- - `ActionColumn`
65
- - Action menu column helper.
66
- - `FilterPannel`
67
- - Filter container panel.
68
- - `MultiSelectFilter`
69
- - Multi-select filter utility for tables.
70
- - `IndexColumn`
71
- - Index/ordinal column helper.
72
- - `MenuButton`
73
- - Row action menu button.
74
- - `PaginatedTable`
75
- - PrimeReact `DataTable` wrapper with Mantis Core defaults.
76
- - Key props:
77
- - `showIndexColumn`
78
- - `showActionColumn`
79
- - `useMantisCoreStyles`
80
- - `actionColumnItems`
81
-
82
- ## Page and Admin Layout
83
-
84
- - `FormSection`
85
- - Structured form section block.
86
- - `PageTitle`
87
- - Page heading helper.
88
- - `AdminPageHeader`
89
- - Page header presentation component.
90
- - `AdminPageConfigurator`
91
- - Configures admin page layout context.
92
- - `AdminPageLayoutProvider`
93
- - Context provider for admin layout.
94
- - `useAdminPageLayout`
95
- - Hook to read/update admin layout state.
96
- - `AdminPageLayoutShell`
97
- - Shared admin page shell renderer.
98
- - `AdminBreadcrumbItem`, `AdminPageLayoutConfig` (types)
99
- - Layout contract types.
100
-
101
- ## Generic UI
102
-
103
- - `Pagination`
104
- - Page navigation component.
105
- - `PaginationInfo`
106
- - Current page range summary.
107
- - `PageSizeSelector`
108
- - Page size control.
109
- - `RichTextPreview`
110
- - Sanitized rich-text display helper.
111
-
112
- ## Maps
113
-
114
- - `MapPicker`
115
- - Dynamic import wrapper for client map rendering.
116
- - `MapPickerClient`
117
- - Leaflet/react-leaflet map picker implementation.
118
- - `MapPickerOSM`
119
- - OpenStreetMap picker variant.
120
- - `LatLng`, `MapPicker*Props` (types)
121
- - Map contracts.
122
-
123
- ## Runtime Notes
124
-
125
- 1. Many components are client-side (`"use client"`).
126
- 2. Map components depend on Leaflet assets and browser APIs.
127
- 3. Table and paginator visuals depend on `@mantis-core/styles` classes.
128
-
129
- ## Integration Rules
130
-
131
- 1. Keep domain logic outside this package.
132
- 2. Keep text/content generic when possible.
133
- 3. If a component cannot be generic, keep it in app layer instead.
134
- 4. Any new export must be added to:
135
- - `src/index.ts`
136
- - this file (`COMPONENTS.md`)
137
- - package README if category-level behavior changes.
138
-
139
- ## Suggested Validation For New Components
140
-
141
- ```bash
142
- pnpm --filter @mantis-core/ui build
143
- pnpm --filter @mantis-core/ui typecheck
144
- pnpm lint
145
- ```
146
-
147
- Also validate in at least one consuming app route.
14
+ - [Button](./docs/components/button.md)
15
+ - [TextInput](./docs/components/text-input.md)
16
+ - [Select](./docs/components/select.md)
17
+ - [PaginatedTable](./docs/components/paginated-table.md)
18
+ - [ConfirmDialog](./docs/components/confirm-dialog.md)
19
+ - [StatusBadge](./docs/components/status-badge.md)
20
+ - [MapPicker](./docs/components/map-picker.md)
@@ -0,0 +1,6 @@
1
+ # @mantis-core/ui Dependency Map
2
+
3
+ The detailed dependency mapping now lives in focused package docs.
4
+
5
+ - [Underlying library map](./docs/contracts/dependency-map.md)
6
+ - [Component index](./docs/README.md)
package/README.md CHANGED
@@ -1,22 +1,22 @@
1
1
  # @mantis-core/ui
2
2
 
3
- Reusable React component library for Mantis Core apps.
3
+ Reusable React component library for Mantis Core applications.
4
4
 
5
5
  ## Purpose
6
6
 
7
- `@mantis-core/ui` centralizes shared UI primitives so feature teams can build pages without duplicating component logic across projects.
7
+ `@mantis-core/ui` centralizes reusable UI building blocks for forms, tables, admin page layout, generic state handling, and maps. The package is intended to be domain-agnostic and portable across multiple apps.
8
8
 
9
9
  ## Scope
10
10
 
11
- - Generic UI components for forms, tables, admin layout, maps, and pagination.
12
- - Components intended to be reused by multiple verticals/apps.
13
- - Components designed to work with `@mantis-core/styles` (`mantis-core-*` class contract).
11
+ - Reusable React components and helper types.
12
+ - Wrappers around PrimeReact, `react-select`, CKEditor, and Leaflet where Mantis needs a stable contract.
13
+ - Components that optionally consume the visual contracts defined in `@mantis-core/styles`.
14
14
 
15
- ## Out Of Scope
15
+ ## Out of Scope
16
16
 
17
- - Domain-specific workflows (real estate, restaurant, carpentry, etc).
18
- - Business rules and domain orchestration.
19
- - App-level provider setup (handled by `@mantis-core/next-core`).
17
+ - Business rules and domain-specific workflows.
18
+ - App-level providers and framework bootstrapping.
19
+ - Client branding logic outside shared tokens and styles.
20
20
 
21
21
  ## Installation
22
22
 
@@ -24,97 +24,81 @@ Reusable React component library for Mantis Core apps.
24
24
  pnpm add @mantis-core/ui @mantis-core/styles
25
25
  ```
26
26
 
27
- Make sure peer dependencies exist in the app (`react`, `react-dom`, `next`, `primereact`, `primeicons`).
27
+ Required peers:
28
28
 
29
- ## Styling Requirement
29
+ - `react`
30
+ - `react-dom`
31
+ - `next`
32
+ - `primereact`
33
+ - `primeicons`
34
+ - `react-hook-form`
30
35
 
31
- Components rely on style contracts from `@mantis-core/styles`.
32
- Import the required SCSS modules in your app, for example:
36
+ Some exports also require optional peers already pulled by this package surface, such as CKEditor, `react-select`, `react-datepicker`, `leaflet`, and `react-leaflet`.
33
37
 
34
- ```scss
35
- @use "@mantis-core/styles/scss/table.scss";
36
- @use "@mantis-core/styles/scss/paginator.scss";
37
- @use "@mantis-core/styles/scss/inputs.scss";
38
- ```
39
-
40
- ## Public API Strategy
38
+ ## Import Strategy
41
39
 
42
- Preferred import style:
40
+ Preferred:
43
41
 
44
42
  ```ts
45
- import { PaginatedTable, TableToolbar, FormFieldRender } from "@mantis-core/ui";
43
+ import { PaginatedTable, TableToolbar, TextInput } from "@mantis-core/ui";
46
44
  ```
47
45
 
48
- Supported subpath imports:
46
+ Supported subpaths:
49
47
 
50
48
  - `@mantis-core/ui/components/*`
51
49
  - `@mantis-core/ui/table-toolbar`
52
50
  - `@mantis-core/ui/table-filter-field`
53
51
 
54
- Use subpaths only when you need explicit boundaries.
55
-
56
- ## Component Catalog
57
-
58
- See full catalog in [COMPONENTS.md](./COMPONENTS.md).
59
-
60
- Top-level categories:
61
-
62
- - Buttons: `Button`
63
- - Loaders: `Loading`
64
- - Forms: `CKEditorInput`, `TextInput`, `Select`, `Switch`, `UploadFilesPreview`, etc
65
- - Tables: `PaginatedTable`, `TableToolbar`, `TableFilterField`, `ActionColumn`, etc
66
- - Page/Admin layout: `AdminPageConfigurator`, `AdminPageLayoutProvider`, `AdminPageLayoutShell`
67
- - Generic UI: `Pagination`, `PaginationInfo`, `PageSizeSelector`, `RichTextPreview`
68
- - Maps: `MapPicker`, `MapPickerClient`, `MapPickerOSM`
69
-
70
- ## Core Usage Patterns
52
+ Use subpaths only when you need a narrow import boundary.
71
53
 
72
- ### 1) Forms
54
+ ## Styling Model
73
55
 
74
- - Compose fields with `FormFieldRender` + specific input components.
75
- - Keep validation/business rules in the app layer.
56
+ This package does not inject CSS automatically.
76
57
 
77
- ### 2) Data Tables
58
+ - PrimeReact wrappers inherit your PrimeReact theme plus any Mantis SCSS overrides you import.
59
+ - Components with `mantis-core-*` classes require the matching partial from `@mantis-core/styles`.
60
+ - Some components use utility classes or inline styles and do not depend on a Mantis SCSS partial.
78
61
 
79
- Recommended stack:
62
+ Example:
80
63
 
81
- 1. `TableToolbar`
82
- 2. `TableFilterField` / `FilterPannel`
83
- 3. `PaginatedTable`
84
- 4. `Pagination` helpers when needed
64
+ ```scss
65
+ @use "@mantis-core/styles/scss/buttons.scss";
66
+ @use "@mantis-core/styles/scss/inputs.scss";
67
+ @use "@mantis-core/styles/scss/select.scss";
68
+ @use "@mantis-core/styles/scss/table.scss";
69
+ @use "@mantis-core/styles/scss/confirm-dialog.scss";
70
+ ```
85
71
 
86
- ### 3) Admin Page Layout
72
+ ## Documentation Index
87
73
 
88
- Use the layout contract together:
74
+ - [docs/README.md](./docs/README.md): package documentation index
75
+ - [COMPONENTS.md](./COMPONENTS.md): lightweight component index
76
+ - [PRIMEREACT_MAPPING.md](./PRIMEREACT_MAPPING.md): lightweight dependency-map pointer
89
77
 
90
- - `AdminPageLayoutProvider`
91
- - `AdminPageLayoutShell`
92
- - `AdminPageConfigurator`
78
+ ## Public API Summary
93
79
 
94
- ### 4) Maps
80
+ Main export groups:
95
81
 
96
- - `MapPicker` is dynamic/SSR-safe wrapper.
97
- - `MapPickerClient` and `MapPickerOSM` run on client.
82
+ - Buttons: `Button`
83
+ - Loaders: `Loading`
84
+ - Forms: `TextInput`, `TextArea`, `NumberInput`, `DropDown`, `DateInput`, `Select`, `AsyncSelect`, `Switch`, `Toggle`, `ToggleInlineButton`, `CKEditorInput`, `FileDropzone`, `UploadFilesPreview`
85
+ - Form helpers: `RenderField`, `FormFieldRender`, `FormActionsBar`, `DirtyFormGuard`, `useDirtyFormGuard`, `ErrorMessage`, `HiddenField`
86
+ - Tables: `PaginatedTable`, `TableToolbar`, `TableFilterField`, `ActionColumn`, `MenuButton`, `IndexColumn`, `FilterPannel`, `MultiSelectFilter`
87
+ - Page layout: `AdminPageConfigurator`, `AdminPageLayoutProvider`, `useAdminPageLayout`, `AdminPageLayoutShell`, `AdminPageHeader`, `FormSection`, `PageTitle`
88
+ - Generic UI: `Pagination`, `PaginationInfo`, `PageSizeSelector`, `RichTextPreview`, `StatusBadge`, `DataState`, `ConfirmDialog`
89
+ - Maps: `MapPicker`, `MapPickerClient`, `MapPickerOSM`
98
90
 
99
- ## Architecture Rules For Contributors
91
+ ## Contributor Rules
100
92
 
101
- 1. New components must be domain-agnostic.
102
- 2. Avoid direct business terms in props, labels, or naming.
103
- 3. Keep runtime boundaries explicit (`"use client"` only when required).
104
- 4. Export through `src/index.ts` and document in `COMPONENTS.md`.
105
- 5. Preserve `mantis-core-*` visual contract for shared styles.
93
+ 1. Keep new exports domain-agnostic.
94
+ 2. Keep the public API anchored in `src/index.ts`.
95
+ 3. Document new exports in `COMPONENTS.md`.
96
+ 4. Update `PRIMEREACT_MAPPING.md` when the underlying implementation library changes.
97
+ 5. Preserve the `mantis-core-*` style contract where shared styles are intended.
106
98
 
107
- ## Build
99
+ ## Local Validation
108
100
 
109
101
  ```bash
110
102
  pnpm --filter @mantis-core/ui build
111
103
  pnpm --filter @mantis-core/ui typecheck
112
104
  ```
113
-
114
- ## Release Checklist
115
-
116
- 1. Component behavior verified in consuming app.
117
- 2. Props/types documented.
118
- 3. `src/index.ts` export updated.
119
- 4. `COMPONENTS.md` updated.
120
- 5. Add changeset.
@@ -0,0 +1,20 @@
1
+ import { ButtonVariant } from "../Buttons/Button";
2
+ import React from "react";
3
+ import type { Props as ReactSelectProps } from "react-select";
4
+ import { ControllerProps } from "./types";
5
+ type SelectOption = unknown;
6
+ export interface AsyncSelectProps extends Omit<ReactSelectProps<SelectOption>, "name" | "defaultValue" | "options"> {
7
+ controller: ControllerProps;
8
+ block?: boolean;
9
+ variant?: ButtonVariant;
10
+ isCreatable?: boolean;
11
+ loadOptions: (inputValue: string) => Promise<readonly SelectOption[]> | readonly SelectOption[];
12
+ defaultOptions?: readonly SelectOption[] | boolean;
13
+ cacheOptions?: boolean;
14
+ debounceMs?: number;
15
+ onCreateOption?: (inputValue: string) => void | Promise<void>;
16
+ formatCreateLabel?: (inputValue: string) => React.ReactNode;
17
+ }
18
+ declare const AsyncSelect: React.FC<AsyncSelectProps>;
19
+ export default AsyncSelect;
20
+ //# sourceMappingURL=AsyncSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncSelect.d.ts","sourceRoot":"","sources":["../../../src/components/Forms/AsyncSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,KAAyC,MAAM,OAAO,CAAC;AAI9D,OAAO,KAAK,EAAE,KAAK,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,KAAK,YAAY,GAAG,OAAO,CAAC;AAE5B,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IACjF,UAAU,EAAE,eAAe,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC,GAAG,SAAS,YAAY,EAAE,CAAC;IAChG,cAAc,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAAC;IACnD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CAC7D;AAcD,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAkH3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -0,0 +1,77 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import classNames from "classnames";
4
+ import { useCallback, useEffect, useRef } from "react";
5
+ import { Controller } from "react-hook-form";
6
+ import { default as RAsyncSelect } from "react-select/async";
7
+ import { default as RAsyncCreatableSelect } from "react-select/async-creatable";
8
+ const SELECT_VARIANT_TOKENS = {
9
+ primary: { color: "--primary", foreground: "--primary-foreground" },
10
+ secondary: { color: "--secondary", foreground: "--secondary-foreground" },
11
+ accent: { color: "--accent", foreground: "--accent-foreground" },
12
+ success: { color: "--success", foreground: "--success-foreground" },
13
+ warning: { color: "--warning", foreground: "--warning-foreground" },
14
+ error: { color: "--error", foreground: "--error-foreground" },
15
+ info: { color: "--info", foreground: "--info-foreground" },
16
+ gray: { color: "--bluegray-500", foreground: "--primary-foreground" },
17
+ danger: { color: "--error", foreground: "--error-foreground" },
18
+ };
19
+ const AsyncSelect = (props) => {
20
+ const { controller, block, variant = "primary", isCreatable = false, loadOptions, defaultOptions = true, cacheOptions = true, debounceMs = 250, onCreateOption, formatCreateLabel, ...rest } = props;
21
+ const debounceRef = useRef(null);
22
+ const variantTokens = SELECT_VARIANT_TOKENS[variant];
23
+ const SelectComponent = (isCreatable ? RAsyncCreatableSelect : RAsyncSelect);
24
+ useEffect(() => {
25
+ return () => {
26
+ if (debounceRef.current) {
27
+ clearTimeout(debounceRef.current);
28
+ }
29
+ };
30
+ }, []);
31
+ const debouncedLoadOptions = useCallback((inputValue) => new Promise((resolve, reject) => {
32
+ const executeLoad = async () => {
33
+ try {
34
+ const options = await loadOptions(inputValue);
35
+ resolve(options ?? []);
36
+ }
37
+ catch (error) {
38
+ reject(error);
39
+ }
40
+ };
41
+ if (debounceRef.current) {
42
+ clearTimeout(debounceRef.current);
43
+ }
44
+ if (debounceMs <= 0) {
45
+ void executeLoad();
46
+ return;
47
+ }
48
+ debounceRef.current = setTimeout(() => {
49
+ void executeLoad();
50
+ }, debounceMs);
51
+ }), [debounceMs, loadOptions]);
52
+ return (_jsx(Controller, { defaultValue: controller.defaultValue ?? null, ...controller, render: ({ field, fieldState, formState }) => (_jsx(SelectComponent, { instanceId: field.name, id: field.name, className: classNames("select-input cursor-pointer", `select-variant-${variant}`, rest.className, {
53
+ "w-full": block,
54
+ "select-invalid": fieldState.invalid,
55
+ }), classNamePrefix: 'react-select', value: field.value, onChange: field.onChange, onBlur: field.onBlur, name: field.name, placeholder: 'SELECCIONAR', noOptionsMessage: () => "Sin resultados", loadingMessage: () => "Cargando...", ref: field.ref, cacheOptions: cacheOptions, defaultOptions: defaultOptions, loadOptions: debouncedLoadOptions, menuPortalTarget: typeof document !== "undefined" ? document.body : undefined, menuPosition: 'fixed', ...rest, ...(isCreatable
56
+ ? {
57
+ onCreateOption: (inputValue) => {
58
+ void onCreateOption?.(inputValue);
59
+ },
60
+ formatCreateLabel: formatCreateLabel ?? ((inputValue) => `Crear "${inputValue}"`),
61
+ }
62
+ : {}), isDisabled: formState.isSubmitting || rest.isDisabled || rest.isLoading, styles: {
63
+ menuPortal: (base) => ({
64
+ ...base,
65
+ zIndex: 1300,
66
+ ["--select-accent"]: `var(${variantTokens.color})`,
67
+ ["--select-accent-foreground"]: `var(${variantTokens.foreground})`,
68
+ }),
69
+ menu: (base) => ({
70
+ ...base,
71
+ zIndex: 1300,
72
+ }),
73
+ ...(rest.styles || {}),
74
+ } })) }));
75
+ };
76
+ export default AsyncSelect;
77
+ //# sourceMappingURL=AsyncSelect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncSelect.js","sourceRoot":"","sources":["../../../src/components/Forms/AsyncSelect.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { type UseDirtyFormGuardOptions } from "./useDirtyFormGuard";
2
+ export type DirtyFormGuardProps = UseDirtyFormGuardOptions;
3
+ declare const DirtyFormGuard: ({ isDirty, enabled, message }: DirtyFormGuardProps) => null;
4
+ export default DirtyFormGuard;
5
+ //# sourceMappingURL=DirtyFormGuard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DirtyFormGuard.d.ts","sourceRoot":"","sources":["../../../src/components/Forms/DirtyFormGuard.tsx"],"names":[],"mappings":"AAEA,OAA0B,EAAE,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEvF,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAE3D,QAAA,MAAM,cAAc,GAAI,+BAAsC,mBAAmB,SAGhF,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import useDirtyFormGuard from "./useDirtyFormGuard";
3
+ const DirtyFormGuard = ({ isDirty, enabled = true, message }) => {
4
+ useDirtyFormGuard({ isDirty, enabled, message });
5
+ return null;
6
+ };
7
+ export default DirtyFormGuard;
8
+ //# sourceMappingURL=DirtyFormGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DirtyFormGuard.js","sourceRoot":"","sources":["../../../src/components/Forms/DirtyFormGuard.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,iBAAoD,MAAM,qBAAqB,CAAC;AAIvF,MAAM,cAAc,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAuB,EAAE,EAAE;IACnF,iBAAiB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { ControllerProps } from "./types";
2
+ type FileDropzoneRejectCode = "too-many-files" | "file-too-large" | "invalid-file-type";
3
+ export interface FileDropzoneRejectedFile {
4
+ file: File;
5
+ code: FileDropzoneRejectCode;
6
+ message: string;
7
+ }
8
+ export interface FileDropzoneProps {
9
+ controller?: ControllerProps;
10
+ value?: File[];
11
+ onChange?: (files: File[]) => void;
12
+ onFilesAccepted?: (files: File[]) => void;
13
+ onFilesRejected?: (rejections: FileDropzoneRejectedFile[]) => void;
14
+ multiple?: boolean;
15
+ maxFiles?: number;
16
+ maxSizeBytes?: number;
17
+ accept?: string | string[];
18
+ disabled?: boolean;
19
+ block?: boolean;
20
+ label?: string;
21
+ hint?: string;
22
+ dropTitle?: string;
23
+ dragOverTitle?: string;
24
+ className?: string;
25
+ }
26
+ declare const FileDropzone: ({ controller, value, onChange, ...rest }: FileDropzoneProps) => import("react/jsx-runtime").JSX.Element;
27
+ export default FileDropzone;
28
+ export type { FileDropzoneRejectCode };
29
+ //# sourceMappingURL=FileDropzone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileDropzone.d.ts","sourceRoot":"","sources":["../../../src/components/Forms/FileDropzone.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,KAAK,sBAAsB,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;AAExF,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,sBAAsB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACnC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAC1C,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,wBAAwB,EAAE,KAAK,IAAI,CAAC;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+ND,QAAA,MAAM,YAAY,GAAI,0CAKnB,iBAAiB,4CAsBnB,CAAC;AAEF,eAAe,YAAY,CAAC;AAE5B,YAAY,EAAE,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,137 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { cn } from "@mantis-core/utils";
4
+ import { AlertCircle, File as FileIcon, UploadCloud, X } from "lucide-react";
5
+ import { useMemo, useRef, useState } from "react";
6
+ import { Controller } from "react-hook-form";
7
+ const DEFAULT_DROP_TITLE = "Arrastra y suelta archivos aqui";
8
+ const DEFAULT_DRAG_OVER_TITLE = "Suelta los archivos aqui";
9
+ const DEFAULT_HINT = "o haz clic para seleccionar archivos";
10
+ const toArray = (accept) => {
11
+ if (!accept)
12
+ return [];
13
+ if (Array.isArray(accept))
14
+ return accept.map((item) => item.trim()).filter(Boolean);
15
+ return accept
16
+ .split(",")
17
+ .map((item) => item.trim())
18
+ .filter(Boolean);
19
+ };
20
+ const isAcceptedType = (file, acceptList) => {
21
+ if (acceptList.length === 0)
22
+ return true;
23
+ const fileName = file.name.toLowerCase();
24
+ const fileType = file.type.toLowerCase();
25
+ return acceptList.some((rule) => {
26
+ const normalizedRule = rule.toLowerCase();
27
+ if (normalizedRule.startsWith(".")) {
28
+ return fileName.endsWith(normalizedRule);
29
+ }
30
+ if (normalizedRule.endsWith("/*")) {
31
+ const prefix = normalizedRule.slice(0, normalizedRule.length - 1);
32
+ return fileType.startsWith(prefix);
33
+ }
34
+ return fileType === normalizedRule;
35
+ });
36
+ };
37
+ const formatBytes = (bytes) => {
38
+ if (bytes < 1024)
39
+ return `${bytes} B`;
40
+ if (bytes < 1024 ** 2)
41
+ return `${(bytes / 1024).toFixed(1)} KB`;
42
+ return `${(bytes / 1024 ** 2).toFixed(1)} MB`;
43
+ };
44
+ const FileDropzoneInner = ({ value, onChange, onFilesAccepted, onFilesRejected, multiple = true, maxFiles = 10, maxSizeBytes = 10 * 1024 * 1024, accept, disabled = false, block = true, label, hint = DEFAULT_HINT, dropTitle = DEFAULT_DROP_TITLE, dragOverTitle = DEFAULT_DRAG_OVER_TITLE, className, }) => {
45
+ const [isDraggingOver, setIsDraggingOver] = useState(false);
46
+ const [lastRejections, setLastRejections] = useState([]);
47
+ const inputRef = useRef(null);
48
+ const acceptList = useMemo(() => toArray(accept), [accept]);
49
+ const appendFiles = (incomingFiles) => {
50
+ if (!incomingFiles || incomingFiles.length === 0 || disabled)
51
+ return;
52
+ const current = value ?? [];
53
+ const accepted = [];
54
+ const rejected = [];
55
+ for (const file of Array.from(incomingFiles)) {
56
+ if (!isAcceptedType(file, acceptList)) {
57
+ rejected.push({
58
+ file,
59
+ code: "invalid-file-type",
60
+ message: `El archivo ${file.name} no cumple el tipo permitido.`,
61
+ });
62
+ continue;
63
+ }
64
+ if (file.size > maxSizeBytes) {
65
+ rejected.push({
66
+ file,
67
+ code: "file-too-large",
68
+ message: `El archivo ${file.name} supera el maximo permitido (${formatBytes(maxSizeBytes)}).`,
69
+ });
70
+ continue;
71
+ }
72
+ if (!multiple && current.length + accepted.length >= 1) {
73
+ rejected.push({
74
+ file,
75
+ code: "too-many-files",
76
+ message: "Solo se permite un archivo.",
77
+ });
78
+ continue;
79
+ }
80
+ if (current.length + accepted.length >= maxFiles) {
81
+ rejected.push({
82
+ file,
83
+ code: "too-many-files",
84
+ message: `Solo se permiten ${maxFiles} archivos.`,
85
+ });
86
+ continue;
87
+ }
88
+ accepted.push(file);
89
+ }
90
+ if (accepted.length > 0) {
91
+ const mergedFiles = [...current, ...accepted];
92
+ onChange(mergedFiles);
93
+ onFilesAccepted?.(accepted);
94
+ }
95
+ if (rejected.length > 0) {
96
+ setLastRejections(rejected);
97
+ onFilesRejected?.(rejected);
98
+ }
99
+ else {
100
+ setLastRejections([]);
101
+ }
102
+ };
103
+ return (_jsxs("div", { className: cn("mantis-core-file-dropzone", className, { "w-full": block }), children: [label ? _jsx("p", { className: 'mantis-core-file-dropzone__label', children: label }) : null, _jsxs("div", { role: 'button', tabIndex: disabled ? -1 : 0, className: cn("mantis-core-file-dropzone__zone", {
104
+ "mantis-core-file-dropzone__zone--drag": isDraggingOver && !disabled,
105
+ "mantis-core-file-dropzone__zone--disabled": disabled,
106
+ }), onClick: () => !disabled && inputRef.current?.click(), onKeyDown: (event) => {
107
+ if ((event.key === "Enter" || event.key === " ") && !disabled) {
108
+ event.preventDefault();
109
+ inputRef.current?.click();
110
+ }
111
+ }, onDragOver: (event) => {
112
+ event.preventDefault();
113
+ if (!disabled)
114
+ setIsDraggingOver(true);
115
+ }, onDragLeave: () => setIsDraggingOver(false), onDrop: (event) => {
116
+ event.preventDefault();
117
+ setIsDraggingOver(false);
118
+ appendFiles(event.dataTransfer.files);
119
+ }, children: [_jsx("input", { ref: inputRef, type: 'file', className: 'hidden', disabled: disabled, multiple: multiple, accept: acceptList.join(","), onChange: (event) => {
120
+ appendFiles(event.target.files);
121
+ event.target.value = "";
122
+ } }), _jsx("div", { className: 'mantis-core-file-dropzone__icon', children: _jsx(UploadCloud, { size: 22 }) }), _jsx("p", { className: 'mantis-core-file-dropzone__title', children: isDraggingOver && !disabled ? dragOverTitle : dropTitle }), _jsx("p", { className: 'mantis-core-file-dropzone__hint', children: hint })] }), value.length > 0 ? (_jsx("ul", { className: 'mantis-core-file-dropzone__list', children: value.map((file, index) => (_jsxs("li", { className: 'mantis-core-file-dropzone__item', children: [_jsxs("span", { className: 'mantis-core-file-dropzone__item-copy', children: [_jsx(FileIcon, { size: 14 }), _jsx("span", { className: 'mantis-core-file-dropzone__item-name', children: file.name }), _jsx("span", { className: 'mantis-core-file-dropzone__item-size', children: formatBytes(file.size) })] }), _jsx("button", { type: 'button', className: 'mantis-core-file-dropzone__remove', onClick: () => {
123
+ const nextFiles = value.filter((_, itemIndex) => itemIndex !== index);
124
+ onChange(nextFiles);
125
+ }, title: 'Quitar archivo', disabled: disabled, children: _jsx(X, { size: 14 }) })] }, `${file.name}-${file.lastModified}-${index}`))) })) : null, lastRejections.length > 0 ? (_jsx("ul", { className: 'mantis-core-file-dropzone__error-list', children: lastRejections.map((rejection, index) => (_jsxs("li", { className: 'mantis-core-file-dropzone__error-item', children: [_jsx(AlertCircle, { size: 12 }), _jsx("span", { children: rejection.message })] }, `${rejection.file.name}-${rejection.code}-${index}`))) })) : null] }));
126
+ };
127
+ const FileDropzone = ({ controller, value, onChange, ...rest }) => {
128
+ if (controller) {
129
+ return (_jsx(Controller, { defaultValue: controller.defaultValue ?? [], ...controller, render: ({ field, formState }) => (_jsx(FileDropzoneInner, { ...rest, value: Array.isArray(field.value) ? field.value : [], onChange: (files) => {
130
+ field.onChange(files);
131
+ onChange?.(files);
132
+ }, disabled: formState.isSubmitting || rest.disabled })) }));
133
+ }
134
+ return _jsx(FileDropzoneInner, { ...rest, value: value ?? [], onChange: onChange ?? (() => undefined) });
135
+ };
136
+ export default FileDropzone;
137
+ //# sourceMappingURL=FileDropzone.js.map