@nexdom/uimed-vue 1.3.0-beta.3 → 2.0.0-beta.10

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/AGENTS.md CHANGED
@@ -30,7 +30,7 @@ Add the Vite plugin:
30
30
 
31
31
  ```ts
32
32
  // vite.config.ts
33
- import { vitePluginUimed } from "@nexdom/uimed-vue/plugins.ts";
33
+ import { vitePluginUimed } from "@nexdom/uimed-vue/plugins";
34
34
 
35
35
  // ...
36
36
 
@@ -55,23 +55,35 @@ createApp(App).use(uimed).mount("#app");
55
55
 
56
56
  ### Usage
57
57
 
58
- Place the `Root` component at the top of `App.vue`, then add other components as needed:
58
+ Place the `UMain` component at the top of `App.vue`, then add other components as needed:
59
59
 
60
60
  ```vue
61
61
  <!-- App.vue -->
62
62
  <template>
63
- <root>
63
+ <u-main>
64
64
  <!-- ... -->
65
- </root>
65
+ </u-main>
66
66
  </template>
67
67
 
68
68
  <script setup lang="ts">
69
- import { Root } from "@nexdom/uimed-vue/components";
69
+ import { UMain } from "@nexdom/uimed-vue/components";
70
70
  </script>
71
71
  ```
72
72
 
73
73
  Never write CSS, classes or any kind of styling. Always use component props.
74
74
 
75
+ The library doesn't export prop types. Derive them with `ComponentProps` from `vue-component-type-helpers`:
76
+
77
+ ```ts
78
+ import type { ComponentProps } from "vue-component-type-helpers";
79
+ import { UMain, USection } from "@nexdom/uimed-vue/components";
80
+
81
+ type MainProps = ComponentProps<typeof UMain>;
82
+ type AppBar = NonNullable<MainProps["appBar"]>;
83
+ type NavigationMenu = NonNullable<MainProps["navigationMenu"]>;
84
+ type SectionAction = NonNullable<ComponentProps<typeof USection>["actions"]>[number];
85
+ ```
86
+
75
87
  Available entry points: `@nexdom/uimed-vue` (root), `@nexdom/uimed-vue/components`, `@nexdom/uimed-vue/composables`, `@nexdom/uimed-vue/plugins`, `@nexdom/uimed-vue/unit-test` (test helpers, e.g. `vueTestUtilsPluginUimed()` for mounting components with Vuetify in Vitest).
76
88
 
77
89
  Full component/composable reference lives in the [docs](https://nexdom-healthtech.github.io/uimed-vue/).
@@ -90,23 +102,70 @@ vp env setup # create shims like vpr and vpx
90
102
  vp install # install dependencies
91
103
  ```
92
104
 
105
+ On Windows, prefer VSCode's "Dev Containers: Clone Repository in Container Volume" over opening a folder cloned on the host:
106
+
107
+ - A host clone with `core.autocrlf=true` checks files out with CRLF, and `vpr check` then reports formatting issues on every file. `.gitattributes` enforces LF, but clones made before it was added need `git rm -rq --cached . && git reset --hard` to be re-normalized (commit or stash local changes first, since `reset --hard` discards them).
108
+ - A host folder bind-mounted into the container is roughly 10x slower (unit tests alone go from seconds to minutes), which makes Stryker's initial test run time out.
109
+
93
110
  ## Commands
94
111
 
95
- - `vpr check` — lint, formatter, and type-check (requires `build`/`pack` to have run first for the type-check step)
112
+ - `vpr check` — lint, formatter, and type-check (builds the library first, since the type-check reads `dist`)
96
113
  - `vp test --coverage` — unit tests with coverage (Vitest, jsdom, 100% coverage threshold enforced)
97
- - `vpr test:mutations` — mutation tests (Stryker; thresholds: high 100, low 95, break 95)
98
- - `vpr test:e2e` — E2E tests (Playwright, runs against the built docs preview site)
114
+ - `vpr test:mutations` — mutation tests (Stryker; thresholds: high 100, low 100, break 100). It starts one test runner per CPU core; on machines with limited memory, run `vpx stryker run --concurrency 4` instead
115
+ - `vpr test:e2e` — E2E tests (Playwright, runs against the built docs preview site). Outside CI it reuses any server already on port 4173, which is also `vpr docs:dev`'s port: stop the dev server first, or the tests run against it instead of the built site
99
116
  - `vpr depcruise` — architecture/dependency rules (dependency-cruiser)
100
117
  - `vp pack` / `vpr build` — build the library
101
118
  - `vpr docs` / `vpr docs:dev` — run docs site (imports the lib from `dist`, not `src` — run `vpr dev` in a second terminal to keep `dist` updated while iterating)
102
119
 
103
120
  CI (`.github/workflows/ci.yml`) runs, in order: commitlint on PR commits, `vp pack`, `vpr check`, `vpr depcruise`, `vp test --coverage`, `vpr test:mutations`, `vpr test:e2e`. Match this locally before opening a PR.
104
121
 
122
+ ### Focused runs while iterating
123
+
124
+ The full suite takes minutes; while working on a single component or composable, scope each step to it (`button` below is an example) and run the full suite only before opening a PR:
125
+
126
+ ```bash
127
+ # Unit tests of one or more folders
128
+ vp test src/components/button
129
+
130
+ # Same, with coverage limited to the files you changed. Without `--coverage.include`, files that
131
+ # are only imported (e.g. the children of `main.vue`) count as uncovered and fail the 100% threshold
132
+ vp test src/components/button --coverage --coverage.include="src/components/button/**"
133
+
134
+ # Mutation tests of specific files. List several files in a single comma-separated `--mutate`
135
+ # (repeating the flag keeps only the last one)
136
+ vpx stryker run --mutate "src/components/button/button.vue,src/composables/button/button.ts"
137
+
138
+ # One E2E spec
139
+ vpr test:e2e e2e/components/button.spec.ts
140
+ ```
141
+
142
+ ## Adding a new component
143
+
144
+ Use an existing component (e.g. `button`) as the reference, and deliver all of the following in the same PR:
145
+
146
+ 1. `src/components/<name>/<name>.vue` (following the pattern in [Code conventions](#code-conventions)), `types.ts` and `__tests__/<name>.test.ts`.
147
+ 2. The `U`-prefixed export in `src/components/index.ts`.
148
+ 3. A usage guide at `docs/guide/components/<name>.md`, with `<demo>` examples (and a `<playground>` section when the component has configurable props), and an API reference at `docs/api/components/<name>.md` (props, events and slots tables). Both in Portuguese.
149
+ 4. Both pages registered in the sidebar at `docs/.vitepress/config.ts`.
150
+ 5. `e2e/components/<name>.spec.ts` covering the guide's interactive examples and a "UI consistency" screenshot check (plus accessible snapshots where relevant). Commit the generated files under `__snapshots__`/`__screenshot__`.
151
+ 6. The full CI sequence passing locally.
152
+
153
+ ## Adding a new composable
154
+
155
+ Use an existing composable (e.g. `use-toast`) as the reference, and deliver in the same PR:
156
+
157
+ 1. `src/composables/<group>/<name>.ts` and `__tests__/<name>.test.ts`, plus the types in the group's `types.ts`. If it relies on an internal component (as `useToast` relies on the internal `Toast` rendered by `UMain`), that component follows the component layout but isn't exported.
158
+ 2. The export in `src/composables/index.ts`, and its assertion in `src/composables/__tests__/index.test.ts`.
159
+ 3. A usage guide at `docs/guide/composables/<name>.md` and an API reference at `docs/api/composables/<name>.md`, both in Portuguese, registered in both sidebars at `docs/.vitepress/config.ts` and listed in `docs/api/index.md` and in the table of `docs/guide/index.md`. If it relies on `UMain` (like `useToast`), also mention it in `UMain`'s guide and API pages.
160
+ 4. `e2e/composables/<name>.spec.ts` covering the guide's examples and a "UI consistency" screenshot check.
161
+ 5. The full CI sequence passing locally.
162
+
105
163
  ## Code conventions
106
164
 
107
165
  - All `src` code is written in English. `docs` content is written in Portuguese (aimed at Brazilian users), even though file/dir names stay in English.
108
166
  - `docs` must not mention Vuetify
109
- - Never write CSS, classes or any kind of styling. Always use component props.
167
+ - A new component/composable must be listed in its guide page (`docs/guide/…`), its API page (`docs/api/…`), both sidebars in `docs/.vitepress/config.ts`, the guide index table (`docs/guide/index.md`) and the API index list (`docs/api/index.md`).
168
+ - Never write CSS or `<style>` blocks, and expose styling to consumers only through props. Inside the library's own components, a Vuetify utility class is acceptable when no Vuetify prop covers the need (e.g. `text-wrap` on a card title), with a comment saying why.
110
169
  - Path aliases: `@/*` → `src/*`, `@e2e/*` → `e2e/*`.
111
170
  - Every public component follows this pattern to block access to internals and give it an editor-hover description:
112
171
 
@@ -126,8 +185,10 @@ CI (`.github/workflows/ci.yml`) runs, in order: commitlint on PR commits, `vp pa
126
185
  </script>
127
186
  ```
128
187
 
129
- - Component layout: `src/components/<name>/<name>.vue`, `types.ts` for prop/option types, `__tests__/<name>.test.ts` for unit tests. Composables follow the same shape under `src/composables/<name>/`.
130
- - Public components/composables/types are re-exported from `src/components/index.ts` and `src/composables/index.ts`.
188
+ - Component layout: `src/components/<name>/<name>.vue`, `types.ts` for prop/option types, `__tests__/<name>.test.ts` for unit tests. Components that belong to a group live in the group's folder (e.g. the internal `src/components/dialogs/toast.vue`).
189
+ - Composables live in a group folder: `src/composables/<group>/<name>.ts`, with `types.ts` and `__tests__/` in the group folder (e.g. `src/composables/dialogs/use-toast.ts`).
190
+ - Public components/composables are re-exported from `src/components/index.ts` and `src/composables/index.ts`. Prop types stay internal (`types.ts` is not re-exported); consumers derive them with `ComponentProps` (see [Usage](#usage)).
191
+ - Every publicly exported component must use the `U` prefix on its export identifier (e.g., `UButton`, `UMain`), while internal file names and component names remain unprefixed.
131
192
  - Use [JSDoc](https://jsdoc.app/about-getting-started) on every method/prop/type intended to be part of the public API — it's the primary documentation surface and supports markdown/code examples.
132
193
  - Known workarounds (see CONTRIBUTING.md before touching related config): `stryker-vue-ignorer` patches a Stryker/Vue macro-hoisting issue; `vue-tsc` is used for type-check instead of Vite+'s built-in one due to an oxlint/Vue support gap. Both are meant to be removed once their upstream issues are fixed — don't build further on top of them without checking if they're still needed.
133
194
 
@@ -135,8 +196,34 @@ CI (`.github/workflows/ci.yml`) runs, in order: commitlint on PR commits, `vp pa
135
196
 
136
197
  - Unit tests use Vitest + `@vue/test-utils`, with `vueTestUtilsPluginUimed()` from `@/unit-test.ts` to mount a Vuetify instance.
137
198
  - Global unit test setup (`src/__tests__/setup.ts`) stubs `visualViewport`, uses fake timers, and silences `console.error/warn/log`.
138
- - Coverage threshold is 100%; mutation testing threshold is 100% (break at 100). Don't add code paths without covering tests.
199
+ - With fake timers in jsdom, Vuetify transitions (e.g. of `VDialog`, `VMenu`) don't finish on their own. Emit the transition events on the Vuetify component (`wrapper.findComponent(VDialog).vm.$emit("afterLeave")`) or advance the timers with `await vi.runAllTimersAsync()`.
200
+ - Coverage threshold is 100%; mutation testing threshold is 100% (break at 100). Don't add code paths without covering tests. Mutants that don't compile are reported as compile errors and don't count toward the score.
139
201
  - E2E tests (Playwright, `e2e/`) run against the built docs preview (`http://localhost:4173/uimed-vue/`). Snapshots/screenshots live under `__snapshots__`/`__screenshot__` next to each spec.
202
+ - In E2E, a paused `page.clock` also freezes transitions, so overlays never finish leaving. Use `page.clock.pauseAt` to hold time-based work (e.g. a demo action with `setTimeout`), `page.clock.fastForward` to complete it, then `page.clock.resume()` before expecting the overlay to be hidden (see `e2e/composables/use-confirm.spec.ts`).
203
+
204
+ ## Library documentation and dependencies
205
+
206
+ The stack is newer than most AI models' training data (Vue 3.5, Vuetify 4, Vue Router 5, Vite+ 0.2, Vitest 4, TypeScript 6, VitePress 2 alpha, Stryker 10, Playwright 1.62), so don't rely on memory for library APIs.
207
+
208
+ - Before using an API this repo doesn't use yet, or implementing something from scratch, look it up in the version declared in `package.json`. The project's `.mcp.json` provides two servers for that:
209
+ - `context7`, with these library IDs: Vue `/websites/vuejs`, Vuetify `/websites/vuetifyjs_en`, Vue Router `/websites/router_vuejs`, Vite+ `/websites/viteplus_dev`, Vitest `/vitest-dev/vitest`, Vue Test Utils `/vuejs/test-utils`, Playwright `/microsoft/playwright`, VitePress `/vuejs/vitepress`, Stryker `/stryker-mutator/stryker-js`.
210
+ - `vuetify`, Vuetify's own server, for component and composable APIs and release notes. Its tools that create or update bins, links, playgrounds or bug reports publish content outside the repo and are denied in `.claude/settings.json`.
211
+ - Queries to both servers leave your machine: describe what you need in generic terms and never include source code or business rules.
212
+ - Before adding a dependency, check whether Vuetify, `@nexdom/shared` or the current dependencies already cover the need. If not, confirm with the requester, check the package's docs, maintenance and license, and declare runtime dependencies as `peerDependencies` (enforced by dependency-cruiser's `use-peer-deps` rule).
213
+ - Vuetify is an internal detail: consumers use the library's props, and `docs` never mention Vuetify.
214
+
215
+ ## AI agents
216
+
217
+ Besides this file, the repo ships Claude Code subagents in `.claude/agents/`:
218
+
219
+ - `issue-planner`: turns an issue into an API proposal plus open questions, before any code is written.
220
+ - `issue-implementer`: implements an issue end to end (source, tests, docs, E2E).
221
+ - `code-reviewer`: reviews a branch or PR against these conventions, without changing code.
222
+ - `dependency-updater`: evaluates and applies dependency updates, such as Dependabot PRs.
223
+
224
+ Issues and PRs live in `nexdom-healthtech/uimed-vue`. Pass `-R nexdom-healthtech/uimed-vue` to `gh`, since clones from forks have issues disabled, and read issues with `gh issue view <number> -R nexdom-healthtech/uimed-vue --json title,body,comments` (`--comments` prints nothing in non-interactive shells).
225
+
226
+ To resolve an issue, run `/resolve-issue <number>` (`.claude/skills/resolve-issue/`). It chains planner, implementer and reviewer, asks you about open questions and waits for your approval of the public API before any code is written.
140
227
 
141
228
  ## Git workflow
142
229
 
package/README.md CHANGED
@@ -41,7 +41,7 @@ Add Vite config:
41
41
 
42
42
  ```ts
43
43
  // vite.config.ts
44
- import { vitePluginUimed } from "@nexdom/uimed-vue/plugins.ts";
44
+ import { vitePluginUimed } from "@nexdom/uimed-vue/plugins";
45
45
 
46
46
  /// ...
47
47
 
@@ -50,7 +50,7 @@ plugins: [vue(), vitePluginUimed()];
50
50
  // ...
51
51
  ```
52
52
 
53
- Use Uimed inside the Vue app:
53
+ Use UIMed inside the Vue app:
54
54
 
55
55
  ```ts
56
56
  // main.js or main.ts