@nextlyhq/ui 0.0.2-alpha.54 → 0.0.2-alpha.57
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/dist/color.cjs +193 -0
- package/dist/color.cjs.map +1 -0
- package/dist/color.d.cts +251 -0
- package/dist/color.d.ts +251 -0
- package/dist/color.mjs +179 -0
- package/dist/color.mjs.map +1 -0
- package/dist/index.cjs +1246 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +445 -1
- package/dist/index.d.ts +445 -1
- package/dist/index.mjs +1230 -44
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.scoped.css +1 -1
- package/dist/theme.css +138 -104
- package/docs/plugin-ui-authoring.md +12 -10
- package/package.json +22 -8
package/dist/theme.css
CHANGED
|
@@ -180,8 +180,9 @@
|
|
|
180
180
|
--color-destructive-800: color-mix(in srgb, var(--nx-destructive), black 50%);
|
|
181
181
|
--color-destructive-900: color-mix(in srgb, var(--nx-destructive), black 70%);
|
|
182
182
|
--color-destructive-950: color-mix(in srgb, var(--nx-destructive), black 85%);
|
|
183
|
-
/* Saturated fill for solid buttons
|
|
184
|
-
*
|
|
183
|
+
/* Saturated fill for solid buttons, kept separate from the text-tuned base
|
|
184
|
+
* so each can be solved for its own job. The ink that lands on it is
|
|
185
|
+
* `-foreground`, which is white in light mode and black in dark. */
|
|
185
186
|
--color-destructive-solid: var(--nx-destructive-solid);
|
|
186
187
|
--color-destructive-foreground: var(--nx-destructive-foreground);
|
|
187
188
|
|
|
@@ -417,16 +418,18 @@
|
|
|
417
418
|
* rounded-xl / rounded-2xl are NOT tiers of this knob. `tailwind-preset.ts`
|
|
418
419
|
* exports only lg/md/sm, so a plugin using the preset gets Tailwind's fixed
|
|
419
420
|
* 0.75rem / 1rem for them, detached from --radius; and the definitions below
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
421
|
+
* ADD to the knob rather than subtracting, so they always sit rounder than
|
|
422
|
+
* the container tier and drift further as the knob grows. Nothing in the repo
|
|
423
|
+
* uses them. Treat them as off-contract and pick from sm/md/lg.
|
|
423
424
|
*
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
425
|
+
* At the shipped 0.5rem the three tiers are 4px, 6px and 8px. All positive,
|
|
426
|
+
* which matters: `sm` and `md` SUBTRACT from the knob, so a knob under 4px
|
|
427
|
+
* makes them negative. They still render square, because border-radius clamps
|
|
428
|
+
* a negative length to 0 at used-value time — but the token keeps its
|
|
429
|
+
* negative value, so reading `--radius-sm` for a padding, an inset, or
|
|
430
|
+
* through getComputedStyle yields -4px rather than 0. Anything consuming a
|
|
431
|
+
* step as a LENGTH rather than as a corner must clamp it itself, and that
|
|
432
|
+
* obligation returns the moment someone dials the knob back down.
|
|
430
433
|
*
|
|
431
434
|
* A site that genuinely must stay square keeps `rounded-none` WITH an inline
|
|
432
435
|
* comment saying why — overlapped-border strips, full-bleed fills inside an
|
|
@@ -518,11 +521,34 @@
|
|
|
518
521
|
* and it shadows the real weight utility rather than adding to it.
|
|
519
522
|
* ============================================ */
|
|
520
523
|
@theme {
|
|
521
|
-
|
|
524
|
+
/* The host app supplies the face through the variable; the family name is the
|
|
525
|
+
* var()'s own FALLBACK ARGUMENT, covering a host that installed the font
|
|
526
|
+
* without `next/font`, and the generic stack after it covers a host that did
|
|
527
|
+
* neither. Naming only the family would resolve to nothing under `next/font`,
|
|
528
|
+
* which self-hosts the face and exposes it ONLY as a variable -- a bare
|
|
529
|
+
* "Geist" there silently falls through to the system sans.
|
|
530
|
+
*
|
|
531
|
+
* The fallback has to sit INSIDE the parentheses. A family listed after the
|
|
532
|
+
* closing `)` is not reached when the variable is undefined: an unresolved
|
|
533
|
+
* `var()` with no fallback makes the whole declaration invalid at
|
|
534
|
+
* computed-value time, which for an inherited property like font-family means
|
|
535
|
+
* the element inherits its parent's face and the entire stack is discarded.
|
|
536
|
+
* The comma list looks like a fallback chain and is not one, so a host that
|
|
537
|
+
* skipped the variable rendered in whatever the page already used rather than
|
|
538
|
+
* in the generic sans this stack names.
|
|
539
|
+
*
|
|
540
|
+
* These are declared in a non-inline `@theme`, so they are emitted into
|
|
541
|
+
* `:root` and substitution happens THERE, not on the consuming element. A
|
|
542
|
+
* host must expose the variable at or above that scope -- `next/font`'s
|
|
543
|
+
* generated class belongs on `<html>`. On `<body>` the variable is invisible
|
|
544
|
+
* to this declaration no matter how it is spelled. */
|
|
545
|
+
--font-sans:
|
|
546
|
+
var(--font-geist, Geist), ui-sans-serif, system-ui, -apple-system,
|
|
547
|
+
"Segoe UI", sans-serif;
|
|
522
548
|
--font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
|
523
549
|
--font-mono:
|
|
524
|
-
ui-monospace, SFMono-Regular, Menlo,
|
|
525
|
-
"Courier New", monospace;
|
|
550
|
+
var(--font-geist-mono, "Geist Mono"), ui-monospace, SFMono-Regular, Menlo,
|
|
551
|
+
Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
526
552
|
|
|
527
553
|
/* Body text, captions */
|
|
528
554
|
--font-weight-normal: 400;
|
|
@@ -685,22 +711,23 @@
|
|
|
685
711
|
|
|
686
712
|
:root {
|
|
687
713
|
/* Base colors - using Slate neutral scale */
|
|
688
|
-
--nx-background: oklch(
|
|
714
|
+
--nx-background: oklch(0.99 0 0);
|
|
689
715
|
/* Pure white for weightless aesthetic */
|
|
690
|
-
--nx-page-background: oklch(0.
|
|
716
|
+
--nx-page-background: oklch(0.97 0 0);
|
|
691
717
|
/* #f9f9f9 for page content area */
|
|
692
|
-
--nx-foreground: oklch(0
|
|
693
|
-
/* slate-900 */
|
|
718
|
+
--nx-foreground: oklch(0 0 0);
|
|
694
719
|
|
|
695
720
|
/* Component colors */
|
|
696
721
|
--nx-card: oklch(1 0 0);
|
|
697
722
|
/* pure white for cards to pop on off-white bg */
|
|
698
|
-
--nx-card-foreground: oklch(0
|
|
699
|
-
|
|
700
|
-
--nx-popover: oklch(1 0 0);
|
|
723
|
+
--nx-card-foreground: oklch(0 0 0);
|
|
724
|
+
--nx-popover: oklch(0.99 0 0);
|
|
701
725
|
/* white */
|
|
702
|
-
--nx-popover-foreground: oklch(0
|
|
703
|
-
/*
|
|
726
|
+
--nx-popover-foreground: oklch(0 0 0);
|
|
727
|
+
/* Table headers, table footers and the pagination bar. A surface, so it lives
|
|
728
|
+
with the other surfaces: declared next to the component that paints it, a
|
|
729
|
+
palette change would move everything around it and leave it behind. */
|
|
730
|
+
--nx-table-header-bg: oklch(1 0 0);
|
|
704
731
|
|
|
705
732
|
/* Brand colors - Blue-Cyan Professional Palette */
|
|
706
733
|
--nx-primary: oklch(0 0 0);
|
|
@@ -709,41 +736,41 @@
|
|
|
709
736
|
/* white */
|
|
710
737
|
|
|
711
738
|
/* Secondary colors - using slate-100 for subtle backgrounds */
|
|
712
|
-
--nx-secondary: oklch(0.
|
|
739
|
+
--nx-secondary: oklch(0.94 0 0);
|
|
713
740
|
/* slate-100 */
|
|
714
|
-
--nx-secondary-foreground: oklch(0
|
|
715
|
-
/* slate-900 */
|
|
741
|
+
--nx-secondary-foreground: oklch(0 0 0);
|
|
716
742
|
|
|
717
743
|
/* Utility colors */
|
|
718
|
-
--nx-muted: oklch(0.
|
|
744
|
+
--nx-muted: oklch(0.97 0 0);
|
|
719
745
|
/* Darkened so muted text clears WCAG 4.5:1 on the muted surface (was 4.35:1). */
|
|
720
|
-
--nx-muted-foreground: oklch(0.
|
|
721
|
-
/*
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
--nx-accent-foreground: oklch(
|
|
725
|
-
/* white */
|
|
746
|
+
--nx-muted-foreground: oklch(0.44 0 0);
|
|
747
|
+
/* A hover and selection SURFACE, not ink: one step off the page, with
|
|
748
|
+
`--nx-accent-foreground` as the only thing meant to be read on it. */
|
|
749
|
+
--nx-accent: oklch(0.94 0 0);
|
|
750
|
+
--nx-accent-foreground: oklch(0 0 0);
|
|
726
751
|
|
|
727
752
|
/* State colors - WCAG 2.2 AA Compliant.
|
|
728
753
|
* Each status has two roles kept as separate tokens, the industry-standard
|
|
729
754
|
* split (Radix/Primer): the base token is the readable TEXT color used by
|
|
730
755
|
* `text-destructive` and derived shades, and `-solid` is the saturated FILL
|
|
731
|
-
* used by buttons under
|
|
732
|
-
*
|
|
733
|
-
* on the page
|
|
756
|
+
* used by buttons under the on-color ink. In light mode both roles can be
|
|
757
|
+
* the same value and the ink is white. In dark mode they cannot: a fill
|
|
758
|
+
* light enough to read as text on the page is too light for white text, so
|
|
759
|
+
* success splits the fill and destructive flips its ink to black instead.
|
|
760
|
+
* The on-color token is what varies, not just the fill. */
|
|
734
761
|
/* Darkened from red-500; renders as #d92c32, ~4.8:1 as text on white. */
|
|
735
|
-
--nx-destructive: oklch(0.
|
|
736
|
-
--nx-destructive-solid: oklch(0.
|
|
762
|
+
--nx-destructive: oklch(0.5661 0.19 23.03);
|
|
763
|
+
--nx-destructive-solid: oklch(0.5661 0.19 23.03);
|
|
737
764
|
--nx-destructive-foreground: oklch(1 0 0);
|
|
738
765
|
/* white */
|
|
739
766
|
/* Darkened from green-600; renders as #00852c, ~4.8:1 as text on white. */
|
|
740
|
-
--nx-success: oklch(0.
|
|
767
|
+
--nx-success: oklch(0.4981 0.17 149.2);
|
|
741
768
|
--nx-success-solid: oklch(0.53 0.17 149.2);
|
|
742
769
|
--nx-success-foreground: oklch(1 0 0);
|
|
743
770
|
/* white */
|
|
744
771
|
/* Darkened from amber-500 so it reads as text on white at WCAG 4.5:1 (was
|
|
745
772
|
* 2.15:1); its light shades still tint badge/alert surfaces. */
|
|
746
|
-
--nx-warning: oklch(0.
|
|
773
|
+
--nx-warning: oklch(0.529 0.1646 70.11);
|
|
747
774
|
--nx-warning-foreground: oklch(0.2079 0.0399 265.73);
|
|
748
775
|
/* slate-900 - REQUIRED for AA contrast (warning-500 on white = 3.4:1, fails AA) */
|
|
749
776
|
|
|
@@ -763,14 +790,14 @@
|
|
|
763
790
|
--nx-code-bg: oklch(0.9761 0.0035 247.86);
|
|
764
791
|
--nx-code-fg: oklch(0.2079 0.0399 265.73);
|
|
765
792
|
/* Darkened slightly to clear WCAG 4.5:1 on the code surface (was 4.44:1). */
|
|
766
|
-
--nx-code-comment: oklch(0.
|
|
793
|
+
--nx-code-comment: oklch(0.5264 0.0407 257.44);
|
|
767
794
|
--nx-code-keyword: oklch(0.4882 0.2172 303.9);
|
|
768
795
|
--nx-code-string: oklch(0.4478 0.1189 152.1);
|
|
769
796
|
--nx-code-number: oklch(0.5106 0.1518 44.2);
|
|
770
797
|
--nx-code-function: oklch(0.4757 0.1444 254.6);
|
|
771
798
|
--nx-code-operator: oklch(0.4936 0.1418 8.4);
|
|
772
799
|
/* Darkened slightly to clear WCAG 4.5:1 on the code surface (was 4.44:1). */
|
|
773
|
-
--nx-code-punctuation: oklch(0.
|
|
800
|
+
--nx-code-punctuation: oklch(0.5264 0.0407 257.44);
|
|
774
801
|
--nx-code-variable: oklch(0.4694 0.1173 62.3);
|
|
775
802
|
--nx-code-tag: oklch(0.5054 0.1905 27.5);
|
|
776
803
|
--nx-code-deleted: oklch(0.5054 0.1905 27.5);
|
|
@@ -799,12 +826,12 @@
|
|
|
799
826
|
/* For a scrim over CONTENT rather than the page: an image's hover actions,
|
|
800
827
|
* where the content beneath still has to read through. */
|
|
801
828
|
--nx-overlay-soft: oklch(0 0 0 / 0.4);
|
|
802
|
-
--nx-border-subtle: oklch(0 0 0
|
|
803
|
-
--nx-border: oklch(0 0 0
|
|
829
|
+
--nx-border-subtle: color-mix(in srgb, oklch(0.92 0 0), transparent 60%);
|
|
830
|
+
--nx-border: oklch(0.92 0 0);
|
|
804
831
|
/* Alpha raised so the composited strong border clears WCAG 3:1 / ~4:1 (was 2.11:1). */
|
|
805
|
-
--nx-border-strong: oklch(0 0 0
|
|
832
|
+
--nx-border-strong: oklch(0.58 0 0);
|
|
806
833
|
/* Darkened so the field border clears WCAG 3:1 on the page (was 2.32:1). */
|
|
807
|
-
--nx-input: oklch(0.
|
|
834
|
+
--nx-input: oklch(0.6154 0 0);
|
|
808
835
|
--nx-ring: var(--nx-primary);
|
|
809
836
|
|
|
810
837
|
/* The base colour of the elevation ramp (--shadow-sm..xl, -inner-subtle,
|
|
@@ -815,7 +842,6 @@
|
|
|
815
842
|
/* Chart colors for data visualization */
|
|
816
843
|
--nx-chart-1: var(--nx-primary);
|
|
817
844
|
--nx-chart-2: oklch(0.7399 0.1277 209.34);
|
|
818
|
-
/* cyan-500 */
|
|
819
845
|
--nx-chart-3: oklch(0.6273 0.17 149.2);
|
|
820
846
|
/* green-600 */
|
|
821
847
|
--nx-chart-4: oklch(0.7686 0.1646 70.11);
|
|
@@ -824,7 +850,10 @@
|
|
|
824
850
|
/* red-500 */
|
|
825
851
|
|
|
826
852
|
/* Design tokens */
|
|
827
|
-
|
|
853
|
+
/* The one corner knob. Every tier below derives from it, so this single
|
|
854
|
+
* declaration re-rounds the whole admin and a plugin built against the
|
|
855
|
+
* published preset re-rounds with it. */
|
|
856
|
+
--radius: 0.5rem;
|
|
828
857
|
|
|
829
858
|
/* Control sizing — derived from a single height knob so control density
|
|
830
859
|
* scales from one place. Steps map to the control size variants:
|
|
@@ -840,25 +869,25 @@
|
|
|
840
869
|
/* white */
|
|
841
870
|
|
|
842
871
|
/* Sidebar specific colors - using Slate scale */
|
|
843
|
-
--nx-sidebar-background:
|
|
872
|
+
--nx-sidebar-background: oklch(0.99 0 0);
|
|
844
873
|
/* flat with the content surface; nav is separated by borders, not fill */
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
--nx-sidebar-
|
|
874
|
+
/* Resting nav ink sits a step back from the active ink, so an active row
|
|
875
|
+
* reads as emphasised by its INK as well as its fill. The chosen palette
|
|
876
|
+
* used one value for both, which leaves the fill carrying the whole signal
|
|
877
|
+
* -- and the fill is the part a low-contrast surface weakens first. */
|
|
878
|
+
--nx-sidebar-foreground: oklch(0.44 0 0);
|
|
879
|
+
--nx-sidebar-primary: oklch(0 0 0);
|
|
880
|
+
--nx-sidebar-primary-foreground: oklch(1 0 0);
|
|
850
881
|
/* slate-50 */
|
|
851
|
-
--nx-sidebar-accent: oklch(0.
|
|
882
|
+
--nx-sidebar-accent: oklch(0.94 0 0);
|
|
852
883
|
/* slate-100 */
|
|
853
|
-
--nx-sidebar-accent-foreground: oklch(0
|
|
854
|
-
/* slate-900 */
|
|
884
|
+
--nx-sidebar-accent-foreground: oklch(0 0 0);
|
|
855
885
|
/* Darkened so the sidebar border clears WCAG 3:1 on its surface (was 1.23:1). */
|
|
856
|
-
--nx-sidebar-border: oklch(0.
|
|
857
|
-
/* slate-200 */
|
|
886
|
+
--nx-sidebar-border: oklch(0.63 0 0);
|
|
858
887
|
--nx-sidebar-ring: var(--nx-primary);
|
|
859
888
|
|
|
860
889
|
/* Data table specific colors */
|
|
861
|
-
--nx-table-row-hover: oklch(0.
|
|
890
|
+
--nx-table-row-hover: oklch(0.97 0 0);
|
|
862
891
|
--nx-table-row-selected: var(--nx-primary);
|
|
863
892
|
--nx-table-border: var(--nx-border);
|
|
864
893
|
}
|
|
@@ -866,61 +895,67 @@
|
|
|
866
895
|
/* Dark theme overrides when using class-based theming */
|
|
867
896
|
.dark {
|
|
868
897
|
/* Base colors - using Slate dark scale */
|
|
869
|
-
--nx-background: oklch(0
|
|
898
|
+
--nx-background: oklch(0 0 0);
|
|
870
899
|
/* ultra deep dark background (darker than slate-950) */
|
|
871
|
-
--nx-page-background: oklch(0.
|
|
900
|
+
--nx-page-background: oklch(0.23 0 0);
|
|
872
901
|
/* Matches background in dark mode */
|
|
873
|
-
--nx-foreground: oklch(0
|
|
902
|
+
--nx-foreground: oklch(1 0 0);
|
|
874
903
|
/* slate-50 */
|
|
875
904
|
|
|
876
905
|
/* Component colors */
|
|
877
|
-
--nx-card: oklch(0.
|
|
906
|
+
--nx-card: oklch(0.14 0 0);
|
|
878
907
|
/* raised one tonal step above --nx-background (222 47% 4%) so panels/cards
|
|
879
908
|
* read as distinct surfaces in dark mode instead of merging into the page */
|
|
880
|
-
--nx-card-foreground: oklch(0
|
|
909
|
+
--nx-card-foreground: oklch(1 0 0);
|
|
881
910
|
/* slate-50 */
|
|
882
911
|
/* Darkened toward the card elevation so borders, inputs, and muted text
|
|
883
912
|
* placed on a popover clear their WCAG minimums (border was 2.85:1, input
|
|
884
913
|
* 1.73:1); the surface was too light for its own contents. */
|
|
885
|
-
--nx-popover: oklch(0.
|
|
886
|
-
|
|
887
|
-
--nx-popover-foreground: oklch(0.9838 0.0035 247.86);
|
|
914
|
+
--nx-popover: oklch(0.18 0 0);
|
|
915
|
+
--nx-popover-foreground: oklch(1 0 0);
|
|
888
916
|
/* slate-50 */
|
|
917
|
+
/* A step above the card beneath it, carrying no chroma of its own: a hue here
|
|
918
|
+
would tint the header band independently of every surface around it. */
|
|
919
|
+
--nx-table-header-bg: oklch(0.1573 0 0);
|
|
889
920
|
|
|
890
921
|
/* Brand colors - Blue-Cyan Professional Palette (Dark Mode) */
|
|
891
922
|
--nx-primary: oklch(1 0 0); /* High contrast White for dark mode */
|
|
892
|
-
--nx-primary-foreground: oklch(0
|
|
893
|
-
/* slate-900 */
|
|
923
|
+
--nx-primary-foreground: oklch(0 0 0);
|
|
894
924
|
|
|
895
925
|
/* Secondary colors - using slate-800 for dark backgrounds */
|
|
896
|
-
--nx-secondary: oklch(0.
|
|
926
|
+
--nx-secondary: oklch(0.25 0 0);
|
|
897
927
|
/* slate-800 */
|
|
898
|
-
--nx-secondary-foreground: oklch(0
|
|
928
|
+
--nx-secondary-foreground: oklch(1 0 0);
|
|
899
929
|
/* slate-50 */
|
|
900
930
|
|
|
901
931
|
/* Utility colors */
|
|
902
|
-
--nx-muted: oklch(0.
|
|
903
|
-
|
|
904
|
-
--nx-muted
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
932
|
+
--nx-muted: oklch(0.23 0 0);
|
|
933
|
+
--nx-muted-foreground: oklch(0.72 0 0);
|
|
934
|
+
/* The hover and selected surface: one step lighter than --nx-muted so a row
|
|
935
|
+
under the pointer separates from a merely quiet one. Neutral, not the blue
|
|
936
|
+
it was once labelled -- a tinted accent reads as a status on a surface that
|
|
937
|
+
carries none. */
|
|
938
|
+
--nx-accent: oklch(0.32 0 0);
|
|
909
939
|
--nx-accent-foreground: oklch(1 0 0);
|
|
910
940
|
/* white */
|
|
911
941
|
|
|
912
942
|
/* State colors - WCAG 2.2 AA Compliant (Dark Mode).
|
|
913
943
|
* The base token is lightened from the fill color so it reads as text on the
|
|
914
|
-
* dark page at 4.5:1
|
|
915
|
-
*
|
|
916
|
-
*
|
|
944
|
+
* dark page at 4.5:1. The two statuses then resolve the on-color problem
|
|
945
|
+
* differently, because a fill light enough to read as text on a dark page is
|
|
946
|
+
* too light for white text: destructive keeps ONE value for base and fill
|
|
947
|
+
* and flips its ink to black (6.90:1), while success keeps a darker separate
|
|
948
|
+
* fill and keeps its ink white (4.80:1). Warning is already light enough to
|
|
949
|
+
* read on dark, so its base is unchanged here. */
|
|
917
950
|
/* Lightened red so it reads as text at WCAG 4.5:1 on the dark page and on the
|
|
918
951
|
* lighter popover surface (was 4.17:1 on the page, 4.25:1 on a popover). */
|
|
919
|
-
--nx-destructive: oklch(0.
|
|
920
|
-
/*
|
|
921
|
-
|
|
922
|
-
--nx-destructive-
|
|
923
|
-
/* white
|
|
952
|
+
--nx-destructive: oklch(0.69 0.2 23.91);
|
|
953
|
+
/* Same value as the base: the button fill needs no darkening here because
|
|
954
|
+
its ink is black rather than white. */
|
|
955
|
+
--nx-destructive-solid: oklch(0.69 0.2 23.91);
|
|
956
|
+
/* Black, not white. The dark-mode fill is light enough that black on-color
|
|
957
|
+
text reads at 6.90:1 where white would fall below the minimum. */
|
|
958
|
+
--nx-destructive-foreground: oklch(0 0 0);
|
|
924
959
|
/* Lightened green so it reads as text at WCAG 4.5:1 on the dark page and on
|
|
925
960
|
* the lighter popover surface (was 4.17:1 on the page, 4.29:1 on a popover). */
|
|
926
961
|
--nx-success: oklch(0.6 0.1921 149.58);
|
|
@@ -968,23 +1003,25 @@
|
|
|
968
1003
|
--nx-overlay: oklch(0 0 0 / 0.7);
|
|
969
1004
|
--nx-overlay-strong: oklch(0 0 0 / 0.85);
|
|
970
1005
|
--nx-overlay-soft: oklch(0 0 0 / 0.5);
|
|
971
|
-
--nx-border-subtle: oklch(
|
|
972
|
-
--nx-border: oklch(
|
|
1006
|
+
--nx-border-subtle: color-mix(in srgb, oklch(0.26 0 0), transparent 60%);
|
|
1007
|
+
--nx-border: oklch(0.26 0 0);
|
|
973
1008
|
/* Alpha raised so the composited strong border clears WCAG 3:1 / ~4:1 (was 3.00:1). */
|
|
974
|
-
--nx-border-strong: oklch(
|
|
1009
|
+
--nx-border-strong: oklch(0.5444 0 0);
|
|
975
1010
|
/* Brightened so the field border clears WCAG 3:1 on the lighter popover
|
|
976
1011
|
* surface as well as the page and card (was 1.73:1 on a popover). */
|
|
977
|
-
--nx-input: oklch(0.
|
|
1012
|
+
--nx-input: oklch(0.5445 0 0);
|
|
978
1013
|
--nx-ring: var(--nx-primary);
|
|
979
1014
|
|
|
980
1015
|
/* Black in dark mode too: the ramp reads as depth against the deep surfaces
|
|
981
|
-
* rather than as a glow, which a lightened shadow colour would produce.
|
|
1016
|
+
* rather than as a glow, which a lightened shadow colour would produce.
|
|
1017
|
+
* One --shadow-* ramp serves both modes and inlines a single set of
|
|
1018
|
+
* color-mix opacities, so this token is the only place elevation is
|
|
1019
|
+
* retuned -- overriding it resolves the whole ramp to that hue. */
|
|
982
1020
|
--nx-shadow-color: oklch(0 0 0);
|
|
983
1021
|
|
|
984
1022
|
/* Chart colors for data visualization (same as light mode) */
|
|
985
1023
|
--nx-chart-1: var(--nx-primary);
|
|
986
1024
|
--nx-chart-2: oklch(0.7399 0.1277 209.34);
|
|
987
|
-
/* cyan-500 */
|
|
988
1025
|
--nx-chart-3: oklch(0.7229 0.1921 149.58);
|
|
989
1026
|
/* green-500 */
|
|
990
1027
|
--nx-chart-4: oklch(0.7686 0.1646 70.11);
|
|
@@ -993,7 +1030,7 @@
|
|
|
993
1030
|
/* red-500 */
|
|
994
1031
|
|
|
995
1032
|
/* Sidebar specific colors - dark mode */
|
|
996
|
-
--nx-sidebar-background:
|
|
1033
|
+
--nx-sidebar-background: oklch(0.18 0 0);
|
|
997
1034
|
/* flat with the content surface; nav is separated by borders, not fill */
|
|
998
1035
|
/* Resting nav ink, dimmed off slate-50 so it sits a step below
|
|
999
1036
|
* --nx-sidebar-accent-foreground the way the light pair does: the lightness
|
|
@@ -1001,22 +1038,19 @@
|
|
|
1001
1038
|
* slate-900, so an active row reads as emphasised by its ink and not only by
|
|
1002
1039
|
* its fill. Chroma and hue track the theme's other secondary ink
|
|
1003
1040
|
* (--nx-muted-foreground) so lightness alone carries the hierarchy. */
|
|
1004
|
-
--nx-sidebar-foreground: oklch(0.
|
|
1005
|
-
--nx-sidebar-primary: oklch(0
|
|
1041
|
+
--nx-sidebar-foreground: oklch(0.72 0 0);
|
|
1042
|
+
--nx-sidebar-primary: oklch(1 0 0);
|
|
1006
1043
|
/* slate-50 */
|
|
1007
|
-
--nx-sidebar-primary-foreground: oklch(0
|
|
1008
|
-
|
|
1009
|
-
--nx-sidebar-accent: oklch(0
|
|
1010
|
-
/* slate-800 */
|
|
1011
|
-
--nx-sidebar-accent-foreground: oklch(0.9838 0.0035 247.86);
|
|
1044
|
+
--nx-sidebar-primary-foreground: oklch(0 0 0);
|
|
1045
|
+
--nx-sidebar-accent: oklch(0.32 0 0);
|
|
1046
|
+
--nx-sidebar-accent-foreground: oklch(1 0 0);
|
|
1012
1047
|
/* slate-50 */
|
|
1013
1048
|
/* Lightened so the sidebar border clears WCAG 3:1 on its surface (was 1.19:1). */
|
|
1014
|
-
--nx-sidebar-border: oklch(0.
|
|
1049
|
+
--nx-sidebar-border: oklch(0.519 0 0);
|
|
1015
1050
|
--nx-sidebar-ring: var(--nx-primary);
|
|
1016
1051
|
|
|
1017
1052
|
/* Data table specific colors - dark mode */
|
|
1018
|
-
--nx-table-row-hover: oklch(0.
|
|
1019
|
-
/* slate-800 */
|
|
1053
|
+
--nx-table-row-hover: oklch(0.23 0 0);
|
|
1020
1054
|
--nx-table-row-selected: var(--nx-primary);
|
|
1021
1055
|
--nx-table-border: var(--nx-border);
|
|
1022
1056
|
/* inherit the retuned white-alpha border (was a fixed faint slate) */
|
|
@@ -88,8 +88,8 @@ Do not hardcode hex, `rgb()`, `rgba()`, or named colors. The only literals allow
|
|
|
88
88
|
|
|
89
89
|
### Corner radius: pick a tier, never a value
|
|
90
90
|
|
|
91
|
-
The admin ships
|
|
92
|
-
knob, so an operator who sets `--radius:
|
|
91
|
+
The admin ships rounded today (`--radius: 0.5rem`), and the whole scale derives from that
|
|
92
|
+
one knob, so an operator who sets `--radius: 0` squares every surface at once. Your plugin
|
|
93
93
|
keeps up with that only if it picks a **tier by element category** rather than writing a
|
|
94
94
|
length. Hardcoding a corner — `rounded-none` just as much as `rounded-[6px]` or
|
|
95
95
|
`border-radius: 4px` — pins your UI at that value and opts it out of the knob.
|
|
@@ -113,14 +113,16 @@ Four consequences worth internalising:
|
|
|
113
113
|
- **`rounded-xl` and `rounded-2xl` are not tiers of this knob.** The preset exports only
|
|
114
114
|
`lg`, `md` and `sm`, so a plugin built against it gets Tailwind's fixed `0.75rem` /
|
|
115
115
|
`1rem` for those two, detached from `--radius`. Inside the admin's own build they are
|
|
116
|
-
defined, but as `--radius + 4px` and `--radius + 8px`, so at the shipped `--radius: 0`
|
|
117
|
-
they resolve to `
|
|
118
|
-
`sm` / `md` / `lg`.
|
|
119
|
-
-
|
|
120
|
-
and
|
|
121
|
-
`
|
|
122
|
-
|
|
123
|
-
|
|
116
|
+
defined, but as `--radius + 4px` and `--radius + 8px`, so at the shipped `--radius: 0.5rem`
|
|
117
|
+
they resolve to `12px` and `16px` — rounder than the container tier, and drifting further
|
|
118
|
+
as the knob grows. Pick from `sm` / `md` / `lg`.
|
|
119
|
+
- **A low knob drives the lower steps negative.** At the shipped `0.5rem` the three tiers
|
|
120
|
+
are `4px`, `6px` and `8px`, all positive. But `sm` and `md` SUBTRACT from the knob, so
|
|
121
|
+
anything under `4px` — `--radius: 0` most obviously — computes them to `-4px` and `-2px`.
|
|
122
|
+
They _render_ square only because `border-radius` clamps a negative length to `0` at
|
|
123
|
+
used-value time. The token keeps its negative value, so reading a step for padding, for an
|
|
124
|
+
inset, or through `getComputedStyle` gives you `-4px`, not `0`. Clamp it yourself if you
|
|
125
|
+
consume a step as a length rather than as a corner.
|
|
124
126
|
- **A rounded container must handle full-bleed children.** If a child paints a background
|
|
125
127
|
all the way to the container's edge (a tinted footer, a sticky header, a hover row), give
|
|
126
128
|
the container `overflow-hidden` or give the child a matching corner with
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextlyhq/ui",
|
|
3
|
-
"version": "0.0.2-alpha.
|
|
3
|
+
"version": "0.0.2-alpha.57",
|
|
4
4
|
"description": "Nextly UI — Reusable React component library for Nextly plugins and custom admin UIs",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -46,6 +46,16 @@
|
|
|
46
46
|
"default": "./dist/utils.cjs"
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
|
+
"./color": {
|
|
50
|
+
"import": {
|
|
51
|
+
"types": "./dist/color.d.ts",
|
|
52
|
+
"default": "./dist/color.mjs"
|
|
53
|
+
},
|
|
54
|
+
"require": {
|
|
55
|
+
"types": "./dist/color.d.cts",
|
|
56
|
+
"default": "./dist/color.cjs"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
49
59
|
"./theme.css": "./dist/theme.css",
|
|
50
60
|
"./styles.css": "./dist/styles.css",
|
|
51
61
|
"./styles.scoped.css": "./dist/styles.scoped.css"
|
|
@@ -55,10 +65,11 @@
|
|
|
55
65
|
],
|
|
56
66
|
"files": [
|
|
57
67
|
"dist",
|
|
58
|
-
"docs"
|
|
68
|
+
"docs",
|
|
69
|
+
"!dist/metafile-*.json"
|
|
59
70
|
],
|
|
60
71
|
"engines": {
|
|
61
|
-
"node": "
|
|
72
|
+
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
62
73
|
},
|
|
63
74
|
"peerDependencies": {
|
|
64
75
|
"lucide-react": ">=0.400.0",
|
|
@@ -68,6 +79,7 @@
|
|
|
68
79
|
"devDependencies": {
|
|
69
80
|
"@tailwindcss/cli": "^4.3.2",
|
|
70
81
|
"@types/culori": "^4.0.1",
|
|
82
|
+
"@types/node": "^20.19.17",
|
|
71
83
|
"@types/react": "19.2.0",
|
|
72
84
|
"@types/react-dom": "19.2.0",
|
|
73
85
|
"@vitejs/plugin-react": "^5.1.0",
|
|
@@ -86,9 +98,10 @@
|
|
|
86
98
|
"typescript": "^5.9.3",
|
|
87
99
|
"vite-tsconfig-paths": "^5.1.4",
|
|
88
100
|
"vitest": "^4.1.0",
|
|
89
|
-
"@nextlyhq/admin-css": "0.0.2-alpha.
|
|
90
|
-
"@nextlyhq/eslint-config": "0.0.2-alpha.
|
|
91
|
-
"@nextlyhq/
|
|
101
|
+
"@nextlyhq/admin-css": "0.0.2-alpha.57",
|
|
102
|
+
"@nextlyhq/eslint-config": "0.0.2-alpha.57",
|
|
103
|
+
"@nextlyhq/module-specifiers": "0.0.2-alpha.57",
|
|
104
|
+
"@nextlyhq/tsconfig": "0.0.2-alpha.57"
|
|
92
105
|
},
|
|
93
106
|
"dependencies": {
|
|
94
107
|
"@radix-ui/react-accordion": "^1.2.12",
|
|
@@ -104,6 +117,7 @@
|
|
|
104
117
|
"@radix-ui/react-radio-group": "^1.3.8",
|
|
105
118
|
"@radix-ui/react-select": "^2.2.6",
|
|
106
119
|
"@radix-ui/react-separator": "^1.1.8",
|
|
120
|
+
"@radix-ui/react-slider": "^1.4.7",
|
|
107
121
|
"@radix-ui/react-slot": "^1.2.4",
|
|
108
122
|
"@radix-ui/react-switch": "^1.2.6",
|
|
109
123
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
@@ -133,10 +147,10 @@
|
|
|
133
147
|
"author": "Nextly <contact@nextlyhq.com> (https://nextlyhq.com)",
|
|
134
148
|
"scripts": {
|
|
135
149
|
"build": "pnpm build:js && node scripts/build-css.mjs",
|
|
136
|
-
"build:js": "rimraf dist && tsup && tsup --config tsup.server-safe.config.ts && node scripts/check-client-directive.mjs",
|
|
150
|
+
"build:js": "rimraf dist && tsup && tsup --config tsup.server-safe.config.ts && node scripts/check-client-directive.mjs && node scripts/check-server-safe-artifacts.mjs",
|
|
137
151
|
"build:css": "node scripts/build-css.mjs",
|
|
138
152
|
"dev": "tsup --watch & tsup --config tsup.server-safe.config.ts --watch & wait",
|
|
139
|
-
"check-types": "tsc --noEmit",
|
|
153
|
+
"check-types": "tsc --noEmit && tsc --noEmit -p tsconfig.tests.json",
|
|
140
154
|
"lint": "eslint . --max-warnings 0",
|
|
141
155
|
"lint:fix": "eslint . --fix",
|
|
142
156
|
"test": "vitest run --passWithNoTests",
|