@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.
Files changed (42) hide show
  1. package/dist/app-shell-core.css +1 -1
  2. package/dist/app-shell.d.ts +692 -106
  3. package/dist/app-shell.js +6294 -4939
  4. package/dist/{appshell-B0wh5Lq0.js → appshell-CahhZy7v.js} +316 -297
  5. package/dist/semantic-contrast.test.ts +154 -0
  6. package/dist/style-entry.d.ts +117 -82
  7. package/dist/testing.d.ts +122 -85
  8. package/dist/testing.js +1 -1
  9. package/dist/theme-bridge.test.ts +101 -1
  10. package/dist/theme.bridge.css +91 -0
  11. package/dist/theme.css +6 -1
  12. package/dist/themes/_template.css +7 -1
  13. package/dist/themes/bloom.css +0 -6
  14. package/dist/themes/cream.css +0 -6
  15. package/dist/themes/default.css +389 -69
  16. package/dist/vite-plugin.d.ts +117 -82
  17. package/package.json +1 -1
  18. package/skills/app-shell-patterns/SKILL.md +7 -5
  19. package/skills/app-shell-patterns/references/api/define-module.md +2 -2
  20. package/skills/app-shell-patterns/references/api/define-resource.md +2 -2
  21. package/skills/app-shell-patterns/references/api/use-app-shell-config.md +53 -47
  22. package/skills/app-shell-patterns/references/api/use-app-shell-data.md +30 -26
  23. package/skills/app-shell-patterns/references/api/use-app-shell.md +37 -30
  24. package/skills/app-shell-patterns/references/api/use-toast.md +28 -31
  25. package/skills/app-shell-patterns/references/components/app-shell.md +4 -4
  26. package/skills/app-shell-patterns/references/components/card.md +79 -7
  27. package/skills/app-shell-patterns/references/components/data-table.md +267 -52
  28. package/skills/app-shell-patterns/references/components/date-picker.md +32 -21
  29. package/skills/app-shell-patterns/references/components/filter-rail.md +165 -0
  30. package/skills/app-shell-patterns/references/components/sidebar-group.md +6 -0
  31. package/skills/app-shell-patterns/references/components/sidebar-section.md +114 -0
  32. package/skills/app-shell-patterns/references/concepts/custom-components.md +1 -1
  33. package/skills/app-shell-patterns/references/concepts/file-based-routing.md +7 -1
  34. package/skills/app-shell-patterns/references/concepts/graphql.md +20 -14
  35. package/skills/app-shell-patterns/references/concepts/routing-navigation.md +41 -3
  36. package/skills/app-shell-patterns/references/concepts/sidebar-navigation.md +32 -0
  37. package/skills/app-shell-patterns/references/concepts/styling-theming.md +255 -58
  38. package/skills/app-shell-patterns/references/migrations.md +21 -0
  39. package/skills/app-shell-patterns/references/pages/document-detail.md +6 -6
  40. package/skills/app-shell-patterns/references/patterns/form-modal.md +26 -20
  41. package/skills/app-shell-patterns/references/patterns/interaction-multi-select.md +129 -118
  42. 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 function that receives the URL segment.
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) => 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) => 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 Title {
575
+ declare namespace Image {
574
576
  var displayName: string;
575
577
  }
576
578
 
577
579
 
578
- declare namespace Description {
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 List {
590
+ declare namespace Header {
589
591
  var displayName: string;
590
592
  }
591
593
 
592
594
 
593
- declare namespace Tab {
595
+ declare namespace Body {
594
596
  var displayName: string;
595
597
  }
596
598
 
597
599
 
598
- declare namespace Panel {
600
+ declare namespace Footer {
599
601
  var displayName: string;
600
602
  }
601
603
 
602
604
 
603
- declare namespace Root {
605
+ declare namespace Row {
604
606
  var displayName: string;
605
607
  }
606
608
 
607
609
 
608
- declare namespace Image {
610
+ declare namespace Head {
609
611
  var displayName: string;
610
612
  }
611
613
 
612
614
 
613
- declare namespace Fallback {
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 Body {
635
+ declare namespace Content {
629
636
  var displayName: string;
630
637
  }
631
638
 
632
639
 
633
- declare namespace Footer {
640
+ declare namespace Root {
634
641
  var displayName: string;
635
642
  }
636
643
 
637
644
 
638
- declare namespace Row {
645
+ declare namespace Trigger {
639
646
  var displayName: string;
640
647
  }
641
648
 
642
649
 
643
- declare namespace Head {
650
+ declare namespace Close {
644
651
  var displayName: string;
645
652
  }
646
653
 
647
654
 
648
- declare namespace Cell {
655
+ declare namespace Content {
649
656
  var displayName: string;
650
657
  }
651
658
 
652
659
 
653
- declare namespace Caption {
660
+ declare namespace Header {
654
661
  var displayName: string;
655
662
  }
656
663
 
657
664
 
658
- declare namespace Root {
665
+ declare namespace Footer {
659
666
  var displayName: string;
660
667
  }
661
668
 
662
669
 
663
- declare namespace Header {
670
+ declare namespace Title {
664
671
  var displayName: string;
665
672
  }
666
673
 
667
674
 
668
- declare namespace Content {
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 Trigger {
685
+ declare namespace Legend {
679
686
  var displayName: string;
680
687
  }
681
688
 
682
689
 
683
- declare namespace Close {
690
+ declare namespace ComboboxRoot {
684
691
  var displayName: string;
685
692
  }
686
693
 
687
694
 
688
- declare namespace Content {
695
+ declare namespace ComboboxInput {
689
696
  var displayName: string;
690
697
  }
691
698
 
692
699
 
693
- declare namespace Header {
700
+ declare namespace ComboboxTrigger {
694
701
  var displayName: string;
695
702
  }
696
703
 
697
704
 
698
- declare namespace Footer {
705
+ declare namespace ComboboxInputGroup {
699
706
  var displayName: string;
700
707
  }
701
708
 
702
709
 
703
- declare namespace Title {
710
+ declare namespace ComboboxContent {
704
711
  var displayName: string;
705
712
  }
706
713
 
707
714
 
708
- declare namespace Description {
715
+ declare namespace ComboboxList {
709
716
  var displayName: string;
710
717
  }
711
718
 
712
719
 
713
- declare namespace Root {
720
+ declare namespace ComboboxItem {
714
721
  var displayName: string;
715
722
  }
716
723
 
717
724
 
718
- declare namespace Label {
725
+ declare namespace ComboboxEmpty {
719
726
  var displayName: string;
720
727
  }
721
728
 
722
729
 
723
- declare namespace Control {
730
+ declare namespace ComboboxGroup {
724
731
  var displayName: string;
725
732
  }
726
733
 
727
734
 
728
- declare namespace Description {
735
+ declare namespace ComboboxGroupLabel {
729
736
  var displayName: string;
730
737
  }
731
738
 
732
739
 
733
- declare namespace Error {
740
+ declare namespace ComboboxClear {
734
741
  var displayName: string;
735
742
  }
736
743
 
737
744
 
738
- declare namespace Validity {
745
+ declare namespace ComboboxChips {
739
746
  var displayName: string;
740
747
  }
741
748
 
742
749
 
743
- declare namespace Root {
750
+ declare namespace ComboboxChip {
744
751
  var displayName: string;
745
752
  }
746
753
 
747
754
 
748
- declare namespace Legend {
755
+ declare namespace ComboboxChipRemove {
749
756
  var displayName: string;
750
757
  }
751
758
 
752
759
 
753
- declare namespace Root {
760
+ declare namespace ComboboxValue {
754
761
  var displayName: string;
755
762
  }
756
763
 
757
764
 
758
- declare namespace Trigger {
765
+ declare namespace ComboboxStatus {
759
766
  var displayName: string;
760
767
  }
761
768
 
762
769
 
763
- declare namespace Content {
770
+ declare namespace ComboboxCollection {
764
771
  var displayName: string;
765
772
  }
766
773
 
767
774
 
768
- declare namespace Item {
775
+ declare namespace Root {
769
776
  var displayName: string;
770
777
  }
771
778
 
772
779
 
773
- declare namespace LinkItem {
780
+ declare namespace Label {
774
781
  var displayName: string;
775
782
  }
776
783
 
777
784
 
778
- declare namespace CheckboxItem {
785
+ declare namespace Control {
779
786
  var displayName: string;
780
787
  }
781
788
 
782
789
 
783
- declare namespace CheckboxItemIndicator {
790
+ declare namespace Description {
784
791
  var displayName: string;
785
792
  }
786
793
 
787
794
 
788
- declare namespace RadioItem {
795
+ declare namespace Error {
789
796
  var displayName: string;
790
797
  }
791
798
 
792
799
 
793
- declare namespace RadioItemIndicator {
800
+ declare namespace Validity {
794
801
  var displayName: string;
795
802
  }
796
803
 
797
804
 
798
- declare namespace RadioGroup {
805
+ declare namespace Root {
799
806
  var displayName: string;
800
807
  }
801
808
 
802
809
 
803
- declare namespace Group {
810
+ declare namespace Trigger {
804
811
  var displayName: string;
805
812
  }
806
813
 
807
814
 
808
- declare namespace GroupLabel {
815
+ declare namespace Content {
809
816
  var displayName: string;
810
817
  }
811
818
 
812
819
 
813
- declare namespace MenuSeparator {
820
+ declare namespace Item {
814
821
  var displayName: string;
815
822
  }
816
823
 
817
824
 
818
- declare namespace SubmenuRoot {
825
+ declare namespace LinkItem {
819
826
  var displayName: string;
820
827
  }
821
828
 
822
829
 
823
- declare namespace SubmenuTrigger {
830
+ declare namespace CheckboxItem {
824
831
  var displayName: string;
825
832
  }
826
833
 
827
834
 
828
- declare namespace Root {
835
+ declare namespace CheckboxItemIndicator {
829
836
  var displayName: string;
830
837
  }
831
838
 
832
839
 
833
- declare namespace Trigger {
840
+ declare namespace RadioItem {
834
841
  var displayName: string;
835
842
  }
836
843
 
837
844
 
838
- declare namespace Close {
845
+ declare namespace RadioItemIndicator {
839
846
  var displayName: string;
840
847
  }
841
848
 
842
849
 
843
- declare namespace Content {
850
+ declare namespace RadioGroup {
844
851
  var displayName: string;
845
852
  }
846
853
 
847
854
 
848
- declare namespace Header {
855
+ declare namespace Group {
849
856
  var displayName: string;
850
857
  }
851
858
 
852
859
 
853
- declare namespace Footer {
860
+ declare namespace GroupLabel {
854
861
  var displayName: string;
855
862
  }
856
863
 
857
864
 
858
- declare namespace Title {
865
+ declare namespace MenuSeparator {
859
866
  var displayName: string;
860
867
  }
861
868
 
862
869
 
863
- declare namespace Description {
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 SelectRoot {
900
+ declare namespace Root {
889
901
  var displayName: string;
890
902
  }
891
903
 
892
904
 
893
- declare namespace SelectTrigger {
905
+ declare namespace Trigger {
894
906
  var displayName: string;
895
907
  }
896
908
 
897
909
 
898
- declare namespace SelectValue {
910
+ declare namespace Close {
899
911
  var displayName: string;
900
912
  }
901
913
 
902
914
 
903
- declare namespace SelectContent {
915
+ declare namespace Content {
904
916
  var displayName: string;
905
917
  }
906
918
 
907
919
 
908
- declare namespace SelectItem {
920
+ declare namespace Header {
909
921
  var displayName: string;
910
922
  }
911
923
 
912
924
 
913
- declare namespace SelectGroup {
925
+ declare namespace Footer {
914
926
  var displayName: string;
915
927
  }
916
928
 
917
929
 
918
- declare namespace SelectGroupLabel {
930
+ declare namespace Title {
919
931
  var displayName: string;
920
932
  }
921
933
 
922
934
 
923
- declare namespace SelectSeparator {
935
+ declare namespace Description {
924
936
  var displayName: string;
925
937
  }
926
938
 
927
939
 
928
- declare namespace Provider {
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 Content {
980
+ declare namespace Settings {
944
981
  var displayName: string;
945
982
  }
946
983
 
947
984
 
948
- declare namespace ComboboxRoot {
985
+ declare namespace Provider {
949
986
  var displayName: string;
950
987
  }
951
988
 
952
989
 
953
- declare namespace ComboboxInput {
990
+ declare namespace Root {
954
991
  var displayName: string;
955
992
  }
956
993
 
957
994
 
958
- declare namespace ComboboxTrigger {
995
+ declare namespace Header {
959
996
  var displayName: string;
960
997
  }
961
998
 
962
999
 
963
- declare namespace ComboboxInputGroup {
1000
+ declare namespace ClearAll {
964
1001
  var displayName: string;
965
1002
  }
966
1003
 
967
1004
 
968
- declare namespace ComboboxContent {
1005
+ declare namespace Sections {
969
1006
  var displayName: string;
970
1007
  }
971
1008
 
972
1009
 
973
- declare namespace ComboboxList {
1010
+ declare namespace Provider {
974
1011
  var displayName: string;
975
1012
  }
976
1013
 
977
1014
 
978
- declare namespace ComboboxItem {
1015
+ declare namespace Root {
979
1016
  var displayName: string;
980
1017
  }
981
1018
 
982
1019
 
983
- declare namespace ComboboxEmpty {
1020
+ declare namespace Trigger {
984
1021
  var displayName: string;
985
1022
  }
986
1023
 
987
1024
 
988
- declare namespace ComboboxGroup {
1025
+ declare namespace Content {
989
1026
  var displayName: string;
990
1027
  }
991
1028
 
992
1029
 
993
- declare namespace ComboboxGroupLabel {
1030
+ declare namespace SelectRoot {
994
1031
  var displayName: string;
995
1032
  }
996
1033
 
997
1034
 
998
- declare namespace ComboboxClear {
1035
+ declare namespace SelectTrigger {
999
1036
  var displayName: string;
1000
1037
  }
1001
1038
 
1002
1039
 
1003
- declare namespace ComboboxChips {
1040
+ declare namespace SelectValue {
1004
1041
  var displayName: string;
1005
1042
  }
1006
1043
 
1007
1044
 
1008
- declare namespace ComboboxChip {
1045
+ declare namespace SelectContent {
1009
1046
  var displayName: string;
1010
1047
  }
1011
1048
 
1012
1049
 
1013
- declare namespace ComboboxChipRemove {
1050
+ declare namespace SelectItem {
1014
1051
  var displayName: string;
1015
1052
  }
1016
1053
 
1017
1054
 
1018
- declare namespace ComboboxValue {
1055
+ declare namespace SelectGroup {
1019
1056
  var displayName: string;
1020
1057
  }
1021
1058
 
1022
1059
 
1023
- declare namespace ComboboxStatus {
1060
+ declare namespace SelectGroupLabel {
1024
1061
  var displayName: string;
1025
1062
  }
1026
1063
 
1027
1064
 
1028
- declare namespace ComboboxCollection {
1065
+ declare namespace SelectSeparator {
1029
1066
  var displayName: string;
1030
1067
  }
1031
1068
 
package/dist/testing.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as e } from "./appshell-B0wh5Lq0.js";
1
+ import { n as e } from "./appshell-CahhZy7v.js";
2
2
  import { MemoryRouter as t, Route as n, Routes as r } from "react-router";
3
3
  import { jsx as i } from "react/jsx-runtime";
4
4
  //#region src/testing/test-router.tsx
@@ -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(["alert", "status"])("--%s-* tokens", (prefix) => {
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
  });