@visns-studio/visns-components 6.17.2 → 6.20.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.json +10 -7
- package/src/components/AssociationManager.jsx +344 -177
- package/src/components/AsyncSelect.jsx +2 -2
- package/src/components/Autocomplete.jsx +57 -12
- package/src/components/Breadcrumb.jsx +23 -4
- package/src/components/ClientAssociationManager.jsx +321 -145
- package/src/components/DataGrid.jsx +625 -20
- package/src/components/DropZone.jsx +4 -1
- package/src/components/Form.jsx +233 -6
- package/src/components/MultiSelect.jsx +2 -2
- package/src/components/Navigation.jsx +39 -23
- package/src/components/TableFilter.jsx +172 -12
- package/src/components/UniversalSearch.jsx +390 -0
- package/src/components/auth/Login.jsx +164 -8
- package/src/components/auth/Profile.jsx +209 -22
- package/src/components/auth/authEndpoints.js +4 -0
- package/src/components/auth/webauthn.js +194 -0
- package/src/components/columns/ColumnRenderers.jsx +6 -1
- package/src/components/controls/DataGridSearch.jsx +11 -5
- package/src/components/generic/GenericAuth.jsx +6 -0
- package/src/components/generic/GenericDashboard.jsx +93 -36
- package/src/components/generic/GenericDetail.jsx +146 -61
- package/src/components/generic/GenericIndex.jsx +134 -38
- package/src/components/generic/GenericSettings.jsx +220 -0
- package/src/components/generic/StandardModal.jsx +165 -8
- package/src/components/generic/dashboardChartDefaults.js +230 -0
- package/src/components/generic/shared/indexLayout.js +38 -0
- package/src/components/settings/IntegrationsManager.jsx +474 -0
- package/src/components/sms/SmsLineSettings.jsx +16 -12
- package/src/components/styles/AssociationManager.module.scss +4 -363
- package/src/components/styles/AuditLog.module.scss +6 -6
- package/src/components/styles/AuditLogs.module.scss +3 -3
- package/src/components/styles/Autocomplete.module.scss +7 -7
- package/src/components/styles/BusinessCardOcr.module.scss +6 -1
- package/src/components/styles/CallQueueSettings.module.scss +4 -1
- package/src/components/styles/CameraPlacement.module.scss +19 -19
- package/src/components/styles/CategorizedDropZone.module.scss +6 -1
- package/src/components/styles/ClientAssociationManager.module.scss +5 -289
- package/src/components/styles/ClientAuth.module.scss +1 -1
- package/src/components/styles/DataGrid.module.scss +455 -8
- package/src/components/styles/Field.module.scss +32 -24
- package/src/components/styles/Form.module.scss +123 -3
- package/src/components/styles/GenericDashboard.module.scss +612 -825
- package/src/components/styles/GenericDetail.module.scss +406 -61
- package/src/components/styles/GenericDynamic.module.scss +25 -25
- package/src/components/styles/GenericEditableTable.module.scss +33 -33
- package/src/components/styles/GenericFormBuilder.module.scss +119 -119
- package/src/components/styles/GenericIndex.module.scss +483 -38
- package/src/components/styles/GenericMain.module.scss +6 -3
- package/src/components/styles/GenericQuote.module.scss +399 -81
- package/src/components/styles/GenericReport.module.scss +8 -8
- package/src/components/styles/GenericSettings.module.scss +209 -0
- package/src/components/styles/GenericSort.module.scss +9 -9
- package/src/components/styles/Integrations.module.scss +321 -0
- package/src/components/styles/List.module.scss +4 -4
- package/src/components/styles/Login.module.scss +57 -0
- package/src/components/styles/MultiSelect.module.scss +4 -4
- package/src/components/styles/Navigation.module.scss +12 -12
- package/src/components/styles/Notification.module.scss +12 -8
- package/src/components/styles/NotificationList.module.scss +5 -5
- package/src/components/styles/Profile.module.scss +5 -5
- package/src/components/styles/QrCode.module.scss +4 -4
- package/src/components/styles/QuickAction.module.scss +20 -20
- package/src/components/styles/SortableQuoteItems.module.scss +4 -4
- package/src/components/styles/TableFilter.module.scss +128 -17
- package/src/components/styles/TicketConversation.module.scss +497 -0
- package/src/components/styles/UniversalSearch.module.scss +229 -0
- package/src/components/styles/Vault.module.scss +413 -0
- package/src/components/styles/_associationManager.scss +467 -0
- package/src/components/styles/_authBrandPanel.scss +15 -9
- package/src/components/styles/_controls.scss +43 -39
- package/src/components/styles/global-datagrid.css +196 -0
- package/src/components/styles/global.css +168 -17
- package/src/components/tickets/TicketConversation.jsx +455 -0
- package/src/components/utils/rowActionSettings.js +117 -0
- package/src/components/vault/VaultClientPicker.jsx +183 -0
- package/src/components/vault/VaultEntryForm.jsx +23 -0
- package/src/components/vault/VaultManager.jsx +382 -34
- package/src/components/vault/VaultShareModal.jsx +454 -0
- package/src/components/vault/vaultEndpoints.js +16 -2
- package/src/components/vault/vaultShares.js +247 -0
- package/src/index.js +35 -0
- package/src/utils/fetchUtil.js +38 -14
|
@@ -589,3 +589,199 @@ body.tablet-mode .InovuaReactDataGrid__cell.cell-word-wrap > div {
|
|
|
589
589
|
.visns-native-date-filter__range .visns-native-date-filter {
|
|
590
590
|
flex: 1 1 0;
|
|
591
591
|
}
|
|
592
|
+
|
|
593
|
+
/* ==========================================================================
|
|
594
|
+
2026 pass — the grid's cells
|
|
595
|
+
--------------------------------------------------------------------------
|
|
596
|
+
The grid itself is the vendored @visns-studio/visns-datagrid fork, whose
|
|
597
|
+
markup is not ours. It is styled from here rather than from that package,
|
|
598
|
+
because this file is already the override layer the library ships for it —
|
|
599
|
+
so a restyle costs no fork, no rebuild of a TypeScript+Babel+PostCSS
|
|
600
|
+
pipeline, and no npm publish.
|
|
601
|
+
|
|
602
|
+
`!important` throughout, reluctantly: the vendored theme's own selectors are
|
|
603
|
+
high-specificity and this file is imported before it. That is a property of
|
|
604
|
+
the host, not a preference.
|
|
605
|
+
========================================================================== */
|
|
606
|
+
|
|
607
|
+
.InovuaReactDataGrid {
|
|
608
|
+
--dgx-ink: var(--paragraph-color, #2b2b2b);
|
|
609
|
+
--dgx-surface: var(--background-color, #fff);
|
|
610
|
+
--dgx-line: color-mix(in srgb, var(--dgx-ink) 10%, transparent);
|
|
611
|
+
--dgx-muted: color-mix(in srgb, var(--dgx-ink) 60%, transparent);
|
|
612
|
+
--dgx-hover: color-mix(in srgb, var(--primary-color, #1b3933) 4%, var(--dgx-surface));
|
|
613
|
+
--dgx-selected: color-mix(in srgb, var(--primary-color, #1b3933) 8%, var(--dgx-surface));
|
|
614
|
+
|
|
615
|
+
border: 0 !important;
|
|
616
|
+
background: var(--dgx-surface) !important;
|
|
617
|
+
font-family: inherit !important;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/* -- column header -------------------------------------------------------- */
|
|
621
|
+
|
|
622
|
+
.InovuaReactDataGrid__header,
|
|
623
|
+
.InovuaReactDataGrid__header-wrapper {
|
|
624
|
+
background: var(--dgx-surface) !important;
|
|
625
|
+
border-bottom: 1px solid var(--dgx-line) !important;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
.InovuaReactDataGrid__column-header {
|
|
629
|
+
background: transparent !important;
|
|
630
|
+
border: 0 !important;
|
|
631
|
+
border-bottom: 0 !important;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
.InovuaReactDataGrid__column-header__content {
|
|
635
|
+
padding: 0.65rem 0.85rem !important;
|
|
636
|
+
color: var(--dgx-muted) !important;
|
|
637
|
+
font-size: 0.6875rem !important;
|
|
638
|
+
font-weight: 600 !important;
|
|
639
|
+
letter-spacing: 0.05em !important;
|
|
640
|
+
text-transform: uppercase !important;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/* -- rows and cells ------------------------------------------------------- */
|
|
644
|
+
|
|
645
|
+
/* 44px rather than the vendored 36: a row a finger can hit on the iPad these
|
|
646
|
+
are used on, and enough air that a table of twelve does not read as a wall. */
|
|
647
|
+
.InovuaReactDataGrid__row {
|
|
648
|
+
min-height: 44px !important;
|
|
649
|
+
border: 0 !important;
|
|
650
|
+
background: var(--dgx-surface) !important;
|
|
651
|
+
transition: background 140ms cubic-bezier(0.4, 0, 0.2, 1) !important;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
.InovuaReactDataGrid__row:hover,
|
|
655
|
+
.InovuaReactDataGrid__row--hover-target:hover {
|
|
656
|
+
background: var(--dgx-hover) !important;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
.InovuaReactDataGrid__row--selected,
|
|
660
|
+
.InovuaReactDataGrid__row--active {
|
|
661
|
+
background: var(--dgx-selected) !important;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/* The vendored theme draws a border on every cell, so a table arrives as a
|
|
665
|
+
grid of boxes. One hairline under the row is all the separation a row needs;
|
|
666
|
+
the columns are separated by alignment. */
|
|
667
|
+
.InovuaReactDataGrid__cell {
|
|
668
|
+
border: 0 !important;
|
|
669
|
+
border-bottom: 1px solid var(--dgx-line) !important;
|
|
670
|
+
background: transparent !important;
|
|
671
|
+
color: var(--dgx-ink) !important;
|
|
672
|
+
font-size: 0.8125rem !important;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
.InovuaReactDataGrid__cell__content {
|
|
676
|
+
padding: 0 0.85rem !important;
|
|
677
|
+
line-height: 1.45 !important;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/* Columns of numbers line up; everything else keeps proportional figures. */
|
|
681
|
+
.InovuaReactDataGrid__cell--align-end .InovuaReactDataGrid__cell__content,
|
|
682
|
+
.InovuaReactDataGrid__cell--align-right .InovuaReactDataGrid__cell__content {
|
|
683
|
+
font-variant-numeric: tabular-nums !important;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
.InovuaReactDataGrid__row:last-child .InovuaReactDataGrid__cell {
|
|
687
|
+
border-bottom: 0 !important;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/* -- checkbox ------------------------------------------------------------- */
|
|
691
|
+
|
|
692
|
+
.InovuaReactDataGrid__checkbox {
|
|
693
|
+
accent-color: var(--primary-color, #1b3933) !important;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/* -- group header --------------------------------------------------------- */
|
|
697
|
+
|
|
698
|
+
.InovuaReactDataGrid__group-cell,
|
|
699
|
+
.InovuaReactDataGrid__group-row {
|
|
700
|
+
background: color-mix(in srgb, var(--dgx-ink) 3%, var(--dgx-surface)) !important;
|
|
701
|
+
color: var(--dgx-ink) !important;
|
|
702
|
+
font-weight: 600 !important;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/* -- column filter row ---------------------------------------------------- */
|
|
706
|
+
|
|
707
|
+
.InovuaReactDataGrid__column-header__filter input,
|
|
708
|
+
.InovuaReactDataGrid__column-header__filter select {
|
|
709
|
+
height: 28px !important;
|
|
710
|
+
padding: 0 0.5rem !important;
|
|
711
|
+
border: 1px solid var(--dgx-line) !important;
|
|
712
|
+
border-radius: 6px !important;
|
|
713
|
+
background: var(--dgx-surface) !important;
|
|
714
|
+
color: var(--dgx-ink) !important;
|
|
715
|
+
font: inherit !important;
|
|
716
|
+
font-size: 0.75rem !important;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/* The toolkit WRAPPER around that input drew its own box too: a 1px #cdcecd
|
|
720
|
+
border at 1px radius, with the styled 6px-radius input sitting inside it.
|
|
721
|
+
Two nested borders a pixel apart, which is what made the filter row read as
|
|
722
|
+
one enormous raw text box spanning the column rather than as a filter.
|
|
723
|
+
|
|
724
|
+
Only the input keeps an edge. The wrapper is a layout box. */
|
|
725
|
+
.InovuaReactDataGrid__column-header__filter.inovua-react-toolkit-text-input,
|
|
726
|
+
.InovuaReactDataGrid__column-header__filter.inovua-react-toolkit-numeric-input {
|
|
727
|
+
border: 0 !important;
|
|
728
|
+
border-radius: 0 !important;
|
|
729
|
+
background: none !important;
|
|
730
|
+
box-shadow: none !important;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/* A COMBO BOX is built the other way round, and it matters.
|
|
734
|
+
|
|
735
|
+
In a text or numeric filter the inner `<input>` fills the wrapper, so the
|
|
736
|
+
input carries the edge and the wrapper is a layout box. In a combo box the
|
|
737
|
+
inner `<input>` is only a narrow typing sliver sitting NEXT to a placeholder
|
|
738
|
+
span — measured at 18px wide inside a 130px control. Putting the edge on it
|
|
739
|
+
drew a bordered 18px box beside the word "ALL", which is why the ALL filters
|
|
740
|
+
looked like they had a stray empty checkbox in front of them.
|
|
741
|
+
|
|
742
|
+
So for combo boxes the wrapper carries the edge and the sliver gets none. */
|
|
743
|
+
.InovuaReactDataGrid__column-header__filter.inovua-react-toolkit-combo-box {
|
|
744
|
+
/* min/max as well as height: the grid theme pins the filter cell to
|
|
745
|
+
`min-height: 32px`, and min-height beats height, so `height` alone left
|
|
746
|
+
the ALL dropdowns 4px taller than the text and date filters beside
|
|
747
|
+
them. */
|
|
748
|
+
height: 28px !important;
|
|
749
|
+
min-height: 28px !important;
|
|
750
|
+
max-height: 28px !important;
|
|
751
|
+
border: 1px solid var(--dgx-line) !important;
|
|
752
|
+
border-radius: 6px !important;
|
|
753
|
+
background: var(--dgx-surface) !important;
|
|
754
|
+
box-shadow: none !important;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
.InovuaReactDataGrid__column-header__filter.inovua-react-toolkit-combo-box
|
|
758
|
+
.inovua-react-toolkit-combo-box__input {
|
|
759
|
+
border: 0 !important;
|
|
760
|
+
border-radius: 0 !important;
|
|
761
|
+
background: none !important;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/* The native date filter is the odd one out in the row.
|
|
765
|
+
|
|
766
|
+
Measured on /tickets: every other filter editor is 28px tall with a 6px
|
|
767
|
+
radius and the `--dgx-line` hairline, while this one was 34px with a 1px
|
|
768
|
+
radius and the toolkit's old #cdcecd border. Six pixels taller and squarer
|
|
769
|
+
than its neighbours is exactly what makes one control in a row look
|
|
770
|
+
"selected" or broken when nothing is wrong with it.
|
|
771
|
+
|
|
772
|
+
Note the edge lives on the WRAPPER here, not on the input — the input is
|
|
773
|
+
`border: none` because Chrome's date segments need to fill the box — so the
|
|
774
|
+
wrapper is what has to carry the 2026 treatment. */
|
|
775
|
+
.InovuaReactDataGrid__column-header__filter .visns-native-date-filter,
|
|
776
|
+
.visns-native-date-filter {
|
|
777
|
+
height: 28px !important;
|
|
778
|
+
min-height: 28px !important;
|
|
779
|
+
max-height: 28px !important;
|
|
780
|
+
border: 1px solid var(--dgx-line) !important;
|
|
781
|
+
border-radius: 6px !important;
|
|
782
|
+
background: var(--dgx-surface) !important;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
.visns-native-date-filter__input {
|
|
786
|
+
font-size: 0.75rem !important;
|
|
787
|
+
}
|
|
@@ -228,13 +228,54 @@ ul {
|
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
a {
|
|
231
|
+
/* `outline: none` used to sit here alone, stripping the focus ring from
|
|
232
|
+
every link in every consuming app with nothing put back. The outline is
|
|
233
|
+
removed only for the mouse; keyboard focus keeps a real ring. */
|
|
231
234
|
outline: none;
|
|
232
235
|
}
|
|
233
236
|
|
|
237
|
+
a:focus-visible {
|
|
238
|
+
outline: 2px solid var(--highlight-color, #3cbf7d);
|
|
239
|
+
outline-offset: 2px;
|
|
240
|
+
border-radius: var(--radius-sm, 4px);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/* The two rules above force `appearance: none` and `outline: none !important`
|
|
244
|
+
on every checkbox and radio, which left them with a 14px hit target and NO
|
|
245
|
+
keyboard focus indicator anywhere in the library. Restoring the ring is
|
|
246
|
+
separated from the drawn control deliberately: other rules depend on the
|
|
247
|
+
custom box, but nothing depends on focus being invisible. */
|
|
248
|
+
input[type='checkbox']:focus-visible,
|
|
249
|
+
input[type='radio']:focus-visible,
|
|
250
|
+
.radio-input:focus-visible {
|
|
251
|
+
outline: 2px solid var(--highlight-color, #3cbf7d) !important;
|
|
252
|
+
outline-offset: 2px !important;
|
|
253
|
+
}
|
|
254
|
+
|
|
234
255
|
.loginbg {
|
|
235
256
|
background: var(--tertiary-color);
|
|
236
257
|
}
|
|
237
258
|
|
|
259
|
+
/* The grid's own toolbar and column-filter fields opt out of this rule, same
|
|
260
|
+
as the Inovua toolkit inputs listed in it.
|
|
261
|
+
|
|
262
|
+
This selector carries about a dozen chained `:not()` clauses, and every one
|
|
263
|
+
of them adds specificity — so at roughly (0,13,1) it silently beat
|
|
264
|
+
`.searchInput` (0,1,0) in DataGrid.module.scss and imposed `padding: 1rem`
|
|
265
|
+
on a 34px-tall field, which is what pushed the magnifier glyph on top of the
|
|
266
|
+
placeholder text.
|
|
267
|
+
|
|
268
|
+
The exclusions match on a class SUBSTRING because these are CSS-module
|
|
269
|
+
classes: by the time this plain stylesheet applies, the name is
|
|
270
|
+
`_searchInput_17s7g_654`, so a bare `.searchInput` here would match nothing.
|
|
271
|
+
|
|
272
|
+
KEEP THE SELECTOR ON ONE UNBROKEN COMPOUND. A newline — or a comment, which
|
|
273
|
+
is whitespace — between two `:not()` clauses is a DESCENDANT COMBINATOR, and
|
|
274
|
+
it silently retargets the rule at descendants of an `<input>`, which do not
|
|
275
|
+
exist. That is not a hypothetical: it happened here, and every text field in
|
|
276
|
+
the app fell back to the browser's default 2px inset border while selects
|
|
277
|
+
and textareas kept their styling. Hence three different-looking controls in
|
|
278
|
+
one form. */
|
|
238
279
|
textarea,
|
|
239
280
|
select,
|
|
240
281
|
input[type]:not([type='search']):not([type='url']):not([type='hidden']):not(
|
|
@@ -249,10 +290,10 @@ input[type]:not([type='search']):not([type='url']):not([type='hidden']):not(
|
|
|
249
290
|
.react-datepicker__year-select
|
|
250
291
|
):not(.visns-native-date-filter__input):not([type='date']):not(
|
|
251
292
|
[type='datetime-local']
|
|
252
|
-
):not([type='time']) {
|
|
293
|
+
):not([type='time']):not([class*='searchInput']):not([class*='filterInput']):not([class*='rowActionPickerSearch']) {
|
|
253
294
|
background: white;
|
|
254
295
|
border-radius: var(--br);
|
|
255
|
-
border: 1px solid rgba(var(--paragraph-color-rgb), 0.15);
|
|
296
|
+
border: 1px solid rgba(var(--paragraph-color-rgb, 43, 43, 43), 0.15);
|
|
256
297
|
box-shadow: none;
|
|
257
298
|
padding: 1rem;
|
|
258
299
|
outline: none;
|
|
@@ -344,7 +385,7 @@ input[type='time'] {
|
|
|
344
385
|
background-color: var(--tertiary-color);
|
|
345
386
|
padding: 0;
|
|
346
387
|
margin: 0;
|
|
347
|
-
border: 1px solid rgba(var(--primary-rgb), 0.25);
|
|
388
|
+
border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.25);
|
|
348
389
|
border-radius: var(--br);
|
|
349
390
|
overflow: hidden;
|
|
350
391
|
font-size: 1rem;
|
|
@@ -384,21 +425,17 @@ input[type='time'] {
|
|
|
384
425
|
|
|
385
426
|
/* Async Select */
|
|
386
427
|
|
|
428
|
+
/* The control's appearance is defined once, further down, next to the rule
|
|
429
|
+
for native inputs it has to match. This rule keeps only the structural
|
|
430
|
+
properties — it used to also set `min-height: 50px`, a second border and a
|
|
431
|
+
4px radius, all of which fought the later block. */
|
|
387
432
|
.visns-select__control {
|
|
388
433
|
width: 100%;
|
|
389
434
|
cursor: default;
|
|
390
|
-
min-height: 50px;
|
|
391
|
-
outline: 0 !important;
|
|
392
435
|
position: relative;
|
|
393
|
-
|
|
394
|
-
transition: all 100ms;
|
|
395
|
-
background-color: hsl(0, 0%, 100%);
|
|
396
|
-
border-color: hsl(0, 0%, 80%);
|
|
397
|
-
border-radius: 4px;
|
|
398
|
-
border-style: solid;
|
|
399
|
-
border-width: 1px;
|
|
436
|
+
outline: 0 !important;
|
|
400
437
|
box-sizing: border-box;
|
|
401
|
-
|
|
438
|
+
transition: border-color 0.15s linear;
|
|
402
439
|
}
|
|
403
440
|
|
|
404
441
|
/* These were written as `&--is-focused` / `&--menu-is-open` nested inside the
|
|
@@ -661,10 +698,11 @@ input[type='time'] {
|
|
|
661
698
|
}
|
|
662
699
|
|
|
663
700
|
/* Fix for specific toggle in forms */
|
|
664
|
-
form div:has(span:contains('Use T-Bar?'))
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
701
|
+
/* Removed: `form div:has(span:contains('Use T-Bar?'))` — `:contains()` is a
|
|
702
|
+
jQuery extension, not CSS, so this selector was invalid and the rule had
|
|
703
|
+
never applied to anything. Restore it with a real class or data attribute
|
|
704
|
+
on the toggle if the behaviour is still wanted. */
|
|
705
|
+
|
|
668
706
|
|
|
669
707
|
/* Hide checkboxes when they're next to a toggle */
|
|
670
708
|
.react-toggle + input[type='checkbox'],
|
|
@@ -998,3 +1036,116 @@ form div:has(.react-toggle) input[type='checkbox'] {
|
|
|
998
1036
|
font-weight: bold !important;
|
|
999
1037
|
}
|
|
1000
1038
|
}
|
|
1039
|
+
|
|
1040
|
+
/* ---------------------------------------------------------------------------
|
|
1041
|
+
react-select, wearing the same clothes as every other field
|
|
1042
|
+
---------------------------------------------------------------------------
|
|
1043
|
+
The dropdowns are react-select with `classNamePrefix="visns-select"`, so
|
|
1044
|
+
they arrive with react-select's OWN defaults: a #cccccc 1px border and a 4px
|
|
1045
|
+
radius. Everything else in a form gets the rule above — a
|
|
1046
|
+
`rgba(paragraph, .15)` hairline at `var(--br)`. Measured side by side in one
|
|
1047
|
+
form: 1px #cccccc / 4px on the selects, 1px rgba(68,60,43,.15) / 5px on the
|
|
1048
|
+
inputs.
|
|
1049
|
+
|
|
1050
|
+
One pixel of radius and a different grey is not something anyone can name
|
|
1051
|
+
when they look at it, which is exactly why it reads as "these don't match".
|
|
1052
|
+
------------------------------------------------------------------------ */
|
|
1053
|
+
|
|
1054
|
+
.visns-select__control {
|
|
1055
|
+
/* Same token the native inputs below use. 51px was 3px taller than a text
|
|
1056
|
+
input, which is exactly the kind of difference nobody can name but
|
|
1057
|
+
everybody sees when the two sit side by side in one form. */
|
|
1058
|
+
min-height: var(--field-height, 51px);
|
|
1059
|
+
border: 1px solid rgba(var(--paragraph-rgb, 43, 43, 43), 0.15) !important;
|
|
1060
|
+
border-radius: var(--br, 5px) !important;
|
|
1061
|
+
background: var(--background-color, #fff);
|
|
1062
|
+
/* react-select paints its own shadow on focus; the app's focus ring is the
|
|
1063
|
+
one below, so this one goes. */
|
|
1064
|
+
box-shadow: none !important;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
.visns-select__control:hover {
|
|
1068
|
+
border-color: rgba(var(--paragraph-rgb, 43, 43, 43), 0.28) !important;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
.visns-select__control--is-focused {
|
|
1072
|
+
border-color: color-mix(
|
|
1073
|
+
in srgb,
|
|
1074
|
+
var(--primary-color, #1b3933) 45%,
|
|
1075
|
+
rgba(var(--paragraph-rgb, 43, 43, 43), 0.15)
|
|
1076
|
+
) !important;
|
|
1077
|
+
box-shadow: 0 0 0 3px
|
|
1078
|
+
color-mix(in srgb, var(--highlight-color, #3cbf7d) 22%, transparent) !important;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
.visns-select__control--is-disabled {
|
|
1082
|
+
background: rgba(var(--paragraph-rgb, 43, 43, 43), 0.04);
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
/* The menu is a surface like any other popover in the app, not a browser
|
|
1086
|
+
dropdown: same radius, same hairline, one shadow. */
|
|
1087
|
+
.visns-select__menu {
|
|
1088
|
+
border: 1px solid rgba(var(--paragraph-rgb, 43, 43, 43), 0.15);
|
|
1089
|
+
border-radius: var(--br, 5px);
|
|
1090
|
+
box-shadow: 0 12px 28px -12px rgba(0, 0, 0, 0.28);
|
|
1091
|
+
overflow: hidden;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
.visns-select__option--is-focused {
|
|
1095
|
+
background: color-mix(
|
|
1096
|
+
in srgb,
|
|
1097
|
+
var(--primary-color, #1b3933) 8%,
|
|
1098
|
+
transparent
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
.visns-select__option--is-selected {
|
|
1103
|
+
background: var(--primary-color, #1b3933);
|
|
1104
|
+
color: #fff;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/* react-select builds the control out of nested boxes that each carry their
|
|
1108
|
+
own padding, so matching the outer height is not enough — the text still
|
|
1109
|
+
sits differently from a native input. These line the inner boxes up with
|
|
1110
|
+
the `padding: 1rem` / `font-size: 0.85rem` of the input rule below, and
|
|
1111
|
+
drop the indicator separator, a divider no other field in the app has. */
|
|
1112
|
+
.visns-select__value-container {
|
|
1113
|
+
padding: 0 1rem !important;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
.visns-select__input-container,
|
|
1117
|
+
.visns-select__single-value,
|
|
1118
|
+
.visns-select__placeholder {
|
|
1119
|
+
margin: 0 !important;
|
|
1120
|
+
padding: 0 !important;
|
|
1121
|
+
font-size: 0.85rem;
|
|
1122
|
+
line-height: 1;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
.visns-select__indicator-separator {
|
|
1126
|
+
display: none !important;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/* react-select puts a real `<input>` inside the control so you can type to
|
|
1130
|
+
filter. It is an `input[type="text"]`, so the padded native-input rule
|
|
1131
|
+
further up was styling it as a form field in its own right: 1rem of padding
|
|
1132
|
+
and the full 48px control height, nested INSIDE the 48px control. That is
|
|
1133
|
+
what made every dropdown ~6px taller than the input beside it. */
|
|
1134
|
+
.visns-select__input {
|
|
1135
|
+
min-height: 0 !important;
|
|
1136
|
+
height: auto !important;
|
|
1137
|
+
padding: 0 !important;
|
|
1138
|
+
border: 0 !important;
|
|
1139
|
+
background: transparent !important;
|
|
1140
|
+
box-shadow: none !important;
|
|
1141
|
+
line-height: 1 !important;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
.visns-select__indicator {
|
|
1145
|
+
padding: 0 0.5rem !important;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
.visns-select__option {
|
|
1149
|
+
font-size: 0.85rem;
|
|
1150
|
+
}
|
|
1151
|
+
|