@visns-studio/visns-components 6.3.1 → 6.3.3
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.json +1 -1
- package/src/components/DataGrid.jsx +30 -37
- package/src/components/styles/DataGrid.module.scss +99 -0
- package/src/components/styles/Field.module.scss +31 -3
- package/src/components/styles/Form.module.scss +44 -4
- package/src/components/styles/GenericFormBuilder.module.scss +15 -2
package/package.json
CHANGED
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
92
92
|
},
|
|
93
93
|
"name": "@visns-studio/visns-components",
|
|
94
|
-
"version": "6.3.
|
|
94
|
+
"version": "6.3.3",
|
|
95
95
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
96
96
|
"main": "src/index.js",
|
|
97
97
|
"files": [
|
|
@@ -4630,44 +4630,37 @@ const DataGrid = forwardRef(
|
|
|
4630
4630
|
|
|
4631
4631
|
{/* Opt-in colour legend (config key `legend`: array of
|
|
4632
4632
|
{colour, label}); entries without a colour render as
|
|
4633
|
-
plain lead-in text
|
|
4633
|
+
plain lead-in text.
|
|
4634
|
+
|
|
4635
|
+
Styling lives in DataGrid.module.scss (`.legend` and
|
|
4636
|
+
friends) rather than inline, so a consuming project can
|
|
4637
|
+
actually reach it — see the notes there. The only inline
|
|
4638
|
+
style left is the swatch's own fill, which is data from
|
|
4639
|
+
the config rather than a design decision. */}
|
|
4634
4640
|
{Array.isArray(legend) && legend.length > 0 && (
|
|
4635
|
-
<div
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
width: '14px',
|
|
4659
|
-
height: '14px',
|
|
4660
|
-
borderRadius: '3px',
|
|
4661
|
-
backgroundColor:
|
|
4662
|
-
item.colour || item.color,
|
|
4663
|
-
display: 'inline-block',
|
|
4664
|
-
flexShrink: 0,
|
|
4665
|
-
}}
|
|
4666
|
-
/>
|
|
4667
|
-
)}
|
|
4668
|
-
{item.label}
|
|
4669
|
-
</span>
|
|
4670
|
-
))}
|
|
4641
|
+
<div className={styles.legend}>
|
|
4642
|
+
{legend.map((item, index) => {
|
|
4643
|
+
const swatch = item.colour || item.color;
|
|
4644
|
+
|
|
4645
|
+
return (
|
|
4646
|
+
<span
|
|
4647
|
+
key={index}
|
|
4648
|
+
className={
|
|
4649
|
+
swatch
|
|
4650
|
+
? styles.legendItem
|
|
4651
|
+
: `${styles.legendItem} ${styles.legendLead}`
|
|
4652
|
+
}
|
|
4653
|
+
>
|
|
4654
|
+
{swatch && (
|
|
4655
|
+
<span
|
|
4656
|
+
className={styles.legendSwatch}
|
|
4657
|
+
style={{ backgroundColor: swatch }}
|
|
4658
|
+
/>
|
|
4659
|
+
)}
|
|
4660
|
+
{item.label}
|
|
4661
|
+
</span>
|
|
4662
|
+
);
|
|
4663
|
+
})}
|
|
4671
4664
|
</div>
|
|
4672
4665
|
)}
|
|
4673
4666
|
|
|
@@ -205,8 +205,16 @@
|
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
+
/* The gallery modal's close control — this class is consumed by
|
|
209
|
+
modals/GalleryModal.jsx, which imports this stylesheet (DataGrid.jsx itself
|
|
210
|
+
never uses it). Same hardening as the header close in Form.module.scss; the
|
|
211
|
+
long note on the svg block there explains why a close glyph needs an
|
|
212
|
+
explicit box and `flex: none` rather than trusting its size attributes. */
|
|
208
213
|
.modal__close {
|
|
209
214
|
width: max-content;
|
|
215
|
+
min-width: 2rem;
|
|
216
|
+
min-height: 2rem;
|
|
217
|
+
box-sizing: border-box;
|
|
210
218
|
background: rgba(var(--paragraph-rgb), 0.05);
|
|
211
219
|
cursor: pointer;
|
|
212
220
|
padding: 0.25rem;
|
|
@@ -225,6 +233,9 @@
|
|
|
225
233
|
}
|
|
226
234
|
|
|
227
235
|
svg {
|
|
236
|
+
width: 1.25rem;
|
|
237
|
+
height: 1.25rem;
|
|
238
|
+
flex: none;
|
|
228
239
|
color: var(--primary-color);
|
|
229
240
|
display: block;
|
|
230
241
|
}
|
|
@@ -526,6 +537,94 @@
|
|
|
526
537
|
justify-content: flex-end;
|
|
527
538
|
}
|
|
528
539
|
|
|
540
|
+
/* ============================================================================
|
|
541
|
+
Colour legend
|
|
542
|
+
----------------------------------------------------------------------------
|
|
543
|
+
The opt-in caption above the grid (config key `legend`: an array of
|
|
544
|
+
`{ colour | color, label }`, where an entry carrying no colour renders as
|
|
545
|
+
lead-in text introducing the swatches after it).
|
|
546
|
+
|
|
547
|
+
This was inline styles on the elements themselves — `fontSize: '0.8rem'`,
|
|
548
|
+
`color: '#555'`, a hardcoded 14px swatch, `padding: '6px 4px 8px'`. Inline
|
|
549
|
+
styles are unreachable from a consuming project's stylesheet, so the one
|
|
550
|
+
thing a legend needs to be — tuned to the app it sits in — was the one
|
|
551
|
+
thing it could not be. It was also set off any scale in the library: 0.8rem
|
|
552
|
+
falls between two steps of the type ramp, and #555 is a grey that appears
|
|
553
|
+
nowhere else.
|
|
554
|
+
|
|
555
|
+
It is a caption for the table below it, so it is set as one: the same
|
|
556
|
+
`--font-size-xs`, `--muted-color` and `--font-weight-semibold` the grid's
|
|
557
|
+
own header row uses, so the two label rows stacked above the data read as
|
|
558
|
+
one family. It deliberately stops short of that header's uppercase and
|
|
559
|
+
0.06em tracking — legend labels are sentences ("No Goods Received entered
|
|
560
|
+
yet"), not column names, and setting a sentence in caps would undo the
|
|
561
|
+
quiet the rest of this is after.
|
|
562
|
+
|
|
563
|
+
Density hooks, following the `--nav-*` set documented at the top of
|
|
564
|
+
Navigation.module.scss: every declaration below is written
|
|
565
|
+
`var(--hook, <the value it always had>)`, so an unset hook is a no-op and a
|
|
566
|
+
project retunes from `:root` with no fork, no prop and no class of its own.
|
|
567
|
+
The plant-floor tablet case is the one that needs them — 12px is small when
|
|
568
|
+
the screen is at arm's length on a bench.
|
|
569
|
+
|
|
570
|
+
--grid-legend-font-size label type size.
|
|
571
|
+
default: var(--font-size-xs, 0.75rem)
|
|
572
|
+
--grid-legend-gap space between entries along a line.
|
|
573
|
+
default: var(--spacing-md, 1rem)
|
|
574
|
+
--grid-legend-swatch-size the colour chip. default: 0.875rem (14px)
|
|
575
|
+
========================================================================= */
|
|
576
|
+
|
|
577
|
+
.legend {
|
|
578
|
+
display: flex;
|
|
579
|
+
flex-wrap: wrap;
|
|
580
|
+
align-items: center;
|
|
581
|
+
/* Row gap and column gap differ on purpose: a legend that wraps (despatch
|
|
582
|
+
runs to seven entries) needs its lines closer together than its entries
|
|
583
|
+
are along a line, or the wrapped rows read as separate captions. */
|
|
584
|
+
gap: var(--spacing-sm, 0.5rem)
|
|
585
|
+
var(--grid-legend-gap, var(--spacing-md, 1rem));
|
|
586
|
+
/* A caption belongs to the thing it describes, so it sits nearer the grid
|
|
587
|
+
than the toolbar row above it — which is also what stops it crowding
|
|
588
|
+
that row, the complaint this change came from. No horizontal padding:
|
|
589
|
+
`.dataGridContainer` has none either, so the caption starts on the
|
|
590
|
+
grid's own left edge rather than floating 4px off it. */
|
|
591
|
+
margin: var(--spacing-md, 1rem) 0 var(--spacing-sm, 0.5rem);
|
|
592
|
+
padding: 0;
|
|
593
|
+
font-size: var(--grid-legend-font-size, var(--font-size-xs, 0.75rem));
|
|
594
|
+
line-height: 1.4;
|
|
595
|
+
color: var(--muted-color, #6b7688);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.legendItem {
|
|
599
|
+
display: inline-flex;
|
|
600
|
+
align-items: center;
|
|
601
|
+
gap: var(--spacing-xs, 0.25rem);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/* The lead-in entry: a legend line with no colour of its own, labelling the
|
|
605
|
+
swatches that follow. Weight and a darker ink rather than a different size,
|
|
606
|
+
so it introduces the row without breaking its line. */
|
|
607
|
+
.legendLead {
|
|
608
|
+
font-weight: var(--font-weight-semibold, 600);
|
|
609
|
+
color: var(--paragraph-color, #374151);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
.legendSwatch {
|
|
613
|
+
width: var(--grid-legend-swatch-size, 0.875rem);
|
|
614
|
+
height: var(--grid-legend-swatch-size, 0.875rem);
|
|
615
|
+
flex-shrink: 0;
|
|
616
|
+
display: inline-block;
|
|
617
|
+
border-radius: var(--radius-sm, 6px);
|
|
618
|
+
/* These are row tints, so they are pale by design — #FFEAEA has no edge
|
|
619
|
+
of its own against a white page and the swatch dissolves into it. A
|
|
620
|
+
low-alpha ink hairline gives every chip its shape back while staying
|
|
621
|
+
invisible against the darker ones. `--border-color` is the wrong token
|
|
622
|
+
here: it is tuned to be barely there on a white surface, which is
|
|
623
|
+
exactly where it is needed most. */
|
|
624
|
+
border: 1px solid rgba(var(--paragraph-color-rgb, 34, 30, 51), 0.18);
|
|
625
|
+
box-sizing: border-box;
|
|
626
|
+
}
|
|
627
|
+
|
|
529
628
|
/* Date field styling for uniform width */
|
|
530
629
|
:global {
|
|
531
630
|
// Target date cells specifically
|
|
@@ -708,24 +708,52 @@ input[type='file']:hover {
|
|
|
708
708
|
font-size: 1.15em;
|
|
709
709
|
}
|
|
710
710
|
|
|
711
|
+
/* The "Edit Canvas" modal's close control (Field.jsx). Hardened
|
|
712
|
+
the same way as the header close in Form.module.scss — see the
|
|
713
|
+
note on the svg block there. */
|
|
711
714
|
.modal__close {
|
|
712
715
|
width: max-content;
|
|
716
|
+
min-width: 2rem;
|
|
717
|
+
min-height: 2rem;
|
|
713
718
|
position: absolute;
|
|
714
719
|
right: 5px;
|
|
715
720
|
top: 5px;
|
|
716
721
|
box-sizing: border-box;
|
|
717
|
-
|
|
722
|
+
/* Was `rgba(var(--primary-color), 1.08)`, which is not a
|
|
723
|
+
colour: `--primary-color` is a hex, rgba() wants three
|
|
724
|
+
channels, and an alpha above 1 is out of range either way.
|
|
725
|
+
The declaration was invalid and dropped, so this button had
|
|
726
|
+
no background at all. It sits on `&__header`, which is
|
|
727
|
+
`var(--primary-color)`, so what it wants is a light lift off
|
|
728
|
+
that ground — the same treatment the equivalent control in
|
|
729
|
+
GenericFormBuilder.module.scss uses on its coloured header. */
|
|
730
|
+
background: rgba(255, 255, 255, 0.15);
|
|
718
731
|
cursor: pointer;
|
|
719
732
|
padding: 8px 8px;
|
|
720
733
|
margin: 0;
|
|
721
734
|
outline: none;
|
|
722
735
|
border: none;
|
|
723
736
|
border-radius: var(--br);
|
|
724
|
-
display:
|
|
737
|
+
display: flex;
|
|
738
|
+
align-items: center;
|
|
739
|
+
justify-content: center;
|
|
725
740
|
line-height: 1;
|
|
741
|
+
transition: background 0.2s ease;
|
|
742
|
+
|
|
743
|
+
&:hover {
|
|
744
|
+
background: rgba(255, 255, 255, 0.25);
|
|
745
|
+
}
|
|
726
746
|
|
|
727
747
|
svg {
|
|
728
|
-
|
|
748
|
+
width: 1.25rem;
|
|
749
|
+
height: 1.25rem;
|
|
750
|
+
flex: none;
|
|
751
|
+
/* The header behind this is `--primary-color`, so the
|
|
752
|
+
glyph is set against it rather than in a brand hue that
|
|
753
|
+
may be a near-match for it. Field.jsx also passes
|
|
754
|
+
`color="#FFF"`, which lucide writes as a `stroke`
|
|
755
|
+
attribute; this keeps the two in agreement. */
|
|
756
|
+
color: #fff;
|
|
729
757
|
display: block;
|
|
730
758
|
}
|
|
731
759
|
}
|
|
@@ -242,23 +242,63 @@ input[type='file'] {
|
|
|
242
242
|
justify-content: center;
|
|
243
243
|
width: 2rem;
|
|
244
244
|
height: 2rem;
|
|
245
|
+
/* The box is stated three ways on purpose. `width`/`height` alone is not a
|
|
246
|
+
box a consuming app cannot move: every one of these buttons lives under
|
|
247
|
+
whatever ambient `button { … }` rule the host stylesheet carries, and
|
|
248
|
+
with the library's own `* { box-sizing: border-box }` in play, a host
|
|
249
|
+
padding rule eats this button's *content* box rather than growing it.
|
|
250
|
+
The min-* pair holds the outer size and `box-sizing` states the
|
|
251
|
+
assumption rather than inheriting it — but see the svg block for what
|
|
252
|
+
actually keeps the glyph safe. */
|
|
253
|
+
min-width: 2rem;
|
|
254
|
+
min-height: 2rem;
|
|
255
|
+
box-sizing: border-box;
|
|
245
256
|
flex: none;
|
|
246
257
|
background: none;
|
|
247
258
|
cursor: pointer;
|
|
248
259
|
padding: 0;
|
|
249
260
|
margin: 0;
|
|
250
261
|
border: none;
|
|
251
|
-
border-radius: var(--radius-sm);
|
|
262
|
+
border-radius: var(--radius-sm, 6px);
|
|
252
263
|
line-height: 1;
|
|
253
|
-
transition: background-color var(--speed) var(--ease);
|
|
264
|
+
transition: background-color var(--speed, 0.18s) var(--ease, ease);
|
|
254
265
|
|
|
255
266
|
&:hover {
|
|
256
|
-
background: var(--hover-color);
|
|
267
|
+
background: var(--hover-color, rgba(var(--paragraph-color-rgb, 34, 30, 51), 0.06));
|
|
257
268
|
}
|
|
258
269
|
|
|
259
270
|
svg {
|
|
260
|
-
|
|
271
|
+
/* This is the rule that stops the icon disappearing.
|
|
272
|
+
|
|
273
|
+
An `<svg width="24" height="24">` inside a flex container is a flex
|
|
274
|
+
item with the default `flex-shrink: 1`, so when the button's content
|
|
275
|
+
box is squeezed the glyph shrinks with it — all the way down.
|
|
276
|
+
Hartway's plant-floor stylesheet carries
|
|
277
|
+
`body.tablet-mode button:not([class*='InovuaReactDataGrid'])
|
|
278
|
+
{ padding: 8px 14px }`,
|
|
279
|
+
which outweighs this module's single class (0,2,2 against 0,1,0) and
|
|
280
|
+
left a 2rem border-box button with a 4px content box; the X
|
|
281
|
+
collapsed with it and read as a smudge at the end of the header.
|
|
282
|
+
|
|
283
|
+
`flex: none` refuses to shrink, and the explicit width/height also
|
|
284
|
+
makes the glyph immune to the `width: 100%` sizing pattern used on
|
|
285
|
+
svgs elsewhere in this library. Both are needed: the size fixes the
|
|
286
|
+
basis, `flex: none` stops it being overruled. Sized here rather than
|
|
287
|
+
trusting the `size` prop at each call site, so every modal header
|
|
288
|
+
agrees on one glyph. */
|
|
289
|
+
width: 1.25rem;
|
|
290
|
+
height: 1.25rem;
|
|
291
|
+
flex: none;
|
|
292
|
+
/* Recessive, but a control the user has to be able to find has no
|
|
293
|
+
business being fainter than the body text around it. */
|
|
294
|
+
color: var(--muted-color, #6b7688);
|
|
261
295
|
display: block;
|
|
296
|
+
transition: color var(--speed, 0.18s) var(--ease, ease);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
&:hover svg,
|
|
300
|
+
&:focus-visible svg {
|
|
301
|
+
color: var(--paragraph-color, #374151);
|
|
262
302
|
}
|
|
263
303
|
}
|
|
264
304
|
|
|
@@ -741,8 +741,13 @@ select:not(:placeholder-shown) + .fi__span {
|
|
|
741
741
|
letter-spacing: 0.01em;
|
|
742
742
|
}
|
|
743
743
|
|
|
744
|
+
/* The form builder's modal close control (GenericFormBuilder.jsx, two call
|
|
745
|
+
sites). Hardened the same way as the header close in Form.module.scss — see
|
|
746
|
+
the note on the svg block there. */
|
|
744
747
|
.modal__close {
|
|
745
748
|
width: max-content;
|
|
749
|
+
min-width: 2rem;
|
|
750
|
+
min-height: 2rem;
|
|
746
751
|
position: absolute;
|
|
747
752
|
right: 8px;
|
|
748
753
|
top: 8px;
|
|
@@ -754,7 +759,9 @@ select:not(:placeholder-shown) + .fi__span {
|
|
|
754
759
|
outline: none;
|
|
755
760
|
border: none;
|
|
756
761
|
border-radius: 6px;
|
|
757
|
-
display:
|
|
762
|
+
display: flex;
|
|
763
|
+
align-items: center;
|
|
764
|
+
justify-content: center;
|
|
758
765
|
line-height: 1;
|
|
759
766
|
transition: background 0.2s ease;
|
|
760
767
|
|
|
@@ -764,7 +771,13 @@ select:not(:placeholder-shown) + .fi__span {
|
|
|
764
771
|
}
|
|
765
772
|
|
|
766
773
|
.modal__close svg {
|
|
767
|
-
|
|
774
|
+
width: 1.25rem;
|
|
775
|
+
height: 1.25rem;
|
|
776
|
+
flex: none;
|
|
777
|
+
/* `.modal__header` above is `var(--primary-color)`, so the glyph is set
|
|
778
|
+
against that ground rather than in a second brand hue that may be a
|
|
779
|
+
near-match for it — which is what `--secondary-color` was doing here. */
|
|
780
|
+
color: #fff;
|
|
768
781
|
display: block;
|
|
769
782
|
}
|
|
770
783
|
|