@santi020k/lumen 4.0.0 → 4.2.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/README.md CHANGED
@@ -68,6 +68,10 @@ also want to import its framework-neutral registry or diagnostics APIs:
68
68
  pnpm add @santi020k/lumen
69
69
  ```
70
70
 
71
+ Set direction with the `dir` attribute on `html` or a containing element. Select and NativeSelect
72
+ place their chevron from the nearest `dir="rtl"` or `dir="ltr"` ancestor, so nested LTR regions
73
+ inside RTL work even when a consumer CSS pipeline compiles `:dir()` into language selectors.
74
+
71
75
  ## Typography
72
76
 
73
77
  Lumen defaults `--ui-font` to the canonical Santi020k Montserrat family stack:
@@ -28,7 +28,7 @@
28
28
  "gradle": "9.8.0",
29
29
  "instrumentationApi": 35,
30
30
  "jdk": 21,
31
- "kotlin": "2.4.20",
31
+ "kotlin": "2.4.21",
32
32
  "minSdk": 23
33
33
  }
34
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@santi020k/lumen",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -51,7 +51,7 @@
51
51
  "lumen": "./bin/lumen.mjs"
52
52
  },
53
53
  "dependencies": {
54
- "@santi020k/lumen-core": "^4.0.0",
54
+ "@santi020k/lumen-core": "^4.1.0",
55
55
  "semver": "^7.8.5",
56
56
  "typescript": "~6.0.3"
57
57
  },
@@ -14,17 +14,17 @@
14
14
  "peerDependencies": {
15
15
  "astro": ">=5"
16
16
  },
17
- "version": "4.0.0"
17
+ "version": "4.1.0"
18
18
  },
19
19
  "@santi020k/lumen-core": {
20
20
  "peerDependencies": {
21
21
  "@rive-app/canvas": "^2.44.0"
22
22
  },
23
- "version": "4.0.0"
23
+ "version": "4.1.0"
24
24
  },
25
25
  "@santi020k/lumen-elements": {
26
26
  "peerDependencies": {},
27
- "version": "4.0.0"
27
+ "version": "4.2.0"
28
28
  },
29
29
  "@santi020k/lumen-icons-brand": {
30
30
  "peerDependencies": {},
@@ -34,18 +34,18 @@
34
34
  "peerDependencies": {
35
35
  "react": ">=19"
36
36
  },
37
- "version": "4.0.0"
37
+ "version": "4.2.0"
38
38
  },
39
39
  "@santi020k/lumen-mcp": {
40
40
  "peerDependencies": {},
41
- "version": "4.0.0"
41
+ "version": "4.2.0"
42
42
  },
43
43
  "@santi020k/lumen-react": {
44
44
  "peerDependencies": {
45
45
  "react": ">=19",
46
46
  "motion": "^14.0.0"
47
47
  },
48
- "version": "4.0.0"
48
+ "version": "4.1.0"
49
49
  },
50
50
  "@santi020k/lumen-react-hook-form": {
51
51
  "peerDependencies": {
@@ -53,7 +53,7 @@
53
53
  "react": ">=19",
54
54
  "react-hook-form": ">=7.76.0 <8"
55
55
  },
56
- "version": "4.0.0"
56
+ "version": "4.0.1"
57
57
  },
58
58
  "@santi020k/lumen-react-native": {
59
59
  "peerDependencies": {
@@ -62,7 +62,7 @@
62
62
  "react-native": ">=0.86.2",
63
63
  "react-native-svg": ">=12 <16"
64
64
  },
65
- "version": "4.0.0"
65
+ "version": "4.0.1"
66
66
  },
67
67
  "@santi020k/lumen-tokens": {
68
68
  "peerDependencies": {},
@@ -73,9 +73,9 @@
73
73
  "swift": {
74
74
  "package": "https://github.com/santi020k/lumen.git",
75
75
  "revision": null,
76
- "tag": "v4.0.0"
76
+ "tag": "v4.2.0"
77
77
  },
78
- "version": "4.0.0"
78
+ "version": "4.2.0"
79
79
  },
80
80
  "migration": {
81
81
  "codemod": null,
@@ -172,6 +172,17 @@
172
172
  }
173
173
  }
174
174
 
175
+ @keyframes ui-skeleton-pulse {
176
+ 0%,
177
+ 100% {
178
+ opacity: 1;
179
+ }
180
+
181
+ 50% {
182
+ opacity: 0.55;
183
+ }
184
+ }
185
+
175
186
  @keyframes ui-spin {
176
187
  to {
177
188
  transform: rotate(360deg);
@@ -790,15 +801,21 @@
790
801
  background-image:
791
802
  linear-gradient(45deg, transparent 50%, hsl(var(--ink-muted)) 50%),
792
803
  linear-gradient(135deg, hsl(var(--ink-muted)) 50%, transparent 50%);
793
- background-position:
794
- calc(100% - 1rem) 50%,
795
- calc(100% - 0.72rem) 50%;
804
+ background-position: var(--_ui-select-chevron, calc(100% - 1rem) 50%, calc(100% - 0.72rem) 50%);
796
805
  background-size:
797
806
  0.32rem 0.32rem,
798
807
  0.32rem 0.32rem;
799
808
  background-repeat: no-repeat;
800
809
  }
801
810
 
811
+ [dir="rtl"] {
812
+ --_ui-select-chevron: 0.72rem 50%, 1rem 50%;
813
+ }
814
+
815
+ [dir="ltr"] {
816
+ --_ui-select-chevron: calc(100% - 1rem) 50%, calc(100% - 0.72rem) 50%;
817
+ }
818
+
802
819
  .ui-label {
803
820
  color: hsl(var(--ink));
804
821
  font-size: 0.875rem;
@@ -820,6 +837,10 @@
820
837
  width: min(100%, 34rem);
821
838
  }
822
839
 
840
+ lumen-date-picker.ui-date-picker-field {
841
+ display: block;
842
+ }
843
+
823
844
  .ui-combobox > .ui-input {
824
845
  width: 100%;
825
846
  }
@@ -1007,7 +1028,9 @@
1007
1028
  }
1008
1029
 
1009
1030
  .ui-skeleton {
1010
- min-height: 1rem;
1031
+ /* A default height, not a minimum, lets explicit styles and classes size placeholders below 1rem. */
1032
+ width: var(--ui-skeleton-width, auto);
1033
+ height: var(--ui-skeleton-height, 1rem);
1011
1034
  border-radius: var(--ui-radius-sm);
1012
1035
  background: linear-gradient(
1013
1036
  90deg,
@@ -1019,6 +1042,42 @@
1019
1042
  animation: ui-shimmer 2.2s linear infinite;
1020
1043
  }
1021
1044
 
1045
+ .ui-skeleton:where(:not(:empty)) {
1046
+ height: var(--ui-skeleton-height, auto);
1047
+ min-height: 1rem;
1048
+ }
1049
+
1050
+ lumen-skeleton.ui-skeleton,
1051
+ lumen-progress.ui-progress {
1052
+ display: block;
1053
+ }
1054
+
1055
+ .ui-skeleton--text {
1056
+ height: var(--ui-skeleton-height, 0.75rem);
1057
+ }
1058
+
1059
+ .ui-skeleton--circle {
1060
+ flex: 0 0 auto;
1061
+ width: var(--ui-skeleton-width, var(--ui-skeleton-height, 2.5rem));
1062
+ height: var(--ui-skeleton-height, var(--ui-skeleton-width, 2.5rem));
1063
+ border-radius: 50%;
1064
+ }
1065
+
1066
+ .ui-skeleton--pulse {
1067
+ background: hsl(var(--surface-strong));
1068
+ animation: ui-skeleton-pulse 1.6s ease-in-out infinite;
1069
+ }
1070
+
1071
+ .ui-skeleton--static {
1072
+ animation: none;
1073
+ }
1074
+
1075
+ @media (prefers-reduced-motion: reduce) {
1076
+ .ui-skeleton {
1077
+ animation: none;
1078
+ }
1079
+ }
1080
+
1022
1081
  .ui-spinner {
1023
1082
  box-sizing: border-box;
1024
1083
  display: inline-block;
@@ -1586,7 +1645,9 @@ lumen-dialog.ui-dialog:not([hidden]):has(> [data-slot="dialog-body"]) {
1586
1645
 
1587
1646
  .ui-input-otp__native[data-ui-enhanced="true"] {
1588
1647
  position: absolute;
1589
- width: 1px;
1648
+ inset-block-start: 0;
1649
+ inset-inline-start: 0;
1650
+ width: 100%;
1590
1651
  height: 1px;
1591
1652
  overflow: hidden;
1592
1653
  clip-path: inset(50%);
package/styles.css CHANGED
@@ -179,6 +179,17 @@
179
179
  }
180
180
  }
181
181
 
182
+ @keyframes ui-skeleton-pulse {
183
+ 0%,
184
+ 100% {
185
+ opacity: 1;
186
+ }
187
+
188
+ 50% {
189
+ opacity: 0.55;
190
+ }
191
+ }
192
+
182
193
  @keyframes ui-spin {
183
194
  to {
184
195
  transform: rotate(360deg);
@@ -1663,15 +1674,26 @@
1663
1674
  background-image:
1664
1675
  linear-gradient(45deg, transparent 50%, hsl(var(--ink-muted)) 50%),
1665
1676
  linear-gradient(135deg, hsl(var(--ink-muted)) 50%, transparent 50%);
1666
- background-position:
1667
- calc(100% - 1rem) 50%,
1668
- calc(100% - 0.72rem) 50%;
1677
+ background-position: var(--_ui-select-chevron, calc(100% - 1rem) 50%, calc(100% - 0.72rem) 50%);
1669
1678
  background-size:
1670
1679
  0.32rem 0.32rem,
1671
1680
  0.32rem 0.32rem;
1672
1681
  background-repeat: no-repeat;
1673
1682
  }
1674
1683
 
1684
+ /*
1685
+ * Keep the chevron inside the inline-end padding. The private property inherits from the nearest
1686
+ * explicit `dir` attribute, so nested LTR regions inside RTL work and consumer CSS pipelines that
1687
+ * rewrite `:dir()` into language selectors cannot misplace it.
1688
+ */
1689
+ [dir="rtl"] {
1690
+ --_ui-select-chevron: 0.72rem 50%, 1rem 50%;
1691
+ }
1692
+
1693
+ [dir="ltr"] {
1694
+ --_ui-select-chevron: calc(100% - 1rem) 50%, calc(100% - 0.72rem) 50%;
1695
+ }
1696
+
1675
1697
  .ui-label {
1676
1698
  color: hsl(var(--ink));
1677
1699
  font-size: 0.875rem;
@@ -1693,6 +1715,10 @@
1693
1715
  width: min(100%, 34rem);
1694
1716
  }
1695
1717
 
1718
+ lumen-date-picker.ui-date-picker-field {
1719
+ display: block;
1720
+ }
1721
+
1696
1722
  .ui-combobox > .ui-input {
1697
1723
  width: 100%;
1698
1724
  }
@@ -1785,6 +1811,7 @@
1785
1811
 
1786
1812
  .ui-date-picker__popover {
1787
1813
  width: min(21rem, calc(100vw - 2rem));
1814
+ color: inherit;
1788
1815
  max-height: none;
1789
1816
  overflow: visible;
1790
1817
  border-radius: var(--ui-radius-lg);
@@ -2126,7 +2153,9 @@
2126
2153
  }
2127
2154
 
2128
2155
  .ui-skeleton {
2129
- min-height: 1rem;
2156
+ /* A default height, not a minimum, lets explicit styles and classes size placeholders below 1rem. */
2157
+ width: var(--ui-skeleton-width, auto);
2158
+ height: var(--ui-skeleton-height, 1rem);
2130
2159
  border-radius: var(--ui-radius-sm);
2131
2160
  background: linear-gradient(
2132
2161
  90deg,
@@ -2138,6 +2167,44 @@
2138
2167
  animation: ui-shimmer 2.2s linear infinite;
2139
2168
  }
2140
2169
 
2170
+ /* Skeletons that wrap text or elements keep growing with their content. */
2171
+ .ui-skeleton:where(:not(:empty)) {
2172
+ height: var(--ui-skeleton-height, auto);
2173
+ min-height: 1rem;
2174
+ }
2175
+
2176
+ lumen-skeleton.ui-skeleton,
2177
+ lumen-progress.ui-progress {
2178
+ display: block;
2179
+ }
2180
+
2181
+ .ui-skeleton--text {
2182
+ height: var(--ui-skeleton-height, 0.75rem);
2183
+ }
2184
+
2185
+ .ui-skeleton--circle {
2186
+ flex: 0 0 auto;
2187
+ width: var(--ui-skeleton-width, var(--ui-skeleton-height, 2.5rem));
2188
+ height: var(--ui-skeleton-height, var(--ui-skeleton-width, 2.5rem));
2189
+ border-radius: 50%;
2190
+ }
2191
+
2192
+ .ui-skeleton--pulse {
2193
+ background: hsl(var(--surface-strong));
2194
+ animation: ui-skeleton-pulse 1.6s ease-in-out infinite;
2195
+ }
2196
+
2197
+ .ui-skeleton--static {
2198
+ animation: none;
2199
+ }
2200
+
2201
+ /* Critical CSS omits the universal reduction below, so Skeleton stops its own loop. */
2202
+ @media (prefers-reduced-motion: reduce) {
2203
+ .ui-skeleton {
2204
+ animation: none;
2205
+ }
2206
+ }
2207
+
2141
2208
  .ui-icon {
2142
2209
  --ui-icon-size: 1em;
2143
2210
  display: inline-flex;
@@ -4271,9 +4338,12 @@ lumen-dialog-close {
4271
4338
  text-align: center;
4272
4339
  }
4273
4340
 
4341
+ /* A 1px-wide text field makes Chromium apply maxlength to the old value when input replaces a selection. */
4274
4342
  .ui-input-otp__native[data-ui-enhanced="true"] {
4275
4343
  position: absolute;
4276
- width: 1px;
4344
+ inset-block-start: 0;
4345
+ inset-inline-start: 0;
4346
+ width: 100%;
4277
4347
  height: 1px;
4278
4348
  overflow: hidden;
4279
4349
  clip-path: inset(50%);
package/v4-migration.json CHANGED
@@ -437,11 +437,12 @@
437
437
  "approval": {
438
438
  "approver": "Santiago Molina (santi020k)",
439
439
  "date": "2026-10-07",
440
- "decision": "Publish Lumen 4.0.0 and deploy the coordinated release; deliver playground 1.0.3 for Apple and Android review with current screenshots and listing metadata under the standing authorization, after all checks and reviews pass. Standing authorization is recorded by santi020k in PR #95 comment 6027959606.",
441
- "reviewedRevision": "cdb28a38aca0071af35021341bb7fbbefd7730a6",
440
+ "decision": "Approve the independently reviewed Mac certificate extraction correction and real macOS tool regression under the standing authorization recorded by santi020k in PR #95 comment 6027959606. Delivery remains conditional on all required hosted checks and current Codex review passing before protected merge. Preserve immutable v4.0.0 artifacts and approved iOS and Android submissions and rollout holds; deliver the corrected Mac build from merged main.",
441
+ "reviewedRevision": "eea78c5a5d49f9f6610fbe23b75a8e721db03f7e",
442
442
  "evidence": [
443
- "https://github.com/santi020k/lumen/commit/cdb28a38aca0071af35021341bb7fbbefd7730a6",
444
- "https://github.com/santi020k/lumen/pull/95"
443
+ "https://github.com/santi020k/lumen/commit/eea78c5a5d49f9f6610fbe23b75a8e721db03f7e",
444
+ "https://github.com/santi020k/lumen/pull/95",
445
+ "https://github.com/santi020k/lumen/pull/101"
445
446
  ]
446
447
  }
447
448
  }