@zambon-dev/ui 0.0.1-bootstrap.0 → 1.1.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.
- package/CHANGELOG.md +177 -0
- package/README.md +81 -81
- package/fesm2022/zambon-dev-ui-framework.mjs +5995 -3980
- package/fesm2022/zambon-dev-ui-framework.mjs.map +1 -1
- package/fesm2022/zambon-dev-ui-library.mjs +6003 -4272
- package/fesm2022/zambon-dev-ui-library.mjs.map +1 -1
- package/fesm2022/zambon-dev-ui-shared.mjs +2758 -1790
- package/fesm2022/zambon-dev-ui-shared.mjs.map +1 -1
- package/fesm2022/zambon-dev-ui-testing.mjs +73 -77
- package/fesm2022/zambon-dev-ui-testing.mjs.map +1 -1
- package/fesm2022/zambon-dev-ui.mjs +6 -8
- package/i18n/framework/en.json +63 -63
- package/i18n/framework/pt.json +63 -63
- package/i18n/shared/external-content/en.json +12 -12
- package/i18n/shared/external-content/pt.json +12 -12
- package/i18n/shared/language-selector/en.json +5 -5
- package/i18n/shared/language-selector/pt.json +5 -5
- package/i18n/shared/login/en.json +16 -14
- package/i18n/shared/login/pt.json +16 -14
- package/i18n/shared/operations-history/en.json +5 -5
- package/i18n/shared/operations-history/pt.json +5 -5
- package/i18n/shared/services-history/en.json +14 -14
- package/i18n/shared/services-history/pt.json +14 -14
- package/i18n/shared/top-bar/en.json +10 -7
- package/i18n/shared/top-bar/pt.json +10 -7
- package/package.json +1 -1
- package/styles/common.scss +9 -10
- package/styles/components/card.scss +19 -13
- package/styles/components/dropdown-static.scss +33 -35
- package/styles/components/input-group.scss +48 -44
- package/styles/components/input.scss +120 -99
- package/styles/components/label.scss +6 -3
- package/styles/components/row.scss +48 -48
- package/styles/mixins/background.scss +31 -31
- package/styles/theme.css +307 -75
- package/styles/variables.scss +86 -60
- package/types/zambon-dev-ui-framework.d.ts +1470 -1029
- package/types/zambon-dev-ui-library.d.ts +1689 -1165
- package/types/zambon-dev-ui-shared.d.ts +630 -543
- package/types/zambon-dev-ui-testing.d.ts +25 -30
- package/types/zambon-dev-ui.d.ts +6 -3
- package/fesm2022/zambon-dev-ui.mjs.map +0 -1
- package/styles/components/button.scss +0 -101
package/CHANGELOG.md
CHANGED
|
@@ -23,6 +23,183 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
23
23
|
|
|
24
24
|
### ⚠ Breaking Changes / Migration
|
|
25
25
|
|
|
26
|
+
## [1.1.0] - 2026-10-25
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **A button component, `lib-button`.** One component with an `intent` -- `primary`, `secondary`,
|
|
31
|
+
`danger`, `ghost` -- in place of a class that named a colour. It carries the loading, success and
|
|
32
|
+
error states the old classes carried, and it blocks activation with the `disabled` attribute
|
|
33
|
+
rather than `pointer-events: none`, so the keyboard cannot fire an action the mouse cannot. There
|
|
34
|
+
is no click output: the element inside is a real `<button>`, so `(click)` on `<lib-button>`
|
|
35
|
+
receives the bubbled event and `type="submit"` works inside a form with no wiring. Every button is at
|
|
36
|
+
least 2.25rem tall -- the height of the user block in the top bar -- and one with no label is a
|
|
37
|
+
square of that size, because the padding that suits text would leave a lone glyph in a box wider
|
|
38
|
+
than it is tall.
|
|
39
|
+
|
|
40
|
+
- **At the root barrel the new button is `LibButtonComponent`.** Both layers now define a
|
|
41
|
+
`ButtonComponent` -- the library's `lib-button` and the framework's long-standing
|
|
42
|
+
`framework-button` -- so `@zambon-dev/ui` exports the framework one under the bare name it
|
|
43
|
+
already had and the library one under an alias. From the layer entry points
|
|
44
|
+
(`@zambon-dev/ui/library`, `@zambon-dev/ui/framework`) both are just `ButtonComponent`,
|
|
45
|
+
which is how they read in context and what the examples below use.
|
|
46
|
+
|
|
47
|
+
- **A semantic token core.** 59 tokens that name a role -- a surface, a piece of content, a line, a
|
|
48
|
+
state, a shape, a duration -- defined in `@zambon-dev/ui/styles/theme.css`. Each is also a
|
|
49
|
+
Tailwind utility: `bg-surface-glass`, `text-content-secondary`, `rounded-surface`. The
|
|
50
|
+
[design tokens guide](https://github.com/RicardoZambon/ZLibraries/blob/main/docs/guides/design-tokens.md)
|
|
51
|
+
lists them and explains what is safe to override.
|
|
52
|
+
|
|
53
|
+
- **A dark theme, and a switch for it in the top bar.** The slot reserved there since July is
|
|
54
|
+
filled. The switch steps light, dark, follow-the-system, and `ThemeService` exposes the same
|
|
55
|
+
thing to your code: `preference()` for what the user chose, `resolved()` for what is applied.
|
|
56
|
+
Your application opts in by adding one snippet to `index.html`; leave it out and every screen
|
|
57
|
+
stays light. The guide above has the snippet and explains why it cannot be an Angular service.
|
|
58
|
+
|
|
59
|
+
- **`AppConfig.loginLogoUrl` and `AppConfig.loginBackgroundUrl`.** The sign-in screen used to load
|
|
60
|
+
`/logo-login.png` and `/background.jpg` from fixed absolute paths that no application ships, so
|
|
61
|
+
in practice it rendered a broken image over no background. Both are optional: without a logo the
|
|
62
|
+
card simply has none, and without a background the app backdrop shows through.
|
|
63
|
+
|
|
64
|
+
- **`LoginLayoutComponent` projects content.** It rendered a `<router-outlet>` and nothing else,
|
|
65
|
+
so a sign-in screen placed inside the element was silently dropped. It now renders projected
|
|
66
|
+
content beside the outlet, which lets an application host a sign-in screen that is not reached
|
|
67
|
+
through the router.
|
|
68
|
+
|
|
69
|
+
- **The two login translation keys that were missing.** `Login-Title` and `Login-Copyright` were
|
|
70
|
+
used by the template and defined in neither language file, so the card's heading and its footer
|
|
71
|
+
rendered the raw key. Both now exist in English and Portuguese, and `Login-SelectLanguage` --
|
|
72
|
+
which had been sitting unused -- labels the language picker on that screen.
|
|
73
|
+
|
|
74
|
+
### Changed
|
|
75
|
+
|
|
76
|
+
- **Every component now draws from the tokens**, so a theme moves them all at once. The data grid,
|
|
77
|
+
the group containers, the modal, the multi-select, the catalog select, the ribbon and the form
|
|
78
|
+
controls had their colours, radii, shadows and durations written into their stylesheets; they now
|
|
79
|
+
name a role instead. Expect small shifts where a literal and its nearest token were not identical
|
|
80
|
+
-- borders settle on one grey, selection on one blue.
|
|
81
|
+
|
|
82
|
+
- **`--sidebar-*` and `--tabs-*` derive from that core.** They are still the names you override and
|
|
83
|
+
they still compute the same values. They moved into `@layer tokens`, which means an override of
|
|
84
|
+
yours now wins whatever the import order -- previously it only won if your stylesheet came last.
|
|
85
|
+
Write the override without a layer.
|
|
86
|
+
|
|
87
|
+
- **Focus is shown on `:focus-visible` and is thinner.** Fields and buttons used `focus:ring-4` on
|
|
88
|
+
plain `:focus`, so a four-pixel halo appeared on every mouse click. The ring is now two pixels,
|
|
89
|
+
reads `--color-focus-ring`, and appears when focus is actually worth showing.
|
|
90
|
+
|
|
91
|
+
- **Form labels are no longer uppercase, bold and letter-spaced.** They are a quiet caption at the
|
|
92
|
+
same size. This is the single change that most alters how a dense form reads; labels also get
|
|
93
|
+
narrower, so field columns gain a little width.
|
|
94
|
+
|
|
95
|
+
- **Transitions read duration tokens**, which collapse to 1ms under `prefers-reduced-motion:
|
|
96
|
+
reduce`. There is nothing to configure.
|
|
97
|
+
|
|
98
|
+
- **The sign-in screen was rebuilt.** It had had no design decision since May 2025 and used the
|
|
99
|
+
brand colour nowhere: an amber frame around the logo, slate field icons, a generic blue border.
|
|
100
|
+
It is now the same glass card as the rest of the product. Concretely:
|
|
101
|
+
|
|
102
|
+
- The logo sits inside the card instead of hanging above it on a -160px margin over a fixed
|
|
103
|
+
160px height, so a logo that is not square no longer skews everything around it.
|
|
104
|
+
- The card has a maximum width that shrinks. The previous `w-10/12 md:w-8/12 xl:w-5/12`
|
|
105
|
+
resolved against an absolutely positioned parent with no width of its own, so those
|
|
106
|
+
breakpoints never did what their names suggested.
|
|
107
|
+
- The page scrolls when the card does not fit. On a 768px-tall laptop it used to be cut off at
|
|
108
|
+
both ends with no way to reach what was missing.
|
|
109
|
+
- Both fields carry `autocomplete`, so password managers recognise them; the error block is a
|
|
110
|
+
live region, so it is announced; and the submit button is genuinely disabled while signing in
|
|
111
|
+
rather than only unclickable.
|
|
112
|
+
|
|
113
|
+
- **The application toolbar joined the glass language.** It was the one surface of the shell still
|
|
114
|
+
outside the token system -- opaque white, square, with a hairline under it, directly above a
|
|
115
|
+
rounded translucent panel. The hairline is gone: in this language surfaces are separated by
|
|
116
|
+
elevation.
|
|
117
|
+
|
|
118
|
+
- **The ribbon, the top bar, the notifications panel, the language picker and the audit history
|
|
119
|
+
views draw from the design tokens**, as does the environment badge -- it keeps its four hues, but
|
|
120
|
+
fill, text and ring are now derived from one of them, so the badge stays readable when the
|
|
121
|
+
surface behind it goes dark.
|
|
122
|
+
|
|
123
|
+
- **The top bar's controls on the right are one size, in two groups.** Notifications, language
|
|
124
|
+
and theme came out at three different heights with three different paddings -- the language
|
|
125
|
+
toggle wrapped the button in padding of its own, on top of the button's, which made the smallest
|
|
126
|
+
control the widest -- and all five sat 12px apart. They are now identical squares, shoulder to
|
|
127
|
+
shoulder, with the user and the way out as their own group beside them.
|
|
128
|
+
|
|
129
|
+
- **The confirmation buttons render `lib-button`.** Their own API is unchanged apart from
|
|
130
|
+
`ButtonConfirmComponent` below; what changed is that their modal footers no longer depend on the
|
|
131
|
+
global `.btn` classes.
|
|
132
|
+
|
|
133
|
+
### Removed
|
|
134
|
+
|
|
135
|
+
- **The global `.btn` classes.** See the migration note below.
|
|
136
|
+
|
|
137
|
+
### Fixed
|
|
138
|
+
|
|
139
|
+
- **The sidebar's collapse handle no longer disappears into the page.** It is a disc that
|
|
140
|
+
straddles the sidebar's edge, so most of it sits on the app backdrop, and two things hid it: its
|
|
141
|
+
outline was a hairline the weight of a divider, and hovering it swapped the solid fill for a 40%
|
|
142
|
+
tint -- which let the rail show through one half of the handle and the page through the other.
|
|
143
|
+
The outline is the stronger line colour now, and the hover wash sits over the fill rather than
|
|
144
|
+
replacing it.
|
|
145
|
+
|
|
146
|
+
- **Hovering a secondary button now shows something.** It went from a 40% tint of one grey to a 6%
|
|
147
|
+
wash of another, and those land on nearly the same colour, so on a white page nothing happened;
|
|
148
|
+
on any other surface the button faded instead. That wash also layers over the fill now.
|
|
149
|
+
|
|
150
|
+
### ⚠ Breaking Changes / Migration
|
|
151
|
+
|
|
152
|
+
- **`.btn` and its 154 colour variants are gone.** They were generated by interpolating Tailwind
|
|
153
|
+
colour names in a loop, so a button's appearance was a palette decision rather than a statement
|
|
154
|
+
of what it was for, and none of them could follow a theme. Replace each one with `lib-button`
|
|
155
|
+
from `@zambon-dev/ui/library`:
|
|
156
|
+
|
|
157
|
+
```html
|
|
158
|
+
<!-- before -->
|
|
159
|
+
<button type="button" class="btn blue-500" (click)="save()">Save</button>
|
|
160
|
+
|
|
161
|
+
<!-- after -->
|
|
162
|
+
<lib-button intent="primary" (click)="save()">Save</lib-button>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
| Class | Intent |
|
|
166
|
+
| ----------------------------------------------------- | ----------- |
|
|
167
|
+
| `blue-*`, `green-*`, any brand colour | `primary` |
|
|
168
|
+
| `red-*` | `danger` |
|
|
169
|
+
| `gray-*`, `slate-*`, `neutral-*`, `stone-*`, `zinc-*` | `secondary` |
|
|
170
|
+
| a bare `.btn` inside a toolbar | `ghost` |
|
|
171
|
+
|
|
172
|
+
The state classes move to inputs: `[class.loading]` becomes `[loading]`, `.success` becomes
|
|
173
|
+
`[success]`, `.error` becomes `[error]`. `[disabled]` is unchanged. `(click)` still works, since
|
|
174
|
+
the component renders a real button and the event bubbles.
|
|
175
|
+
|
|
176
|
+
- **`ButtonConfirmComponent.modalConfirmButtonColor` is now `modalConfirmButtonIntent`.** It took a
|
|
177
|
+
Tailwind palette name, which said nothing about what the button was for and could not follow a
|
|
178
|
+
theme. Replace the colour with the intent it stood for:
|
|
179
|
+
|
|
180
|
+
| Before | After |
|
|
181
|
+
| ------------------------------------- | -------------------------------------- |
|
|
182
|
+
| `modalConfirmButtonColor="red-500"` | `modalConfirmButtonIntent="danger"` |
|
|
183
|
+
| `modalConfirmButtonColor="blue-500"` | `modalConfirmButtonIntent="primary"` |
|
|
184
|
+
| `modalConfirmButtonColor="green-500"` | `modalConfirmButtonIntent="primary"` |
|
|
185
|
+
| any grey | `modalConfirmButtonIntent="secondary"` |
|
|
186
|
+
|
|
187
|
+
The input now has a default of `danger`, so a confirmation that deletes something needs nothing
|
|
188
|
+
at all.
|
|
189
|
+
|
|
190
|
+
- **`@zambon-dev/ui/styles/theme.css` is now required** in your global stylesheet. It already was
|
|
191
|
+
in practice for anything using the sidebar; it now carries every component's colours, and
|
|
192
|
+
without it they resolve to nothing and render transparent.
|
|
193
|
+
|
|
194
|
+
- **Component tokens moved into `@layer tokens`.** Not a break, but worth knowing: an override of
|
|
195
|
+
`--sidebar-bg` or `--tabs-*` now wins whatever the import order, where before it only won if your
|
|
196
|
+
stylesheet came after ours. Write overrides without a layer. A static override holds in both
|
|
197
|
+
themes; to vary one by theme, write it under `:root[data-theme='dark']`.
|
|
198
|
+
|
|
199
|
+
## [1.0.0] - 2026-10-24
|
|
200
|
+
|
|
201
|
+
### ⚠ Breaking Changes / Migration
|
|
202
|
+
|
|
26
203
|
- **The layers in this release are `library` 4.0.5, `framework` 5.0.5 and `shared` 6.0.4.**
|
|
27
204
|
Moving here from an earlier version of any of the three means taking that layer's remaining
|
|
28
205
|
releases too; they are under **Package history** below. The one worth naming is
|
package/README.md
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
# @zambon-dev/ui
|
|
2
|
-
|
|
3
|
-
Angular UI components, an application shell and a shared application layer for Zambon
|
|
4
|
-
applications, in one package on one version.
|
|
5
|
-
|
|
6
|
-
The three layers are separate entry points, and they stack one way: `shared` builds on
|
|
7
|
-
`framework`, `framework` builds on `library`, and `library` builds on neither.
|
|
8
|
-
|
|
9
|
-
| Import | What is in it |
|
|
10
|
-
| -------------------------- | ------------------------------------------------------------- |
|
|
11
|
-
| `@zambon-dev/ui` | all three layers |
|
|
12
|
-
| `@zambon-dev/ui/library` | form controls, data grids, modals, the ribbon and the sidebar |
|
|
13
|
-
| `@zambon-dev/ui/framework` | tabbed navigation, view base classes, ribbon buttons |
|
|
14
|
-
| `@zambon-dev/ui/shared` | authentication, layouts, audit-history features |
|
|
15
|
-
| `@zambon-dev/ui/testing` | a test harness for rendering under an OnPush ancestor |
|
|
16
|
-
|
|
17
|
-
Importing a layer directly keeps the dependency honest and the bundle smaller; importing the root
|
|
18
|
-
is fine where the layer does not matter.
|
|
19
|
-
|
|
20
|
-
## Install
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npm i @zambon-dev/ui
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Peer dependencies are the union of what the three layers need, and all are required:
|
|
27
|
-
`@angular/cdk`, `@angular/common`, `@angular/core`, `@angular/forms`, `@angular/platform-browser`,
|
|
28
|
-
`@angular/router`, `@auth0/angular-jwt`, `@microsoft/signalr`, `@ngx-translate/core`,
|
|
29
|
-
`ngx-resize-observer`, `ngx-translate-multi-http-loader` and `rxjs`. Angular 22 or later.
|
|
30
|
-
|
|
31
|
-
**Coming from the three separate packages?** See
|
|
32
|
-
[the migration guide](../../docs/guides/migrating-to-ui.md).
|
|
33
|
-
|
|
34
|
-
## Styles
|
|
35
|
-
|
|
36
|
-
Each stylesheet is named by its own subpath:
|
|
37
|
-
|
|
38
|
-
```scss
|
|
39
|
-
@use '@zambon-dev/ui/styles/variables.scss';
|
|
40
|
-
@use '@zambon-dev/ui/styles/common.scss';
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
`@zambon-dev/ui/styles/theme.css` is the Tailwind entry point and carries the design tokens. An
|
|
44
|
-
application that uses the components' Tailwind utilities needs it in its own build.
|
|
45
|
-
|
|
46
|
-
## Translations
|
|
47
|
-
|
|
48
|
-
The shipped translation files live under `i18n/framework` and `i18n/shared`. Spread the exported
|
|
49
|
-
asset patterns into your build rather than writing the paths out:
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
import { ZAMBON_FRAMEWORK_I18N_ASSET, provideZambonFrameworkTranslateService } from '@zambon-dev/ui/framework';
|
|
53
|
-
import { ZAMBON_SHARED_I18N_ASSET } from '@zambon-dev/ui/shared';
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Selectors
|
|
57
|
-
|
|
58
|
-
Each layer kept the prefix it published under, so a selector still says which layer it came from:
|
|
59
|
-
`<lib-*>` for library, `<framework-*>` for framework, `<shared-*>` for shared.
|
|
60
|
-
|
|
61
|
-
## Development
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
npx nx build ui # production package into dist/libs/ui
|
|
65
|
-
npx nx test ui # Jest
|
|
66
|
-
npx nx lint ui # ESLint
|
|
67
|
-
npx nx storybook ui # Storybook on :4400
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Every change under `src/` needs an entry under `## [Unreleased]` in `CHANGELOG.md`; CI enforces
|
|
71
|
-
it. The release pipeline stamps the version — do not write it yourself.
|
|
72
|
-
|
|
73
|
-
## Layering
|
|
74
|
-
|
|
75
|
-
The one-way rule is enforced by `no-restricted-imports` overrides in `eslint.config.mjs`, which
|
|
76
|
-
reject both the published subpath and the equivalent relative path. As three packages the rule
|
|
77
|
-
held because npm cannot express a cycle; inside one package only the lint rule holds it.
|
|
78
|
-
|
|
79
|
-
## License
|
|
80
|
-
|
|
81
|
-
MIT © Ricardo Zambon
|
|
1
|
+
# @zambon-dev/ui
|
|
2
|
+
|
|
3
|
+
Angular UI components, an application shell and a shared application layer for Zambon
|
|
4
|
+
applications, in one package on one version.
|
|
5
|
+
|
|
6
|
+
The three layers are separate entry points, and they stack one way: `shared` builds on
|
|
7
|
+
`framework`, `framework` builds on `library`, and `library` builds on neither.
|
|
8
|
+
|
|
9
|
+
| Import | What is in it |
|
|
10
|
+
| -------------------------- | ------------------------------------------------------------- |
|
|
11
|
+
| `@zambon-dev/ui` | all three layers |
|
|
12
|
+
| `@zambon-dev/ui/library` | form controls, data grids, modals, the ribbon and the sidebar |
|
|
13
|
+
| `@zambon-dev/ui/framework` | tabbed navigation, view base classes, ribbon buttons |
|
|
14
|
+
| `@zambon-dev/ui/shared` | authentication, layouts, audit-history features |
|
|
15
|
+
| `@zambon-dev/ui/testing` | a test harness for rendering under an OnPush ancestor |
|
|
16
|
+
|
|
17
|
+
Importing a layer directly keeps the dependency honest and the bundle smaller; importing the root
|
|
18
|
+
is fine where the layer does not matter.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm i @zambon-dev/ui
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Peer dependencies are the union of what the three layers need, and all are required:
|
|
27
|
+
`@angular/cdk`, `@angular/common`, `@angular/core`, `@angular/forms`, `@angular/platform-browser`,
|
|
28
|
+
`@angular/router`, `@auth0/angular-jwt`, `@microsoft/signalr`, `@ngx-translate/core`,
|
|
29
|
+
`ngx-resize-observer`, `ngx-translate-multi-http-loader` and `rxjs`. Angular 22 or later.
|
|
30
|
+
|
|
31
|
+
**Coming from the three separate packages?** See
|
|
32
|
+
[the migration guide](../../docs/guides/migrating-to-ui.md).
|
|
33
|
+
|
|
34
|
+
## Styles
|
|
35
|
+
|
|
36
|
+
Each stylesheet is named by its own subpath:
|
|
37
|
+
|
|
38
|
+
```scss
|
|
39
|
+
@use '@zambon-dev/ui/styles/variables.scss';
|
|
40
|
+
@use '@zambon-dev/ui/styles/common.scss';
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`@zambon-dev/ui/styles/theme.css` is the Tailwind entry point and carries the design tokens. An
|
|
44
|
+
application that uses the components' Tailwind utilities needs it in its own build.
|
|
45
|
+
|
|
46
|
+
## Translations
|
|
47
|
+
|
|
48
|
+
The shipped translation files live under `i18n/framework` and `i18n/shared`. Spread the exported
|
|
49
|
+
asset patterns into your build rather than writing the paths out:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { ZAMBON_FRAMEWORK_I18N_ASSET, provideZambonFrameworkTranslateService } from '@zambon-dev/ui/framework';
|
|
53
|
+
import { ZAMBON_SHARED_I18N_ASSET } from '@zambon-dev/ui/shared';
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Selectors
|
|
57
|
+
|
|
58
|
+
Each layer kept the prefix it published under, so a selector still says which layer it came from:
|
|
59
|
+
`<lib-*>` for library, `<framework-*>` for framework, `<shared-*>` for shared.
|
|
60
|
+
|
|
61
|
+
## Development
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx nx build ui # production package into dist/libs/ui
|
|
65
|
+
npx nx test ui # Jest
|
|
66
|
+
npx nx lint ui # ESLint
|
|
67
|
+
npx nx storybook ui # Storybook on :4400
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Every change under `src/` needs an entry under `## [Unreleased]` in `CHANGELOG.md`; CI enforces
|
|
71
|
+
it. The release pipeline stamps the version — do not write it yourself.
|
|
72
|
+
|
|
73
|
+
## Layering
|
|
74
|
+
|
|
75
|
+
The one-way rule is enforced by `no-restricted-imports` overrides in `eslint.config.mjs`, which
|
|
76
|
+
reject both the published subpath and the equivalent relative path. As three packages the rule
|
|
77
|
+
held because npm cannot express a cycle; inside one package only the lint rule holds it.
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
MIT © Ricardo Zambon
|