@visns-studio/visns-components 6.32.0 → 6.32.1
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/README.md
CHANGED
|
@@ -9,6 +9,19 @@ A comprehensive React component library used by the VISNS Studio team for CRM an
|
|
|
9
9
|
|
|
10
10
|
VISNS Components is a React-based UI component library that provides a set of reusable, consistent, and customizable components for building web applications. It includes components for authentication, data grids, forms, navigation, and more, designed to work seamlessly together.
|
|
11
11
|
|
|
12
|
+
## Recent Updates (v6.32.1)
|
|
13
|
+
|
|
14
|
+
### Boxed overview: one card per section, no note accent
|
|
15
|
+
|
|
16
|
+
Follow-up to 6.32.0's opt-in boxed overview. The tinted heading bar alone did
|
|
17
|
+
not separate sections once every field was a box, so in boxed mode each
|
|
18
|
+
section is now its own bordered card with its heading as the card's header
|
|
19
|
+
strip — Transport and PPE Requirement read as two things rather than one long
|
|
20
|
+
run of boxes. Note-shaped fields (Description, Comments) are ordinary fields
|
|
21
|
+
here too: the same neutral border as every other box, with no accent colour.
|
|
22
|
+
Plain mode renders byte-identical markup; nothing changes for apps that did
|
|
23
|
+
not opt in.
|
|
24
|
+
|
|
12
25
|
## Recent Updates (v6.32.0)
|
|
13
26
|
|
|
14
27
|
### The pre-6.15 boxed overview is back, as an opt-in
|
package/package.json
CHANGED
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
94
94
|
},
|
|
95
95
|
"name": "@visns-studio/visns-components",
|
|
96
|
-
"version": "6.32.
|
|
96
|
+
"version": "6.32.1",
|
|
97
97
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
98
98
|
"main": "src/index.js",
|
|
99
99
|
"files": [
|
|
@@ -300,6 +300,22 @@ function GenericDetail({
|
|
|
300
300
|
const overviewStyle = resolveOverviewStyle(page?.overviewStyle);
|
|
301
301
|
const overviewIsBoxed = overviewStyle === 'boxed';
|
|
302
302
|
|
|
303
|
+
/**
|
|
304
|
+
* How one overview section is wrapped.
|
|
305
|
+
*
|
|
306
|
+
* Boxed mode draws every section as its own card, so it needs a real
|
|
307
|
+
* element around the heading and the field list. Plain mode must NOT gain
|
|
308
|
+
* one: its rules are written as `.gridtxt > ul.customer__overview`, and a
|
|
309
|
+
* wrapper would stop the list being a direct child — so it keeps the
|
|
310
|
+
* `React.Fragment` it has always used and its markup is unchanged. A
|
|
311
|
+
* Fragment accepts `key` but nothing else, hence the separate props
|
|
312
|
+
* object rather than a className passed unconditionally.
|
|
313
|
+
*/
|
|
314
|
+
const SectionWrap = overviewIsBoxed ? 'section' : React.Fragment;
|
|
315
|
+
const sectionWrapProps = overviewIsBoxed
|
|
316
|
+
? { className: styles.gridtxt__section }
|
|
317
|
+
: {};
|
|
318
|
+
|
|
303
319
|
/** Fileupload states */
|
|
304
320
|
const [files, setFiles] = useState([]);
|
|
305
321
|
|
|
@@ -2940,8 +2956,9 @@ function GenericDetail({
|
|
|
2940
2956
|
>
|
|
2941
2957
|
{activeTabConfig.sections.map(
|
|
2942
2958
|
(section, sectionIndex) => (
|
|
2943
|
-
<
|
|
2959
|
+
<SectionWrap
|
|
2944
2960
|
key={`section-${activeTabConfig.id}-${sectionIndex}`}
|
|
2961
|
+
{...sectionWrapProps}
|
|
2945
2962
|
>
|
|
2946
2963
|
<div
|
|
2947
2964
|
className={
|
|
@@ -3154,7 +3171,7 @@ function GenericDetail({
|
|
|
3154
3171
|
)}
|
|
3155
3172
|
</ul>
|
|
3156
3173
|
)}
|
|
3157
|
-
</
|
|
3174
|
+
</SectionWrap>
|
|
3158
3175
|
)
|
|
3159
3176
|
)}
|
|
3160
3177
|
</div>
|
|
@@ -485,6 +485,28 @@
|
|
|
485
485
|
`page.overviewStyle`), GenericDetail adds `.gridtxt--boxed`, and these
|
|
486
486
|
rules put the 5.26 geometry back.
|
|
487
487
|
|
|
488
|
+
Each section is also its own card here, wrapped in `.gridtxt__section`.
|
|
489
|
+
The tinted heading bar on its own was enough to separate sections while the
|
|
490
|
+
fields below it were plain stacked pairs, but once every field is a tinted,
|
|
491
|
+
bordered box the bar reads as one more box in the run: bar, boxes, bar,
|
|
492
|
+
boxes, all inside a single panel, with nothing saying where Transport ends
|
|
493
|
+
and PPE Requirement begins. So the section gets a bordered card and the
|
|
494
|
+
heading becomes that card's header strip — square, full-bleed, hairline
|
|
495
|
+
underneath. Plain mode keeps emitting the header and the `<ul>` as direct
|
|
496
|
+
children of `.gridtxt` (the rules above depend on it), so every selector
|
|
497
|
+
below reaches through `> .gridtxt__section >` and only boxed markup has
|
|
498
|
+
one.
|
|
499
|
+
|
|
500
|
+
One thing from 5.26 is deliberately NOT restored: the red accent on a
|
|
501
|
+
`.notecolor` field. Description and Comments are ordinary fields here too,
|
|
502
|
+
and the brand red read as an error on a page with nothing wrong — the same
|
|
503
|
+
reasoning that removed it from the plain overview. There is no boxed
|
|
504
|
+
`.notecolor` rule below because there does not need to be: the generic
|
|
505
|
+
boxed `li` rule is `.gridtxt.gridtxt--boxed > .gridtxt__section >
|
|
506
|
+
ul.customer__overview li` (0,4,2) and the plain accent it has to beat is
|
|
507
|
+
`.gridtxt > ul .notecolor` (0,2,1), so a note field simply takes the same
|
|
508
|
+
neutral border and tint as every other box.
|
|
509
|
+
|
|
488
510
|
Specificity is doing real work here. The rules being undone are
|
|
489
511
|
`.gridtxt > ul.customer__overview li` above AND the bare `.overviewLabel` /
|
|
490
512
|
`.gridtxt__header` in the 2026 pass at the bottom of the file, which win on
|
|
@@ -496,11 +518,37 @@
|
|
|
496
518
|
this file: a bare var() for a token the host has not declared is invalid at
|
|
497
519
|
computed-value time and the declaration is simply dropped. */
|
|
498
520
|
|
|
499
|
-
/* The
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
521
|
+
/* The panel's own inset is dialled back once the sections are cards: the tab
|
|
522
|
+
card already pads, and `.gridtxt`'s 1rem/1.5rem on top of a card border on
|
|
523
|
+
top of the `<ul>`'s 0.85rem stacked three insets between the panel edge and
|
|
524
|
+
the first field. Small but not zero — the cards still need to sit off the
|
|
525
|
+
panel border. */
|
|
526
|
+
.gridtxt.gridtxt--boxed {
|
|
527
|
+
padding: var(--spacing-sm, 0.5rem);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/* One section, one card. `overflow: hidden` is what lets the square heading
|
|
531
|
+
strip below sit flush inside the rounded corners. */
|
|
532
|
+
.gridtxt.gridtxt--boxed > .gridtxt__section {
|
|
533
|
+
display: block;
|
|
534
|
+
box-sizing: border-box;
|
|
535
|
+
background: var(--surface-color, #fff);
|
|
536
|
+
border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.12);
|
|
537
|
+
border-radius: var(--br, 5px);
|
|
538
|
+
overflow: hidden;
|
|
539
|
+
margin: 0 0 var(--spacing-md, 1rem);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
.gridtxt.gridtxt--boxed > .gridtxt__section:last-child {
|
|
543
|
+
margin-bottom: 0;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/* The heading, back to a centred tinted bar — and now the card's header
|
|
547
|
+
strip, so it runs the full width with square corners and a hairline under
|
|
548
|
+
it. `display: flex` is kept so a section's optional `.gridtxt__meta` still
|
|
549
|
+
renders; it is centred with the title rather than pushed to the far edge,
|
|
550
|
+
since there is no edge to push to once the bar is tinted. */
|
|
551
|
+
.gridtxt.gridtxt--boxed > .gridtxt__section > .gridtxt__header {
|
|
504
552
|
width: 100%;
|
|
505
553
|
display: flex;
|
|
506
554
|
align-items: baseline;
|
|
@@ -509,8 +557,8 @@
|
|
|
509
557
|
flex-wrap: wrap;
|
|
510
558
|
box-sizing: border-box;
|
|
511
559
|
padding: 10px 20px;
|
|
512
|
-
border-bottom: 0;
|
|
513
|
-
border-radius:
|
|
560
|
+
border-bottom: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.08);
|
|
561
|
+
border-radius: 0;
|
|
514
562
|
margin-bottom: 0;
|
|
515
563
|
background: rgba(var(--primary-rgb, 27, 57, 51), 0.05);
|
|
516
564
|
font-size: var(--font-size-md, 0.9rem);
|
|
@@ -523,13 +571,13 @@
|
|
|
523
571
|
|
|
524
572
|
/* The meta sits beside the centred title, not opposite it, so it needs its own
|
|
525
573
|
small gap where the header's `space-between` used to provide one. */
|
|
526
|
-
.gridtxt.gridtxt--boxed > .gridtxt__header > .gridtxt__meta {
|
|
574
|
+
.gridtxt.gridtxt--boxed > .gridtxt__section > .gridtxt__header > .gridtxt__meta {
|
|
527
575
|
margin-left: var(--spacing-sm, 0.5rem);
|
|
528
576
|
}
|
|
529
577
|
|
|
530
578
|
/* A wrapping row of boxes, not a two-column grid: a full-width field can then
|
|
531
579
|
sit between two half-width ones without leaving a hole in a grid track. */
|
|
532
|
-
.gridtxt.gridtxt--boxed > ul.customer__overview {
|
|
580
|
+
.gridtxt.gridtxt--boxed > .gridtxt__section > ul.customer__overview {
|
|
533
581
|
width: 100%;
|
|
534
582
|
display: flex;
|
|
535
583
|
justify-content: flex-start;
|
|
@@ -544,7 +592,7 @@
|
|
|
544
592
|
|
|
545
593
|
/* The box itself. `display: block` is the whole point — the label and the
|
|
546
594
|
value are inline text in one paragraph, not two stacked rows. */
|
|
547
|
-
.gridtxt.gridtxt--boxed > ul.customer__overview li {
|
|
595
|
+
.gridtxt.gridtxt--boxed > .gridtxt__section > ul.customer__overview li {
|
|
548
596
|
width: auto;
|
|
549
597
|
flex: 0 0 calc(50% - 10px);
|
|
550
598
|
min-width: 0;
|
|
@@ -560,16 +608,11 @@
|
|
|
560
608
|
line-height: 1.45;
|
|
561
609
|
}
|
|
562
610
|
|
|
563
|
-
.gridtxt.gridtxt--boxed > ul.customer__overview .fw-grid-item {
|
|
611
|
+
.gridtxt.gridtxt--boxed > .gridtxt__section > ul.customer__overview .fw-grid-item {
|
|
564
612
|
flex: 0 0 calc(100% - 10px);
|
|
565
613
|
grid-column: auto;
|
|
566
614
|
}
|
|
567
615
|
|
|
568
|
-
/* The accent on a note-shaped field, as it was before 6.15. */
|
|
569
|
-
.gridtxt.gridtxt--boxed > ul.customer__overview .notecolor {
|
|
570
|
-
border: 1px solid var(--secondary-color, #b23c3c);
|
|
571
|
-
}
|
|
572
|
-
|
|
573
616
|
/* Run-in label: ordinary bold text with a colon after it, not the eyebrow the
|
|
574
617
|
stacked layout wears. */
|
|
575
618
|
.gridtxt--boxed .overviewLabel {
|
|
@@ -590,8 +633,8 @@
|
|
|
590
633
|
|
|
591
634
|
/* One column on a phone — half of a narrow screen is not a readable box. */
|
|
592
635
|
@media (max-width: 759px) {
|
|
593
|
-
.gridtxt.gridtxt--boxed > ul.customer__overview li,
|
|
594
|
-
.gridtxt.gridtxt--boxed > ul.customer__overview .fw-grid-item {
|
|
636
|
+
.gridtxt.gridtxt--boxed > .gridtxt__section > ul.customer__overview li,
|
|
637
|
+
.gridtxt.gridtxt--boxed > .gridtxt__section > ul.customer__overview .fw-grid-item {
|
|
595
638
|
flex: 0 0 calc(100% - 10px);
|
|
596
639
|
}
|
|
597
640
|
}
|