@dataworkz/crystal 0.1.0-beta.0 → 0.1.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +151 -13
- package/README.md +6 -0
- package/fesm2022/dataworkz-crystal-icons.mjs +32 -322
- package/fesm2022/dataworkz-crystal-icons.mjs.map +1 -1
- package/fesm2022/dataworkz-crystal-markdown.mjs +1 -1
- package/fesm2022/dataworkz-crystal-markdown.mjs.map +1 -1
- package/fesm2022/dataworkz-crystal-primeng.mjs +31 -5
- package/fesm2022/dataworkz-crystal-primeng.mjs.map +1 -1
- package/fesm2022/dataworkz-crystal.mjs +2635 -257
- package/fesm2022/dataworkz-crystal.mjs.map +1 -1
- package/icons/index.d.ts +33 -97
- package/icons/svg/files/csv.svg +0 -1
- package/icons/svg/files/generic.svg +0 -1
- package/icons/svg/files/multimedia.svg +0 -1
- package/icons/svg/glyphs/agentBuilder.svg +1 -1
- package/icons/svg/glyphs/notesPad.svg +1 -1
- package/icons/svg/glyphs/panelCollapse.svg +1 -1
- package/icons/svg/glyphs/panelExpand.svg +1 -1
- package/icons/svg/glyphs/play.svg +1 -1
- package/icons/svg/glyphs/robot.svg +1 -1
- package/icons/svg/glyphs/sidebarCollapse.svg +1 -1
- package/icons/svg/glyphs/sidebarExpand.svg +1 -1
- package/icons/svg/glyphs/tagFilled.svg +1 -1
- package/icons/svg/glyphs/testShield.svg +1 -1
- package/icons/svg/storage/generic.svg +0 -1
- package/icons/svg/storage/legacy/microsoft-mail.svg +0 -1
- package/icons/svg/storage/local/microsoft-mail.svg +0 -1
- package/index.d.ts +1207 -68
- package/package.json +5 -7
- package/primeng/index.d.ts +45 -5
- package/styles/base.css +4 -4
- package/styles/components/button.css +3 -0
- package/styles/components/content.css +89 -91
- package/styles/components/data.css +24 -1
- package/styles/components/form.css +116 -13
- package/styles/components/navigation.css +31 -1
- package/styles/components/overlay.css +16 -1
- package/styles/components/surface.css +38 -2
- package/styles/components/toast.css +1 -1
- package/styles/crystal-no-fonts.css +3 -2
- package/styles/icons.css +6 -0
- package/styles/tokens/primitives.css +1 -3
- package/styles/tokens/semantic-dark.css +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dataworkz/crystal",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.10",
|
|
4
4
|
"description": "Dataworkz core UI for Angular: dw-* components, icons, toasts, design tokens, theme CSS and bundled fonts.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Dataworkz",
|
|
@@ -19,21 +19,19 @@
|
|
|
19
19
|
"@angular/forms": "^20.3.0",
|
|
20
20
|
"@angular/platform-browser": "^20.3.0",
|
|
21
21
|
"@angular/router": "^20.3.0",
|
|
22
|
-
"@primeng/themes": "^21.0.0",
|
|
23
22
|
"ngx-markdown": "^20.0.0",
|
|
24
|
-
"primeicons": "^7.0.0",
|
|
25
|
-
"primeng": "^20.4.0",
|
|
26
23
|
"rxjs": "~7.8.0"
|
|
27
24
|
},
|
|
28
25
|
"peerDependenciesMeta": {
|
|
29
|
-
"@primeng/themes": {
|
|
30
|
-
"optional": true
|
|
31
|
-
},
|
|
32
26
|
"ngx-markdown": {
|
|
33
27
|
"optional": true
|
|
34
28
|
}
|
|
35
29
|
},
|
|
36
30
|
"dependencies": {
|
|
31
|
+
"@primeng/themes": "^21.0.0",
|
|
32
|
+
"chart.js": "^4.5.1",
|
|
33
|
+
"primeicons": "^7.0.0",
|
|
34
|
+
"primeng": "~20.4.0",
|
|
37
35
|
"tslib": "^2.8.1"
|
|
38
36
|
},
|
|
39
37
|
"exports": {
|
package/primeng/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { PrimeNGConfigType } from 'primeng/config';
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Azure Electric primary ramp. Same hex values as `--dw-primary-*` in
|
|
8
|
-
*
|
|
8
|
+
* tokens/primitives.css — PrimeNG needs literal hex for the
|
|
9
9
|
* primitive ramp because it derives other tokens from it at build time.
|
|
10
10
|
*/
|
|
11
11
|
declare const AZURE_PRIMARY_RAMP: {
|
|
@@ -23,8 +23,8 @@ declare const AZURE_PRIMARY_RAMP: {
|
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
25
25
|
* PrimeNG color scheme, used for both light and dark. Every value points at a
|
|
26
|
-
* design-system CSS variable, so PrimeNG follows
|
|
27
|
-
* and semantic-dark.css: switching theme re-points the variables, the preset
|
|
26
|
+
* design-system CSS variable, so PrimeNG follows the semantic tokens (tokens/semantic.css
|
|
27
|
+
* and semantic-dark.css): switching theme re-points the variables, the preset
|
|
28
28
|
* never changes. (The surface ramp is the raw neutral scale, light → dark,
|
|
29
29
|
* which is the order Aura's own light and dark schemes expect.)
|
|
30
30
|
*/
|
|
@@ -608,8 +608,48 @@ declare const DW_PRESET_OVERRIDES: {
|
|
|
608
608
|
/** Dataworkz PrimeNG preset: Aura retargeted to the design system. */
|
|
609
609
|
declare const DwPreset: _primeuix_themes_types.Preset<_primeuix_themes_aura_base.AuraBaseDesignTokens>;
|
|
610
610
|
|
|
611
|
-
/** PrimeNG's dark mode follows the attribute ThemeService (and provideCrystal()) put on
|
|
611
|
+
/** PrimeNG's dark mode follows the attribute ThemeService (and provideCrystal()) put on `<html>`. */
|
|
612
612
|
declare const DW_DARK_MODE_SELECTOR = "[data-theme=\"dark\"]";
|
|
613
|
+
/** Panel class that sizes a select's option list for a small trigger (components/form.css). */
|
|
614
|
+
declare const DW_SELECT_PANEL_SM = "dw-select-panel--sm";
|
|
615
|
+
type SizedInstance = {
|
|
616
|
+
size?: () => string | null | undefined;
|
|
617
|
+
};
|
|
618
|
+
/**
|
|
619
|
+
* Crystal's pass-through defaults: a small `p-select` / `p-multiselect` gets small options even when its list is
|
|
620
|
+
* appended to `<body>` (where CSS can't see the trigger).
|
|
621
|
+
*/
|
|
622
|
+
declare const DW_PRIMENG_PT: {
|
|
623
|
+
readonly select: {
|
|
624
|
+
readonly overlay: ({ instance }: {
|
|
625
|
+
instance?: SizedInstance;
|
|
626
|
+
}) => {
|
|
627
|
+
class: string;
|
|
628
|
+
} | {
|
|
629
|
+
class?: undefined;
|
|
630
|
+
};
|
|
631
|
+
};
|
|
632
|
+
readonly multiselect: {
|
|
633
|
+
readonly overlay: ({ instance }: {
|
|
634
|
+
instance?: SizedInstance;
|
|
635
|
+
}) => {
|
|
636
|
+
class: string;
|
|
637
|
+
} | {
|
|
638
|
+
class?: undefined;
|
|
639
|
+
};
|
|
640
|
+
};
|
|
641
|
+
};
|
|
642
|
+
/**
|
|
643
|
+
* PrimeNG's z-index bases, with tooltips raised to 5000: PrimeNG already stacks a tooltip above the overlays it manages
|
|
644
|
+
* (dialogs, drawers, popovers), and the higher base keeps it above layers that set their own z-index too (a panel or
|
|
645
|
+
* page chrome with `z-index` in CSS), so a tooltip is never hidden under what it describes.
|
|
646
|
+
*/
|
|
647
|
+
declare const DW_PRIMENG_Z_INDEX: {
|
|
648
|
+
readonly modal: 1100;
|
|
649
|
+
readonly overlay: 1000;
|
|
650
|
+
readonly menu: 1000;
|
|
651
|
+
readonly tooltip: 5000;
|
|
652
|
+
};
|
|
613
653
|
/**
|
|
614
654
|
* PrimeNG with the Dataworkz preset, dark mode on `[data-theme="dark"]`. Pass app-specific PrimeNG settings
|
|
615
655
|
* (ripple, zIndex, translation…) as `config`; its `theme.options` are merged over crystal's.
|
|
@@ -620,4 +660,4 @@ declare const DW_DARK_MODE_SELECTOR = "[data-theme=\"dark\"]";
|
|
|
620
660
|
*/
|
|
621
661
|
declare function provideCrystalPrimeNG(config?: PrimeNGConfigType): EnvironmentProviders;
|
|
622
662
|
|
|
623
|
-
export { AZURE_PRIMARY_RAMP, DW_COLOR_SCHEME, DW_DARK_MODE_SELECTOR, DW_PRESET_OVERRIDES, DwPreset, provideCrystalPrimeNG };
|
|
663
|
+
export { AZURE_PRIMARY_RAMP, DW_COLOR_SCHEME, DW_DARK_MODE_SELECTOR, DW_PRESET_OVERRIDES, DW_PRIMENG_PT, DW_PRIMENG_Z_INDEX, DW_SELECT_PANEL_SM, DwPreset, provideCrystalPrimeNG };
|
package/styles/base.css
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/* ============================================================================
|
|
2
2
|
Dataworkz Design System — BASE
|
|
3
|
-
The ONLY place in the
|
|
4
|
-
its equivalent for
|
|
3
|
+
The ONLY place in the theme that declares font-family (element-base.css is
|
|
4
|
+
its equivalent for components embedded in a page crystal doesn't own). Everything else
|
|
5
5
|
inherits (`font: inherit`) or uses the typography classes.
|
|
6
6
|
============================================================================ */
|
|
7
7
|
|
|
8
|
-
/* ── Reset — the element defaults the
|
|
9
|
-
Bootstrap 4 Reboot
|
|
8
|
+
/* ── Reset — the element defaults the components are built on (in the spirit of the
|
|
9
|
+
Bootstrap 4 Reboot) ── */
|
|
10
10
|
*,
|
|
11
11
|
*::before,
|
|
12
12
|
*::after {
|
|
@@ -325,6 +325,9 @@
|
|
|
325
325
|
.dw-icon-btn.is-active { background: var(--dw-accent-tint); color: var(--dw-accent); }
|
|
326
326
|
/* Hovering the active (selected) button keeps it accented, a step stronger */
|
|
327
327
|
.dw-icon-btn.is-active:hover:not(:disabled) { background: var(--dw-accent-tint-strong); color: var(--dw-accent); }
|
|
328
|
+
/* A selected danger toggle (e.g. a "not helpful" rating) keeps its danger colour instead of the accent. */
|
|
329
|
+
.dw-icon-btn--danger.is-active,
|
|
330
|
+
.dw-icon-btn--danger.is-active:hover:not(:disabled) { background: var(--dw-danger-tint); color: var(--dw-danger-solid); }
|
|
328
331
|
.dw-icon-btn--inverse { color: var(--dw-text-muted); }
|
|
329
332
|
.dw-icon-btn--inverse:hover:not(:disabled),
|
|
330
333
|
.dw-icon-btn--inverse.is-active { background: color-mix(in srgb, var(--dw-text-inverse) 12%, transparent); color: var(--dw-text-inverse); }
|
|
@@ -153,108 +153,106 @@ dw-markdown.dw-prose { display: block; }
|
|
|
153
153
|
.dw-prose--compact { font-size: var(--dw-font-size-12); line-height: 1.5; }
|
|
154
154
|
.dw-prose--compact p { margin-bottom: var(--dw-space-1); }
|
|
155
155
|
|
|
156
|
-
/* ── Citation chip — numbered source reference in rendered answers (RAG run,
|
|
157
|
-
Q&A history, probe). The markup is generated by the RAG answer services. ── */
|
|
158
|
-
.dw-rag-cite-chip {
|
|
159
|
-
display: inline-flex;
|
|
160
|
-
align-items: center;
|
|
161
|
-
justify-content: center;
|
|
162
|
-
min-width: 22px;
|
|
163
|
-
height: 22px;
|
|
164
|
-
padding: 0 6px;
|
|
165
|
-
margin: 0 2px;
|
|
166
|
-
border-radius: var(--dw-radius-sm);
|
|
167
|
-
border: 1px solid var(--dw-border-accent);
|
|
168
|
-
background: var(--dw-accent-tint);
|
|
169
|
-
color: var(--dw-accent-text);
|
|
170
|
-
font-size: var(--dw-font-size-12);
|
|
171
|
-
font-weight: var(--dw-font-weight-semibold);
|
|
172
|
-
line-height: var(--dw-line-height-20);
|
|
173
|
-
text-decoration: none;
|
|
174
|
-
vertical-align: middle;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
a.dw-rag-cite-chip:hover {
|
|
178
|
-
background: var(--dw-accent-tint-strong);
|
|
179
|
-
text-decoration: none;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
156
|
/* ── dw-icon: app SVG glyphs, drawn in currentColor at the text size ── */
|
|
183
157
|
.dw-icon { display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center; line-height: 0; vertical-align: -0.125em; }
|
|
184
158
|
.dw-icon svg { display: block; }
|
|
159
|
+
/* A PrimeIcons glyph (dw-icon pi="…") is a font glyph: it needs a line box, which the SVG case sets to 0. */
|
|
160
|
+
.dw-icon.pi { line-height: 1; }
|
|
161
|
+
.dw-icon--spin { animation: dw-icon-spin 1s linear infinite; }
|
|
162
|
+
@keyframes dw-icon-spin { to { transform: rotate(360deg); } }
|
|
163
|
+
@media (prefers-reduced-motion: reduce) { .dw-icon--spin, .dw-icon.pi-spin { animation-duration: 3s; } }
|
|
185
164
|
|
|
186
|
-
/* ──
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
.dw-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
background: var(--dw-surface-
|
|
203
|
-
|
|
204
|
-
|
|
165
|
+
/* ── dw-accordion: panels that open and close under a header row (PrimeNG's p-accordion underneath) ──
|
|
166
|
+
PrimeNG reads its accordion design tokens as --p-accordion-* variables, so the look is set through them (no
|
|
167
|
+
specificity race with its own :hover / :first-child rules). flush (default): rows on the container, a divider
|
|
168
|
+
between panels; card: each panel a bordered card, the list spaced, a divider under an open header. */
|
|
169
|
+
.dw-accordion {
|
|
170
|
+
display: block;
|
|
171
|
+
min-width: 0;
|
|
172
|
+
--p-accordion-panel-border-width: 0;
|
|
173
|
+
--p-accordion-panel-border-color: var(--dw-border);
|
|
174
|
+
--p-accordion-header-padding: var(--dw-space-3) var(--dw-space-4);
|
|
175
|
+
--p-accordion-header-font-weight: var(--dw-font-weight-semibold);
|
|
176
|
+
--p-accordion-header-color: var(--dw-text-strong);
|
|
177
|
+
--p-accordion-header-hover-color: var(--dw-text-strong);
|
|
178
|
+
--p-accordion-header-active-color: var(--dw-text-strong);
|
|
179
|
+
--p-accordion-header-active-hover-color: var(--dw-text-strong);
|
|
180
|
+
--p-accordion-header-background: transparent;
|
|
181
|
+
--p-accordion-header-hover-background: var(--dw-surface-hover);
|
|
182
|
+
--p-accordion-header-active-background: transparent;
|
|
183
|
+
--p-accordion-header-active-hover-background: var(--dw-surface-hover);
|
|
184
|
+
--p-accordion-header-border-width: 0;
|
|
185
|
+
--p-accordion-header-border-color: var(--dw-border);
|
|
186
|
+
--p-accordion-header-border-radius: 0;
|
|
187
|
+
--p-accordion-header-first-border-width: 0;
|
|
188
|
+
--p-accordion-header-first-top-border-radius: 0;
|
|
189
|
+
--p-accordion-header-last-bottom-border-radius: 0;
|
|
190
|
+
--p-accordion-header-last-active-bottom-border-radius: 0;
|
|
191
|
+
--p-accordion-header-focus-ring-width: 0;
|
|
192
|
+
--p-accordion-header-focus-ring-shadow: inset var(--dw-focus-ring);
|
|
193
|
+
--p-accordion-content-background: transparent;
|
|
194
|
+
--p-accordion-content-color: var(--dw-text);
|
|
195
|
+
--p-accordion-content-padding: 0 var(--dw-space-4) var(--dw-space-4);
|
|
205
196
|
}
|
|
206
|
-
|
|
207
|
-
.dw-
|
|
208
|
-
|
|
209
|
-
.dw-msg__role { color: var(--dw-text-secondary); font-size: var(--dw-font-size-12); }
|
|
210
|
-
.dw-msg__bubble {
|
|
211
|
-
padding: 10px 14px;
|
|
212
|
-
border: 1px solid var(--dw-border);
|
|
213
|
-
border-radius: var(--dw-radius-md) var(--dw-radius-md) var(--dw-radius-md) 2px;
|
|
214
|
-
background: var(--dw-surface-pressed);
|
|
215
|
-
color: var(--dw-text);
|
|
197
|
+
|
|
198
|
+
.dw-accordion .p-accordionheader {
|
|
199
|
+
gap: var(--dw-space-3);
|
|
216
200
|
font-size: var(--dw-font-size-14);
|
|
217
|
-
line-height:
|
|
218
|
-
white-space: pre-wrap;
|
|
219
|
-
overflow-wrap: anywhere;
|
|
201
|
+
line-height: 1.4;
|
|
220
202
|
}
|
|
221
|
-
|
|
222
|
-
.dw-
|
|
223
|
-
.dw-msg--agent .dw-msg__avatar { border-color: var(--dw-status-success-border); background: var(--dw-status-success-bg); color: var(--dw-status-success-fg); }
|
|
224
|
-
|
|
225
|
-
/* ── Chat composer: a borderless textarea + toolbar inside one card ──
|
|
226
|
-
<div class="dw-composer"><textarea class="dw-composer__input" …></textarea>
|
|
227
|
-
<div class="dw-composer__toolbar"><dw-button …/><span class="dw-composer__spacer"></span>
|
|
228
|
-
<span class="dw-composer__hint">⌘ Enter</span><dw-button label="Send" …/></div></div> */
|
|
229
|
-
.dw-composer {
|
|
203
|
+
|
|
204
|
+
.dw-accordion__header {
|
|
230
205
|
display: flex;
|
|
231
|
-
flex
|
|
206
|
+
flex: 1 1 auto;
|
|
207
|
+
align-items: center;
|
|
232
208
|
gap: var(--dw-space-2);
|
|
233
|
-
|
|
209
|
+
min-width: 0;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.dw-accordion__title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
213
|
+
|
|
214
|
+
.dw-accordion__chevron {
|
|
215
|
+
flex: none;
|
|
216
|
+
font-size: var(--dw-font-size-12);
|
|
217
|
+
color: var(--dw-text-secondary);
|
|
218
|
+
transition: transform var(--dw-dur-enter) var(--dw-ease);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.dw-accordion .p-accordionpanel-active > .p-accordionheader .dw-accordion__chevron { transform: rotate(180deg); }
|
|
222
|
+
.dw-accordion .p-accordionpanel.p-disabled > .p-accordionheader { cursor: default; }
|
|
223
|
+
|
|
224
|
+
/* flush: a divider between panels */
|
|
225
|
+
.dw-accordion--flush .p-accordionpanel + .p-accordionpanel { --p-accordion-panel-border-width: 1px 0 0; }
|
|
226
|
+
|
|
227
|
+
/* card: each panel its own card; a closed one lifts on hover, an open one divides its header from its content */
|
|
228
|
+
.dw-accordion--card {
|
|
229
|
+
--p-accordion-header-hover-background: transparent;
|
|
230
|
+
--p-accordion-header-active-hover-background: transparent;
|
|
231
|
+
--p-accordion-header-border-radius: calc(var(--dw-radius-card) - 1px);
|
|
232
|
+
--p-accordion-header-first-top-border-radius: calc(var(--dw-radius-card) - 1px);
|
|
233
|
+
--p-accordion-header-last-bottom-border-radius: calc(var(--dw-radius-card) - 1px);
|
|
234
|
+
--p-accordion-content-padding: var(--dw-space-4);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.dw-accordion--card > .p-accordion { display: flex; flex-direction: column; gap: var(--dw-space-2); }
|
|
238
|
+
|
|
239
|
+
.dw-accordion--card .p-accordionpanel {
|
|
234
240
|
border: 1px solid var(--dw-border);
|
|
235
|
-
border-radius: var(--dw-radius-
|
|
241
|
+
border-radius: var(--dw-radius-card);
|
|
236
242
|
background: var(--dw-surface);
|
|
237
|
-
box-shadow
|
|
238
|
-
transition: border-color var(--dw-dur-micro) var(--dw-ease), box-shadow var(--dw-dur-micro) var(--dw-ease);
|
|
243
|
+
transition: box-shadow var(--dw-dur-enter) var(--dw-ease);
|
|
239
244
|
}
|
|
240
|
-
|
|
241
|
-
.dw-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
border: 0;
|
|
247
|
-
|
|
248
|
-
resize: none;
|
|
249
|
-
background: transparent;
|
|
250
|
-
color: var(--dw-text);
|
|
251
|
-
font-size: var(--dw-font-size-14);
|
|
252
|
-
line-height: var(--dw-line-height-20);
|
|
245
|
+
|
|
246
|
+
.dw-accordion--card .p-accordionpanel:not(.p-accordionpanel-active):not(.p-disabled):hover { box-shadow: var(--dw-shadow-md); }
|
|
247
|
+
|
|
248
|
+
.dw-accordion--card .p-accordionpanel-active {
|
|
249
|
+
--p-accordion-header-border-width: 0 0 1px;
|
|
250
|
+
--p-accordion-header-first-border-width: 0 0 1px;
|
|
251
|
+
--p-accordion-header-border-radius: calc(var(--dw-radius-card) - 1px) calc(var(--dw-radius-card) - 1px) 0 0;
|
|
252
|
+
--p-accordion-header-last-active-bottom-border-radius: 0;
|
|
253
253
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
.dw-
|
|
257
|
-
.dw-
|
|
258
|
-
color: var(--dw-text-muted);
|
|
259
|
-
font-size: var(--dw-font-size-12);
|
|
254
|
+
|
|
255
|
+
@media (prefers-reduced-motion: reduce) {
|
|
256
|
+
.dw-accordion__chevron,
|
|
257
|
+
.dw-accordion--card .p-accordionpanel { transition: none; }
|
|
260
258
|
}
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
overflow-wrap: anywhere;
|
|
80
80
|
word-break: break-word;
|
|
81
81
|
}
|
|
82
|
-
/* Dense detail panels
|
|
82
|
+
/* Dense detail panels: 13px values; key column and spacing unchanged. */
|
|
83
83
|
.dw-kv-list--sm .dw-kv-list__value { font-size: var(--dw-font-size-13); }
|
|
84
84
|
.dw-kv-list__action { flex-shrink: 0; opacity: 0; transition: opacity var(--dw-dur-micro) var(--dw-ease); }
|
|
85
85
|
.dw-kv-list__row:hover .dw-kv-list__action,
|
|
@@ -138,6 +138,29 @@ body .p-treetable .p-treetable-tbody > tr.p-treetable-row-selected {
|
|
|
138
138
|
border-left: 1px solid var(--dw-tree-spine);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
/* dw-tree: no box of its own (it sits on its container); --framed draws one. Node content fills the row, so a
|
|
142
|
+
dwTreeNode template can lay out across it. */
|
|
143
|
+
.dw-tree-view { display: block; min-width: 0; }
|
|
144
|
+
.dw-tree-view > .p-tree { padding: 0; border: 0; border-radius: 0; background: transparent; }
|
|
145
|
+
.dw-tree-view.dw-tree-view--framed > .p-tree {
|
|
146
|
+
padding: var(--dw-space-2);
|
|
147
|
+
border: 1px solid var(--dw-border-strong);
|
|
148
|
+
border-radius: var(--dw-radius-control);
|
|
149
|
+
background: var(--dw-surface);
|
|
150
|
+
}
|
|
151
|
+
.dw-tree-view .p-tree-node-label { flex: 1 1 auto; min-width: 0; }
|
|
152
|
+
/* --sm: compact rows, through PrimeNG's own tree variables (row ~28px instead of ~36px). */
|
|
153
|
+
.dw-tree-view.dw-tree-view--sm {
|
|
154
|
+
--p-tree-node-padding: var(--dw-space-1) var(--dw-space-2);
|
|
155
|
+
--p-tree-node-gap: var(--dw-space-1);
|
|
156
|
+
--p-tree-node-toggle-button-size: var(--dw-space-5);
|
|
157
|
+
--p-tree-gap: 0;
|
|
158
|
+
font-size: var(--dw-font-size-13);
|
|
159
|
+
}
|
|
160
|
+
/* --marker: the selected row's accent bar, as dw-nav-list [marker] (an inset shadow, so nothing shifts). Specific
|
|
161
|
+
enough to outlast PrimeNG's focus styles, which it loads after crystal. */
|
|
162
|
+
.dw-tree-view.dw-tree-view--marker .p-tree-node-content.p-tree-node-selected { box-shadow: inset 3px 0 0 var(--dw-accent); }
|
|
163
|
+
|
|
141
164
|
/* ── Skeleton ── */
|
|
142
165
|
.dw-skeleton {
|
|
143
166
|
height: 20px;
|
|
@@ -225,14 +225,15 @@ dw-field.dw-field--inline:has(.dw-field__control :is(.p-inputtext-sm, .p-textare
|
|
|
225
225
|
.dw-field__control > :first-child:not([dwFieldSuffix]) { flex: 1 1 auto; min-width: 0; }
|
|
226
226
|
/* Switches, checkboxes and radios keep their own size — stretching one turns a toggle into a bar. */
|
|
227
227
|
/* (Same specificity as the stretch rule above, plus the element, so it wins.) */
|
|
228
|
-
.dw-field__control > :is(p-toggleswitch, p-checkbox, p-radiobutton):first-child:not([dwFieldSuffix]) { flex: none; }
|
|
228
|
+
.dw-field__control > :is(p-toggleswitch, p-checkbox, p-radiobutton, dw-switch, dw-checkbox, dw-radio):first-child:not([dwFieldSuffix]) { flex: none; }
|
|
229
229
|
.dw-field__control > input,
|
|
230
230
|
.dw-field__control > textarea,
|
|
231
231
|
.dw-field__control > p-select,
|
|
232
232
|
.dw-field__control > p-multiselect,
|
|
233
233
|
.dw-field__control > p-inputnumber,
|
|
234
234
|
.dw-field__control > p-datepicker,
|
|
235
|
-
.dw-field__control > p-autocomplete
|
|
235
|
+
.dw-field__control > p-autocomplete,
|
|
236
|
+
.dw-field__control > :is(dw-select, dw-multiselect, dw-number-input, dw-date-picker, dw-autocomplete, dw-slider) { width: 100%; }
|
|
236
237
|
.dw-field__error { display: inline-flex; align-items: center; gap: var(--dw-space-1); }
|
|
237
238
|
/* Field errors are text only (the red text and border carry the state): no leading icon, even in
|
|
238
239
|
hand-written error lines. */
|
|
@@ -391,12 +392,6 @@ dw-search-input.dw-search--block { width: 100%; }
|
|
|
391
392
|
display: none;
|
|
392
393
|
}
|
|
393
394
|
|
|
394
|
-
/* PrimeNG's slider host is inline; give it the field's width. */
|
|
395
|
-
p-slider {
|
|
396
|
-
display: block;
|
|
397
|
-
width: 100%;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
395
|
/* pSize="small" inputs: base.css's `font: inherit` would keep them at 14px, so restate the
|
|
401
396
|
small type here — 5px padding + 16px line + 1px borders = 28px, the small dw-button height. */
|
|
402
397
|
/* Small selects match small inputs exactly (28px): their label gets the same 16px line
|
|
@@ -470,12 +465,14 @@ p-slider {
|
|
|
470
465
|
|
|
471
466
|
|
|
472
467
|
/* Small selects (size="small"): their option list matches the 12px trigger instead of the default
|
|
473
|
-
14px rows.
|
|
474
|
-
|
|
468
|
+
14px rows. A list rendered inside the select matches `.p-select-sm`; a list appended elsewhere
|
|
469
|
+
(appendTo="body") gets `dw-select-panel--sm` from provideCrystalPrimeNG()'s pass-through, so no
|
|
470
|
+
screen sets it by hand. */
|
|
475
471
|
.p-select-sm .p-select-option,
|
|
476
472
|
.p-multiselect-sm .p-multiselect-option,
|
|
477
473
|
.dw-select-panel--sm .p-select-option,
|
|
478
|
-
.dw-select-panel--sm .p-multiselect-option
|
|
474
|
+
.dw-select-panel--sm .p-multiselect-option,
|
|
475
|
+
.dw-autocomplete-panel--sm .p-autocomplete-option {
|
|
479
476
|
padding: 5px 10px;
|
|
480
477
|
font-size: var(--dw-font-size-12);
|
|
481
478
|
line-height: var(--dw-line-height-16);
|
|
@@ -483,7 +480,8 @@ p-slider {
|
|
|
483
480
|
.p-select-sm .p-select-empty-message,
|
|
484
481
|
.p-multiselect-sm .p-multiselect-empty-message,
|
|
485
482
|
.dw-select-panel--sm .p-select-empty-message,
|
|
486
|
-
.dw-select-panel--sm .p-multiselect-empty-message
|
|
483
|
+
.dw-select-panel--sm .p-multiselect-empty-message,
|
|
484
|
+
.dw-autocomplete-panel--sm .p-autocomplete-empty-message {
|
|
487
485
|
padding: 5px 10px;
|
|
488
486
|
font-size: var(--dw-font-size-12);
|
|
489
487
|
}
|
|
@@ -635,7 +633,7 @@ body .dw-var-field .p-textarea {
|
|
|
635
633
|
.dw-check-toggle.is-on .dw-check-toggle__label { color: var(--dw-text-strong); font-weight: var(--dw-font-weight-medium); }
|
|
636
634
|
|
|
637
635
|
/* Compact calendar (inline in popovers): smaller day cells and type, quieter weekday row and a
|
|
638
|
-
tighter time picker. <
|
|
636
|
+
tighter time picker. <dw-date-picker [compact]="true" [inline]="true" />.
|
|
639
637
|
Two classes per rule so they outrank PrimeNG's own (unlayered) datepicker styles. */
|
|
640
638
|
.dw-datepicker--compact .p-datepicker-header { padding: 0 0 var(--dw-space-2); }
|
|
641
639
|
.dw-datepicker--compact .p-datepicker-title,
|
|
@@ -675,3 +673,108 @@ body .dw-var-field .p-textarea {
|
|
|
675
673
|
.config-form-body .toggle-label { margin: 0; cursor: pointer; }
|
|
676
674
|
/* Host of a config form component inside .config-drawer-body: fill the drawer height. */
|
|
677
675
|
.config-form-host { display: flex; flex: 1; flex-direction: column; min-height: 0; }
|
|
676
|
+
|
|
677
|
+
/* ── dw-select / dw-multiselect (components) ──
|
|
678
|
+
The host takes the screen's sizing (a width, `dw-w-full`, a grid track) and the PrimeNG control fills it; with no
|
|
679
|
+
width set, the host is as wide as the control would be on its own. */
|
|
680
|
+
.dw-select,
|
|
681
|
+
.dw-multiselect {
|
|
682
|
+
display: inline-flex;
|
|
683
|
+
min-width: 0;
|
|
684
|
+
max-width: 100%;
|
|
685
|
+
vertical-align: middle;
|
|
686
|
+
}
|
|
687
|
+
.dw-select > p-select,
|
|
688
|
+
.dw-multiselect > p-multiselect {
|
|
689
|
+
flex: 1 1 auto;
|
|
690
|
+
min-width: 0;
|
|
691
|
+
}
|
|
692
|
+
.dw-select.dw-select--fluid,
|
|
693
|
+
.dw-multiselect.dw-multiselect--fluid {
|
|
694
|
+
display: flex;
|
|
695
|
+
width: 100%;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/* ── dw-checkbox / dw-radio / dw-switch (components): the control and its label on one line (dw-check) ── */
|
|
699
|
+
.dw-checkbox__label--empty:empty,
|
|
700
|
+
.dw-radio__label--empty:empty { display: none; }
|
|
701
|
+
|
|
702
|
+
/* ── dw-number-input (component): sized by the screen like dw-select ── */
|
|
703
|
+
.dw-number-input { display: inline-flex; min-width: 0; max-width: 100%; vertical-align: middle; }
|
|
704
|
+
.dw-number-input > p-inputnumber { flex: 1 1 auto; min-width: 0; }
|
|
705
|
+
.dw-number-input.dw-number-input--fluid { display: flex; width: 100%; }
|
|
706
|
+
|
|
707
|
+
/* ── dw-date-picker (component): sized by the screen like dw-select; the inline calendar keeps its own width unless fluid ── */
|
|
708
|
+
.dw-date-picker { display: inline-flex; min-width: 0; max-width: 100%; vertical-align: middle; }
|
|
709
|
+
.dw-date-picker > p-datepicker { flex: 1 1 auto; min-width: 0; }
|
|
710
|
+
.dw-date-picker.dw-date-picker--fluid { display: flex; width: 100%; }
|
|
711
|
+
.dw-date-picker.dw-date-picker--inline > p-datepicker { flex: none; }
|
|
712
|
+
.dw-date-picker.dw-date-picker--inline.dw-date-picker--fluid > p-datepicker { flex: 1 1 auto; }
|
|
713
|
+
/* flush: the inline calendar loses its own box and sits on its container's surface (a popover or a panel pads it). */
|
|
714
|
+
.dw-date-picker.dw-date-picker--flush .p-datepicker-panel-inline {
|
|
715
|
+
padding: 0;
|
|
716
|
+
border: 0;
|
|
717
|
+
border-radius: 0;
|
|
718
|
+
background: transparent;
|
|
719
|
+
box-shadow: none;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/* ── dw-autocomplete (component): sized by the screen like dw-select; the text input fills it ──
|
|
723
|
+
(The extra elements outweigh PrimeNG's `width: 1%` on the input beside a dropdown button, whose styles load after ours.) */
|
|
724
|
+
.dw-autocomplete { display: inline-flex; min-width: 0; max-width: 100%; vertical-align: middle; }
|
|
725
|
+
.dw-autocomplete > p-autocomplete { display: flex; flex: 1 1 auto; min-width: 0; }
|
|
726
|
+
.dw-autocomplete > p-autocomplete.p-autocomplete > input.p-autocomplete-input { flex: 1 1 auto; width: auto; min-width: 0; }
|
|
727
|
+
.dw-autocomplete.dw-autocomplete--fluid { display: flex; width: 100%; }
|
|
728
|
+
/* Its list (appended to <body>, so styled by its panel classes): rows in the 14px body type, unless small. */
|
|
729
|
+
body .dw-autocomplete-panel:not(.dw-autocomplete-panel--sm) :is(.p-autocomplete-option, .p-autocomplete-empty-message) {
|
|
730
|
+
font-size: var(--dw-font-size-14);
|
|
731
|
+
}
|
|
732
|
+
/* panelWidth="field": exactly as wide as the field, as select lists are (see above): PrimeNG puts the field's width in
|
|
733
|
+
the overlay's inline min-width, a zero width lets it win, and long suggestions ellipsise. */
|
|
734
|
+
.p-overlay:has(> .p-overlay-content > .dw-autocomplete-panel--field) { width: 0; }
|
|
735
|
+
.dw-autocomplete-panel--field .p-autocomplete-option > * {
|
|
736
|
+
min-width: 0;
|
|
737
|
+
overflow: hidden;
|
|
738
|
+
text-overflow: ellipsis;
|
|
739
|
+
}
|
|
740
|
+
/* size="sm" gives it the small select rows (`.dw-autocomplete-panel--sm`, with the small select lists above). */
|
|
741
|
+
|
|
742
|
+
/* ── dw-slider (component): fills its container, in crystal's tokens ──
|
|
743
|
+
A 4px track in the meter's colours (dw-meter) and a 16px accent handle with a surface centre; the padding keeps the
|
|
744
|
+
handle clear of what sits above and below. PrimeNG draws it from these variables. */
|
|
745
|
+
.dw-slider {
|
|
746
|
+
--p-slider-track-size: 4px;
|
|
747
|
+
--p-slider-track-background: var(--dw-surface-pressed);
|
|
748
|
+
--p-slider-track-border-radius: var(--dw-radius-full);
|
|
749
|
+
--p-slider-range-background: var(--dw-accent);
|
|
750
|
+
--p-slider-handle-width: 16px;
|
|
751
|
+
--p-slider-handle-height: 16px;
|
|
752
|
+
--p-slider-handle-border-radius: var(--dw-radius-full);
|
|
753
|
+
--p-slider-handle-background: var(--dw-accent);
|
|
754
|
+
--p-slider-handle-hover-background: var(--dw-accent-hover);
|
|
755
|
+
--p-slider-handle-content-width: 8px;
|
|
756
|
+
--p-slider-handle-content-height: 8px;
|
|
757
|
+
--p-slider-handle-content-border-radius: var(--dw-radius-full);
|
|
758
|
+
--p-slider-handle-content-background: var(--dw-surface);
|
|
759
|
+
--p-slider-handle-content-hover-background: var(--dw-surface);
|
|
760
|
+
--p-slider-handle-content-shadow: none;
|
|
761
|
+
--p-slider-handle-focus-ring-width: 0;
|
|
762
|
+
--p-slider-handle-focus-ring-shadow: var(--dw-focus-ring);
|
|
763
|
+
|
|
764
|
+
display: block;
|
|
765
|
+
width: 100%;
|
|
766
|
+
padding-block: var(--dw-space-2);
|
|
767
|
+
}
|
|
768
|
+
/* PrimeNG shows a grab cursor on the handle; show it grabbing while held. */
|
|
769
|
+
.dw-slider .p-slider-handle:active { cursor: grabbing; }
|
|
770
|
+
.dw-slider.dw-slider--invalid {
|
|
771
|
+
--p-slider-range-background: var(--dw-danger-solid);
|
|
772
|
+
--p-slider-handle-background: var(--dw-danger-solid);
|
|
773
|
+
--p-slider-handle-hover-background: var(--dw-danger-solid);
|
|
774
|
+
--p-slider-handle-focus-ring-shadow: var(--dw-focus-ring-danger);
|
|
775
|
+
}
|
|
776
|
+
.dw-slider.dw-slider--vertical { display: inline-block; width: auto; height: 100%; padding-block: 0; padding-inline: var(--dw-space-2); }
|
|
777
|
+
.dw-slider.dw-slider--vertical > p-slider { height: 100%; }
|
|
778
|
+
/* p-slider used directly (until its screens move to dw-slider): a block as wide as its field. */
|
|
779
|
+
p-slider { display: block; width: 100%; }
|
|
780
|
+
.dw-slider--vertical > p-slider { width: var(--p-slider-track-size); }
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
/* Selected marker: an accent left border that follows the item's rounded corners. Only the agents
|
|
218
|
-
list page's sidebar has it (dw-nav-list [marker], and its tags tree: dw-
|
|
218
|
+
list page's sidebar has it (dw-nav-list [marker], and its tags tree: dw-tree [marker]); every
|
|
219
219
|
other selection is the plain selected fill. An inset shadow, not a border, so the item's content
|
|
220
220
|
does not shift when it is selected. */
|
|
221
221
|
.dw-nav-list--marker .dw-nav-item.is-active,
|
|
@@ -547,6 +547,36 @@ dw-nav-list.dw-nav-list--minimizable { overflow: hidden; padding-bottom: 0; }
|
|
|
547
547
|
.dw-steps__item.is-done .dw-steps__no { border-color: var(--dw-accent); background: var(--dw-accent); color: var(--dw-text-inverse); }
|
|
548
548
|
.dw-steps__sep { flex: 0 0 48px; height: 1px; background: var(--dw-border-strong); }
|
|
549
549
|
|
|
550
|
+
/* ── dw-stepper: the component over .dw-steps. Each step is a button; a done step goes back,
|
|
551
|
+
an upcoming step of a linear stepper is disabled but drawn as upcoming (not faded).
|
|
552
|
+
--inline drops the sub-header strip (a wizard header); --md is the wizard size, --sm the strip above. ── */
|
|
553
|
+
.dw-stepper { display: block; min-width: 0; }
|
|
554
|
+
.dw-steps--inline { padding: 0; border-bottom: 0; }
|
|
555
|
+
.dw-steps__btn {
|
|
556
|
+
display: inline-flex;
|
|
557
|
+
align-items: center;
|
|
558
|
+
gap: var(--dw-space-2);
|
|
559
|
+
margin: calc(-1 * var(--dw-space-1));
|
|
560
|
+
padding: var(--dw-space-1);
|
|
561
|
+
border: 0;
|
|
562
|
+
border-radius: var(--dw-radius-md);
|
|
563
|
+
background: transparent;
|
|
564
|
+
color: inherit;
|
|
565
|
+
font-weight: inherit;
|
|
566
|
+
white-space: nowrap;
|
|
567
|
+
transition: color var(--dw-dur-micro) var(--dw-ease);
|
|
568
|
+
}
|
|
569
|
+
.dw-steps__btn:disabled,
|
|
570
|
+
.dw-steps__btn[aria-current='step'] { cursor: default; }
|
|
571
|
+
.dw-steps__btn:not(:disabled, [aria-current='step']):hover { color: var(--dw-text-link); }
|
|
572
|
+
.dw-steps__btn:focus-visible { outline: none; box-shadow: var(--dw-focus-ring); }
|
|
573
|
+
.dw-steps__no { flex: none; transition: background-color var(--dw-dur-micro) var(--dw-ease), border-color var(--dw-dur-micro) var(--dw-ease); }
|
|
574
|
+
.dw-steps__item.is-disabled { opacity: 0.5; }
|
|
575
|
+
.dw-steps__item.is-disabled .dw-steps__btn { cursor: not-allowed; }
|
|
576
|
+
.dw-steps__sep.is-done { background: var(--dw-accent); }
|
|
577
|
+
.dw-steps--md .dw-steps__no { width: 32px; height: 32px; border-width: 2px; font-size: var(--dw-font-size-14); }
|
|
578
|
+
.dw-steps--md .dw-steps__sep { height: 2px; }
|
|
579
|
+
|
|
550
580
|
/* ── dw-rail-tabs: vertical icon-over-label tab strip at a panel edge ── */
|
|
551
581
|
.dw-rail-tabs { display: flex; flex-shrink: 0; width: 64px; }
|
|
552
582
|
.dw-rail-tabs__nav {
|
|
@@ -339,9 +339,24 @@ body .p-drawer-right {
|
|
|
339
339
|
}
|
|
340
340
|
.p-tooltip.dw-tooltip--multiline .p-tooltip-text { white-space: pre-line; }
|
|
341
341
|
.p-tooltip.dw-tooltip--error .p-tooltip-text { background: var(--dw-status-danger-fg); color: var(--dw-text-inverse); }
|
|
342
|
+
/* Preview (dwTooltipVariant="preview"): a long value shown whole, up to 720 × 340px, then scrolled; line breaks kept,
|
|
343
|
+
long tokens broken anywhere. Pair it with dwTooltipInteractive so the pointer can scroll it. */
|
|
344
|
+
.p-tooltip.dw-tooltip--preview { width: auto; max-width: min(720px, 68vw); }
|
|
345
|
+
.p-tooltip.dw-tooltip--preview .p-tooltip-text {
|
|
346
|
+
display: inline-block;
|
|
347
|
+
box-sizing: border-box;
|
|
348
|
+
width: max-content;
|
|
349
|
+
max-width: min(720px, 68vw);
|
|
350
|
+
max-height: min(42vh, 340px);
|
|
351
|
+
overflow: auto;
|
|
352
|
+
white-space: pre-wrap;
|
|
353
|
+
overflow-wrap: anywhere;
|
|
354
|
+
font-size: var(--dw-font-size-12);
|
|
355
|
+
line-height: 1.45;
|
|
356
|
+
}
|
|
342
357
|
.p-tooltip.dw-tooltip--error .p-tooltip-arrow { border-top-color: var(--dw-status-danger-fg); }
|
|
343
358
|
/* Long code / JSON: wide, scrollable, monospace, wrapped. */
|
|
344
|
-
.p-tooltip.dw-tooltip--code { width: min(520px, calc(100vw - 48px)); max-width: min(520px, calc(100vw - 48px));
|
|
359
|
+
.p-tooltip.dw-tooltip--code { width: min(520px, calc(100vw - 48px)); max-width: min(520px, calc(100vw - 48px)); }
|
|
345
360
|
.p-tooltip.dw-tooltip--code .p-tooltip-text {
|
|
346
361
|
display: block;
|
|
347
362
|
width: 100%;
|