@cratis/pi 2.21.3 → 2.23.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/package/corpus/agents/backend-developer.md +6 -5
- package/package/corpus/agents/code-reviewer.md +7 -7
- package/package/corpus/agents/coordinator.md +5 -4
- package/package/corpus/agents/frontend-developer.md +34 -40
- package/package/corpus/agents/orchestrator.md +5 -4
- package/package/corpus/agents/performance-reviewer.md +5 -4
- package/package/corpus/agents/planner.md +5 -4
- package/package/corpus/agents/repository-investigation-reviewer.md +2 -1
- package/package/corpus/agents/repository-investigator.md +2 -1
- package/package/corpus/agents/security-reviewer.md +5 -4
- package/package/corpus/agents/slice-implementer.md +8 -2
- package/package/corpus/agents/spec-writer.md +6 -4
- package/package/corpus/harnesses/pi/extensions/subagent/agents.ts +52 -7
- package/package/corpus/harnesses/pi/extensions/subagent/index.ts +14 -0
- package/package/corpus/hooks/README.md +29 -27
- package/package/corpus/hooks/agent-stop.md +1 -5
- package/package/corpus/hooks/scripts/cratis-patterns.json +1 -1
- package/package/corpus/hooks/scripts/validate-package-subpaths.sh +1 -2
- package/package/corpus/prompts/verify-ai-setup.prompt.md +17 -7
- package/package/corpus/rules/ai-distribution.md +58 -0
- package/package/corpus/rules/components.md +77 -44
- package/package/corpus/rules/dialogs.md +24 -20
- package/package/corpus/rules/efcore.md +35 -187
- package/package/corpus/rules/framework.md +1 -1
- package/package/corpus/rules/frontend-quality.md +1 -1
- package/package/corpus/rules/frontend-testing.md +4 -4
- package/package/corpus/rules/general.md +29 -105
- package/package/corpus/rules/new-repository-intake.md +34 -0
- package/package/corpus/rules/orleans.md +13 -27
- package/package/corpus/rules/react.md +12 -12
- package/package/corpus/rules/reactors.md +28 -5
- package/package/corpus/rules/specs.scenarios.csharp.md +18 -3
- package/package/corpus/rules/specs.typescript.md +1 -1
- package/package/corpus/rules/storybook.md +2 -2
- package/package/corpus/rules/typescript.md +1 -0
- package/package/corpus/rules/vertical-slices.md +20 -15
- package/package/corpus/rules/writing-correct-examples.md +1 -0
- package/package/corpus/skills/cratis-application-react-specifications/SKILL.md +4 -4
- package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +16 -8
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +6 -4
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authentication.md +1 -1
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +1 -1
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/frontend.md +1 -1
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/local-development.md +1 -1
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/tenancy.md +7 -4
- package/package/corpus/skills/cratis-arc-command/SKILL.md +9 -7
- package/package/corpus/skills/cratis-arc-command/references/command-result.md +1 -1
- package/package/corpus/skills/cratis-arc-command/references/handler-shapes.md +2 -2
- package/package/corpus/skills/cratis-arc-command/references/proxy-generation.md +6 -3
- package/package/corpus/skills/cratis-arc-command/references/read-model-injection.md +1 -1
- package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +12 -2
- package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +5 -3
- package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +7 -4
- package/package/corpus/skills/cratis-arc-observable-query-http/SKILL.md +10 -3
- package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +13 -8
- package/package/corpus/skills/cratis-arc-react-page/SKILL.md +27 -24
- package/package/corpus/skills/cratis-arc-react-page/references/data-page.md +15 -11
- package/package/corpus/skills/cratis-arc-react-page/references/data-tables.md +9 -2
- package/package/corpus/skills/cratis-arc-react-page/references/dialogs.md +11 -9
- package/package/corpus/skills/cratis-arc-react-page/references/queries-and-commands.md +26 -2
- package/package/corpus/skills/cratis-chronicle-cli-operations/SKILL.md +19 -13
- package/package/corpus/skills/cratis-chronicle-client-dotnet/SKILL.md +17 -15
- package/package/corpus/skills/cratis-chronicle-client-elixir/SKILL.md +24 -20
- package/package/corpus/skills/cratis-chronicle-client-kotlin/SKILL.md +26 -15
- package/package/corpus/skills/cratis-chronicle-client-typescript/SKILL.md +15 -11
- package/package/corpus/skills/cratis-chronicle-compliance/SKILL.md +14 -3
- package/package/corpus/skills/cratis-chronicle-event-constraints/SKILL.md +13 -6
- package/package/corpus/skills/cratis-chronicle-event-modeling/SKILL.md +2 -2
- package/package/corpus/skills/cratis-chronicle-event-specifications/SKILL.md +11 -5
- package/package/corpus/skills/cratis-chronicle-event-type-migration/SKILL.md +2 -2
- package/package/corpus/skills/cratis-chronicle-multi-tenancy/SKILL.md +2 -2
- package/package/corpus/skills/cratis-chronicle-projection/SKILL.md +23 -4
- package/package/corpus/skills/cratis-chronicle-projection/references/fluent-builder.md +1 -1
- package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md +2 -2
- package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +22 -8
- package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +1 -1
- package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +1 -1
- package/package/corpus/skills/cratis-chronicle-read-model-specifications/SKILL.md +3 -1
- package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +1 -1
- package/package/corpus/skills/cratis-chronicle-web-workbench/SKILL.md +19 -11
- package/package/corpus/skills/cratis-cli-terminal-workbench/SKILL.md +11 -6
- package/package/corpus/skills/cratis-code-review/SKILL.md +8 -6
- package/package/corpus/skills/cratis-components-accessibility/SKILL.md +112 -82
- package/package/corpus/skills/cratis-components-schema-editor/SKILL.md +12 -10
- package/package/corpus/skills/cratis-components-stepper-command-dialog/SKILL.md +11 -12
- package/package/corpus/skills/cratis-components-styling/SKILL.md +204 -170
- package/package/corpus/skills/cratis-components-toolbar/SKILL.md +32 -26
- package/package/corpus/skills/cratis-event-model-diagram/SKILL.md +1 -1
- package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +2 -2
- package/package/corpus/skills/cratis-fundamentals-type-discovery/SKILL.md +2 -2
- package/package/corpus/skills/cratis-lens-browser-extension/SKILL.md +4 -2
- package/package/corpus/skills/cratis-performance-review/SKILL.md +4 -2
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +15 -5
- package/package/corpus/skills/cratis-security-review/SKILL.md +20 -3
- package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +3 -3
- package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +12 -8
- package/package/corpus/skills/cratis-specifications-csharp/references/csharp-patterns.md +1 -1
- package/package/corpus/skills/cratis-specifications-csharp/references/integration-specs.md +7 -3
- package/package/corpus/skills/cratis-specifications-typescript/SKILL.md +6 -3
- package/package/corpus/skills/cratis-specifications-typescript/references/typescript-patterns.md +21 -4
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +29 -17
- package/package.json +1 -1
|
@@ -1,221 +1,255 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cratis-components-styling
|
|
3
|
-
description: Style and theme an application built on Cratis Components — the stylesheet
|
|
3
|
+
description: Style and theme an application built on Cratis Components 4 — the three stylesheet entries an app must import, the --cratis-* design-token seam, choosing between the baseline theme, a product theme and fully owned styling, dark mode, the typed pt parts and data-cratis-part selectors, the optional renderer adapters, and where Tailwind actually fits. Use when setting up a new Cratis frontend, changing colors or theming, fixing components that render unstyled, or styling one part of a component. Do not use for component API or page composition questions.
|
|
4
4
|
license: MIT
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Styling Cratis Components
|
|
8
8
|
|
|
9
|
-
Cratis Components
|
|
10
|
-
|
|
11
|
-
looks like
|
|
9
|
+
Cratis Components 4 owns its markup and its styling contract. There is no
|
|
10
|
+
third-party theme engine, preset or provider underneath it: what a Cratis
|
|
11
|
+
application looks like is decided by three Cratis-owned stylesheet entries and
|
|
12
|
+
the `--cratis-*` custom properties they read. Getting the setup wrong shows up as
|
|
12
13
|
components rendering completely unstyled, which is the single most common
|
|
13
|
-
first-run problem.
|
|
14
|
+
first-run problem — and it is fixed with two `import` lines.
|
|
14
15
|
|
|
15
16
|
## Verified product sources
|
|
16
17
|
|
|
17
18
|
| Package | Version | Verified from |
|
|
18
19
|
| --- | --- | --- |
|
|
19
|
-
| `@cratis/components` | `
|
|
20
|
-
| `primereact` | `^11.0.0` | peer of `@cratis/components@3.0.0` |
|
|
21
|
-
| `@primereact/core`, `@primereact/headless`, `@primereact/hooks` | `^11.0.0` | peers of `@cratis/components@3.0.0` |
|
|
22
|
-
| `@primereact/styles`, `@primereact/types`, `@primeuix/themes` | optional peers | `@primereact/styles`/`types` `^11.0.0`, `@primeuix/themes` `^3.0.0` |
|
|
23
|
-
| `primeicons` | `^8.0.0` | peer of `@cratis/components@3.0.0` |
|
|
20
|
+
| `@cratis/components` | `4.6.0` | its package manifest (`exports`, no vendor UI dependency or peer), `Source/tokens.css`, `Source/MIGRATION.md`, `Documentation/Styling/*`, `Documentation/Common/cratis-components-provider.md`, `Documentation/renderers/*` |
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
Components declares **no** PrimeReact, PrimeIcons or PrimeUI dependency or peer.
|
|
23
|
+
React Aria supplies focus, overlay, collection and date behavior *internally* —
|
|
24
|
+
you never import it, never style its class names, and it never appears in an
|
|
25
|
+
application's manifest. Remove any leftover Prime packages that only Components
|
|
26
|
+
used to need (`Source/MIGRATION.md` lists them); keep one only if the application
|
|
27
|
+
itself still imports it directly, and then that island's provider, theme and
|
|
28
|
+
license are the application's.
|
|
29
29
|
|
|
30
30
|
## Step 1 — What an app must do
|
|
31
31
|
|
|
32
32
|
Two things, or the components render unstyled:
|
|
33
33
|
|
|
34
|
-
1. **
|
|
35
|
-
above every Cratis component. It wraps the PrimeReact provider and merges
|
|
36
|
-
your configuration over the Cratis defaults, so anything you pass wins.
|
|
37
|
-
2. **Import the stylesheets explicitly**, in this order — components no longer
|
|
38
|
-
import their own CSS:
|
|
34
|
+
1. **Import the stylesheets, in this order**, once, at the entry point:
|
|
39
35
|
|
|
40
36
|
```ts
|
|
41
|
-
import '@cratis/components/tokens'; // the --cratis-*
|
|
42
|
-
import '@cratis/components/styles'; // every component
|
|
43
|
-
import '@cratis/components/theme'; // optional: the
|
|
37
|
+
import '@cratis/components/tokens'; // the semantic --cratis-* seam, with conservative light defaults on :root
|
|
38
|
+
import '@cratis/components/styles'; // structural rules for every component, in low-priority Cratis layers
|
|
39
|
+
import '@cratis/components/theme'; // optional: the maintained baseline look, dark mode, forced colors
|
|
44
40
|
```
|
|
45
41
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
`tokens` first — `styles` and `theme` both read it. `styles` also carries the
|
|
43
|
+
split-pane CSS the `DataPage` details pane needs, so it is not optional even
|
|
44
|
+
in a fully custom-styled app. `styles` contains **no** Tailwind Preflight, no
|
|
45
|
+
global reset and no copy of the token values.
|
|
46
|
+
|
|
47
|
+
2. **Mount `CratisComponentsProvider`** (from the package root,
|
|
48
|
+
`@cratis/components`) above every Cratis component. It carries `locale` and
|
|
49
|
+
the Components-owned `messages`, and mounts the toast region with `toaster`;
|
|
50
|
+
it carries **no** styling. The Components 3 renderer keys — `license`, `theme`,
|
|
51
|
+
`defaults`, global `pt`, `ptOptions`, `ripple`, `unstyled`, z-index — are a
|
|
52
|
+
type error on purpose, so a migrated app cannot compile a provider whose
|
|
53
|
+
visual configuration silently does nothing.
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import { CratisComponentsProvider } from '@cratis/components';
|
|
57
|
+
|
|
58
|
+
<CratisComponentsProvider value={{ locale: 'en-US' }} toaster>
|
|
59
|
+
<App />
|
|
60
|
+
</CratisComponentsProvider>
|
|
61
|
+
```
|
|
49
62
|
|
|
50
|
-
## Step 2 — Pick one of
|
|
63
|
+
## Step 2 — Pick one of three setups
|
|
51
64
|
|
|
52
|
-
| Setup |
|
|
65
|
+
| Setup | Imports | You own |
|
|
53
66
|
| --- | --- | --- |
|
|
54
|
-
| **Baseline theme** |
|
|
55
|
-
| **
|
|
56
|
-
| **
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
###
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
part a bare preset is missing.
|
|
75
|
-
- `styledMode(options?)` — returns `{ theme, defaults }` ready to hand to the
|
|
76
|
-
provider.
|
|
77
|
-
|
|
78
|
-
```tsx
|
|
79
|
-
import { CratisComponentsProvider } from '@cratis/components/Common';
|
|
80
|
-
import { styledMode } from '@cratis/components/styled';
|
|
81
|
-
|
|
82
|
-
<CratisComponentsProvider value={styledMode()}>
|
|
83
|
-
<App />
|
|
84
|
-
</CratisComponentsProvider>
|
|
67
|
+
| **Baseline theme** | `tokens` + `styles` + `theme` | choosing `cratis-dark` / `cratis-light` / system preference; overriding only the brand values you mean to |
|
|
68
|
+
| **Product theme** | `tokens` + `styles` + *your* CSS, imported after them | mapping your complete palette onto `--cratis-*`; typography, spacing, motion, contrast; component treatment through parts |
|
|
69
|
+
| **Fully owned** | `tokens` + `styles` + your CSS | the same, plus every `--cratis-*` value — omit `theme` entirely |
|
|
70
|
+
|
|
71
|
+
A theme is **CSS**. No JavaScript preset, provider option or wrapper class is
|
|
72
|
+
required for the normal whole-application setup. The product's CSS is written
|
|
73
|
+
*outside* a cascade layer, so it wins over all three Components layers
|
|
74
|
+
(`cratis-theme`, `cratis-components`, `cratis-utilities`) without specificity
|
|
75
|
+
tricks; if the product uses its own layers, declare their order explicitly after
|
|
76
|
+
the Components imports.
|
|
77
|
+
|
|
78
|
+
### Baseline theme and dark mode
|
|
79
|
+
|
|
80
|
+
`theme` adds document foreground/background, system dark-mode values, the
|
|
81
|
+
explicit scheme classes, forced-colors tuning and `.cratis-theme` subtree
|
|
82
|
+
defaults. It stays visually familiar to Components 2/3 — Lara-adjacent blue
|
|
83
|
+
actions, neutral surfaces, 6px radii — implemented entirely with Cratis tokens.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
document.documentElement.classList.toggle('cratis-dark', darkMode);
|
|
85
87
|
```
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
`
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
###
|
|
89
|
+
- Without a class, the baseline follows `prefers-color-scheme`.
|
|
90
|
+
- `cratis-light` keeps light values when the OS prefers dark; an explicit light
|
|
91
|
+
wins over an ambient root `cratis-dark`.
|
|
92
|
+
- An independently themed island puts `cratis-theme` on the subtree and adds
|
|
93
|
+
`cratis-dark` or `cratis-light` there (on the same element, or on an ancestor).
|
|
94
|
+
- Override any `--cratis-*` variable *after* the theme import to adapt it.
|
|
95
|
+
|
|
96
|
+
### Product theme
|
|
97
|
+
|
|
98
|
+
```css
|
|
99
|
+
:root {
|
|
100
|
+
--cratis-primary-color: var(--brand-accent-700);
|
|
101
|
+
--cratis-primary-color-text: var(--brand-text-inverse);
|
|
102
|
+
--cratis-action-background: var(--brand-action);
|
|
103
|
+
--cratis-action-background-hover: var(--brand-action-hover);
|
|
104
|
+
--cratis-action-background-active: var(--brand-action-active);
|
|
105
|
+
--cratis-action-text: var(--brand-on-action);
|
|
106
|
+
--cratis-surface-ground: var(--brand-canvas);
|
|
107
|
+
--cratis-surface-card: var(--brand-surface);
|
|
108
|
+
--cratis-surface-overlay: var(--brand-surface);
|
|
109
|
+
--cratis-surface-border: var(--brand-border);
|
|
110
|
+
--cratis-control-background: var(--brand-control);
|
|
111
|
+
--cratis-control-border: var(--brand-control-border);
|
|
112
|
+
--cratis-text-color: var(--brand-text-primary);
|
|
113
|
+
--cratis-text-color-secondary: var(--brand-text-secondary);
|
|
114
|
+
--cratis-focus-ring: var(--brand-focus-ring);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
[data-theme='dark'] {
|
|
118
|
+
--brand-canvas: #171717; /* switch schemes by redefining the *product* values under the product's own selector */
|
|
119
|
+
}
|
|
120
|
+
```
|
|
95
121
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
selector by default.
|
|
122
|
+
Nothing sits between the product tokens and the rendered component — no
|
|
123
|
+
renderer preset, no internal selector, no commercial theme package.
|
|
99
124
|
|
|
100
|
-
## Step 3 — Colors: use the token
|
|
125
|
+
## Step 3 — Colors: use the token seam
|
|
101
126
|
|
|
102
127
|
Never hard-code a hex or `rgb()` value for UI chrome — it breaks the moment the
|
|
103
|
-
theme changes. Read a `--cratis-*` custom property instead.
|
|
104
|
-
|
|
105
|
-
The chain is: **preset (JavaScript) → `--p-*` (runtime) → `--cratis-*` (the
|
|
106
|
-
tokens stylesheet) → component CSS.** Each `--cratis-*` token resolves a
|
|
107
|
-
PrimeReact 11 token with a PrimeReact 10 name as fallback, so both eras work.
|
|
108
|
-
The tokens are intentionally fallback-free at the end of the chain: if nothing
|
|
109
|
-
resolves, the rule no-ops rather than painting a wrong color.
|
|
110
|
-
|
|
111
|
-
The full vocabulary:
|
|
128
|
+
theme changes. Read a `--cratis-*` custom property instead. The full vocabulary
|
|
129
|
+
(from `tokens.css`):
|
|
112
130
|
|
|
113
131
|
| Group | Tokens |
|
|
114
132
|
| --- | --- |
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
| Effects | `--cratis-focus-ring`, `--cratis-maskbg` |
|
|
133
|
+
| Accent | `--cratis-primary-color`, `--cratis-primary-color-text`, `--cratis-primary-300` … `-600`, `--cratis-primary-600-text` |
|
|
134
|
+
| Primary action | `--cratis-action-background` / `-hover` / `-active`, `--cratis-action-text` |
|
|
135
|
+
| Status pairs | `--cratis-info-background` / `-text`, `--cratis-success-*`, `--cratis-warning-*`, `--cratis-danger-*`; single indicators `--cratis-green-500`, `--cratis-orange-500`, `--cratis-red-500` |
|
|
136
|
+
| Surfaces | `--cratis-surface-ground` (page), `-section`, `-card`, `-overlay` (dialogs, popovers, toasts), `-hover`, `-border`, `-0`, `-100` |
|
|
137
|
+
| Controls | `--cratis-control-background`, `--cratis-control-border`, `--cratis-control-height` / `-small` / `-large` |
|
|
138
|
+
| Text & highlight | `--cratis-text-color`, `--cratis-text-color-secondary`, `--cratis-highlight-bg`, `--cratis-highlight-text-color` |
|
|
139
|
+
| Effects | `--cratis-focus-ring`, `--cratis-maskbg`, `--cratis-border-radius`, `--cratis-disabled-opacity`, `--cratis-shadow-subtle` / `-overlay` / `-dialog` / `-toast` |
|
|
140
|
+
| Layering | `--cratis-z-index-dialog` (1100), `-overlay` (1200), `-filter` (1250), `-tooltip` (1300), `-toast` (1400) |
|
|
122
141
|
|
|
123
142
|
Only hard-code a color that is intentionally theme-independent — a brand accent
|
|
124
143
|
dot, a traffic-light indicator.
|
|
125
144
|
|
|
126
|
-
A back-compatibility stylesheet
|
|
127
|
-
(`@cratis/components/primereact-v10-palette`) republishes the PrimeReact 10
|
|
128
|
-
names (`--surface-ground`, `--text-color`, `--primary-color`, and the numbered
|
|
129
|
-
ramps) for code that has not migrated. Import it to keep an old application
|
|
130
|
-
running; **write nothing new against those names.**
|
|
131
|
-
|
|
132
145
|
## Step 4 — Writing styles
|
|
133
146
|
|
|
134
|
-
- Put static styles in a **co-located `.css` file
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
positioning for its children, not the children's own styling.
|
|
141
|
-
- Use inline `style` **only** for runtime-dynamic values such as computed
|
|
142
|
-
pixel positions. A `style` object full of static token names bypasses theming
|
|
143
|
-
and review — move it to a class.
|
|
147
|
+
- Put static styles in a **co-located `.css` file**, one per component. A
|
|
148
|
+
composition root's CSS carries layout and positioning for its children, not the
|
|
149
|
+
children's own styling.
|
|
150
|
+
- Use inline `style` **only** for runtime-dynamic values such as computed pixel
|
|
151
|
+
positions. A `style` object full of static token names bypasses theming and
|
|
152
|
+
review — move it to a class.
|
|
144
153
|
- Name classes with a prefix matching the component.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
components
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
154
|
+
- Import product CSS *after* the Components entries so it wins the cascade.
|
|
155
|
+
|
|
156
|
+
## Step 5 — Parts: reaching inside a component
|
|
157
|
+
|
|
158
|
+
Every meaningful element a component renders carries **`data-cratis-part`**, and
|
|
159
|
+
most components accept a **`pt`** prop typed by their own `*Parts` type. They
|
|
160
|
+
are documented separately because they are not always the same names: for most
|
|
161
|
+
components the typed `pt` key is the camelCase spelling of the kebab-case DOM
|
|
162
|
+
value (`headerRow` ↔ `header-row`), but the Toolbar family prefixes its DOM
|
|
163
|
+
values (`ToolbarButtonParts.root` ↔ `data-cratis-part='button'`,
|
|
164
|
+
`ToolbarFolderParts.root` ↔ `'toolbar-folder'`, `ToolbarFanOutParts.trigger` ↔
|
|
165
|
+
`'fanout-trigger'`). Read the DOM value off the rendered element (or the parts
|
|
166
|
+
manifest in `@cratis/components/types`) before writing a selector. Both spellings
|
|
167
|
+
are stable across internal foundation changes; React Aria class names and
|
|
168
|
+
undocumented DOM structure are not.
|
|
169
|
+
|
|
170
|
+
- **One instance:** `pt` — plain HTML attributes per part.
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
<Dropdown aria-label='Role' options={roles}
|
|
174
|
+
pt={{ trigger: { className: 'product-select-trigger' }, popover: { className: 'product-select-popover' }, option: { className: 'product-select-option' } }} />
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
- **Product-wide:** a CSS rule on the part and its state attributes.
|
|
178
|
+
|
|
179
|
+
```css
|
|
180
|
+
[data-cratis-part='header-cell'] { text-transform: uppercase; }
|
|
181
|
+
[data-cratis-part='row'][data-selected='true'] { background: var(--product-selected-row); }
|
|
182
|
+
.product-dialog[data-cratis-part='root'] { border-radius: 1rem; }
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The typed part families: `ButtonParts`/`IconButtonParts` (`root`, `icon`,
|
|
186
|
+
`label`, `spinner`); `DialogParts` (`backdrop`, `positioner`, `root`, `header`,
|
|
187
|
+
`title`, `close`, `content`, `footer`, `confirm`, `cancel`); `DropdownParts`
|
|
188
|
+
(`root`, `trigger`, `value`, `clear`, `indicator`, `popover`, `listbox`, `option`,
|
|
189
|
+
`filter`, `multiple`); `DataTableParts` (`root`, `search`, `searchInput`,
|
|
190
|
+
`tableContainer`, `table`, `head`, `headerRow`, `headerCell`, `body`, `row`,
|
|
191
|
+
`cell`, `emptyRow`, `emptyCell`); `TablePaginatorParts` (`root`, `range`, `info`,
|
|
192
|
+
`first`, `previous`, `next`, `last`); `StepperParts` (`root`, `list`, `step`,
|
|
193
|
+
`header`, `number`, `title`, `separator`, `panels`, `panel`);
|
|
194
|
+
`ToasterPassThrough` (`region`, `toast`, `icon`, `content`, `title`,
|
|
195
|
+
`description`, `action`, `close`); the `Toolbar*Parts` family; and per-field
|
|
196
|
+
parts for every CommandForm field. The Components `Styling/pass-through`
|
|
197
|
+
reference is the exhaustive table.
|
|
198
|
+
|
|
199
|
+
**Named parts where a component wraps two surfaces** — the usual cause of a
|
|
200
|
+
`pt` that "does nothing" is applying it to the wrong one:
|
|
201
|
+
|
|
202
|
+
- `DataPage`: `tablePt: DataTableParts`, `paginatorPt: TablePaginatorParts`, `menubarPt: ButtonParts`.
|
|
203
|
+
- `StepperCommandDialog`: `pt` is the inner **stepper**, `dialogPt` the outer **dialog**.
|
|
204
|
+
- `Column`: `filterPt: ColumnFilterMenuParts` for the filter popup.
|
|
205
|
+
|
|
206
|
+
**State attributes** are component-specific: `data-active`, `data-selected`,
|
|
207
|
+
`data-invalid`, `data-disabled`, `data-readonly`, `data-loading`, `data-position`,
|
|
208
|
+
`data-orientation`, `data-size`, `data-severity`. Do not assume one exists on
|
|
209
|
+
every component — read the component's parts reference.
|
|
210
|
+
|
|
211
|
+
`ptOptions` and `unstyled` are accepted for Components 3 source compatibility and
|
|
212
|
+
do **nothing**: part attributes always merge, and styling is always CSS-owned.
|
|
213
|
+
There is no global provider `pt`.
|
|
214
|
+
|
|
215
|
+
## Renderer adapters — when a vendor look is wanted
|
|
216
|
+
|
|
217
|
+
The default renderer is built in; omit `library` on the provider. Three optional
|
|
218
|
+
adapter packages exist — `@cratis/components.mui` (MUI 9),
|
|
219
|
+
`@cratis/components.primereact` (PrimeReact 11), `@cratis/components.primereact10`
|
|
220
|
+
— and each adapts exactly **nine primitive slots**: button, icon-button, text
|
|
221
|
+
input, text area, checkbox, radio, switch, progress bar, surface. Pass the
|
|
222
|
+
adapter's manifest to the provider's `library` prop. Dialogs, dropdowns, tables,
|
|
223
|
+
date pickers, tooltips, paginators, toasts and steppers stay Components-owned
|
|
224
|
+
regardless; an adapter never restores a vendor's public API, and the vendor's
|
|
225
|
+
own provider, theme and license remain the application's, outside Components.
|
|
226
|
+
Reach for an adapter only when the product genuinely wants that vendor's look on
|
|
227
|
+
those nine controls — mapping tokens is almost always the smaller change.
|
|
194
228
|
|
|
195
229
|
## Where Tailwind fits
|
|
196
230
|
|
|
197
|
-
Tailwind is **one supported
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
components; reach for the token layer and pass-through first.
|
|
231
|
+
Tailwind is **one supported way to write the CSS above, not the Cratis default.**
|
|
232
|
+
It is a fine tool for authoring the token mapping and part rules; it is not a
|
|
233
|
+
substitute for them. Components' own internal utilities are prefixed (`cratis:*`)
|
|
234
|
+
and are not public styling hooks. `styles` ships no Preflight and no reset of its
|
|
235
|
+
own; if the application uses Tailwind's Preflight or its own cascade layers,
|
|
236
|
+
declare the layer order explicitly after the Components imports (Components says
|
|
237
|
+
nothing more specific than that — verify the result in the running app).
|
|
205
238
|
|
|
206
239
|
## Verify
|
|
207
240
|
|
|
208
|
-
- PrimeReact
|
|
209
|
-
|
|
210
|
-
- `CratisComponentsProvider` wraps the tree
|
|
241
|
+
- No PrimeReact / PrimeIcons / PrimeUI package remains in the manifest unless the
|
|
242
|
+
application itself imports it directly — and then it has its own provider.
|
|
243
|
+
- `CratisComponentsProvider` (root import) wraps the tree and carries only
|
|
244
|
+
`locale`, `messages` and `toaster`.
|
|
211
245
|
- `@cratis/components/tokens` and `@cratis/components/styles` are imported once
|
|
212
|
-
at the entry point, tokens first
|
|
213
|
-
|
|
214
|
-
defaults is not one of them.
|
|
246
|
+
at the entry point, tokens first; `theme` is imported or deliberately omitted;
|
|
247
|
+
product CSS comes after.
|
|
215
248
|
- No hex or `rgb()` value is hard-coded for UI chrome; colors read `--cratis-*`.
|
|
216
|
-
- No
|
|
217
|
-
|
|
249
|
+
- No CSS targets a React Aria class name or undocumented DOM; parts are reached
|
|
250
|
+
through `pt` or `[data-cratis-part=…]`.
|
|
218
251
|
- Inline `style` carries only runtime-dynamic values.
|
|
219
|
-
-
|
|
220
|
-
`
|
|
221
|
-
- Dark mode is toggled with
|
|
252
|
+
- Named parts land on the intended surface (`tablePt` vs `menubarPt`; `pt` vs
|
|
253
|
+
`dialogPt`).
|
|
254
|
+
- Dark mode is toggled with `cratis-dark` / `cratis-light` on the root element
|
|
255
|
+
(or a `cratis-theme` subtree), not through a provider option.
|
|
@@ -15,9 +15,9 @@ over a list, use `DataPage.MenuItems` instead (see the
|
|
|
15
15
|
|
|
16
16
|
| Package | Version | Verified from |
|
|
17
17
|
| --- | --- | --- |
|
|
18
|
-
| `@cratis/components` | `
|
|
19
|
-
| `
|
|
20
|
-
| `react` | `^19.0.0` | peer of `@cratis/components@
|
|
18
|
+
| `@cratis/components` | `4.6.0` | its package manifest, `Source/Toolbar/*` (exports and props), `Documentation/Toolbar/*`, `Documentation/Common/icon.md` |
|
|
19
|
+
| `react-icons` | `5.7.0` | dependency of `@cratis/components@4.6.0` — the icon source the examples use |
|
|
20
|
+
| `react` | `^19.0.0` | peer of `@cratis/components@4.6.0` |
|
|
21
21
|
|
|
22
22
|
## Import from the subpath
|
|
23
23
|
|
|
@@ -53,19 +53,25 @@ Buttons default to a vertical layout. **`title` is the required prop and it is
|
|
|
53
53
|
what appears in the tooltip** — there is no `tooltip` prop on `ToolbarButton`.
|
|
54
54
|
|
|
55
55
|
```tsx
|
|
56
|
+
import { FaArrowPointer, FaPencil, FaVectorSquare } from 'react-icons/fa6';
|
|
56
57
|
import { Toolbar, ToolbarButton } from '@cratis/components/Toolbar';
|
|
57
58
|
|
|
58
59
|
export const DrawingToolbar = () => (
|
|
59
60
|
<Toolbar>
|
|
60
|
-
<ToolbarButton icon=
|
|
61
|
-
<ToolbarButton icon=
|
|
62
|
-
<ToolbarButton icon=
|
|
61
|
+
<ToolbarButton icon={<FaArrowPointer />} title='Select' />
|
|
62
|
+
<ToolbarButton icon={<FaPencil />} title='Draw' />
|
|
63
|
+
<ToolbarButton icon={<FaVectorSquare />} title='Rectangle' />
|
|
63
64
|
</Toolbar>
|
|
64
65
|
);
|
|
65
66
|
```
|
|
66
67
|
|
|
67
|
-
`icon`
|
|
68
|
-
|
|
68
|
+
`icon` is the Components `Icon` type: a **React node** (preferred — the examples
|
|
69
|
+
below take theirs from `react-icons/fa6`, which Components itself depends on, and
|
|
70
|
+
omit the import line after this first one) or a complete, consumer-owned
|
|
71
|
+
icon-font class string. Components installs **no icon font**: a string is rendered
|
|
72
|
+
on an `<i>` unchanged, so the product must load that stylesheet and pass every
|
|
73
|
+
class the font needs. A custom SVG component works directly:
|
|
74
|
+
`<ToolbarButton icon={<CircleIcon />} title='Circle' />`.
|
|
69
75
|
|
|
70
76
|
## Step 2 — Active state
|
|
71
77
|
|
|
@@ -73,9 +79,9 @@ component works directly: `<ToolbarButton icon={<CircleIcon />} title='Circle' /
|
|
|
73
79
|
const [activeTool, setActiveTool] = useState('select');
|
|
74
80
|
|
|
75
81
|
<Toolbar>
|
|
76
|
-
<ToolbarButton icon=
|
|
82
|
+
<ToolbarButton icon={<FaPencil />} title='Draw'
|
|
77
83
|
active={activeTool === 'draw'} onClick={() => setActiveTool('draw')} />
|
|
78
|
-
<ToolbarButton icon=
|
|
84
|
+
<ToolbarButton icon={<FaVectorSquare />} title='Rectangle'
|
|
79
85
|
active={activeTool === 'rect'} onClick={() => setActiveTool('rect')} />
|
|
80
86
|
</Toolbar>
|
|
81
87
|
```
|
|
@@ -87,11 +93,11 @@ tooltips out of the bar's way on a horizontal toolbar:
|
|
|
87
93
|
|
|
88
94
|
```tsx
|
|
89
95
|
<Toolbar orientation='horizontal'>
|
|
90
|
-
<ToolbarButton icon=
|
|
96
|
+
<ToolbarButton icon={<FaMinus />} title='Zoom out' tooltipPosition='bottom' onClick={() => setZoom(z => z - 10)} />
|
|
91
97
|
<ToolbarButton text={`${zoom}%`} title='Reset zoom' tooltipPosition='bottom' onClick={() => setZoom(100)} />
|
|
92
|
-
<ToolbarButton icon=
|
|
98
|
+
<ToolbarButton icon={<FaPlus />} title='Zoom in' tooltipPosition='bottom' onClick={() => setZoom(z => z + 10)} />
|
|
93
99
|
<ToolbarSeparator orientation='horizontal' />
|
|
94
|
-
<ToolbarButton icon=
|
|
100
|
+
<ToolbarButton icon={<FaCircleQuestion />} title='Help' tooltipPosition='bottom' />
|
|
95
101
|
</Toolbar>
|
|
96
102
|
```
|
|
97
103
|
|
|
@@ -108,18 +114,18 @@ unaffected.
|
|
|
108
114
|
const [mode, setMode] = useState<'drawing' | 'text'>('drawing');
|
|
109
115
|
|
|
110
116
|
<Toolbar>
|
|
111
|
-
<ToolbarButton icon=
|
|
117
|
+
<ToolbarButton icon={<FaArrowPointer />} title='Select' />
|
|
112
118
|
<ToolbarSection activeContext={mode}>
|
|
113
119
|
<ToolbarContext name='drawing'>
|
|
114
|
-
<ToolbarButton icon=
|
|
115
|
-
<ToolbarButton icon=
|
|
120
|
+
<ToolbarButton icon={<FaPencil />} title='Draw' />
|
|
121
|
+
<ToolbarButton icon={<FaVectorSquare />} title='Rectangle' />
|
|
116
122
|
</ToolbarContext>
|
|
117
123
|
<ToolbarContext name='text'>
|
|
118
|
-
<ToolbarButton icon=
|
|
119
|
-
<ToolbarButton icon=
|
|
124
|
+
<ToolbarButton icon={<FaAlignLeft />} title='Align left' />
|
|
125
|
+
<ToolbarButton icon={<FaAlignCenter />} title='Align center' />
|
|
120
126
|
</ToolbarContext>
|
|
121
127
|
</ToolbarSection>
|
|
122
|
-
<ToolbarButton icon=
|
|
128
|
+
<ToolbarButton icon={<FaRotateLeft />} title='Undo' />
|
|
123
129
|
</Toolbar>
|
|
124
130
|
```
|
|
125
131
|
|
|
@@ -130,9 +136,9 @@ the one component whose label prop **is** called `tooltip`, and both `icon` and
|
|
|
130
136
|
`tooltip` are required.
|
|
131
137
|
|
|
132
138
|
```tsx
|
|
133
|
-
<ToolbarFanOutItem icon=
|
|
134
|
-
<ToolbarButton icon=
|
|
135
|
-
<ToolbarButton icon=
|
|
139
|
+
<ToolbarFanOutItem icon={<FaShapes />} tooltip='Shapes' fanOutDirection='left'>
|
|
140
|
+
<ToolbarButton icon={<FaVectorSquare />} title='Rectangle' />
|
|
141
|
+
<ToolbarButton icon={<FaCircle />} title='Circle' />
|
|
136
142
|
</ToolbarFanOutItem>
|
|
137
143
|
```
|
|
138
144
|
|
|
@@ -142,9 +148,9 @@ away from the screen edge the toolbar sits against.
|
|
|
142
148
|
`ToolbarFolder` opens a larger panel of buttons as a grid or a list:
|
|
143
149
|
|
|
144
150
|
```tsx
|
|
145
|
-
<ToolbarFolder icon=
|
|
146
|
-
<ToolbarButton icon=
|
|
147
|
-
<ToolbarButton icon=
|
|
151
|
+
<ToolbarFolder icon={<FaShapes />} title='Tools' mode='list'>
|
|
152
|
+
<ToolbarButton icon={<FaPencil />} title='Draw' />
|
|
153
|
+
<ToolbarButton icon={<FaEraser />} title='Erase' />
|
|
148
154
|
</ToolbarFolder>
|
|
149
155
|
```
|
|
150
156
|
|
|
@@ -163,7 +169,7 @@ by rendering a named `ToolbarLayout`.
|
|
|
163
169
|
{mode === 'draw' && <ToolbarSlot slotName='tool-options' order={10}>{drawTools}</ToolbarSlot>}
|
|
164
170
|
<Toolbar>
|
|
165
171
|
<ToolbarGroup>
|
|
166
|
-
<ToolbarButton icon=
|
|
172
|
+
<ToolbarButton icon={<FaArrowPointer />} title='Select' />
|
|
167
173
|
</ToolbarGroup>
|
|
168
174
|
<ToolbarGroup slotName='tool-options' />
|
|
169
175
|
</Toolbar>
|
|
@@ -20,7 +20,7 @@ file and Mermaid disagree. Confirm the Mermaid version available to the renderer
|
|
|
20
20
|
before relying on a construct.
|
|
21
21
|
|
|
22
22
|
The Cratis artifacts a diagram refers to are verified against `Cratis.Chronicle`
|
|
23
|
-
`
|
|
23
|
+
`18.3.0` and the Arc query and command surface it is used with.
|
|
24
24
|
|
|
25
25
|
## What an event model is
|
|
26
26
|
|
|
@@ -15,8 +15,8 @@ This skill is verified against these exact public releases:
|
|
|
15
15
|
|
|
16
16
|
| Package | Version | Purpose |
|
|
17
17
|
| --- | --- | --- |
|
|
18
|
-
| `Cratis.Fundamentals` | `7.
|
|
19
|
-
| `Cratis.Chronicle` | `
|
|
18
|
+
| `Cratis.Fundamentals` | `7.19.2` | `Cratis.Concepts.ConceptAs<T>` |
|
|
19
|
+
| `Cratis.Chronicle` | `18.3.0` | `Cratis.Chronicle.Events.EventSourceId` and `EventSourceId<T>` |
|
|
20
20
|
|
|
21
21
|
Reverify product sources before claiming support for another version.
|
|
22
22
|
|
|
@@ -18,7 +18,7 @@ removing one becomes a single-file change.
|
|
|
18
18
|
|
|
19
19
|
| Package | Version | Purpose |
|
|
20
20
|
| --- | --- | --- |
|
|
21
|
-
| `Cratis.Fundamentals` | `7.
|
|
21
|
+
| `Cratis.Fundamentals` | `7.19.2` | `IInstancesOf<T>`, `IImplementationsOf<T>`, `[Singleton]`, `[Scoped]`, `[IgnoreConvention]`, the convention bindings |
|
|
22
22
|
|
|
23
23
|
Reverify against the Cratis Fundamentals repository before claiming support for
|
|
24
24
|
another version.
|
|
@@ -50,7 +50,7 @@ registered implementation:
|
|
|
50
50
|
`IInstancesOf<T>` finds types by convention across the loaded assemblies. The
|
|
51
51
|
requirements are only:
|
|
52
52
|
|
|
53
|
-
- Each implementation is a non-abstract `public class`.
|
|
53
|
+
- Each implementation is a non-abstract, non-interface class. Discovery reads each assembly's `DefinedTypes` and filters only on `!IsInterface && !IsAbstract`, so an `internal` class is discovered too; `public` is a convention for a type meant to be reached from another assembly, not a discovery requirement. Instances are resolved from the service provider (`GetService(type)`), so each implementation must be registered as itself — `AddSelfBindings()` does that for every concrete, non-static, non-`Exception` class whose constructor is resolvable (visibility is not a criterion), honoring `[Singleton]`/`[Scoped]`/`[IgnoreConvention]`.
|
|
54
54
|
- It implements the interface directly, not through a layer that hides it.
|
|
55
55
|
- `T` is an interface or abstract class — the interface is declared
|
|
56
56
|
`where T : class`.
|