@forsakringskassan/vue-lib-template 1.2.0 → 1.2.2

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 (39) hide show
  1. package/files/docs/build.mts +3 -0
  2. package/files/docs/{kattinformation → guide}/index.md +1 -0
  3. package/files/docs/src/bundle-mocks.mjs +1 -1
  4. package/files/package.json +3 -3
  5. package/files/project-guide/cloneman.md +30 -0
  6. package/files/project-guide/commits-and-releases.md +13 -0
  7. package/files/project-guide/development.md +97 -0
  8. package/files/project-guide/documentation.md +78 -0
  9. package/files/project-guide/index.md +43 -0
  10. package/files/project-guide/testing.md +118 -0
  11. package/files/src/{FcCatInfoComponent.cy.ts → components/guide/FcCatInfo/FcCatInfoComponent.cy.ts} +1 -1
  12. package/files/src/{FcCatInfoComponent.vue → components/guide/FcCatInfo/FcCatInfoComponent.vue} +2 -2
  13. package/files/src/{FcCatInfoComponentLiveExample.vue → components/guide/FcCatInfo/examples/FcCatInfoComponentLiveExample.vue} +5 -3
  14. package/files/src/components/guide/FcCatInfo/index.ts +1 -0
  15. package/files/src/components/guide/README.md +7 -0
  16. package/files/src/components/guide/index.ts +1 -0
  17. package/files/src/components/index.ts +1 -0
  18. package/files/src/index.ts +1 -1
  19. package/files/src/{cat-api-mock.spec.ts → mocks/guide/cat-api-mock.spec.ts} +5 -7
  20. package/files/src/{cat-api.mock.mts → mocks/guide/cat-api.mock.mts} +2 -2
  21. package/files/src/mocks/index.mts +1 -0
  22. package/files/src/selectors/guide/index.ts +1 -0
  23. package/files/src/selectors/index.ts +1 -1
  24. package/files/tsconfig.lib.json +1 -7
  25. package/files/vite.config.mts +1 -1
  26. package/hooks/install.mjs +13 -5
  27. package/index.js +1 -1
  28. package/package.json +30 -18
  29. /package/files/src/{CatInfoEdit.vue → components/guide/FcCatInfo/CatInfoEdit.vue} +0 -0
  30. /package/files/src/{CatInfoShow.vue → components/guide/FcCatInfo/CatInfoShow.vue} +0 -0
  31. /package/files/src/{cat-api.spec.ts → components/guide/FcCatInfo/cat-api.spec.ts} +0 -0
  32. /package/files/src/{cat-api.ts → components/guide/FcCatInfo/cat-api.ts} +0 -0
  33. /package/files/src/{cat-data.ts → components/guide/FcCatInfo/cat-data.ts} +0 -0
  34. /package/files/src/{CatInfoLogic.spec.ts → components/guide/FcCatInfo/cat-info-logic.spec.ts} +0 -0
  35. /package/files/src/{cat-info-logic.ts → components/guide/FcCatInfo/cat-info-logic.ts} +0 -0
  36. /package/files/src/{cat-types.ts → components/guide/FcCatInfo/cat-types.ts} +0 -0
  37. /package/files/src/{examples/CatInfoExample.vue → components/guide/FcCatInfo/examples/FcCatInfoComponentExample.vue} +0 -0
  38. /package/files/src/{mocks.mts → mocks/guide/index.mts} +0 -0
  39. /package/files/src/selectors/{FcCatInfoComponent.selectors.ts → guide/FcCatInfoComponent.selectors.ts} +0 -0
@@ -16,7 +16,10 @@ const docs = new Generator(import.meta.url, {
16
16
  setupPath: path.resolve(import.meta.dirname, "src/setup.ts"),
17
17
  vendor: [
18
18
  { package: "vue", alias: "vue/dist/vue.esm-bundler.js" },
19
+ "@fkui/date",
20
+ "@fkui/logic",
19
21
  "@fkui/vue",
22
+ pkg.name,
20
23
  ],
21
24
  });
22
25
 
@@ -3,6 +3,7 @@ title: Kattinformation
3
3
  status: Draft
4
4
  layout: component
5
5
  component: FcCatInfoComponent
6
+ visible: false
6
7
  ---
7
8
 
8
9
  Komponenten kan visa kattdata i visningsläge eller i ett redigerbart läge.
@@ -1,7 +1,7 @@
1
1
  import { matchRequest } from "@forsakringskassan/apimock-express/browser";
2
2
  import { http } from "msw";
3
3
  import { setupWorker } from "msw/browser";
4
- import mocks from "../../src/mocks.mts";
4
+ import mocks from "../../src/mocks/index.mts";
5
5
 
6
6
  const handlers = [
7
7
  http.all("/api/*", async (req) => {
@@ -92,7 +92,7 @@
92
92
  "@forsakringskassan/cypress-visual-regression": "5.2.0",
93
93
  "@forsakringskassan/docs-generator": "3.6.4",
94
94
  "@forsakringskassan/docs-live-example": "3.0.2",
95
- "@forsakringskassan/eslint-config": "15.9.7",
95
+ "@forsakringskassan/eslint-config": "15.9.10",
96
96
  "@forsakringskassan/eslint-config-cli": "15.9.3",
97
97
  "@forsakringskassan/eslint-config-cypress": "15.9.9",
98
98
  "@forsakringskassan/eslint-config-jest": "15.9.2",
@@ -102,9 +102,9 @@
102
102
  "@forsakringskassan/eslint-config-vue": "15.9.8",
103
103
  "@forsakringskassan/prettier-config": "3.7.8",
104
104
  "@forsakringskassan/stylelint-config": "3.4.6",
105
- "@forsakringskassan/vite-lib-config": "5.11.1",
105
+ "@forsakringskassan/vite-lib-config": "5.12.1",
106
106
  "@forsakringskassan/vitest-config-jsdom": "5.0.0",
107
- "@forsakringskassan/vue-lib-template": "1.2.0",
107
+ "@forsakringskassan/vue-lib-template": "1.2.2",
108
108
  "@html-validate/release-scripts": "7.6.11",
109
109
  "@types/node": "24.13.4",
110
110
  "@typescript/native": "npm:typescript@7.0.2",
@@ -0,0 +1,30 @@
1
+ # Cloneman and template updates
2
+
3
+ [← Back to project guide](./index.md)
4
+
5
+ [Cloneman](https://github.com/Forsakringskassan/cloneman/blob/main/README.md) creates a new component-library repository from a template and keeps files marked as managed in sync with later template updates.
6
+
7
+ The generated repository is a normal project owned by its team. Cloneman does not replace your source code or decide how a component should work. It provides a consistent foundation for configuration, tooling, documentation support, and common CI behavior.
8
+
9
+ ## What is managed
10
+
11
+ Files selected by the template are managed centrally. In this template that includes build and lint configuration, Cypress support, documentation infrastructure, and this `project-guide/` directory. A generated repository also receives the template's dependency and script changes according to Cloneman's update rules.
12
+
13
+ A managed file may be updated when the template is updated. Treat local changes to managed configuration as a deliberate maintenance decision: understand the next template update before diverging from the shared setup.
14
+
15
+ ## Updating a cloned repository
16
+
17
+ When a new template version is available:
18
+
19
+ 1. Read the template release notes and identify configuration or dependency changes.
20
+ 2. Run the update command `npx cloneman@latest update`.
21
+ 3. Review the complete diff, especially package scripts, TypeScript configuration, test configuration, and CI files.
22
+ 4. Resolve conflicts without discarding repository-specific components or tests.
23
+ 5. Run lint, unit tests, component tests, builds, and documentation checks.
24
+ 6. Commit the update separately when possible, so it is easy to review and revert.
25
+
26
+ ## Working with managed files
27
+
28
+ Before editing a managed file, ask whether the change belongs in every library created from the template. If it does, improve the template and update the generated repositories through Cloneman. If it is specific to one component library, keep it in an appropriate consumer-owned file or add a documented local override.
29
+
30
+ The source template is available at [Forsakringskassan/vue-lib-template](https://github.com/Forsakringskassan/vue-lib-template). Use it to inspect the intended baseline, but follow the local repository's pinned versions and release notes when applying an update.
@@ -0,0 +1,13 @@
1
+ # Commits and releases
2
+
3
+ [← Back to project guide](./index.md)
4
+
5
+ Keep commits small enough to review and describe one coherent change. A component feature may still need several files, but its implementation, tests, examples, and documentation should tell one story.
6
+
7
+ Follow the [FKDS developer contribution guide](https://forsakringskassan.github.io/designsystem/latest/gettingstarted/contribute-to-fkds/contributing-developers.html#commit) for the commit convention and examples. Commit messages should make the intent clear to reviewers and release tooling. The prefix used (e.g., `feat:`, `fix:`, or `BREAKING CHANGE:`) determines the version bump (minor, patch, or major) via the automated release process.
8
+
9
+ A useful commit contains the implementation and its verification. Avoid mixing dependency upgrades, formatting churn, and unrelated refactors into a component change unless they are required.
10
+
11
+ ## Release process
12
+
13
+ TODO: Document the release process.
@@ -0,0 +1,97 @@
1
+ # Development
2
+
3
+ [← Back to project guide](./index.md)
4
+
5
+ To get up and running quickly:
6
+
7
+ 1. **Install dependencies**: `npm install`
8
+ 2. **Start development server**: `npm start`
9
+ 3. **Run a specific example**: `npm start <name>` (e.g., `npm start catinfo`)
10
+ 4. **Run tests**: `npm test`
11
+
12
+ ## Architecture: Three Layers
13
+
14
+ We recommend separating Appearance, Logic, and Types into three distinct layers to keep the codebase maintainable. You can find an example component, [`FcCatInfoComponent`](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/FcCatInfoComponent.vue), which demonstrates how this structure can be applied in practice:
15
+
16
+ ### 1. Type Layer
17
+
18
+ In the example [cat-types.ts](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/cat-types.ts), we define _what_ the data is using TypeScript interfaces.
19
+
20
+ - **Why?** It ensures that both the logic and the component know exactly which fields (e.g., `name`, `age`) exist.
21
+
22
+ ### 2. Logic Layer
23
+
24
+ In the example [cat-info-logic.ts](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/cat-info-logic.ts), we create a so-called "composable" (a function that starts with `use...`, e.g., `useCatInfo`).
25
+
26
+ - This is where we handle API calls, state (loading, error), and calculations.
27
+ - **Why?** It makes the logic easy to test with Vitest without needing to start a full browser.
28
+
29
+ ### 3. UI Layer
30
+
31
+ Refer to [FcCatInfoComponent.vue](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/FcCatInfoComponent.vue) for the actual Vue component. This should be "thin".
32
+
33
+ - It imports the logic from `useCatInfo`.
34
+ - It uses components from `@fkui/vue` (such as `FCard` or `FLoader`) to follow the design system.
35
+ - **Focus**: The UI layer should only care about _how to display_ the data and _which user actions_ to trigger. The "brain" is in the logic layer.
36
+
37
+ ## Implementation Flow
38
+
39
+ 1. **Create the files**: Create `MyComponent.vue`, `my-component-logic.ts`, and `my-component-types.ts`.
40
+ 2. **Implement logic**: Create your `useMyComponent` function and export it.
41
+ 3. **Build UI**: Import the logic into the `.vue` file and connect variables to the template.
42
+ 4. **Export**: Open `src/components/index.ts` and add:
43
+
44
+ ```typescript
45
+ export { default as MyComponent } from "./MyComponent.vue";
46
+ ```
47
+
48
+ ## Styling
49
+
50
+ - For small amounts of styling, it is perfectly fine to use `<style lang="scss"></style>` directly within the `.vue` file.
51
+ - For more extensive styles, create a dedicated SCSS file for the component (e.g., `MyComponent.scss`) and import it in the `.vue` file.
52
+ - Use `style.scss` for styles that should apply to the entire library.
53
+
54
+ ## Common commands
55
+
56
+ Use the repository scripts from the root of the project unless stated otherwise. The most important commands for daily development are marked in **bold**.
57
+
58
+ | Command | Use it for |
59
+ | ------------------------ | ------------------------------------------------------------------------------- |
60
+ | **`npm start`** | Start the Vite development server using `src/vite-dev/app.vue`. |
61
+ | **`npm run build`** | Build the library, declaration files, API reports, and the Cloneman template. |
62
+ | `npm run build:lib` | Build the distributable JavaScript and CSS library bundle. |
63
+ | `npm run build:dts` | Check and emit TypeScript declaration files. |
64
+ | `npm run build:api` | Update API Extractor reports for the public package surface. |
65
+ | **`npm run build:docs`** | Build the documentation site into `docs/public/`. |
66
+ | **`npm run start:docs`** | Serve the generated documentation site locally at `http://localhost:8080`. |
67
+ | **`npm test`** | Run the full test command, including the configured pre-test checks. |
68
+ | **`npm run unit`** | Run Vitest without coverage. Useful for a quick unit-test loop. |
69
+ | **`npm run lint`** | Run Prettier, ESLint, Stylelint, and HTML validation checks. |
70
+ | **`npm run lint:fix`** | Apply available automatic formatting and lint fixes. Review the resulting diff. |
71
+ | `npm run prettier:check` | Check formatting without changing files. |
72
+ | `npm run prettier:write` | Format supported files. |
73
+ | `npm run eslint` | Run ESLint with its cache. |
74
+ | `npm run stylelint` | Check styles in `src/**/*.css` and `src/**/*.scss`. |
75
+ | `npm run html-validate` | Validate HTML, Vue files, and Markdown examples. |
76
+ | `npm run clean` | Remove generated `dist/` and `temp/` files. |
77
+
78
+ ## Running examples
79
+
80
+ You can run a specific example file directly by passing a name to the start command:
81
+
82
+ ```bash
83
+ npm start catinfo
84
+ ```
85
+
86
+ This uses fuzzy search to find and start the best matching file in `src/examples/` (e.g., `CatInfoExample.vue`).
87
+
88
+ ## Documentation commands
89
+
90
+ Documentation is maintained in `docs/` and generated with [`@forsakringskassan/docs-generator`](https://forsakringskassan.github.io/docs-generator/latest/). A typical local workflow is:
91
+
92
+ ```bash
93
+ npm run build:docs
94
+ npm run start:docs
95
+ ```
96
+
97
+ The generated site is build output. Edit Markdown and Vue examples in the source locations, then build again.
@@ -0,0 +1,78 @@
1
+ # Component documentation
2
+
3
+ [← Back to project guide](./index.md)
4
+
5
+ Component documentation is written in Markdown and generated into the separate site under `docs/`. The repository-level guide you are reading is ordinary README documentation; it is not processed by docs-generator.
6
+
7
+ The [docs-generator documentation](https://forsakringskassan.github.io/docs-generator/) describes the complete tool. The rules below cover the conventions needed for a component page.
8
+
9
+ ## Create the Markdown page
10
+
11
+ Put the component page in `docs/components/` and give it the same base name as the component. Start with the required front matter:
12
+
13
+ ```md
14
+ ---
15
+ title: Cat information
16
+ status: Draft
17
+ layout: component
18
+ component: FcCatInfoComponent
19
+ ---
20
+ ```
21
+
22
+ Use `Experimentell`, `Draft`, or `Produktionsklar` for `status`, according to the component's actual maturity. The title from front matter becomes the page heading, so do not add a separate `#` heading. Start the body with a short preamble explaining what the component does and when to use it.
23
+
24
+ ## Add an example first
25
+
26
+ Every component must have at least one runnable example so readers can see the component in a useful state. Put examples in `src/`, where the documentation build is configured to find Vue files.
27
+
28
+ A standard runnable example is included with an `import` fence:
29
+
30
+ ````md
31
+ ```import
32
+ CatInfoExample.vue
33
+ ```
34
+ ````
35
+
36
+ The corresponding example is [`FcCatInfoComponentExample.vue`](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/examples/FcCatInfoComponentExample.vue). Keep the example focused on a realistic use case and make its initial state useful without extra setup.
37
+
38
+ Prefer a live example when the documentation needs interactive controls or a richer demonstration. Include a file ending in `LiveExample.vue` with the `live-example` variant:
39
+
40
+ ````md
41
+ ```import live-example
42
+ FcCatInfoComponentLiveExample.vue
43
+ ```
44
+ ````
45
+
46
+ The reference implementation shows this pattern in [FcCatInfoComponentLiveExample.vue](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/examples/FcCatInfoComponentLiveExample.vue) and its [documentation page](https://github.com/Forsakringskassan/vue-lib-template/blob/main/docs/guide/index.md).
47
+
48
+ See the [docs-live-example README](https://github.com/Forsakringskassan/docs-live-example/blob/main/README.md) for the implementation details behind interactive examples.
49
+
50
+ A runnable example is part of the documentation contract, not optional decoration. Add at least one for every component and verify it through `npm run build:docs` and the local documentation server.
51
+
52
+ ## Explain usage and constraints
53
+
54
+ After the preamble and example, use level-two headings for the content readers need. Typical sections are:
55
+
56
+ - When to use the component.
57
+ - Important states and behavior.
58
+ - Content and accessibility considerations.
59
+ - Do's and don'ts.
60
+ - API.
61
+
62
+ Only include sections that apply. Keep guidance task-oriented and describe what a consumer should do, not how the component happens to be implemented.
63
+
64
+ ## Include the generated API
65
+
66
+ Add the Vue API block for every component page:
67
+
68
+ ```md
69
+ ## API
70
+
71
+ ::: api
72
+ vue:FcCatInfoComponent
73
+ :::
74
+ ```
75
+
76
+ The component name must match the Vue component passed to the generator. Public props, events, slots, and documented types are extracted from the component source and its declarations. Keep public API comments accurate because they are part of the generated documentation.
77
+
78
+ If the component has translation keys, add the corresponding translation API block. Do not add empty sections for features the component does not use.
@@ -0,0 +1,43 @@
1
+ # Component library project guide
2
+
3
+ This guide explains how to develop, test, document, and release this Vue component library.
4
+ The documentation in `docs/` describes the library's components, while this guide focuses on the technical aspects of the component library.
5
+
6
+ ## Start here
7
+
8
+ Read the detailed guides in this order:
9
+
10
+ - [Development](./development.md) for the available commands and daily workflow.
11
+ - [Testing](./testing.md) for Vitest, API mocks, Cypress, and quality checks.
12
+ - [Component documentation](./documentation.md) for how to document components and create examples.
13
+ - [Commits and releases](./commits-and-releases.md) for collaboration and publication.
14
+ - [Cloneman](./cloneman.md) for template-managed files and updates.
15
+
16
+ ## Project Structure
17
+
18
+ Here are the most important locations you need to know:
19
+
20
+ - `src/`: This is where all your source code lives.
21
+ - `index.ts`: The "Main Entrance". Everything you want others to be able to import from your library must be exported from here.
22
+ - `style.scss`: Global styles for your library.
23
+ - `components/`: Contains the library's component files.
24
+ - `mocks/`: Contains API mocks and mock-related files for testing.
25
+ - `selectors/`: Contains selector files for Cypress tests, ensuring your tests don't break when CSS classes change.
26
+ - `docs/`: This is where you write the documentation.
27
+ - `docs/components/`: Each component gets its own `.md` file here.
28
+ - `cypress/`: Settings for your component tests.
29
+
30
+ ## A current reference implementation
31
+
32
+ The `vue-lib-template` template repository, which this component library is based on, contains a small cat information component that demonstrates the recommended structure. It is useful as a starting point when creating a new component:
33
+
34
+ - [Component](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/FcCatInfoComponent.vue)
35
+ - [Runnable example](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/examples/FcCatInfoComponentExample.vue)
36
+ - [Live-example](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/examples/FcCatInfoComponentLiveExample.vue)
37
+ - [Unit tests](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/cat-info-logic.spec.ts)
38
+ - [Cypress component tests](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/FcCatInfoComponent.cy.ts)
39
+ - [Cypress selectors](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/selectors/guide/FcCatInfoComponent.selectors.ts)
40
+ - [API mock](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/mocks/guide/cat-api.mock.mts)
41
+ - [Mock registration](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/mocks/index.mts)
42
+
43
+ When comparing your implementation with this example, focus on the separation between rendering, business logic, test selectors, mocks, and examples. The example is just a reference for structure.
@@ -0,0 +1,118 @@
1
+ # Testing and quality checks
2
+
3
+ [← Back to project guide](./index.md)
4
+
5
+ Use different tools for different questions. Unit tests check isolated logic quickly. Cypress checks the component as a user experiences it. API mocks make examples and browser tests deterministic without requiring a live backend.
6
+
7
+ ## Vitest unit tests
8
+
9
+ Use Vitest for composables, business rules, data transformations. Keep these tests independent from the browser whenever possible.
10
+
11
+ Run tests with `npm run unit`.
12
+
13
+ The cat information logic is tested in [`cat-info-logic.spec.ts`](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/cat-info-logic.spec.ts). It mocks the API module and verifies loading, successful data, errors, and updates:
14
+
15
+ ```ts
16
+ import { expect, it, vi } from "vitest";
17
+ import { catGetById } from "./cat-api";
18
+ import { useCatInfo } from "./cat-info-logic";
19
+
20
+ vi.mock("./cat-api");
21
+
22
+ it("loads a cat", async () => {
23
+ vi.mocked(catGetById).mockResolvedValue({ id: "cat-001", name: "Milo" });
24
+
25
+ const { cat, fetchCat } = useCatInfo();
26
+ await fetchCat("cat-001");
27
+
28
+ expect(cat.value?.name).toBe("Milo");
29
+ });
30
+ ```
31
+
32
+ ## API mocks with apimock-express
33
+
34
+ Prefer [@forsakringskassan/apimock-express](https://github.com/Forsakringskassan/apimock-express) when a component calls an HTTP API. A mock documents the endpoint contract and lets the documentation site and Cypress use the same predictable response.
35
+
36
+ Prefer inline mocks when the mock is only needed by a single test or example. See the [inline mocks documentation](https://github.com/Forsakringskassan/apimock-express#inline-mocks) for details.
37
+
38
+ The local example is [`cat-api.mock.mts`](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/mocks/guide/cat-api.mock.mts):
39
+
40
+ ```ts
41
+ import { defineMock } from "@forsakringskassan/apimock-express/helpers";
42
+
43
+ export default defineMock<ResponseType>({
44
+ meta: {
45
+ url: "/resource",
46
+ method: "GET",
47
+ },
48
+ defaultResponse(params) {
49
+ const id = params.parameters?.id;
50
+
51
+ return {
52
+ status: 200,
53
+ body: createResponse(id),
54
+ delay: 300,
55
+ };
56
+ },
57
+ });
58
+ ```
59
+
60
+ To add a new mock:
61
+
62
+ 1. Create a `*.mock.mts` file next to the API code.
63
+ 2. Define its HTTP method, URL, response type, status, body, and any useful delay.
64
+ 3. Import it in [`src/mocks/index.mts`](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/mocks/index.mts).
65
+ 4. Add it to the array passed to `appendBasePath`.
66
+ 5. Use the mock from examples and browser tests, and cover error responses as well as success.
67
+
68
+ Mocks are valuable because they make failures reproducible, keep tests independent of external environments, and expose API assumptions early. Keep mock data representative but small, and do not use real personal or production data.
69
+
70
+ See the [apimock-express README](https://github.com/Forsakringskassan/apimock-express/blob/main/README.md) for advanced request matching and response configuration.
71
+
72
+ ## Cypress component tests
73
+
74
+ Use Cypress for user-visible component behavior: rendering, loading states, form interaction, emitted actions, error states, and accessibility-related behavior. The current example is [`FcCatInfoComponent.cy.ts`](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/components/guide/FcCatInfo/FcCatInfoComponent.cy.ts).
75
+
76
+ The current package does not define a dedicated Cypress npm script, so run Cypress through `npx`:
77
+
78
+ - **Interactive runner** (for development): `npx cypress open --component`
79
+ - **CLI runner** (for CI checks): `npx cypress run --component`
80
+
81
+ Mount the component with realistic props and wait for state changes through visible behavior:
82
+
83
+ ```ts
84
+ cy.mount(FcCatInfoComponent, {
85
+ props: {
86
+ catId: testCat.id,
87
+ isEditable: false,
88
+ },
89
+ });
90
+
91
+ cy.get(catInfoSelectors.loadingContainer()).should("not.exist");
92
+ cy.get(catInfoSelectors.viewContainer()).should("be.visible");
93
+ ```
94
+
95
+ Do not use arbitrary timeouts to wait for the API. Assert on a loading element, a success element, or an error message instead.
96
+
97
+ ### Selectors
98
+
99
+ Keep reusable selectors in a `selectors/` file instead of scattering CSS selectors through specs. The [`FcCatInfoComponent` selector helper](https://github.com/Forsakringskassan/vue-lib-template/blob/main/src/selectors/guide/FcCatInfoComponent.selectors.ts) uses [`data-test`](https://designsystem.forsakringskassan.se/latest/functions/plugins/testplugin.html) attributes and supports scoping a component instance.
100
+
101
+ Selectors should describe stable test targets.
102
+
103
+ ### Accessibility and HTML validation
104
+
105
+ The Cypress configuration includes accessibility and HTML validation plugins. Treat their failures as product issues: fix the component markup or semantics rather than weakening the test by default.
106
+
107
+ Read the [FKDS test tools guide](https://forsakringskassan.github.io/designsystem/latest/gettingstarted/contribute-to-fkds/testverktyg.html) for the wider testing conventions used by the design system.
108
+
109
+ ## Linting and formatting
110
+
111
+ Linting ensures a consistent coding style across the project, catches common bugs early, and reduces noise in git diffs by enforcing a uniform format. Run `npm run lint` regularly during development and always before opening a pull request. It combines:
112
+
113
+ - Prettier for consistent formatting.
114
+ - ESLint for JavaScript, TypeScript, Vue, Vitest, and Cypress rules.
115
+ - Stylelint for CSS and SCSS.
116
+ - HTML Validate for HTML, Vue templates, and Markdown examples.
117
+
118
+ Use `npm run lint:fix` for mechanical fixes, then inspect the diff and run the checks again. Do not disable a rule merely to make a test or example pass; understand why the rule exists first.
@@ -1,7 +1,7 @@
1
1
  import { FLoaderSelectors } from "@fkui/vue/selectors";
2
+ import { FcCatInfoComponentSelectors } from "../../../selectors/guide/FcCatInfoComponent.selectors";
2
3
  import FcCatInfoComponent from "./FcCatInfoComponent.vue";
3
4
  import { cats } from "./cat-data";
4
- import { FcCatInfoComponentSelectors } from "./selectors";
5
5
 
6
6
  describe("FcCatInfoComponent", () => {
7
7
  const testCat = cats[0];
@@ -3,8 +3,8 @@ import { ref, watch } from "vue";
3
3
  import { FCard, FLoader } from "@fkui/vue";
4
4
  import CatInfoEdit from "./CatInfoEdit.vue";
5
5
  import CatInfoShow from "./CatInfoShow.vue";
6
- import { useCatInfo } from "./cat-info-logic";
7
- import { type Cat } from "./cat-types";
6
+ import { useCatInfo } from "./cat-info-logic.js";
7
+ import { type Cat } from "./cat-types.js";
8
8
 
9
9
  interface Props {
10
10
  /**
@@ -2,8 +2,8 @@
2
2
  import { defineComponent } from "vue";
3
3
  import { FCheckboxField, FSelectField } from "@fkui/vue";
4
4
  import { LiveExample } from "@forsakringskassan/docs-live-example";
5
- import FcCatInfoComponent from "./FcCatInfoComponent.vue";
6
- import { getCatIds } from "./cat-data";
5
+ import FcCatInfoComponent from "../FcCatInfoComponent.vue";
6
+ import { getCatIds } from "../cat-data.js";
7
7
 
8
8
  export default defineComponent({
9
9
  name: "FcCatInfoComponentLiveExample",
@@ -23,7 +23,9 @@ export default defineComponent({
23
23
  return this.isEditable ? " is-editable" : "";
24
24
  },
25
25
  template(): string {
26
- return /* HTML */ ` <fc-cat-info-component cat-id="${this.selectedCatId}" ${this.editableAttr} /> `;
26
+ return /* HTML */ `
27
+ <fc-cat-info-component cat-id="${this.selectedCatId}" ${this.editableAttr} />
28
+ `;
27
29
  },
28
30
  },
29
31
  });
@@ -0,0 +1 @@
1
+ export { default as FcCatInfoComponent } from "./FcCatInfoComponent.vue";
@@ -0,0 +1,7 @@
1
+ # Component guide
2
+
3
+ This directory contains an example component, `FcCatInfoComponent`, that demonstrates the setup and conventions used by this template.
4
+ It includes the component, selectors, tests, mock data, related support files, and belonging documentation in `docs/guide`.
5
+
6
+ This guide will stay in sync when you update to later versions of your template,
7
+ with intention to serve as a working reference while building your own components.
@@ -0,0 +1 @@
1
+ export { FcCatInfoComponent } from "./FcCatInfo";
@@ -0,0 +1 @@
1
+ export * from "./guide";
@@ -1,3 +1,3 @@
1
1
  import "./style.scss";
2
2
 
3
- export { default as FcCatInfoComponent } from "./FcCatInfoComponent.vue";
3
+ export * from "./components";
@@ -1,14 +1,12 @@
1
1
  import { matchRequest } from "@forsakringskassan/apimock-express/browser";
2
2
  import { describe, expect, it } from "vitest";
3
- import mocks from "./mocks.mjs";
3
+ import catApiMock from "./cat-api.mock.mts";
4
4
 
5
5
  describe("Cat API Mock Reproduction", () => {
6
6
  it("should return 200 for a valid cat id /api/cat?id=whiskers-001", async () => {
7
7
  expect.assertions(2);
8
- const req = new Request(
9
- "http://localhost:8080/api/cat?id=whiskers-001",
10
- );
11
- const response = await matchRequest(mocks, req);
8
+ const req = new Request("http://localhost:8080/cat?id=whiskers-001");
9
+ const response = await matchRequest([catApiMock], req);
12
10
  expect(response.status).toBe(200);
13
11
 
14
12
  const data = await response.json();
@@ -17,8 +15,8 @@ describe("Cat API Mock Reproduction", () => {
17
15
 
18
16
  it("should return 404 for an invalid cat id /api/cat?id=unknown", async () => {
19
17
  expect.assertions(2);
20
- const req = new Request("http://localhost:8080/api/cat?id=unknown");
21
- const response = await matchRequest(mocks, req);
18
+ const req = new Request("http://localhost:8080/cat?id=unknown");
19
+ const response = await matchRequest([catApiMock], req);
22
20
  expect(response.status).toBe(404);
23
21
 
24
22
  const data = await response.json();
@@ -1,6 +1,6 @@
1
1
  import { defineMock } from "@forsakringskassan/apimock-express/helpers";
2
- import { cats } from "./cat-data.ts";
3
- import type { Cat } from "./cat-types.ts";
2
+ import { cats } from "../../components/guide/FcCatInfo/cat-data.ts";
3
+ import type { Cat } from "../../components/guide/FcCatInfo/cat-types.ts";
4
4
 
5
5
  export default defineMock<Cat | { error: string }>({
6
6
  meta: {
@@ -0,0 +1 @@
1
+ export { default } from "./guide/index.mts";
@@ -0,0 +1 @@
1
+ export { FcCatInfoComponentSelectors } from "./FcCatInfoComponent.selectors";
@@ -1 +1 @@
1
- export { FcCatInfoComponentSelectors } from "./FcCatInfoComponent.selectors";
1
+ export * from "./guide";
@@ -3,17 +3,11 @@
3
3
  {
4
4
  "extends": "@forsakringskassan/vite-lib-config/tsconfig.lib.json",
5
5
  "compilerOptions": {
6
- "allowImportingTsExtensions": true,
7
6
  "paths": {
8
7
  "@forsakringskassan/vue-lib-template/selectors": [
9
8
  "./src/selectors/index.ts"
10
9
  ],
11
10
  "@forsakringskassan/vue-lib-template": ["./src/index.ts"]
12
11
  }
13
- },
14
- "include": [
15
- "${configDir}/src/**/*.mts",
16
- "${configDir}/src/**/*.ts",
17
- "${configDir}/src/**/*.vue"
18
- ]
12
+ }
19
13
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { defineConfig } from "@forsakringskassan/vite-lib-config/vite";
4
4
  import { defineTestConfig } from "@forsakringskassan/vitest-config-jsdom";
5
- import mocks from "./src/mocks.mts";
5
+ import mocks from "./src/mocks/index.mts";
6
6
 
7
7
  export default defineConfig({
8
8
  test: defineTestConfig(),
package/hooks/install.mjs CHANGED
@@ -4,6 +4,8 @@
4
4
  export default async (context) => {
5
5
  const { getParameter, updateJsonFile, getApplicationName, replaceInFile } =
6
6
  context;
7
+ const scopedName = getApplicationName();
8
+ const unscopedName = getApplicationName({ unscoped: true });
7
9
 
8
10
  /* write repository url to "package.json" */
9
11
  const repoUrl = getParameter("repo-url");
@@ -15,9 +17,15 @@ export default async (context) => {
15
17
  });
16
18
 
17
19
  /* update placeholder names with the real application name (from package.json) */
18
- const name = getApplicationName;
19
- const placeholder = "@forsakringskassan/vue-lib-template";
20
- await replaceInFile("tsconfig.lib.json", placeholder, name);
21
- await replaceInFile("tsconfig.cypress.json", placeholder, name);
22
- await replaceInFile("tsconfig.selectors.json", placeholder, name);
20
+ const placeholder = /"@forsakringskassan\/vue-lib-template(?:\/[^"]+)?"/g;
21
+ await replaceInFile("tsconfig.lib.json", placeholder, scopedName);
22
+ await replaceInFile("tsconfig.cypress.json", placeholder, scopedName);
23
+ await replaceInFile("tsconfig.selectors.json", placeholder, scopedName);
24
+
25
+ /* correct exported subpath "style.css" */
26
+ await updateJsonFile("package.json", {
27
+ exports: {
28
+ "./style.css": `./dist/esm/${unscopedName}.css`,
29
+ },
30
+ });
23
31
  };
package/index.js CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  const options = {
9
9
  ...packageJson.cloneman,
10
- fileHash: "36c8f49330d6acb55faacab6e563150ce680f321673ee1d5989144b469ef7839",
10
+ fileHash: "9c70dce9442c78ff9c4b3e4458611ac69b94281d9a08a09a9168a4d0a8bc55f7",
11
11
  filesDir: path.join(import.meta.dirname, "files"),
12
12
  hooksDir: path.join(import.meta.dirname, "hooks"),
13
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forsakringskassan/vue-lib-template",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Vue library template based on Cloneman",
5
5
  "keywords": [
6
6
  "template",
@@ -46,8 +46,8 @@
46
46
  "cypress/tsconfig.json",
47
47
  "cypress/types/mocha.d.ts",
48
48
  "docs/build.mts",
49
+ "docs/guide/index.md",
49
50
  "docs/index.md",
50
- "docs/kattinformation/index.md",
51
51
  "docs/package.json",
52
52
  "docs/src/bundle-mocks.mjs",
53
53
  "docs/src/global.d.ts",
@@ -60,27 +60,39 @@
60
60
  "etc/selectors.api.md",
61
61
  "Jenkinsfile",
62
62
  "LICENSE.md",
63
+ "project-guide/cloneman.md",
64
+ "project-guide/commits-and-releases.md",
65
+ "project-guide/development.md",
66
+ "project-guide/documentation.md",
67
+ "project-guide/index.md",
68
+ "project-guide/testing.md",
63
69
  "README.md",
64
70
  "renovate.json",
65
- "src/cat-api-mock.spec.ts",
66
- "src/cat-api.mock.mts",
67
- "src/cat-api.spec.ts",
68
- "src/cat-api.ts",
69
- "src/cat-data.ts",
70
- "src/cat-info-logic.ts",
71
- "src/cat-types.ts",
72
- "src/CatInfoEdit.vue",
73
- "src/CatInfoLogic.spec.ts",
74
- "src/CatInfoShow.vue",
75
- "src/examples/CatInfoExample.vue",
76
- "src/FcCatInfoComponent.cy.ts",
77
- "src/FcCatInfoComponent.vue",
78
- "src/FcCatInfoComponentLiveExample.vue",
71
+ "src/components/guide/FcCatInfo/cat-api.spec.ts",
72
+ "src/components/guide/FcCatInfo/cat-api.ts",
73
+ "src/components/guide/FcCatInfo/cat-data.ts",
74
+ "src/components/guide/FcCatInfo/cat-info-logic.spec.ts",
75
+ "src/components/guide/FcCatInfo/cat-info-logic.ts",
76
+ "src/components/guide/FcCatInfo/cat-types.ts",
77
+ "src/components/guide/FcCatInfo/CatInfoEdit.vue",
78
+ "src/components/guide/FcCatInfo/CatInfoShow.vue",
79
+ "src/components/guide/FcCatInfo/examples/FcCatInfoComponentExample.vue",
80
+ "src/components/guide/FcCatInfo/examples/FcCatInfoComponentLiveExample.vue",
81
+ "src/components/guide/FcCatInfo/FcCatInfoComponent.cy.ts",
82
+ "src/components/guide/FcCatInfo/FcCatInfoComponent.vue",
83
+ "src/components/guide/FcCatInfo/index.ts",
84
+ "src/components/guide/index.ts",
85
+ "src/components/guide/README.md",
86
+ "src/components/index.ts",
79
87
  "src/index.ts",
80
88
  "src/local.scss",
81
89
  "src/local.ts",
82
- "src/mocks.mts",
83
- "src/selectors/FcCatInfoComponent.selectors.ts",
90
+ "src/mocks/guide/cat-api-mock.spec.ts",
91
+ "src/mocks/guide/cat-api.mock.mts",
92
+ "src/mocks/guide/index.mts",
93
+ "src/mocks/index.mts",
94
+ "src/selectors/guide/FcCatInfoComponent.selectors.ts",
95
+ "src/selectors/guide/index.ts",
84
96
  "src/selectors/index.ts",
85
97
  "src/style.scss",
86
98
  "src/vite-dev/app.vue",
File without changes