@tailor-platform/app-shell 1.16.0 → 1.17.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/dist/app-shell-core.css +1 -1
- package/dist/app-shell.d.ts +692 -106
- package/dist/app-shell.js +6294 -4939
- package/dist/{appshell-B0wh5Lq0.js → appshell-CahhZy7v.js} +316 -297
- package/dist/semantic-contrast.test.ts +154 -0
- package/dist/style-entry.d.ts +117 -82
- package/dist/testing.d.ts +122 -85
- package/dist/testing.js +1 -1
- package/dist/theme-bridge.test.ts +101 -1
- package/dist/theme.bridge.css +91 -0
- package/dist/theme.css +6 -1
- package/dist/themes/_template.css +7 -1
- package/dist/themes/bloom.css +0 -6
- package/dist/themes/cream.css +0 -6
- package/dist/themes/default.css +389 -69
- package/dist/vite-plugin.d.ts +117 -82
- package/package.json +1 -1
- package/skills/app-shell-patterns/SKILL.md +7 -5
- package/skills/app-shell-patterns/references/api/define-module.md +2 -2
- package/skills/app-shell-patterns/references/api/define-resource.md +2 -2
- package/skills/app-shell-patterns/references/api/use-app-shell-config.md +53 -47
- package/skills/app-shell-patterns/references/api/use-app-shell-data.md +30 -26
- package/skills/app-shell-patterns/references/api/use-app-shell.md +37 -30
- package/skills/app-shell-patterns/references/api/use-toast.md +28 -31
- package/skills/app-shell-patterns/references/components/app-shell.md +4 -4
- package/skills/app-shell-patterns/references/components/card.md +79 -7
- package/skills/app-shell-patterns/references/components/data-table.md +267 -52
- package/skills/app-shell-patterns/references/components/date-picker.md +32 -21
- package/skills/app-shell-patterns/references/components/filter-rail.md +165 -0
- package/skills/app-shell-patterns/references/components/sidebar-group.md +6 -0
- package/skills/app-shell-patterns/references/components/sidebar-section.md +114 -0
- package/skills/app-shell-patterns/references/concepts/custom-components.md +1 -1
- package/skills/app-shell-patterns/references/concepts/file-based-routing.md +7 -1
- package/skills/app-shell-patterns/references/concepts/graphql.md +20 -14
- package/skills/app-shell-patterns/references/concepts/routing-navigation.md +41 -3
- package/skills/app-shell-patterns/references/concepts/sidebar-navigation.md +32 -0
- package/skills/app-shell-patterns/references/concepts/styling-theming.md +255 -58
- package/skills/app-shell-patterns/references/migrations.md +21 -0
- package/skills/app-shell-patterns/references/pages/document-detail.md +6 -6
- package/skills/app-shell-patterns/references/patterns/form-modal.md +26 -20
- package/skills/app-shell-patterns/references/patterns/interaction-multi-select.md +129 -118
- package/skills/app-shell-patterns/references/patterns/list-dense-scan.md +2 -2
package/dist/testing.d.ts
CHANGED
|
@@ -52,9 +52,11 @@ declare type AppShellPageProps = {
|
|
|
52
52
|
icon?: ReactNode;
|
|
53
53
|
/**
|
|
54
54
|
* Custom breadcrumb segment title for this page.
|
|
55
|
-
* Can be a static string or a
|
|
55
|
+
* Can be a static string or a `labels.t("key")` translation function.
|
|
56
|
+
* Other callbacks receive the URL segment and may return a LocalizedString
|
|
57
|
+
* (e.g. `(segment) => labels.t("order", { id: segment })`), resolved using the current locale.
|
|
56
58
|
*/
|
|
57
|
-
breadcrumbTitle?: string | ((segment: string) =>
|
|
59
|
+
breadcrumbTitle?: string | ((segment: string) => LocalizedString);
|
|
58
60
|
};
|
|
59
61
|
/**
|
|
60
62
|
* Guards to control access to this page.
|
|
@@ -160,7 +162,7 @@ declare type CommonPageResource = {
|
|
|
160
162
|
meta: {
|
|
161
163
|
title: LocalizedString;
|
|
162
164
|
icon?: ReactNode;
|
|
163
|
-
breadcrumbTitle?: string | ((segment: string) =>
|
|
165
|
+
breadcrumbTitle?: string | ((segment: string) => LocalizedString);
|
|
164
166
|
};
|
|
165
167
|
};
|
|
166
168
|
|
|
@@ -570,12 +572,12 @@ declare namespace Root {
|
|
|
570
572
|
}
|
|
571
573
|
|
|
572
574
|
|
|
573
|
-
declare namespace
|
|
575
|
+
declare namespace Image {
|
|
574
576
|
var displayName: string;
|
|
575
577
|
}
|
|
576
578
|
|
|
577
579
|
|
|
578
|
-
declare namespace
|
|
580
|
+
declare namespace Fallback {
|
|
579
581
|
var displayName: string;
|
|
580
582
|
}
|
|
581
583
|
|
|
@@ -585,32 +587,37 @@ declare namespace Root {
|
|
|
585
587
|
}
|
|
586
588
|
|
|
587
589
|
|
|
588
|
-
declare namespace
|
|
590
|
+
declare namespace Header {
|
|
589
591
|
var displayName: string;
|
|
590
592
|
}
|
|
591
593
|
|
|
592
594
|
|
|
593
|
-
declare namespace
|
|
595
|
+
declare namespace Body {
|
|
594
596
|
var displayName: string;
|
|
595
597
|
}
|
|
596
598
|
|
|
597
599
|
|
|
598
|
-
declare namespace
|
|
600
|
+
declare namespace Footer {
|
|
599
601
|
var displayName: string;
|
|
600
602
|
}
|
|
601
603
|
|
|
602
604
|
|
|
603
|
-
declare namespace
|
|
605
|
+
declare namespace Row {
|
|
604
606
|
var displayName: string;
|
|
605
607
|
}
|
|
606
608
|
|
|
607
609
|
|
|
608
|
-
declare namespace
|
|
610
|
+
declare namespace Head {
|
|
609
611
|
var displayName: string;
|
|
610
612
|
}
|
|
611
613
|
|
|
612
614
|
|
|
613
|
-
declare namespace
|
|
615
|
+
declare namespace Cell {
|
|
616
|
+
var displayName: string;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
declare namespace Caption {
|
|
614
621
|
var displayName: string;
|
|
615
622
|
}
|
|
616
623
|
|
|
@@ -625,47 +632,47 @@ declare namespace Header {
|
|
|
625
632
|
}
|
|
626
633
|
|
|
627
634
|
|
|
628
|
-
declare namespace
|
|
635
|
+
declare namespace Content {
|
|
629
636
|
var displayName: string;
|
|
630
637
|
}
|
|
631
638
|
|
|
632
639
|
|
|
633
|
-
declare namespace
|
|
640
|
+
declare namespace Root {
|
|
634
641
|
var displayName: string;
|
|
635
642
|
}
|
|
636
643
|
|
|
637
644
|
|
|
638
|
-
declare namespace
|
|
645
|
+
declare namespace Trigger {
|
|
639
646
|
var displayName: string;
|
|
640
647
|
}
|
|
641
648
|
|
|
642
649
|
|
|
643
|
-
declare namespace
|
|
650
|
+
declare namespace Close {
|
|
644
651
|
var displayName: string;
|
|
645
652
|
}
|
|
646
653
|
|
|
647
654
|
|
|
648
|
-
declare namespace
|
|
655
|
+
declare namespace Content {
|
|
649
656
|
var displayName: string;
|
|
650
657
|
}
|
|
651
658
|
|
|
652
659
|
|
|
653
|
-
declare namespace
|
|
660
|
+
declare namespace Header {
|
|
654
661
|
var displayName: string;
|
|
655
662
|
}
|
|
656
663
|
|
|
657
664
|
|
|
658
|
-
declare namespace
|
|
665
|
+
declare namespace Footer {
|
|
659
666
|
var displayName: string;
|
|
660
667
|
}
|
|
661
668
|
|
|
662
669
|
|
|
663
|
-
declare namespace
|
|
670
|
+
declare namespace Title {
|
|
664
671
|
var displayName: string;
|
|
665
672
|
}
|
|
666
673
|
|
|
667
674
|
|
|
668
|
-
declare namespace
|
|
675
|
+
declare namespace Description {
|
|
669
676
|
var displayName: string;
|
|
670
677
|
}
|
|
671
678
|
|
|
@@ -675,192 +682,197 @@ declare namespace Root {
|
|
|
675
682
|
}
|
|
676
683
|
|
|
677
684
|
|
|
678
|
-
declare namespace
|
|
685
|
+
declare namespace Legend {
|
|
679
686
|
var displayName: string;
|
|
680
687
|
}
|
|
681
688
|
|
|
682
689
|
|
|
683
|
-
declare namespace
|
|
690
|
+
declare namespace ComboboxRoot {
|
|
684
691
|
var displayName: string;
|
|
685
692
|
}
|
|
686
693
|
|
|
687
694
|
|
|
688
|
-
declare namespace
|
|
695
|
+
declare namespace ComboboxInput {
|
|
689
696
|
var displayName: string;
|
|
690
697
|
}
|
|
691
698
|
|
|
692
699
|
|
|
693
|
-
declare namespace
|
|
700
|
+
declare namespace ComboboxTrigger {
|
|
694
701
|
var displayName: string;
|
|
695
702
|
}
|
|
696
703
|
|
|
697
704
|
|
|
698
|
-
declare namespace
|
|
705
|
+
declare namespace ComboboxInputGroup {
|
|
699
706
|
var displayName: string;
|
|
700
707
|
}
|
|
701
708
|
|
|
702
709
|
|
|
703
|
-
declare namespace
|
|
710
|
+
declare namespace ComboboxContent {
|
|
704
711
|
var displayName: string;
|
|
705
712
|
}
|
|
706
713
|
|
|
707
714
|
|
|
708
|
-
declare namespace
|
|
715
|
+
declare namespace ComboboxList {
|
|
709
716
|
var displayName: string;
|
|
710
717
|
}
|
|
711
718
|
|
|
712
719
|
|
|
713
|
-
declare namespace
|
|
720
|
+
declare namespace ComboboxItem {
|
|
714
721
|
var displayName: string;
|
|
715
722
|
}
|
|
716
723
|
|
|
717
724
|
|
|
718
|
-
declare namespace
|
|
725
|
+
declare namespace ComboboxEmpty {
|
|
719
726
|
var displayName: string;
|
|
720
727
|
}
|
|
721
728
|
|
|
722
729
|
|
|
723
|
-
declare namespace
|
|
730
|
+
declare namespace ComboboxGroup {
|
|
724
731
|
var displayName: string;
|
|
725
732
|
}
|
|
726
733
|
|
|
727
734
|
|
|
728
|
-
declare namespace
|
|
735
|
+
declare namespace ComboboxGroupLabel {
|
|
729
736
|
var displayName: string;
|
|
730
737
|
}
|
|
731
738
|
|
|
732
739
|
|
|
733
|
-
declare namespace
|
|
740
|
+
declare namespace ComboboxClear {
|
|
734
741
|
var displayName: string;
|
|
735
742
|
}
|
|
736
743
|
|
|
737
744
|
|
|
738
|
-
declare namespace
|
|
745
|
+
declare namespace ComboboxChips {
|
|
739
746
|
var displayName: string;
|
|
740
747
|
}
|
|
741
748
|
|
|
742
749
|
|
|
743
|
-
declare namespace
|
|
750
|
+
declare namespace ComboboxChip {
|
|
744
751
|
var displayName: string;
|
|
745
752
|
}
|
|
746
753
|
|
|
747
754
|
|
|
748
|
-
declare namespace
|
|
755
|
+
declare namespace ComboboxChipRemove {
|
|
749
756
|
var displayName: string;
|
|
750
757
|
}
|
|
751
758
|
|
|
752
759
|
|
|
753
|
-
declare namespace
|
|
760
|
+
declare namespace ComboboxValue {
|
|
754
761
|
var displayName: string;
|
|
755
762
|
}
|
|
756
763
|
|
|
757
764
|
|
|
758
|
-
declare namespace
|
|
765
|
+
declare namespace ComboboxStatus {
|
|
759
766
|
var displayName: string;
|
|
760
767
|
}
|
|
761
768
|
|
|
762
769
|
|
|
763
|
-
declare namespace
|
|
770
|
+
declare namespace ComboboxCollection {
|
|
764
771
|
var displayName: string;
|
|
765
772
|
}
|
|
766
773
|
|
|
767
774
|
|
|
768
|
-
declare namespace
|
|
775
|
+
declare namespace Root {
|
|
769
776
|
var displayName: string;
|
|
770
777
|
}
|
|
771
778
|
|
|
772
779
|
|
|
773
|
-
declare namespace
|
|
780
|
+
declare namespace Label {
|
|
774
781
|
var displayName: string;
|
|
775
782
|
}
|
|
776
783
|
|
|
777
784
|
|
|
778
|
-
declare namespace
|
|
785
|
+
declare namespace Control {
|
|
779
786
|
var displayName: string;
|
|
780
787
|
}
|
|
781
788
|
|
|
782
789
|
|
|
783
|
-
declare namespace
|
|
790
|
+
declare namespace Description {
|
|
784
791
|
var displayName: string;
|
|
785
792
|
}
|
|
786
793
|
|
|
787
794
|
|
|
788
|
-
declare namespace
|
|
795
|
+
declare namespace Error {
|
|
789
796
|
var displayName: string;
|
|
790
797
|
}
|
|
791
798
|
|
|
792
799
|
|
|
793
|
-
declare namespace
|
|
800
|
+
declare namespace Validity {
|
|
794
801
|
var displayName: string;
|
|
795
802
|
}
|
|
796
803
|
|
|
797
804
|
|
|
798
|
-
declare namespace
|
|
805
|
+
declare namespace Root {
|
|
799
806
|
var displayName: string;
|
|
800
807
|
}
|
|
801
808
|
|
|
802
809
|
|
|
803
|
-
declare namespace
|
|
810
|
+
declare namespace Trigger {
|
|
804
811
|
var displayName: string;
|
|
805
812
|
}
|
|
806
813
|
|
|
807
814
|
|
|
808
|
-
declare namespace
|
|
815
|
+
declare namespace Content {
|
|
809
816
|
var displayName: string;
|
|
810
817
|
}
|
|
811
818
|
|
|
812
819
|
|
|
813
|
-
declare namespace
|
|
820
|
+
declare namespace Item {
|
|
814
821
|
var displayName: string;
|
|
815
822
|
}
|
|
816
823
|
|
|
817
824
|
|
|
818
|
-
declare namespace
|
|
825
|
+
declare namespace LinkItem {
|
|
819
826
|
var displayName: string;
|
|
820
827
|
}
|
|
821
828
|
|
|
822
829
|
|
|
823
|
-
declare namespace
|
|
830
|
+
declare namespace CheckboxItem {
|
|
824
831
|
var displayName: string;
|
|
825
832
|
}
|
|
826
833
|
|
|
827
834
|
|
|
828
|
-
declare namespace
|
|
835
|
+
declare namespace CheckboxItemIndicator {
|
|
829
836
|
var displayName: string;
|
|
830
837
|
}
|
|
831
838
|
|
|
832
839
|
|
|
833
|
-
declare namespace
|
|
840
|
+
declare namespace RadioItem {
|
|
834
841
|
var displayName: string;
|
|
835
842
|
}
|
|
836
843
|
|
|
837
844
|
|
|
838
|
-
declare namespace
|
|
845
|
+
declare namespace RadioItemIndicator {
|
|
839
846
|
var displayName: string;
|
|
840
847
|
}
|
|
841
848
|
|
|
842
849
|
|
|
843
|
-
declare namespace
|
|
850
|
+
declare namespace RadioGroup {
|
|
844
851
|
var displayName: string;
|
|
845
852
|
}
|
|
846
853
|
|
|
847
854
|
|
|
848
|
-
declare namespace
|
|
855
|
+
declare namespace Group {
|
|
849
856
|
var displayName: string;
|
|
850
857
|
}
|
|
851
858
|
|
|
852
859
|
|
|
853
|
-
declare namespace
|
|
860
|
+
declare namespace GroupLabel {
|
|
854
861
|
var displayName: string;
|
|
855
862
|
}
|
|
856
863
|
|
|
857
864
|
|
|
858
|
-
declare namespace
|
|
865
|
+
declare namespace MenuSeparator {
|
|
859
866
|
var displayName: string;
|
|
860
867
|
}
|
|
861
868
|
|
|
862
869
|
|
|
863
|
-
declare namespace
|
|
870
|
+
declare namespace SubmenuRoot {
|
|
871
|
+
var displayName: string;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
declare namespace SubmenuTrigger {
|
|
864
876
|
var displayName: string;
|
|
865
877
|
}
|
|
866
878
|
|
|
@@ -885,47 +897,62 @@ declare namespace Separator {
|
|
|
885
897
|
}
|
|
886
898
|
|
|
887
899
|
|
|
888
|
-
declare namespace
|
|
900
|
+
declare namespace Root {
|
|
889
901
|
var displayName: string;
|
|
890
902
|
}
|
|
891
903
|
|
|
892
904
|
|
|
893
|
-
declare namespace
|
|
905
|
+
declare namespace Trigger {
|
|
894
906
|
var displayName: string;
|
|
895
907
|
}
|
|
896
908
|
|
|
897
909
|
|
|
898
|
-
declare namespace
|
|
910
|
+
declare namespace Close {
|
|
899
911
|
var displayName: string;
|
|
900
912
|
}
|
|
901
913
|
|
|
902
914
|
|
|
903
|
-
declare namespace
|
|
915
|
+
declare namespace Content {
|
|
904
916
|
var displayName: string;
|
|
905
917
|
}
|
|
906
918
|
|
|
907
919
|
|
|
908
|
-
declare namespace
|
|
920
|
+
declare namespace Header {
|
|
909
921
|
var displayName: string;
|
|
910
922
|
}
|
|
911
923
|
|
|
912
924
|
|
|
913
|
-
declare namespace
|
|
925
|
+
declare namespace Footer {
|
|
914
926
|
var displayName: string;
|
|
915
927
|
}
|
|
916
928
|
|
|
917
929
|
|
|
918
|
-
declare namespace
|
|
930
|
+
declare namespace Title {
|
|
919
931
|
var displayName: string;
|
|
920
932
|
}
|
|
921
933
|
|
|
922
934
|
|
|
923
|
-
declare namespace
|
|
935
|
+
declare namespace Description {
|
|
924
936
|
var displayName: string;
|
|
925
937
|
}
|
|
926
938
|
|
|
927
939
|
|
|
928
|
-
declare namespace
|
|
940
|
+
declare namespace Root {
|
|
941
|
+
var displayName: string;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
declare namespace List {
|
|
946
|
+
var displayName: string;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
declare namespace Tab {
|
|
951
|
+
var displayName: string;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
declare namespace Panel {
|
|
929
956
|
var displayName: string;
|
|
930
957
|
}
|
|
931
958
|
|
|
@@ -935,97 +962,107 @@ declare namespace Root {
|
|
|
935
962
|
}
|
|
936
963
|
|
|
937
964
|
|
|
965
|
+
declare namespace Title {
|
|
966
|
+
var displayName: string;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
declare namespace Description {
|
|
971
|
+
var displayName: string;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
|
|
938
975
|
declare namespace Trigger {
|
|
939
976
|
var displayName: string;
|
|
940
977
|
}
|
|
941
978
|
|
|
942
979
|
|
|
943
|
-
declare namespace
|
|
980
|
+
declare namespace Settings {
|
|
944
981
|
var displayName: string;
|
|
945
982
|
}
|
|
946
983
|
|
|
947
984
|
|
|
948
|
-
declare namespace
|
|
985
|
+
declare namespace Provider {
|
|
949
986
|
var displayName: string;
|
|
950
987
|
}
|
|
951
988
|
|
|
952
989
|
|
|
953
|
-
declare namespace
|
|
990
|
+
declare namespace Root {
|
|
954
991
|
var displayName: string;
|
|
955
992
|
}
|
|
956
993
|
|
|
957
994
|
|
|
958
|
-
declare namespace
|
|
995
|
+
declare namespace Header {
|
|
959
996
|
var displayName: string;
|
|
960
997
|
}
|
|
961
998
|
|
|
962
999
|
|
|
963
|
-
declare namespace
|
|
1000
|
+
declare namespace ClearAll {
|
|
964
1001
|
var displayName: string;
|
|
965
1002
|
}
|
|
966
1003
|
|
|
967
1004
|
|
|
968
|
-
declare namespace
|
|
1005
|
+
declare namespace Sections {
|
|
969
1006
|
var displayName: string;
|
|
970
1007
|
}
|
|
971
1008
|
|
|
972
1009
|
|
|
973
|
-
declare namespace
|
|
1010
|
+
declare namespace Provider {
|
|
974
1011
|
var displayName: string;
|
|
975
1012
|
}
|
|
976
1013
|
|
|
977
1014
|
|
|
978
|
-
declare namespace
|
|
1015
|
+
declare namespace Root {
|
|
979
1016
|
var displayName: string;
|
|
980
1017
|
}
|
|
981
1018
|
|
|
982
1019
|
|
|
983
|
-
declare namespace
|
|
1020
|
+
declare namespace Trigger {
|
|
984
1021
|
var displayName: string;
|
|
985
1022
|
}
|
|
986
1023
|
|
|
987
1024
|
|
|
988
|
-
declare namespace
|
|
1025
|
+
declare namespace Content {
|
|
989
1026
|
var displayName: string;
|
|
990
1027
|
}
|
|
991
1028
|
|
|
992
1029
|
|
|
993
|
-
declare namespace
|
|
1030
|
+
declare namespace SelectRoot {
|
|
994
1031
|
var displayName: string;
|
|
995
1032
|
}
|
|
996
1033
|
|
|
997
1034
|
|
|
998
|
-
declare namespace
|
|
1035
|
+
declare namespace SelectTrigger {
|
|
999
1036
|
var displayName: string;
|
|
1000
1037
|
}
|
|
1001
1038
|
|
|
1002
1039
|
|
|
1003
|
-
declare namespace
|
|
1040
|
+
declare namespace SelectValue {
|
|
1004
1041
|
var displayName: string;
|
|
1005
1042
|
}
|
|
1006
1043
|
|
|
1007
1044
|
|
|
1008
|
-
declare namespace
|
|
1045
|
+
declare namespace SelectContent {
|
|
1009
1046
|
var displayName: string;
|
|
1010
1047
|
}
|
|
1011
1048
|
|
|
1012
1049
|
|
|
1013
|
-
declare namespace
|
|
1050
|
+
declare namespace SelectItem {
|
|
1014
1051
|
var displayName: string;
|
|
1015
1052
|
}
|
|
1016
1053
|
|
|
1017
1054
|
|
|
1018
|
-
declare namespace
|
|
1055
|
+
declare namespace SelectGroup {
|
|
1019
1056
|
var displayName: string;
|
|
1020
1057
|
}
|
|
1021
1058
|
|
|
1022
1059
|
|
|
1023
|
-
declare namespace
|
|
1060
|
+
declare namespace SelectGroupLabel {
|
|
1024
1061
|
var displayName: string;
|
|
1025
1062
|
}
|
|
1026
1063
|
|
|
1027
1064
|
|
|
1028
|
-
declare namespace
|
|
1065
|
+
declare namespace SelectSeparator {
|
|
1029
1066
|
var displayName: string;
|
|
1030
1067
|
}
|
|
1031
1068
|
|
package/dist/testing.js
CHANGED
|
@@ -14,6 +14,9 @@ const here = dirname(fileURLToPath(import.meta.url));
|
|
|
14
14
|
const bridge = readFileSync(join(here, "theme.bridge.css"), "utf8");
|
|
15
15
|
const defaultTheme = readFileSync(join(here, "themes/default.css"), "utf8");
|
|
16
16
|
|
|
17
|
+
/** Semantic colour roles: 5 intents x 8 roles, named `--{intent}-{role}`. */
|
|
18
|
+
const SEMANTIC_PREFIX = "(?:info|success|warning|danger|neutral)";
|
|
19
|
+
|
|
17
20
|
/** Token names defined in the default palette for a given prefix, e.g. `alert`. */
|
|
18
21
|
function definedTokens(prefix: string): string[] {
|
|
19
22
|
const matches = defaultTheme.matchAll(new RegExp(`^\\s*--(${prefix}-[a-z-]+):`, "gm"));
|
|
@@ -29,7 +32,11 @@ function bridgedTokens(prefix: string): Map<string, string> {
|
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
describe("theme bridge", () => {
|
|
32
|
-
describe.each([
|
|
35
|
+
describe.each([
|
|
36
|
+
["alert", "alert"],
|
|
37
|
+
["status", "status"],
|
|
38
|
+
["semantic colour role", SEMANTIC_PREFIX],
|
|
39
|
+
])("--%s-* tokens", (_label, prefix) => {
|
|
33
40
|
const defined = definedTokens(prefix);
|
|
34
41
|
const bridged = bridgedTokens(prefix);
|
|
35
42
|
|
|
@@ -56,4 +63,97 @@ describe("theme bridge", () => {
|
|
|
56
63
|
// both files — fails loudly.
|
|
57
64
|
expect(bridgedTokens("alert").size).toBe(20);
|
|
58
65
|
});
|
|
66
|
+
|
|
67
|
+
it("bridges all 40 semantic colour roles", () => {
|
|
68
|
+
// 5 intents x 8 roles, pinned for the same reason as the alert count.
|
|
69
|
+
expect(bridgedTokens(SEMANTIC_PREFIX).size).toBe(40);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe("typography roles", () => {
|
|
73
|
+
const slots = ["size", "line-height", "weight", "letter-spacing"] as const;
|
|
74
|
+
/** `--app-shell-type-<role>-<slot>` variables in the default palette, grouped by role. */
|
|
75
|
+
const defined = new Map<string, Map<string, string>>();
|
|
76
|
+
for (const m of defaultTheme.matchAll(
|
|
77
|
+
/^\s*--app-shell-type-([a-z-]+)-(size|line-height|weight|letter-spacing):\s*([^;]+);/gm,
|
|
78
|
+
)) {
|
|
79
|
+
const role = m[1];
|
|
80
|
+
defined.set(role, (defined.get(role) ?? new Map()).set(m[2], m[3].trim()));
|
|
81
|
+
}
|
|
82
|
+
/** Bridge entries `--text-<role>[--<suffix>]: var(--app-shell-type-...)`, keyed by property name. */
|
|
83
|
+
const bridgedText = new Map(
|
|
84
|
+
[...bridge.matchAll(/^\s*(--text-[a-z-]+):\s*var\((--app-shell-type-[a-z-]+)\);/gm)].map(
|
|
85
|
+
(m) => [m[1], m[2]],
|
|
86
|
+
),
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
it("pins the role count at 10", () => {
|
|
90
|
+
// Dropping a whole role from both files would still pass the symmetry checks.
|
|
91
|
+
expect(defined.size).toBe(10);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("defines exactly four variables per role", () => {
|
|
95
|
+
for (const [role, values] of defined) {
|
|
96
|
+
expect([...values.keys()].toSorted(), role).toEqual([...slots].toSorted());
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("bridges every role slot to its own variable", () => {
|
|
101
|
+
const suffix = {
|
|
102
|
+
size: "",
|
|
103
|
+
"line-height": "--line-height",
|
|
104
|
+
weight: "--font-weight",
|
|
105
|
+
"letter-spacing": "--letter-spacing",
|
|
106
|
+
} as const;
|
|
107
|
+
const expected = new Map<string, string>();
|
|
108
|
+
for (const role of defined.keys()) {
|
|
109
|
+
for (const slot of slots) {
|
|
110
|
+
expected.set(`--text-${role}${suffix[slot]}`, `--app-shell-type-${role}-${slot}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
expect(bridgedText).toEqual(expected);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("does not collide with a --color-* token that Tailwind resolves first", () => {
|
|
117
|
+
// `text-<name>` resolves against --color-<name> before --text-<name>.
|
|
118
|
+
const colors = [...bridge.matchAll(/^\s*--color-([a-z0-9-]+):/gm)].map((m) => m[1]);
|
|
119
|
+
for (const role of defined.keys()) {
|
|
120
|
+
expect(colors, role).not.toContain(role);
|
|
121
|
+
}
|
|
122
|
+
for (const name of colors) {
|
|
123
|
+
expect(name).not.toMatch(/^(heading|body|label|code)(-|$)/);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("keeps the line boxes on the spec values", () => {
|
|
128
|
+
// size (px) x line-height ratio = line box (px); weight and letter spacing are pinned too. Values from decisions/typography-roles.md.
|
|
129
|
+
const spec: Record<
|
|
130
|
+
string,
|
|
131
|
+
[size: number, lineBox: number, weight: number, letterSpacing: string]
|
|
132
|
+
> = {
|
|
133
|
+
"heading-lg": [24, 32, 700, "-0.025em"],
|
|
134
|
+
"heading-md": [18, 28, 600, "0em"],
|
|
135
|
+
"heading-sm": [14, 20, 600, "0em"],
|
|
136
|
+
"body-md": [14, 20, 400, "0em"],
|
|
137
|
+
"body-sm": [12, 16, 400, "0em"],
|
|
138
|
+
"label-md": [14, 20, 500, "0em"],
|
|
139
|
+
"label-sm": [12, 16, 500, "0em"],
|
|
140
|
+
"code-sm": [12, 18, 400, "0em"],
|
|
141
|
+
"body-md-relaxed": [14, 24, 400, "0em"],
|
|
142
|
+
"body-sm-relaxed": [12, 20, 400, "0em"],
|
|
143
|
+
};
|
|
144
|
+
expect([...defined.keys()].toSorted()).toEqual(Object.keys(spec).toSorted());
|
|
145
|
+
for (const [role, [size, lineBox, weight, letterSpacing]] of Object.entries(spec)) {
|
|
146
|
+
const values = defined.get(role)!;
|
|
147
|
+
const rem = /^([0-9.]+)rem$/.exec(values.get("size") ?? "");
|
|
148
|
+
expect(rem, `${role} size`).not.toBeNull();
|
|
149
|
+
expect(Number(rem![1]) * 16, `${role} size`).toBe(size);
|
|
150
|
+
const ratio = /^calc\((\d+) \/ (\d+)\)$/.exec(values.get("line-height") ?? "");
|
|
151
|
+
expect(ratio, `${role} line-height`).not.toBeNull();
|
|
152
|
+
expect(Number(ratio![2]), `${role} ratio base`).toBe(size);
|
|
153
|
+
expect(Number(ratio![1]), `${role} line box`).toBe(lineBox);
|
|
154
|
+
expect(Number(values.get("weight")), `${role} weight`).toBe(weight);
|
|
155
|
+
expect(values.get("letter-spacing"), `${role} letter-spacing`).toBe(letterSpacing);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
59
159
|
});
|