@mieweb/ui 0.7.3-dev.6 → 0.7.3-dev.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,10 +51,28 @@ npm install react react-dom
51
51
 
52
52
  Heavy or specialized dependencies are kept in separate entry points so they don't bloat the core bundle. Install the peer dependencies for the add-ons you need:
53
53
 
54
- | Entry point | Install | Import path |
55
- | ------------------------ | ---------------------------------------------------- | ------------------------ |
56
- | **AG Grid** | `npm install ag-grid-community ag-grid-react` | `@mieweb/ui/ag-grid` |
57
- | **DataVis** | `npm install @mieweb/datavis datavis-ace` | `@mieweb/ui/datavis` |
54
+ | Entry point | Install | Import path |
55
+ | ------------------------ | --------------------------------------------- | -------------------- |
56
+ | **AG Grid** (deprecated) | `npm install ag-grid-community ag-grid-react` | `@mieweb/ui/ag-grid` |
57
+ | **DataVis** | `npm install @mieweb/datavis datavis-ace` | `@mieweb/ui/datavis` |
58
+
59
+ > ⚠️ **AGGrid is deprecated.** Use DataVis NITRO (`@mieweb/ui/datavis`) for all
60
+ > tables. The `@mieweb/ui/ag-grid` entry remains available for existing
61
+ > consumers but will be removed in a future major release.
62
+
63
+ ### AI Agent Rules
64
+
65
+ Working with AI coding agents (Copilot, Claude Code, Cursor, …)? Install
66
+ @mieweb/ui's agent rules into your repo so agents use library components
67
+ (DataVis NITRO for tables, `Button`/`Badge`/`Modal`/… instead of raw HTML):
68
+
69
+ ```bash
70
+ npx @mieweb/ui init-agent
71
+ ```
72
+
73
+ This writes `.github/instructions/mieweb-ui.instructions.md` (auto-applied by
74
+ VS Code Copilot) and a marked block in `AGENTS.md` (the cross-tool convention).
75
+ Idempotent — rerun after upgrading to refresh the rules. See [agent/](agent/).
58
76
 
59
77
  ## Quick Start
60
78
 
@@ -173,20 +191,20 @@ This watches for source changes and rebuilds automatically. It does **not** star
173
191
 
174
192
  ### Available Scripts
175
193
 
176
- | Script | Description |
177
- | ------------------------- | --------------------------------------------------------- |
178
- | `npm run dev` | Watch & rebuild the library (for local consumers, not Storybook) |
194
+ | Script | Description |
195
+ | ------------------------- | ------------------------------------------------------------------------------------------------- |
196
+ | `npm run dev` | Watch & rebuild the library (for local consumers, not Storybook) |
179
197
  | `npm run build:esheet` | Build eSheet submodule packages (auto-run by `prestorybook`/`prebuild`; skips when already built) |
180
- | `npm run build` | Build the library for production |
181
- | `npm run storybook` | Start Storybook development server |
182
- | `npm run build-storybook` | Build Storybook for static hosting |
183
- | `npm run typecheck` | Run TypeScript type checking |
184
- | `npm run lint` | Run ESLint |
185
- | `npm run lint:fix` | Run ESLint with auto-fix |
186
- | `npm run format` | Check code formatting with Prettier |
187
- | `npm run format:fix` | Fix code formatting with Prettier |
188
- | `npm run test` | Run tests |
189
- | `npm run test:watch` | Run tests in watch mode |
198
+ | `npm run build` | Build the library for production |
199
+ | `npm run storybook` | Start Storybook development server |
200
+ | `npm run build-storybook` | Build Storybook for static hosting |
201
+ | `npm run typecheck` | Run TypeScript type checking |
202
+ | `npm run lint` | Run ESLint |
203
+ | `npm run lint:fix` | Run ESLint with auto-fix |
204
+ | `npm run format` | Check code formatting with Prettier |
205
+ | `npm run format:fix` | Fix code formatting with Prettier |
206
+ | `npm run test` | Run tests |
207
+ | `npm run test:watch` | Run tests in watch mode |
190
208
 
191
209
  ## Date & Time Standard
192
210
 
@@ -211,7 +229,8 @@ const inProviderZone = DateTime.fromISO(timestamp, {
211
229
  zone: 'America/New_York',
212
230
  });
213
231
 
214
- const isOpen = DateTime.now().setZone('America/New_York') <
232
+ const isOpen =
233
+ DateTime.now().setZone('America/New_York') <
215
234
  inProviderZone.plus({ hours: 1 });
216
235
  ```
217
236
 
@@ -692,10 +711,10 @@ This package uses automated releases via GitHub Actions. There are two release c
692
711
 
693
712
  ### Release Channels
694
713
 
695
- | Channel | npm Tag | Install Command | Description |
696
- | ------- | ------- | --------------- | ----------- |
697
- | **Stable** | `latest` | `npm install @mieweb/ui` | Production-ready releases |
698
- | **Prerelease** | `next` | `npm install @mieweb/ui@next` | Latest from `main` branch |
714
+ | Channel | npm Tag | Install Command | Description |
715
+ | -------------- | -------- | ----------------------------- | ------------------------- |
716
+ | **Stable** | `latest` | `npm install @mieweb/ui` | Production-ready releases |
717
+ | **Prerelease** | `next` | `npm install @mieweb/ui@next` | Latest from `main` branch |
699
718
 
700
719
  ### Prerelease (Automatic)
701
720
 
@@ -721,6 +740,7 @@ To create a stable release:
721
740
  5. Click **Run workflow**
722
741
 
723
742
  The workflow will:
743
+
724
744
  1. Bump the version in `package.json`
725
745
  2. Commit and push the change
726
746
  3. Create a git tag (e.g., `v0.2.0`)
@@ -737,6 +757,7 @@ git push origin v1.0.0
737
757
  ```
738
758
 
739
759
  The release workflow will automatically:
760
+
740
761
  - Run tests and build
741
762
  - Publish to npm with the appropriate tag (`latest` for stable, `next` for prereleases like `v1.0.0-beta.1`)
742
763
  - Create a GitHub Release with auto-generated release notes
@@ -752,8 +773,8 @@ We follow [Semantic Versioning](https://semver.org/):
752
773
  ## Contributing
753
774
 
754
775
  We welcome contributions! This README and the [Storybook](https://ui.mieweb.org)
755
- are the **consumer** docs (how to *use* the library). If you want to *build or
756
- change* the library itself, the **provider / maintainer** guide is
776
+ are the **consumer** docs (how to _use_ the library). If you want to _build or
777
+ change_ the library itself, the **provider / maintainer** guide is
757
778
  **[CONTRIBUTING.md](CONTRIBUTING.md)** — it covers repo layout, the component
758
779
  anatomy and conventions, the autodocs story pattern, exports & tree-shaking,
759
780
  build, testing (unit + visual baselines), submodules, brands, and the release
@@ -0,0 +1,20 @@
1
+ # agent/ — AI Agent Rules Shipped with @mieweb/ui
2
+
3
+ Rules that teach AI coding agents (Copilot, Claude Code, Cursor, Codex, …) to
4
+ use `@mieweb/ui` components — most importantly, **DataVis NITRO for all
5
+ tables** — instead of inventing their own UI.
6
+
7
+ Agents don't read files inside `node_modules`, so consumers install the rules
8
+ into their repo with:
9
+
10
+ ```bash
11
+ npx @mieweb/ui init-agent
12
+ ```
13
+
14
+ | File | Purpose |
15
+ | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
16
+ | [mieweb-ui.instructions.md](mieweb-ui.instructions.md) | The rules template. Copied verbatim to the consumer's `.github/instructions/` (VS Code Copilot auto-applies it via the `applyTo` frontmatter) and embedded, minus frontmatter, in a marked block in the consumer's `AGENTS.md` (the cross-tool convention). |
17
+ | [init-agent.mjs](init-agent.mjs) | The `mieweb-ui` bin. Idempotent — rerun after upgrading `@mieweb/ui` to refresh both targets. |
18
+
19
+ Rule content is sourced from [lessons/component-policy.md](../lessons/component-policy.md);
20
+ keep the two in sync when policy changes.
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `npx @mieweb/ui init-agent`
4
+ *
5
+ * Installs @mieweb/ui's AI-agent rules into the consuming repository:
6
+ * 1. `.github/instructions/mieweb-ui.instructions.md` — auto-applied by
7
+ * VS Code Copilot (and compatible tools) to matching files.
8
+ * 2. A marked block in `AGENTS.md` — read by Claude Code, Cursor, Codex,
9
+ * and other agents that follow the AGENTS.md convention.
10
+ *
11
+ * Idempotent: rerun after upgrading @mieweb/ui to refresh both targets.
12
+ */
13
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
14
+ import { dirname, join, resolve } from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+
17
+ const command = process.argv[2];
18
+ if (command !== 'init-agent') {
19
+ console.log('Usage: npx @mieweb/ui init-agent');
20
+ process.exit(command ? 1 : 0);
21
+ }
22
+
23
+ const here = dirname(fileURLToPath(import.meta.url));
24
+ const pkg = JSON.parse(readFileSync(join(here, '..', 'package.json'), 'utf8'));
25
+ const template = readFileSync(join(here, 'mieweb-ui.instructions.md'), 'utf8');
26
+ const targetRoot = resolve(process.cwd());
27
+
28
+ // --- 1. VS Code instructions file --------------------------------------
29
+ const instructionsDir = join(targetRoot, '.github', 'instructions');
30
+ const instructionsPath = join(instructionsDir, 'mieweb-ui.instructions.md');
31
+ mkdirSync(instructionsDir, { recursive: true });
32
+ writeFileSync(instructionsPath, template);
33
+ console.log(`✔ wrote .github/instructions/mieweb-ui.instructions.md`);
34
+
35
+ // --- 2. AGENTS.md marked block ------------------------------------------
36
+ const BEGIN = '<!-- mieweb-ui:begin -->';
37
+ const END = '<!-- mieweb-ui:end -->';
38
+ // Same rules, minus the VS Code-specific frontmatter.
39
+ const body = template.replace(/^---\n[\s\S]*?\n---\n+/, '');
40
+ const block = `${BEGIN}\n${body.trimEnd()}\n${END}`;
41
+
42
+ const agentsPath = join(targetRoot, 'AGENTS.md');
43
+ if (!existsSync(agentsPath)) {
44
+ writeFileSync(agentsPath, `${block}\n`);
45
+ console.log('✔ created AGENTS.md');
46
+ } else {
47
+ const current = readFileSync(agentsPath, 'utf8');
48
+ const start = current.indexOf(BEGIN);
49
+ const end = start === -1 ? -1 : current.indexOf(END, start + BEGIN.length);
50
+ let updated;
51
+ if (start !== -1 && end !== -1) {
52
+ updated = current.slice(0, start) + block + current.slice(end + END.length);
53
+ console.log('✔ refreshed @mieweb/ui block in AGENTS.md');
54
+ } else {
55
+ updated = `${current.trimEnd()}\n\n${block}\n`;
56
+ console.log('✔ appended @mieweb/ui block to AGENTS.md');
57
+ }
58
+ writeFileSync(agentsPath, updated);
59
+ }
60
+
61
+ console.log(`\n@mieweb/ui@${pkg.version} agent rules installed.`);
@@ -0,0 +1,169 @@
1
+ ---
2
+ applyTo: '**/*.{ts,tsx,js,jsx}'
3
+ ---
4
+
5
+ <!-- Generated by `npx @mieweb/ui init-agent`. Do not edit by hand — rerun the command after upgrading @mieweb/ui to refresh. -->
6
+
7
+ # @mieweb/ui — Rules for AI Agents
8
+
9
+ This project uses the `@mieweb/ui` component library. Follow these rules for ALL UI work. Browse the full catalog at https://ui.mieweb.org (Storybook).
10
+
11
+ ## Rule 1: Tables start with DataVis NITRO
12
+
13
+ When asked to create a table, data grid, or any tabular data view:
14
+
15
+ - **Always start with `DataVisNitroGrid` from `@mieweb/ui/datavis`.** It is the default for every table — propose it first, every time.
16
+ - If the human **explicitly insists** on a plain, simple table after you propose DataVis NITRO, fall back to the `Table` component from `@mieweb/ui` (`Table` + `TableHeader`/`TableBody`/`TableRow`/`TableCell`). Do not choose `Table` on your own.
17
+ - **`AGGrid` is deprecated.** Never import from `@mieweb/ui/ag-grid` in new code.
18
+ - **Never hand-roll a data grid** from raw `<table>`, `<div>` grids, or a third-party grid library.
19
+
20
+ ```tsx
21
+ import { DataVisNitroSource, DataVisNitroGrid } from '@mieweb/ui/datavis';
22
+ // Peer deps: npm install @mieweb/datavis datavis-ace
23
+ ```
24
+
25
+ ## Rule 2: Buttons belong in a ButtonGroup
26
+
27
+ - **Two or more adjacent buttons → always wrap them in `ButtonGroup`.** Never lay out sibling buttons with ad-hoc flex/gap divs.
28
+ - **A single button with a long or unpredictable label** (sentence-like labels, translated text, user-provided data — e.g. "Permanently delete this record") **→ also wrap it in a `ButtonGroup`.** The default `orientation="auto"` measures labels and controls text ellipsis/stacking so long labels never truncate silently.
29
+ - A single button with a short, fixed label ("Save", "OK") may stand alone.
30
+ - **Icon-only buttons** → `<Button size="icon" aria-label="...">`. The `aria-label` is required.
31
+
32
+ ```tsx
33
+ import { Button, ButtonGroup } from '@mieweb/ui';
34
+
35
+ // Multiple buttons
36
+ <ButtonGroup split>
37
+ <Button variant="ghost">Back</Button>
38
+ <Button variant="secondary">Cancel</Button>
39
+ <Button variant="danger">Permanently delete this record</Button>
40
+ </ButtonGroup>
41
+
42
+ // Single button, long/dynamic label
43
+ <ButtonGroup>
44
+ <Button>{t('orders.submitForPriorAuthorization')}</Button>
45
+ </ButtonGroup>
46
+ ```
47
+
48
+ ## Rule 3: Use an existing @mieweb/ui component before writing your own
49
+
50
+ Before writing any UI element, check whether `@mieweb/ui` already provides it. It ships 126+ components, including:
51
+
52
+ | Category | Components |
53
+ | ---------- | ------------------------------------------------------------------------------------------------------------- |
54
+ | Actions | `Button`, `ButtonGroup` (see Rule 2), `Dropdown`, `CommandPalette`, `QuickAction` |
55
+ | Forms | `Input`, `Textarea`, `Select`, `Checkbox`, `Radio`, `Switch`, `Slider`, `PhoneInput`, `DateInput` |
56
+ | Display | `Table` (only if the human insists — see Rule 1), `Badge`, `Avatar`, `Card`, `CountBadge`, `Text`, `Timeline` |
57
+ | Feedback | `Alert`, `Toast`, `Spinner`, `Skeleton`, `Progress`, `LoadingPage`, `ErrorPage` |
58
+ | Navigation | `Tabs`, `Breadcrumb`, `Pagination`, `Sidebar`, `AppHeader`, `PageHeader`, `StepIndicator` |
59
+ | Overlays | `Modal`, `Tooltip`, `DropzoneOverlay` |
60
+ | Media | `AudioPlayer`, `AudioRecorder`, `RecordButton`, `DocumentScanner` |
61
+ | Messaging | `MessageBubble`, `MessageList`, `MessageComposer` |
62
+ | Grids | `DataVisNitroGrid` (default for all tables) — `AGGrid` is **deprecated** |
63
+
64
+ Raw HTML that duplicates a component is a violation, even if it looks right:
65
+
66
+ ```tsx
67
+ // ❌ Violations
68
+ <button onClick={save}>Save</button>
69
+ <span className="rounded-full bg-blue-100 px-2 py-1 text-xs">Active</span>
70
+ <div className="rounded-lg border p-4 shadow">...</div>
71
+ <table>...</table>
72
+
73
+ // ✅ Compliant
74
+ <Button onClick={save}>Save</Button>
75
+ <Badge>Active</Badge>
76
+ <Card><CardContent>...</CardContent></Card>
77
+ <DataVisNitroGrid ... />
78
+ ```
79
+
80
+ ## Rule 4: Use composition slots, not custom markup
81
+
82
+ Components ship structural sub-components — use them instead of bespoke divs inside a component:
83
+
84
+ - `Modal` → `ModalHeader` / `ModalBody` / `ModalFooter`
85
+ - `Card` → `CardHeader` / `CardContent`
86
+ - `Table` → `TableHeader` / `TableBody` / `TableRow` / `TableCell`
87
+
88
+ ```tsx
89
+ // ❌ <Modal open={open}><div className="p-4 border-b font-bold">Title</div>...</Modal>
90
+ // ✅
91
+ <Modal open={open} onClose={close}>
92
+ <ModalHeader>Title</ModalHeader>
93
+ <ModalBody>...</ModalBody>
94
+ <ModalFooter>...</ModalFooter>
95
+ </Modal>
96
+ ```
97
+
98
+ ## Rule 5: Use variants and sizes, not className hacks
99
+
100
+ If a component has a prop for it, use the prop. Never restyle a component with utility classes to imitate an existing variant.
101
+
102
+ ```tsx
103
+ // ❌ <Button className="bg-red-600 text-white hover:bg-red-700">Delete</Button>
104
+ // ✅ <Button variant="danger">Delete</Button>
105
+ // ❌ <Button className="text-xs px-2 py-1">Save</Button>
106
+ // ✅ <Button size="sm">Save</Button>
107
+ ```
108
+
109
+ Button variants: `primary`, `secondary`, `ghost`, `outline`, `danger`, `link`. Sizes: `sm`, `md`, `lg`, `icon`.
110
+
111
+ ## Rule 6: Never hardcode colors
112
+
113
+ Use design tokens so multi-brand theming (mieweb, bluehive, webchart, enterprise-health, …) keeps working:
114
+
115
+ - ❌ `bg-blue-500`, `text-[#1a73e8]`, `style={{ color: 'red' }}`
116
+ - ✅ semantic tokens: `bg-primary-600`, `text-muted-foreground`, `border-border`, `bg-background`
117
+ - ✅ charts: `var(--mieweb-chart-1)` … `var(--mieweb-chart-5)`
118
+
119
+ ## Rule 7: Theme through the brand system, never global CSS
120
+
121
+ - Wrap the app in `ThemeProvider`; use `@mieweb/ui/brands` (`generateBrandCSS`, `brands`) for brand switching.
122
+ - **No global resets or element-selector overrides** (`button { … }`, `* { … }`). Styles stay component-scoped and minimal.
123
+
124
+ ## Rule 8: Feedback states use library components
125
+
126
+ - Loading: `Spinner` (inline), `Skeleton` (content placeholder), `LoadingPage` (full page). Never a hand-rolled CSS spinner.
127
+ - Outcomes: `Alert` (inline), `Toast` (transient — announces via aria-live for free). Never a bespoke alert div.
128
+ - Errors/empty pages: `ErrorPage`. Progress: `Progress`.
129
+
130
+ ## Rule 9: Accessibility is not optional
131
+
132
+ - Every interactive element needs an accessible name (`aria-label`, `aria-labelledby`, or visible text).
133
+ - Use semantic HTML (`nav`, `main`, `button`) — never a clickable `div`.
134
+ - Dynamic updates (modals, alerts, notifications) must be announced — prefer `Toast`/`Alert`, which handle aria-live.
135
+ - Preserve logical tab order and visible focus indicators; never remove focus outlines.
136
+
137
+ ## Rule 10: Internationalization and RTL
138
+
139
+ - **Externalize all user-facing text** — no hardcoded English strings in JSX. Use the project's i18n function (`t('…')`).
140
+ - **Use RTL-safe logical classes**: `ms-*`/`me-*`, `ps-*`/`pe-*`, `start-*`/`end-*`, `text-start`/`text-end` — never `ml-*`/`mr-*`, `pl-*`/`pr-*`, `left-*`/`right-*`, `text-left`/`text-right`.
141
+ - Localize dates, numbers, and currency via `Intl` APIs, not string formatting.
142
+
143
+ ## Rule 11: Forms
144
+
145
+ - Always use library fields (`Input`, `Textarea`, `Select`, `Checkbox`, `Radio`, `Switch`, `Slider`) with a properly associated `<label>`.
146
+ - Dates → `DateInput` / `DateRangePicker`, never raw `type="date"`. Phones → `PhoneInput`. URLs → `WebsiteInput`.
147
+
148
+ ## Rule 12: Imports and Tailwind setup
149
+
150
+ ```tsx
151
+ // Most components: named imports from the main barrel
152
+ import { Button, Input, Card, Modal, Badge } from '@mieweb/ui';
153
+
154
+ // Heavy add-ons live behind subpath entries (install their peer deps):
155
+ import { DataVisNitroGrid } from '@mieweb/ui/datavis'; // tables/grids
156
+ import { generateBrandCSS, brands } from '@mieweb/ui/brands'; // branding
157
+ ```
158
+
159
+ Never import from `@mieweb/ui/ag-grid` (deprecated).
160
+
161
+ Tailwind: on Tailwind 4, add an `@source` for `@mieweb/ui` so library classes are generated; on Tailwind 3, use the `@mieweb/ui/tailwind-preset` preset and `miewebUISafelist`. Do not invent purge/content configs.
162
+
163
+ ## Rule 13: Deprecations are law
164
+
165
+ If JSDoc, the console, or the docs mark something deprecated (`AGGrid` today), do not use it in new code and do not suppress the warning. Use the documented replacement.
166
+
167
+ ## Rule 14: When no component exists
168
+
169
+ First verify it truly doesn't exist — check https://ui.mieweb.org (Storybook) rather than guessing. Then build it locally, but in `@mieweb/ui` style: Tailwind utility classes with the library's design tokens, ARIA labels on interactive elements, and externalized user-facing text. Prefer composing existing primitives (`Card`, `Text`, `Badge`) over new bespoke markup. If the pattern is generic, propose contributing it upstream to `@mieweb/ui`.
package/dist/ag-grid.cjs CHANGED
@@ -86,6 +86,14 @@ var getDefaultColDef = (sortable, filterable, resizable) => ({
86
86
  headerClass: "ag-header-cell-custom",
87
87
  cellClass: "ag-cell-custom"
88
88
  });
89
+ var didWarnDeprecated = false;
90
+ function warnDeprecatedOnce() {
91
+ if (process.env.NODE_ENV === "production" || didWarnDeprecated) return;
92
+ didWarnDeprecated = true;
93
+ console.warn(
94
+ "[@mieweb/ui] AGGrid is deprecated. Use DataVis NITRO (@mieweb/ui/datavis) for all tables."
95
+ );
96
+ }
89
97
  function AGGridInner({
90
98
  className,
91
99
  variant,
@@ -111,6 +119,9 @@ function AGGridInner({
111
119
  }, ref) {
112
120
  const internalRef = React__namespace.useRef(null);
113
121
  const gridApiRef = React__namespace.useRef(null);
122
+ React__namespace.useEffect(() => {
123
+ warnDeprecatedOnce();
124
+ }, []);
114
125
  const resolvedRef = gridRef || ref || internalRef;
115
126
  const handleGridReady = React__namespace.useCallback(
116
127
  (event) => {