@photonix/basic 3.5.0 → 3.7.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/index.css CHANGED
@@ -14,6 +14,14 @@
14
14
  --surface-brand-subtle: var(--color-primary-100);
15
15
  --surface-brand-primary-subtle: var(--color-primary-100);
16
16
  }
17
+ :root {
18
+ --corner-scale: 1;
19
+ }
20
+ @supports (corner-shape: squircle) {
21
+ :root {
22
+ --corner-scale: 1.5;
23
+ }
24
+ }
17
25
  :root,
18
26
  [data-theme] {
19
27
  --shadow-xs: var(--shadow-down-xs);
@@ -944,40 +952,52 @@
944
952
  border-radius: var(--radius-none);
945
953
  }
946
954
  .rounded4Xs {
947
- border-radius: var(--radius-4xs);
955
+ border-radius: calc(var(--radius-4xs) * var(--corner-scale, 1));
956
+ corner-shape: squircle;
948
957
  }
949
958
  .rounded3Xs {
950
- border-radius: var(--radius-3xs);
959
+ border-radius: calc(var(--radius-3xs) * var(--corner-scale, 1));
960
+ corner-shape: squircle;
951
961
  }
952
962
  .rounded2Xs {
953
- border-radius: var(--radius-2xs);
963
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
964
+ corner-shape: squircle;
954
965
  }
955
966
  .roundedXs {
956
- border-radius: var(--radius-xs);
967
+ border-radius: calc(var(--radius-xs) * var(--corner-scale, 1));
968
+ corner-shape: squircle;
957
969
  }
958
970
  .roundedSm {
959
- border-radius: var(--radius-sm);
971
+ border-radius: calc(var(--radius-sm) * var(--corner-scale, 1));
972
+ corner-shape: squircle;
960
973
  }
961
974
  .roundedMd {
962
- border-radius: var(--radius-md);
975
+ border-radius: calc(var(--radius-md) * var(--corner-scale, 1));
976
+ corner-shape: squircle;
963
977
  }
964
978
  .roundedLg {
965
- border-radius: var(--radius-lg);
979
+ border-radius: calc(var(--radius-lg) * var(--corner-scale, 1));
980
+ corner-shape: squircle;
966
981
  }
967
982
  .roundedXl {
968
- border-radius: var(--radius-xl);
983
+ border-radius: calc(var(--radius-xl) * var(--corner-scale, 1));
984
+ corner-shape: squircle;
969
985
  }
970
986
  .rounded2Xl {
971
- border-radius: var(--radius-2xl);
987
+ border-radius: calc(var(--radius-2xl) * var(--corner-scale, 1));
988
+ corner-shape: squircle;
972
989
  }
973
990
  .rounded3Xl {
974
- border-radius: var(--radius-3xl);
991
+ border-radius: calc(var(--radius-3xl) * var(--corner-scale, 1));
992
+ corner-shape: squircle;
975
993
  }
976
994
  .rounded4Xl {
977
- border-radius: var(--radius-4xl);
995
+ border-radius: calc(var(--radius-4xl) * var(--corner-scale, 1));
996
+ corner-shape: squircle;
978
997
  }
979
998
  .roundedFull {
980
999
  border-radius: var(--radius-full);
1000
+ corner-shape: round;
981
1001
  }
982
1002
  .borderNone {
983
1003
  border-width: var(--border-none);
@@ -2734,6 +2754,7 @@
2734
2754
  border-radius: var(--radius-full);
2735
2755
  border-style: solid;
2736
2756
  border-width: var(--border-md);
2757
+ corner-shape: round;
2737
2758
  }
2738
2759
  .scrollbarSm::-webkit-scrollbar-thumb:hover {
2739
2760
  background-color: var(--scrollbar-thumb-hover);
@@ -2758,6 +2779,7 @@
2758
2779
  border-radius: var(--radius-full);
2759
2780
  border-style: solid;
2760
2781
  border-width: var(--border-md);
2782
+ corner-shape: round;
2761
2783
  }
2762
2784
  .scrollbarMd::-webkit-scrollbar-thumb:hover {
2763
2785
  background-color: var(--scrollbar-thumb-hover);
@@ -2852,7 +2874,8 @@
2852
2874
  .glass {
2853
2875
  backdrop-filter: var(--effects-blur-md);
2854
2876
  background-color: var(--color-blur-overlay);
2855
- border-radius: var(--radius-md);
2877
+ border-radius: calc(var(--radius-md) * var(--corner-scale, 1));
2878
+ corner-shape: squircle;
2856
2879
  position: relative;
2857
2880
  }
2858
2881
  .glass::before {
@@ -2863,6 +2886,7 @@
2863
2886
  var(--gradient-secondary-end) 100%);
2864
2887
  border-radius: inherit;
2865
2888
  content: "";
2889
+ corner-shape: inherit;
2866
2890
  inset: 0;
2867
2891
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
2868
2892
  mask-composite: exclude;
@@ -4797,6 +4821,12 @@
4797
4821
  @property --box-borderRadius-lg { inherits: false; syntax: "*"; }
4798
4822
  @property --box-borderRadius-xl { inherits: false; syntax: "*"; }
4799
4823
  @property --box-borderRadius-2xl { inherits: false; syntax: "*"; }
4824
+ @property --box-cornerShape-base { inherits: false; syntax: "*"; }
4825
+ @property --box-cornerShape-sm { inherits: false; syntax: "*"; }
4826
+ @property --box-cornerShape-md { inherits: false; syntax: "*"; }
4827
+ @property --box-cornerShape-lg { inherits: false; syntax: "*"; }
4828
+ @property --box-cornerShape-xl { inherits: false; syntax: "*"; }
4829
+ @property --box-cornerShape-2xl { inherits: false; syntax: "*"; }
4800
4830
  @property --box-border-base { inherits: false; syntax: "*"; }
4801
4831
  @property --box-border-sm { inherits: false; syntax: "*"; }
4802
4832
  @property --box-border-md { inherits: false; syntax: "*"; }
@@ -4928,6 +4958,7 @@
4928
4958
  box-shadow: var(--box-shadow-base, none);
4929
4959
  box-sizing: border-box;
4930
4960
  color: var(--box-color-base, inherit);
4961
+ corner-shape: var(--box-cornerShape-base, round);
4931
4962
  cursor: var(--cursor-base, auto);
4932
4963
  gap: var(--rowGap-base, var(--gap-base, normal)) var(--columnGap-base, var(--gap-base, normal));
4933
4964
  display: var(--display-base, block);
@@ -4970,6 +5001,7 @@
4970
5001
  border-radius: var(--box-borderRadius-sm, var(--box-borderRadius-base, 0));
4971
5002
  box-shadow: var(--box-shadow-sm, var(--box-shadow-base, none));
4972
5003
  color: var(--box-color-sm, var(--box-color-base, inherit));
5004
+ corner-shape: var(--box-cornerShape-sm, var(--box-cornerShape-base, round));
4973
5005
  cursor: var(--cursor-sm, var(--cursor-base, auto));
4974
5006
  gap: var(--rowGap-sm, var(--gap-sm, var(--rowGap-base, var(--gap-base, normal)))) var(--columnGap-sm, var(--gap-sm, var(--columnGap-base, var(--gap-base, normal))));
4975
5007
  display: var(--display-sm, var(--display-base, block));
@@ -5013,6 +5045,7 @@
5013
5045
  border-radius: var(--box-borderRadius-md, var(--box-borderRadius-sm, var(--box-borderRadius-base, 0)));
5014
5046
  box-shadow: var(--box-shadow-md, var(--box-shadow-sm, var(--box-shadow-base, none)));
5015
5047
  color: var(--box-color-md, var(--box-color-sm, var(--box-color-base, inherit)));
5048
+ corner-shape: var(--box-cornerShape-md, var(--box-cornerShape-sm, var(--box-cornerShape-base, round)));
5016
5049
  cursor: var(--cursor-md, var(--cursor-sm, var(--cursor-base, auto)));
5017
5050
  gap: var(--rowGap-md, var(--gap-md, var(--rowGap-sm, var(--gap-sm, var(--rowGap-base, var(--gap-base, normal)))))) var(--columnGap-md, var(--gap-md, var(--columnGap-sm, var(--gap-sm, var(--columnGap-base, var(--gap-base, normal))))));
5018
5051
  display: var(--display-md, var(--display-sm, var(--display-base, block)));
@@ -5056,6 +5089,7 @@
5056
5089
  border-radius: var(--box-borderRadius-lg, var(--box-borderRadius-md, var(--box-borderRadius-sm, var(--box-borderRadius-base, 0))));
5057
5090
  box-shadow: var(--box-shadow-lg, var(--box-shadow-md, var(--box-shadow-sm, var(--box-shadow-base, none))));
5058
5091
  color: var(--box-color-lg, var(--box-color-md, var(--box-color-sm, var(--box-color-base, inherit))));
5092
+ corner-shape: var(--box-cornerShape-lg, var(--box-cornerShape-md, var(--box-cornerShape-sm, var(--box-cornerShape-base, round))));
5059
5093
  cursor: var(--cursor-lg, var(--cursor-md, var(--cursor-sm, var(--cursor-base, auto))));
5060
5094
  gap: var(--rowGap-lg, var(--gap-lg, var(--rowGap-md, var(--gap-md, var(--rowGap-sm, var(--gap-sm, var(--rowGap-base, var(--gap-base, normal)))))))) var(--columnGap-lg, var(--gap-lg, var(--columnGap-md, var(--gap-md, var(--columnGap-sm, var(--gap-sm, var(--columnGap-base, var(--gap-base, normal))))))));
5061
5095
  display: var(--display-lg, var(--display-md, var(--display-sm, var(--display-base, block))));
@@ -5099,6 +5133,7 @@
5099
5133
  border-radius: var(--box-borderRadius-xl, var(--box-borderRadius-lg, var(--box-borderRadius-md, var(--box-borderRadius-sm, var(--box-borderRadius-base, 0)))));
5100
5134
  box-shadow: var(--box-shadow-xl, var(--box-shadow-lg, var(--box-shadow-md, var(--box-shadow-sm, var(--box-shadow-base, none)))));
5101
5135
  color: var(--box-color-xl, var(--box-color-lg, var(--box-color-md, var(--box-color-sm, var(--box-color-base, inherit)))));
5136
+ corner-shape: var(--box-cornerShape-xl, var(--box-cornerShape-lg, var(--box-cornerShape-md, var(--box-cornerShape-sm, var(--box-cornerShape-base, round)))));
5102
5137
  cursor: var(--cursor-xl, var(--cursor-lg, var(--cursor-md, var(--cursor-sm, var(--cursor-base, auto)))));
5103
5138
  gap: var(--rowGap-xl, var(--gap-xl, var(--rowGap-lg, var(--gap-lg, var(--rowGap-md, var(--gap-md, var(--rowGap-sm, var(--gap-sm, var(--rowGap-base, var(--gap-base, normal)))))))))) var(--columnGap-xl, var(--gap-xl, var(--columnGap-lg, var(--gap-lg, var(--columnGap-md, var(--gap-md, var(--columnGap-sm, var(--gap-sm, var(--columnGap-base, var(--gap-base, normal))))))))));
5104
5139
  display: var(--display-xl, var(--display-lg, var(--display-md, var(--display-sm, var(--display-base, block)))));
@@ -5142,6 +5177,7 @@
5142
5177
  border-radius: var(--box-borderRadius-2xl, var(--box-borderRadius-xl, var(--box-borderRadius-lg, var(--box-borderRadius-md, var(--box-borderRadius-sm, var(--box-borderRadius-base, 0))))));
5143
5178
  box-shadow: var(--box-shadow-2xl, var(--box-shadow-xl, var(--box-shadow-lg, var(--box-shadow-md, var(--box-shadow-sm, var(--box-shadow-base, none))))));
5144
5179
  color: var(--box-color-2xl, var(--box-color-xl, var(--box-color-lg, var(--box-color-md, var(--box-color-sm, var(--box-color-base, inherit))))));
5180
+ corner-shape: var(--box-cornerShape-2xl, var(--box-cornerShape-xl, var(--box-cornerShape-lg, var(--box-cornerShape-md, var(--box-cornerShape-sm, var(--box-cornerShape-base, round))))));
5145
5181
  cursor: var(--cursor-2xl, var(--cursor-xl, var(--cursor-lg, var(--cursor-md, var(--cursor-sm, var(--cursor-base, auto))))));
5146
5182
  gap: var(--rowGap-2xl, var(--gap-2xl, var(--rowGap-xl, var(--gap-xl, var(--rowGap-lg, var(--gap-lg, var(--rowGap-md, var(--gap-md, var(--rowGap-sm, var(--gap-sm, var(--rowGap-base, var(--gap-base, normal)))))))))))) var(--columnGap-2xl, var(--gap-2xl, var(--columnGap-xl, var(--gap-xl, var(--columnGap-lg, var(--gap-lg, var(--columnGap-md, var(--gap-md, var(--columnGap-sm, var(--gap-sm, var(--columnGap-base, var(--gap-base, normal))))))))))));
5147
5183
  display: var(--display-2xl, var(--display-xl, var(--display-lg, var(--display-md, var(--display-sm, var(--display-base, block))))));
@@ -5399,6 +5435,7 @@
5399
5435
  .customScrollbarThumbVertical {
5400
5436
  background-color: var(--scrollbar-thumb);
5401
5437
  border-radius: var(--radius-full);
5438
+ corner-shape: round;
5402
5439
  cursor: pointer;
5403
5440
  inset-inline: 0;
5404
5441
  margin-inline: auto;
@@ -5421,6 +5458,7 @@
5421
5458
  .customScrollbarThumbHorizontal {
5422
5459
  background-color: var(--scrollbar-thumb);
5423
5460
  border-radius: var(--radius-full);
5461
+ corner-shape: round;
5424
5462
  cursor: pointer;
5425
5463
  inset-block: 0;
5426
5464
  margin-block: auto;
@@ -5446,8 +5484,9 @@
5446
5484
  align-items: center;
5447
5485
  background-color: var(--surface-neutral-secondary);
5448
5486
  border: var(--border-sm) dashed var(--foreground-neutral-primary);
5449
- border-radius: var(--radius-2xs);
5487
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
5450
5488
  box-sizing: border-box;
5489
+ corner-shape: squircle;
5451
5490
  display: flex;
5452
5491
  flex-direction: column;
5453
5492
  gap: var(--space-2xs);
@@ -5941,23 +5980,28 @@
5941
5980
  padding: 0 var(--space-4xs);
5942
5981
  }
5943
5982
  .badgeShapeRounded {
5944
- border-radius: var(--radius-3xs);
5983
+ border-radius: calc(var(--radius-3xs) * var(--corner-scale, 1));
5984
+ corner-shape: squircle;
5945
5985
  }
5946
5986
  .badgeShapePill {
5947
5987
  border-radius: var(--radius-full);
5988
+ corner-shape: round;
5948
5989
  }
5949
5990
  .badgeShapeIcon {
5950
5991
  block-size: var(--dimensions-24);
5951
5992
  border-radius: 50%;
5993
+ corner-shape: round;
5952
5994
  inline-size: var(--dimensions-24);
5953
5995
  padding: var(--space-none);
5954
5996
  }
5955
5997
  .badgeShapeText {
5956
5998
  border-radius: var(--radius-full);
5999
+ corner-shape: round;
5957
6000
  }
5958
6001
  .badgeShapeNumber {
5959
6002
  block-size: var(--dimensions-16);
5960
6003
  border-radius: var(--radius-full);
6004
+ corner-shape: round;
5961
6005
  min-block-size: var(--dimensions-16);
5962
6006
  min-inline-size: var(--dimensions-16);
5963
6007
  padding: var(--space-none);
@@ -5965,6 +6009,7 @@
5965
6009
  .badgeShapeDot {
5966
6010
  block-size: var(--dimensions-8);
5967
6011
  border-radius: 50%;
6012
+ corner-shape: round;
5968
6013
  inline-size: var(--dimensions-8);
5969
6014
  padding: var(--space-none);
5970
6015
  }
@@ -6143,10 +6188,12 @@
6143
6188
  }
6144
6189
  .button.buttonPill {
6145
6190
  border-radius: var(--radius-full) !important;
6191
+ corner-shape: round !important;
6146
6192
  }
6147
6193
  .large {
6148
6194
  block-size: var(--dimensions-48);
6149
- border-radius: var(--radius-2xs);
6195
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
6196
+ corner-shape: squircle;
6150
6197
  font-family: var(--title-md-family);
6151
6198
  font-size: var(--title-md-size);
6152
6199
  font-weight: var(--title-md-weight-emphasize);
@@ -6157,7 +6204,8 @@
6157
6204
  }
6158
6205
  .medium {
6159
6206
  block-size: var(--dimensions-44);
6160
- border-radius: var(--radius-2xs);
6207
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
6208
+ corner-shape: squircle;
6161
6209
  font-family: var(--title-md-family);
6162
6210
  font-size: var(--title-md-size);
6163
6211
  font-weight: var(--title-md-weight-emphasize);
@@ -6168,7 +6216,8 @@
6168
6216
  }
6169
6217
  .small {
6170
6218
  block-size: var(--dimensions-36);
6171
- border-radius: var(--radius-2xs);
6219
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
6220
+ corner-shape: squircle;
6172
6221
  font-family: var(--title-sm-family);
6173
6222
  font-size: var(--title-sm-size);
6174
6223
  font-weight: var(--title-sm-weight-emphasize);
@@ -6372,20 +6421,24 @@
6372
6421
  }
6373
6422
  .iconButtonRoot.iconButtonPill {
6374
6423
  border-radius: var(--radius-full) !important;
6424
+ corner-shape: round !important;
6375
6425
  }
6376
6426
  .large {
6377
6427
  block-size: var(--dimensions-48);
6378
- border-radius: var(--radius-2xs);
6428
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
6429
+ corner-shape: squircle;
6379
6430
  inline-size: var(--dimensions-48);
6380
6431
  }
6381
6432
  .medium {
6382
6433
  block-size: var(--dimensions-44);
6383
- border-radius: var(--radius-2xs);
6434
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
6435
+ corner-shape: squircle;
6384
6436
  inline-size: var(--dimensions-44);
6385
6437
  }
6386
6438
  .small {
6387
6439
  block-size: var(--dimensions-36);
6388
- border-radius: var(--radius-2xs);
6440
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
6441
+ corner-shape: squircle;
6389
6442
  inline-size: var(--dimensions-36);
6390
6443
  }
6391
6444
  .primary {
@@ -6397,6 +6450,7 @@
6397
6450
  background-color: transparent;
6398
6451
  border-radius: inherit;
6399
6452
  content: "";
6453
+ corner-shape: inherit;
6400
6454
  inset: 0;
6401
6455
  pointer-events: none;
6402
6456
  position: absolute;
@@ -6445,6 +6499,7 @@
6445
6499
  background-color: transparent;
6446
6500
  border-radius: inherit;
6447
6501
  content: "";
6502
+ corner-shape: inherit;
6448
6503
  inset: 0;
6449
6504
  pointer-events: none;
6450
6505
  position: absolute;
@@ -6474,6 +6529,7 @@
6474
6529
  background-color: transparent;
6475
6530
  border-radius: inherit;
6476
6531
  content: "";
6532
+ corner-shape: inherit;
6477
6533
  inset: 0;
6478
6534
  pointer-events: none;
6479
6535
  position: absolute;
@@ -6546,6 +6602,7 @@
6546
6602
  block-size: var(--dimensions-40);
6547
6603
  border: none;
6548
6604
  border-radius: var(--radius-full);
6605
+ corner-shape: round;
6549
6606
  cursor: pointer;
6550
6607
  display: inline-flex;
6551
6608
  flex-shrink: 0;
@@ -6578,6 +6635,7 @@
6578
6635
  background-color: transparent;
6579
6636
  border-radius: var(--radius-full);
6580
6637
  content: "";
6638
+ corner-shape: round;
6581
6639
  inset: 0;
6582
6640
  opacity: var(--opacity-visible);
6583
6641
  pointer-events: none;
@@ -6700,6 +6758,7 @@
6700
6758
  block-size: var(--dimensions-40);
6701
6759
  border: none;
6702
6760
  border-radius: var(--radius-full);
6761
+ corner-shape: round;
6703
6762
  cursor: pointer;
6704
6763
  display: inline-flex;
6705
6764
  flex-shrink: 0;
@@ -6723,6 +6782,7 @@
6723
6782
  background-color: transparent;
6724
6783
  border-radius: var(--radius-full);
6725
6784
  content: "";
6785
+ corner-shape: round;
6726
6786
  inset: 0;
6727
6787
  opacity: var(--opacity-visible);
6728
6788
  pointer-events: none;
@@ -6850,6 +6910,7 @@
6850
6910
  .switchTrack {
6851
6911
  background-color: var(--surface-neutral-tertiary);
6852
6912
  border-radius: var(--radius-full);
6913
+ corner-shape: round;
6853
6914
  display: block;
6854
6915
  position: relative;
6855
6916
  transition: background-color var(--motion-duration-fast) var(--motion-ease-out);
@@ -6874,6 +6935,7 @@
6874
6935
  block-size: 100%;
6875
6936
  border-radius: 50%;
6876
6937
  box-shadow: var(--shadow-down-sm);
6938
+ corner-shape: round;
6877
6939
  display: flex;
6878
6940
  inline-size: 100%;
6879
6941
  justify-content: center;
@@ -7052,8 +7114,9 @@
7052
7114
  background-color: var(--surface-neutral-on-surface);
7053
7115
  block-size: var(--dimensions-48);
7054
7116
  border: var(--border-sm) solid transparent;
7055
- border-radius: var(--radius-2xs);
7117
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
7056
7118
  box-sizing: border-box;
7119
+ corner-shape: squircle;
7057
7120
  cursor: text;
7058
7121
  display: flex;
7059
7122
  font-family: var(--body-lg-family);
@@ -7083,6 +7146,7 @@
7083
7146
  }
7084
7147
  .searchFieldRounded {
7085
7148
  border-radius: var(--radius-full);
7149
+ corner-shape: round;
7086
7150
  }
7087
7151
  .searchFieldRoot:hover:not(.searchFieldDisabled) {
7088
7152
  background-color: var(--surface-state-hover);
@@ -7173,8 +7237,9 @@
7173
7237
  .dropdownListRoot {
7174
7238
  background-color: var(--surface-neutral-elevator);
7175
7239
  border: var(--border-xs) solid var(--border-neutral-tertiary);
7176
- border-radius: var(--radius-sm);
7240
+ border-radius: calc(var(--radius-sm) * var(--corner-scale, 1));
7177
7241
  box-shadow: var(--shadow-down-md);
7242
+ corner-shape: squircle;
7178
7243
  display: flex;
7179
7244
  flex-direction: column;
7180
7245
  min-inline-size: calc(var(--dimensions-80) * 3 + var(--dimensions-24) + var(--dimensions-16));
@@ -7243,7 +7308,8 @@
7243
7308
  align-items: center;
7244
7309
  background-color: transparent;
7245
7310
  block-size: var(--dimensions-48);
7246
- border-radius: var(--radius-2xs);
7311
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
7312
+ corner-shape: squircle;
7247
7313
  cursor: pointer;
7248
7314
  display: flex;
7249
7315
  gap: var(--space-xs);
@@ -7381,8 +7447,9 @@
7381
7447
  --text-field-content-gap: var(--space-xs);
7382
7448
  align-items: center;
7383
7449
  border: var(--border-sm) solid var(--border-neutral-tertiary);
7384
- border-radius: var(--radius-2xs);
7450
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
7385
7451
  box-sizing: border-box;
7452
+ corner-shape: squircle;
7386
7453
  display: flex;
7387
7454
  isolation: isolate;
7388
7455
  min-block-size: var(--dimensions-56);
@@ -7471,8 +7538,9 @@
7471
7538
  .textFieldLeadingText {
7472
7539
  align-items: center;
7473
7540
  background-color: var(--surface-neutral-on-surface);
7474
- border-radius: var(--radius-4xs);
7541
+ border-radius: calc(var(--radius-4xs) * var(--corner-scale, 1));
7475
7542
  color: var(--text-neutral-primary);
7543
+ corner-shape: squircle;
7476
7544
  display: flex;
7477
7545
  font-family: var(--body-lg-family);
7478
7546
  font-size: var(--body-lg-size);
@@ -7664,7 +7732,8 @@
7664
7732
  }
7665
7733
  .textFieldChevronOnly:hover {
7666
7734
  background-color: var(--surface-state-hover);
7667
- border-radius: var(--radius-4xs);
7735
+ border-radius: calc(var(--radius-4xs) * var(--corner-scale, 1));
7736
+ corner-shape: squircle;
7668
7737
  }
7669
7738
  .readOnly {
7670
7739
  background-color: var(--surface-neutral-secondary);
@@ -7904,10 +7973,11 @@
7904
7973
  .textAreaInput {
7905
7974
  background-color: transparent;
7906
7975
  border: var(--border-sm) solid var(--border-neutral-tertiary);
7907
- border-radius: var(--radius-2xs);
7976
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
7908
7977
  box-sizing: border-box;
7909
7978
  caret-color: var(--text-neutral-primary);
7910
7979
  color: var(--text-neutral-primary);
7980
+ corner-shape: squircle;
7911
7981
  font-family: var(--body-lg-family);
7912
7982
  font-size: var(--body-lg-size);
7913
7983
  font-weight: var(--body-lg-weight);
@@ -8004,6 +8074,7 @@
8004
8074
  block-size: 100%;
8005
8075
  border-radius: 50%;
8006
8076
  color: var(--foreground-neutral-primary-inverse);
8077
+ corner-shape: round;
8007
8078
  display: flex;
8008
8079
  inline-size: 100%;
8009
8080
  justify-content: center;
@@ -8027,6 +8098,7 @@
8027
8098
  .avatarStatus {
8028
8099
  border-radius: 50%;
8029
8100
  box-shadow: 0 0 0 var(--avatar-status-stroke-width, var(--border-md)) var(--surface-neutral-primary);
8101
+ corner-shape: round;
8030
8102
  inset-block-end: 0;
8031
8103
  inset-inline-end: 0;
8032
8104
  position: absolute;
@@ -8331,7 +8403,8 @@
8331
8403
  }
8332
8404
  .skeletonRoot {
8333
8405
  background-color: var(--surface-neutral-on-surface);
8334
- border-radius: var(--radius-4xs);
8406
+ border-radius: calc(var(--radius-4xs) * var(--corner-scale, 1));
8407
+ corner-shape: squircle;
8335
8408
  overflow: hidden;
8336
8409
  position: relative;
8337
8410
  }
@@ -8361,18 +8434,22 @@
8361
8434
  .skeletonAvatar {
8362
8435
  block-size: var(--dimensions-40);
8363
8436
  border-radius: 50%;
8437
+ corner-shape: round;
8364
8438
  inline-size: var(--dimensions-40);
8365
8439
  }
8366
8440
  .skeletonRectangular {
8367
8441
  block-size: 100%;
8368
- border-radius: var(--radius-2xs);
8442
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
8443
+ corner-shape: squircle;
8369
8444
  inline-size: 100%;
8370
8445
  }
8371
8446
  .skeletonCircular {
8372
8447
  border-radius: 50%;
8448
+ corner-shape: round;
8373
8449
  }
8374
8450
  .skeletonRounded {
8375
8451
  border-radius: var(--radius-full);
8452
+ corner-shape: round;
8376
8453
  }
8377
8454
 
8378
8455
  /* ../ultimate/src/components/chip/Chip.module.css */
@@ -8380,6 +8457,7 @@
8380
8457
  align-items: center;
8381
8458
  border-radius: var(--radius-full);
8382
8459
  box-sizing: border-box;
8460
+ corner-shape: round;
8383
8461
  display: inline-flex;
8384
8462
  flex-shrink: 0;
8385
8463
  font-family:
@@ -8399,7 +8477,8 @@
8399
8477
  vertical-align: middle;
8400
8478
  }
8401
8479
  .chipRoot.rounded {
8402
- border-radius: var(--radius-2xs);
8480
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
8481
+ corner-shape: squircle;
8403
8482
  }
8404
8483
  .chipRoot::after {
8405
8484
  background-color: transparent;
@@ -8463,6 +8542,7 @@
8463
8542
  border: none;
8464
8543
  border-radius: var(--radius-full);
8465
8544
  color: var(--foreground-neutral-primary-inverse);
8545
+ corner-shape: round;
8466
8546
  cursor: pointer;
8467
8547
  display: flex;
8468
8548
  flex-shrink: 0;
@@ -8481,6 +8561,7 @@
8481
8561
  border: none;
8482
8562
  border-radius: var(--radius-full);
8483
8563
  color: inherit;
8564
+ corner-shape: round;
8484
8565
  cursor: pointer;
8485
8566
  display: flex;
8486
8567
  flex-shrink: 0;
@@ -8946,6 +9027,7 @@
8946
9027
  border: none;
8947
9028
  border-radius: var(--radius-full);
8948
9029
  color: var(--text-neutral-primary);
9030
+ corner-shape: round;
8949
9031
  cursor: pointer;
8950
9032
  display: flex;
8951
9033
  inline-size: var(--dimensions-32);
@@ -9003,6 +9085,7 @@
9003
9085
  border: none;
9004
9086
  border-radius: 50%;
9005
9087
  color: var(--foreground-neutral-primary);
9088
+ corner-shape: round;
9006
9089
  cursor: pointer;
9007
9090
  display: inline-flex;
9008
9091
  flex-shrink: 0;
@@ -9027,6 +9110,7 @@
9027
9110
  background-color: transparent;
9028
9111
  border-radius: 50%;
9029
9112
  content: "";
9113
+ corner-shape: round;
9030
9114
  inset: 0;
9031
9115
  opacity: var(--opacity-visible);
9032
9116
  pointer-events: none;
@@ -9109,6 +9193,7 @@
9109
9193
  background-color: var(--text-neutral-primary);
9110
9194
  block-size: var(--dimensions-8);
9111
9195
  border-radius: 50%;
9196
+ corner-shape: round;
9112
9197
  inline-size: var(--dimensions-8);
9113
9198
  inset: 0;
9114
9199
  margin: auto;
@@ -9120,10 +9205,11 @@
9120
9205
  background: transparent;
9121
9206
  block-size: 100%;
9122
9207
  border: var(--border-sm) solid var(--border-neutral-tertiary);
9123
- border-radius: var(--radius-2xs);
9208
+ border-radius: calc(var(--radius-2xs) * var(--corner-scale, 1));
9124
9209
  box-sizing: border-box;
9125
9210
  caret-color: var(--text-neutral-primary);
9126
9211
  color: var(--text-neutral-primary);
9212
+ corner-shape: squircle;
9127
9213
  display: block;
9128
9214
  font: inherit;
9129
9215
  inline-size: 100%;
@@ -9189,6 +9275,7 @@
9189
9275
  }
9190
9276
  .cell.dotFieldInput {
9191
9277
  border-radius: 50%;
9278
+ corner-shape: round;
9192
9279
  padding: 0;
9193
9280
  }
9194
9281
  .cell.dotFieldInput[data-filled=true] {
package/dist/index.d.mts CHANGED
@@ -7,6 +7,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
7
7
  * Layout component type definitions
8
8
  * Provides TypeScript types for design token props used in Box, Stack, Grid, etc.
9
9
  */
10
+
10
11
  /** Public spacing token names mapped to canonical --space-* CSS variables */
11
12
  type SpacingToken = 'none' | '5xs' | '4xs' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | '8xl';
12
13
  /** Public background token names mapped to canonical surface CSS variables */
@@ -690,6 +691,8 @@ interface InputFormatOptions {
690
691
  maxDigits?: number;
691
692
  /** Allow decimal input for currency. Default: true */
692
693
  allowDecimal?: boolean;
694
+ /** Digits kept after the decimal mark for currency. Default: 2 */
695
+ maxDecimals?: number;
693
696
  /**
694
697
  * Calling code for `phone` when it is shown outside the value (a country
695
698
  * picker, say). A `leadingText` such as `+84` is picked up on its own.
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
7
7
  * Layout component type definitions
8
8
  * Provides TypeScript types for design token props used in Box, Stack, Grid, etc.
9
9
  */
10
+
10
11
  /** Public spacing token names mapped to canonical --space-* CSS variables */
11
12
  type SpacingToken = 'none' | '5xs' | '4xs' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | '8xl';
12
13
  /** Public background token names mapped to canonical surface CSS variables */
@@ -690,6 +691,8 @@ interface InputFormatOptions {
690
691
  maxDigits?: number;
691
692
  /** Allow decimal input for currency. Default: true */
692
693
  allowDecimal?: boolean;
694
+ /** Digits kept after the decimal mark for currency. Default: 2 */
695
+ maxDecimals?: number;
693
696
  /**
694
697
  * Calling code for `phone` when it is shown outside the value (a country
695
698
  * picker, say). A `leadingText` such as `+84` is picked up on its own.
package/dist/index.js CHANGED
@@ -519,7 +519,8 @@ var BoxImpl = React.forwardRef(
519
519
  const Component = as || "div";
520
520
  const toPx = (v) => typeof v === "number" ? `${v}px` : v;
521
521
  const spacingMapper = (v) => v === "auto" ? "auto" : spacingVar(v);
522
- const radiusMapper = (v) => radiusVar(v);
522
+ const radiusMapper = (v) => v === "full" || v === "none" ? radiusVar(v) : `calc(${radiusVar(v)} * var(--corner-scale, 1))`;
523
+ const cornerShapeMapper = (v) => v === "full" ? "round" : "squircle";
523
524
  const shadowMapper = (v) => shadowVar(v);
524
525
  const bgMapper = (v) => backgroundVar(v);
525
526
  const pageBgMapper = (v) => pageBackgroundVar(v);
@@ -577,6 +578,7 @@ var BoxImpl = React.forwardRef(
577
578
  ...getResponsiveVars("page-bg", pageBg, pageBgMapper),
578
579
  ...getResponsiveVars("box-bg", bg, bgMapper),
579
580
  ...getResponsiveVars("box-borderRadius", borderRadius, radiusMapper),
581
+ ...getResponsiveVars("box-cornerShape", borderRadius, cornerShapeMapper),
580
582
  ...getResponsiveVars("box-shadow", shadow, shadowMapper),
581
583
  ...getResponsiveVars("box-opacity", opacity),
582
584
  ...getResponsiveVars("box-border", border),
@@ -7577,7 +7579,7 @@ var DropdownList = React235.forwardRef(
7577
7579
  DropdownList.displayName = "DropdownList";
7578
7580
 
7579
7581
  // ../ultimate/src/utils/format.utils.ts
7580
- var formatCurrency = (value, separator = ",", allowDecimal = true) => {
7582
+ var formatCurrency = (value, separator = ",", allowDecimal = true, maxDecimals = 2) => {
7581
7583
  if (!value) return "";
7582
7584
  const decimalChar = separator === "," ? "." : ",";
7583
7585
  let cleaned = value.replace(new RegExp(`[^\\d\\${decimalChar}-]`, "g"), "");
@@ -7591,7 +7593,7 @@ var formatCurrency = (value, separator = ",", allowDecimal = true) => {
7591
7593
  integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
7592
7594
  let result = integerPart;
7593
7595
  if (allowDecimal && decimalPart !== void 0) {
7594
- result += decimalChar + decimalPart;
7596
+ result += decimalChar + decimalPart.slice(0, maxDecimals);
7595
7597
  }
7596
7598
  if (isNegative && result !== "0") {
7597
7599
  result = "-" + result;
@@ -7837,6 +7839,7 @@ var TextField = React237.forwardRef(
7837
7839
  const separator = formatOptions?.separator ?? ",";
7838
7840
  const allowDecimal = formatOptions?.allowDecimal ?? true;
7839
7841
  const maxDigits = formatOptions?.maxDigits;
7842
+ const maxDecimals = formatOptions?.maxDecimals ?? 2;
7840
7843
  const applyFormat = React237.useCallback((raw) => {
7841
7844
  switch (activeFormat) {
7842
7845
  case "currency": {
@@ -7849,7 +7852,7 @@ var TextField = React237.forwardRef(
7849
7852
  cleaned = parts.join(decimalChar);
7850
7853
  }
7851
7854
  }
7852
- return formatCurrency(cleaned, separator, allowDecimal);
7855
+ return formatCurrency(cleaned, separator, allowDecimal, maxDecimals);
7853
7856
  }
7854
7857
  case "phone":
7855
7858
  return formatPhone(raw, { countryCode: phoneCountryCode });
@@ -7862,7 +7865,7 @@ var TextField = React237.forwardRef(
7862
7865
  default:
7863
7866
  return raw;
7864
7867
  }
7865
- }, [activeFormat, separator, allowDecimal, maxDigits, phoneCountryCode]);
7868
+ }, [activeFormat, separator, allowDecimal, maxDigits, maxDecimals, phoneCountryCode]);
7866
7869
  const handleBlur = (e) => {
7867
7870
  setFocused(false);
7868
7871
  if (activeFormat && currentValue) {
@@ -9488,6 +9491,7 @@ function OTP({
9488
9491
  const currentDigits = React251.useRef(digits);
9489
9492
  currentDigits.current = digits;
9490
9493
  const composing = React251.useRef(null);
9494
+ const picked = React251.useRef(false);
9491
9495
  const inputs = React251.useRef([]);
9492
9496
  const first = React251.useRef(null);
9493
9497
  const previousReadOnly = React251.useRef(readOnly);
@@ -9521,6 +9525,9 @@ function OTP({
9521
9525
  const index = sequential ? nextCell(currentDigits.current) : cell;
9522
9526
  const text = normalize(raw);
9523
9527
  if (raw && !text) return;
9528
+ const wasPicked = picked.current;
9529
+ picked.current = false;
9530
+ if (text && text.length < count && index === count - 1 && !wasPicked && currentDigits.current.every(Boolean)) return;
9524
9531
  const start = text.length === count ? 0 : index;
9525
9532
  const next = [...currentDigits.current];
9526
9533
  if (!text) next[index] = "";
@@ -9621,6 +9628,7 @@ function OTP({
9621
9628
  value: digits[index] ?? "",
9622
9629
  tabIndex: sequential && index !== nextCell(digits) ? -1 : void 0,
9623
9630
  onMouseDown: (event) => {
9631
+ picked.current = true;
9624
9632
  if (!sequential || disabled || readOnly) return;
9625
9633
  event.preventDefault();
9626
9634
  focus(nextCell(currentDigits.current));
@@ -9651,6 +9659,7 @@ function OTP({
9651
9659
  if (composing.current === index && next && !/^[0-9]+$/.test(next)) return;
9652
9660
  composing.current = null;
9653
9661
  enter(index, next);
9662
+ event.currentTarget.value = currentDigits.current[index] ?? "";
9654
9663
  },
9655
9664
  onPaste: (event) => {
9656
9665
  event.preventDefault();
@@ -9690,6 +9699,7 @@ function OTP({
9690
9699
  } else if (["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) {
9691
9700
  event.preventDefault();
9692
9701
  if (sequential) return;
9702
+ picked.current = true;
9693
9703
  focus(
9694
9704
  event.key === "Home" ? 0 : event.key === "End" ? count - 1 : Math.max(
9695
9705
  0,
package/dist/index.mjs CHANGED
@@ -229,7 +229,8 @@ var BoxImpl = React.forwardRef(
229
229
  const Component = as || "div";
230
230
  const toPx = (v) => typeof v === "number" ? `${v}px` : v;
231
231
  const spacingMapper = (v) => v === "auto" ? "auto" : spacingVar(v);
232
- const radiusMapper = (v) => radiusVar(v);
232
+ const radiusMapper = (v) => v === "full" || v === "none" ? radiusVar(v) : `calc(${radiusVar(v)} * var(--corner-scale, 1))`;
233
+ const cornerShapeMapper = (v) => v === "full" ? "round" : "squircle";
233
234
  const shadowMapper = (v) => shadowVar(v);
234
235
  const bgMapper = (v) => backgroundVar(v);
235
236
  const pageBgMapper = (v) => pageBackgroundVar(v);
@@ -287,6 +288,7 @@ var BoxImpl = React.forwardRef(
287
288
  ...getResponsiveVars("page-bg", pageBg, pageBgMapper),
288
289
  ...getResponsiveVars("box-bg", bg, bgMapper),
289
290
  ...getResponsiveVars("box-borderRadius", borderRadius, radiusMapper),
291
+ ...getResponsiveVars("box-cornerShape", borderRadius, cornerShapeMapper),
290
292
  ...getResponsiveVars("box-shadow", shadow, shadowMapper),
291
293
  ...getResponsiveVars("box-opacity", opacity),
292
294
  ...getResponsiveVars("box-border", border),
@@ -7287,7 +7289,7 @@ var DropdownList = React235.forwardRef(
7287
7289
  DropdownList.displayName = "DropdownList";
7288
7290
 
7289
7291
  // ../ultimate/src/utils/format.utils.ts
7290
- var formatCurrency = (value, separator = ",", allowDecimal = true) => {
7292
+ var formatCurrency = (value, separator = ",", allowDecimal = true, maxDecimals = 2) => {
7291
7293
  if (!value) return "";
7292
7294
  const decimalChar = separator === "," ? "." : ",";
7293
7295
  let cleaned = value.replace(new RegExp(`[^\\d\\${decimalChar}-]`, "g"), "");
@@ -7301,7 +7303,7 @@ var formatCurrency = (value, separator = ",", allowDecimal = true) => {
7301
7303
  integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
7302
7304
  let result = integerPart;
7303
7305
  if (allowDecimal && decimalPart !== void 0) {
7304
- result += decimalChar + decimalPart;
7306
+ result += decimalChar + decimalPart.slice(0, maxDecimals);
7305
7307
  }
7306
7308
  if (isNegative && result !== "0") {
7307
7309
  result = "-" + result;
@@ -7547,6 +7549,7 @@ var TextField = React237.forwardRef(
7547
7549
  const separator = formatOptions?.separator ?? ",";
7548
7550
  const allowDecimal = formatOptions?.allowDecimal ?? true;
7549
7551
  const maxDigits = formatOptions?.maxDigits;
7552
+ const maxDecimals = formatOptions?.maxDecimals ?? 2;
7550
7553
  const applyFormat = React237.useCallback((raw) => {
7551
7554
  switch (activeFormat) {
7552
7555
  case "currency": {
@@ -7559,7 +7562,7 @@ var TextField = React237.forwardRef(
7559
7562
  cleaned = parts.join(decimalChar);
7560
7563
  }
7561
7564
  }
7562
- return formatCurrency(cleaned, separator, allowDecimal);
7565
+ return formatCurrency(cleaned, separator, allowDecimal, maxDecimals);
7563
7566
  }
7564
7567
  case "phone":
7565
7568
  return formatPhone(raw, { countryCode: phoneCountryCode });
@@ -7572,7 +7575,7 @@ var TextField = React237.forwardRef(
7572
7575
  default:
7573
7576
  return raw;
7574
7577
  }
7575
- }, [activeFormat, separator, allowDecimal, maxDigits, phoneCountryCode]);
7578
+ }, [activeFormat, separator, allowDecimal, maxDigits, maxDecimals, phoneCountryCode]);
7576
7579
  const handleBlur = (e) => {
7577
7580
  setFocused(false);
7578
7581
  if (activeFormat && currentValue) {
@@ -9198,6 +9201,7 @@ function OTP({
9198
9201
  const currentDigits = React251.useRef(digits);
9199
9202
  currentDigits.current = digits;
9200
9203
  const composing = React251.useRef(null);
9204
+ const picked = React251.useRef(false);
9201
9205
  const inputs = React251.useRef([]);
9202
9206
  const first = React251.useRef(null);
9203
9207
  const previousReadOnly = React251.useRef(readOnly);
@@ -9231,6 +9235,9 @@ function OTP({
9231
9235
  const index = sequential ? nextCell(currentDigits.current) : cell;
9232
9236
  const text = normalize(raw);
9233
9237
  if (raw && !text) return;
9238
+ const wasPicked = picked.current;
9239
+ picked.current = false;
9240
+ if (text && text.length < count && index === count - 1 && !wasPicked && currentDigits.current.every(Boolean)) return;
9234
9241
  const start = text.length === count ? 0 : index;
9235
9242
  const next = [...currentDigits.current];
9236
9243
  if (!text) next[index] = "";
@@ -9331,6 +9338,7 @@ function OTP({
9331
9338
  value: digits[index] ?? "",
9332
9339
  tabIndex: sequential && index !== nextCell(digits) ? -1 : void 0,
9333
9340
  onMouseDown: (event) => {
9341
+ picked.current = true;
9334
9342
  if (!sequential || disabled || readOnly) return;
9335
9343
  event.preventDefault();
9336
9344
  focus(nextCell(currentDigits.current));
@@ -9361,6 +9369,7 @@ function OTP({
9361
9369
  if (composing.current === index && next && !/^[0-9]+$/.test(next)) return;
9362
9370
  composing.current = null;
9363
9371
  enter(index, next);
9372
+ event.currentTarget.value = currentDigits.current[index] ?? "";
9364
9373
  },
9365
9374
  onPaste: (event) => {
9366
9375
  event.preventDefault();
@@ -9400,6 +9409,7 @@ function OTP({
9400
9409
  } else if (["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) {
9401
9410
  event.preventDefault();
9402
9411
  if (sequential) return;
9412
+ picked.current = true;
9403
9413
  focus(
9404
9414
  event.key === "Home" ? 0 : event.key === "End" ? count - 1 : Math.max(
9405
9415
  0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@photonix/basic",
3
- "version": "3.5.0",
3
+ "version": "3.7.0",
4
4
  "description": "Photonix Basic - Foundation primitives and essential UI building blocks",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -17,8 +17,8 @@
17
17
  "./dist/index.css": "./dist/index.css"
18
18
  },
19
19
  "dependencies": {
20
- "@photonix/icons": "^3.5.0",
21
- "@photonix/illustrations": "^3.5.0"
20
+ "@photonix/illustrations": "^3.7.0",
21
+ "@photonix/icons": "^3.7.0"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@repo/typescript-config": "*",
@@ -26,7 +26,7 @@
26
26
  "eslint": "^9.39.1",
27
27
  "tsup": "^8.0.2",
28
28
  "typescript": "5.9.2",
29
- "@photonix/ultimate": "^3.5.0"
29
+ "@photonix/ultimate": "^3.7.0"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": "^18.0.0 || ^19.0.0",