@photonix/basic 3.2.0 → 3.3.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
@@ -5486,6 +5486,7 @@
5486
5486
  letter-spacing: var(--phx-letter-spacing-base, inherit);
5487
5487
  line-height: var(--phx-line-height-base, inherit);
5488
5488
  margin: 0;
5489
+ text-align: var(--phx-text-align-base);
5489
5490
  }
5490
5491
  @media (width >= 640px) {
5491
5492
  .textRoot {
@@ -5956,20 +5957,11 @@
5956
5957
  }
5957
5958
  .badgeShapeNumber {
5958
5959
  block-size: var(--dimensions-16);
5960
+ border-radius: var(--radius-full);
5959
5961
  min-block-size: var(--dimensions-16);
5960
5962
  min-inline-size: var(--dimensions-16);
5961
5963
  padding: var(--space-none);
5962
5964
  }
5963
- .badgeShapeText.singleChar {
5964
- block-size: var(--dimensions-16);
5965
- border-radius: var(--radius-full);
5966
- inline-size: auto;
5967
- min-inline-size: var(--dimensions-16);
5968
- padding: var(--space-none) !important;
5969
- }
5970
- .badgeShapeText.singleChar .badgeLabel {
5971
- padding: 0 var(--space-4xs);
5972
- }
5973
5965
  .badgeShapeDot {
5974
5966
  block-size: var(--dimensions-8);
5975
5967
  border-radius: 50%;
@@ -5989,6 +5981,9 @@
5989
5981
  border: var(--border-sm) solid transparent;
5990
5982
  color: var(--badge-text-subtle);
5991
5983
  }
5984
+ .secondary.badgeShapeDot {
5985
+ background-color: var(--badge-color);
5986
+ }
5992
5987
  .brand {
5993
5988
  --badge-color: var(--surface-brand-primary);
5994
5989
  --badge-on-color: var(--text-neutral-primary-inverse);
@@ -6193,7 +6188,7 @@
6193
6188
  .primary:active:not(:disabled)::after {
6194
6189
  background-color: var(--surface-state-inverse-press);
6195
6190
  }
6196
- .primary:disabled {
6191
+ .primary:disabled:not(.buttonLoading) {
6197
6192
  background-color: var(--surface-state-disabled);
6198
6193
  color: var(--text-state-disabled);
6199
6194
  }
@@ -6202,7 +6197,7 @@
6202
6197
  border: var(--border-sm) solid var(--border-neutral-tertiary);
6203
6198
  color: var(--text-neutral-primary);
6204
6199
  }
6205
- .secondary:disabled {
6200
+ .secondary:disabled:not(.buttonLoading) {
6206
6201
  background-color: transparent;
6207
6202
  border-color: var(--border-state-disabled);
6208
6203
  color: var(--text-state-disabled);
@@ -6224,7 +6219,7 @@
6224
6219
  background-color: transparent;
6225
6220
  color: var(--text-neutral-primary);
6226
6221
  }
6227
- .tertiary:disabled {
6222
+ .tertiary:disabled:not(.buttonLoading) {
6228
6223
  background-color: transparent;
6229
6224
  color: var(--text-state-disabled);
6230
6225
  }
@@ -6243,7 +6238,7 @@
6243
6238
  var(--gradient-special-2-end) 100%);
6244
6239
  color: var(--text-neutral-on-dark-fixed);
6245
6240
  }
6246
- .brand:disabled {
6241
+ .brand:disabled:not(.buttonLoading) {
6247
6242
  background: var(--surface-state-disabled);
6248
6243
  color: var(--text-state-disabled);
6249
6244
  }
@@ -6285,7 +6280,7 @@
6285
6280
  .tertiary .buttonIcon {
6286
6281
  color: var(--foreground-neutral-primary);
6287
6282
  }
6288
- .button:disabled .buttonIcon {
6283
+ .button:disabled:not(.buttonLoading) .buttonIcon {
6289
6284
  color: var(--foreground-state-disabled);
6290
6285
  }
6291
6286
  .large .buttonContent,
@@ -8678,6 +8673,87 @@
8678
8673
  color: var(--foreground-state-disabled);
8679
8674
  }
8680
8675
 
8676
+ /* ../ultimate/src/components/sticky-stack/StickyStack.module.css */
8677
+ .stickyStackItem {
8678
+ position: sticky;
8679
+ transition-duration:
8680
+ var(--motion-duration-normal),
8681
+ var(--motion-duration-normal),
8682
+ var(--motion-duration-medium);
8683
+ transition-property:
8684
+ background-color,
8685
+ box-shadow,
8686
+ transform;
8687
+ transition-timing-function: var(--motion-ease-standard);
8688
+ }
8689
+ .stickyStackItem[data-retracted] {
8690
+ transform: translateY(-100%);
8691
+ }
8692
+ .stickyStackItemPainted {
8693
+ background-color: var(--surface-neutral-primary);
8694
+ }
8695
+ .stickyStackItemPainted::after {
8696
+ background-color: var(--border-neutral-tertiary);
8697
+ block-size: var(--border-sm);
8698
+ content: "";
8699
+ inset-block-end: 0;
8700
+ inset-inline: 0;
8701
+ opacity: 0;
8702
+ pointer-events: none;
8703
+ position: absolute;
8704
+ transition: opacity var(--motion-duration-normal) var(--motion-ease-standard);
8705
+ z-index: var(--z-local-above);
8706
+ }
8707
+ .stickyStackItem[data-tonal=false] {
8708
+ --sticky-stack-raised-surface: var(--surface-neutral-primary);
8709
+ }
8710
+ .stickyStackItemPainted[data-surface=merged],
8711
+ .stickyStackItemPainted[data-surface=elevated] {
8712
+ background-color: var(--sticky-stack-raised-surface, var(--surface-neutral-elevator));
8713
+ transition-duration:
8714
+ 0s,
8715
+ 0s,
8716
+ var(--motion-duration-medium);
8717
+ }
8718
+ .stickyStackItemPainted[data-surface=elevated] {
8719
+ box-shadow: var(--shadow-down-sm);
8720
+ }
8721
+ .stickyStackItemPainted[data-surface=elevated]::after {
8722
+ opacity: 1;
8723
+ transition: none;
8724
+ }
8725
+ .stickyStackItemPainted[data-edge=fade]::before {
8726
+ background:
8727
+ linear-gradient(
8728
+ to bottom,
8729
+ var(--sticky-stack-raised-surface, var(--surface-neutral-elevator)),
8730
+ transparent);
8731
+ block-size: var(--dimensions-40);
8732
+ content: "";
8733
+ inset-block-start: 100%;
8734
+ inset-inline: 0;
8735
+ opacity: 0;
8736
+ pointer-events: none;
8737
+ position: absolute;
8738
+ transition: opacity var(--motion-duration-normal) var(--motion-ease-standard);
8739
+ }
8740
+ .stickyStackItemPainted[data-edge=fade][data-surface=elevated] {
8741
+ box-shadow: none;
8742
+ }
8743
+ .stickyStackItemPainted[data-edge=fade][data-surface=elevated]::before {
8744
+ opacity: 1;
8745
+ }
8746
+ .stickyStackItemPainted[data-edge=fade][data-surface=elevated]::after {
8747
+ opacity: 0;
8748
+ }
8749
+ @media (prefers-reduced-motion: reduce) {
8750
+ .stickyStackItem,
8751
+ .stickyStackItemPainted::before,
8752
+ .stickyStackItemPainted::after {
8753
+ transition: none;
8754
+ }
8755
+ }
8756
+
8681
8757
  /* ../ultimate/src/components/chip-bar/ChipBar.module.css */
8682
8758
  .chipBarRoot {
8683
8759
  align-items: center;
@@ -8707,6 +8783,14 @@
8707
8783
  background-color: var(--surface-neutral-elevator);
8708
8784
  box-shadow: inset 0 calc(-1 * var(--border-sm)) 0 0 var(--border-neutral-tertiary), var(--shadow-down-sm);
8709
8785
  }
8786
+ .chipBarMerged,
8787
+ .chipBarRaised {
8788
+ background-color: var(--sticky-stack-raised-surface, var(--surface-neutral-elevator));
8789
+ transition: none;
8790
+ }
8791
+ .chipBarRaised {
8792
+ box-shadow: inset 0 calc(-1 * var(--border-sm)) 0 0 var(--border-neutral-tertiary), var(--shadow-down-sm);
8793
+ }
8710
8794
  .chipBarLeading {
8711
8795
  align-items: center;
8712
8796
  display: flex;
@@ -8893,10 +8977,19 @@
8893
8977
  .chipBarStuck .chipBarNavButton {
8894
8978
  background: var(--surface-neutral-elevator);
8895
8979
  }
8980
+ .chipBarMerged .chipBarNavButton,
8981
+ .chipBarRaised .chipBarNavButton {
8982
+ background: var(--sticky-stack-raised-surface, var(--surface-neutral-elevator));
8983
+ transition-duration: 0s;
8984
+ }
8896
8985
  @media (hover: hover) and (pointer: fine) {
8897
8986
  .chipBarStuck .chipBarNavButton {
8898
8987
  background: var(--surface-neutral-elevator);
8899
8988
  }
8989
+ .chipBarMerged .chipBarNavButton,
8990
+ .chipBarRaised .chipBarNavButton {
8991
+ background: var(--sticky-stack-raised-surface, var(--surface-neutral-elevator));
8992
+ }
8900
8993
  }
8901
8994
 
8902
8995
  /* ../ultimate/src/components/star/Star.module.css */
package/dist/index.d.mts CHANGED
@@ -690,6 +690,11 @@ interface InputFormatOptions {
690
690
  maxDigits?: number;
691
691
  /** Allow decimal input for currency. Default: true */
692
692
  allowDecimal?: boolean;
693
+ /**
694
+ * Calling code for `phone` when it is shown outside the value (a country
695
+ * picker, say). A `leadingText` such as `+84` is picked up on its own.
696
+ */
697
+ countryCode?: string;
693
698
  }
694
699
  interface TextFieldDropdownOption {
695
700
  label: string;
@@ -807,10 +812,13 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
807
812
  * - pill: Fully rounded (capsule) - DEFAULT
808
813
  * - icon: 24px circle holding an icon, or a one- or two-character label
809
814
  * (a step number) when no icon is given
810
- * - text: Pill shape with text only
811
- * - dot: Small dot status indicator (8px)
815
+ * - number: Compact 16px capsule for a count (Figma `number`, native `.number`)
816
+ * - text: Web-only shorthand that picks for the content: `number` for a count
817
+ * ("3", "99+") or a single character, `pill` without an icon otherwise
818
+ * - dot: Small dot status indicator (8px). Always the solid colour: `variant`
819
+ * does not change a dot (a subtle dot is too faint to read)
812
820
  */
813
- shape?: 'rounded' | 'pill' | 'icon' | 'text' | 'dot';
821
+ shape?: 'rounded' | 'pill' | 'icon' | 'number' | 'text' | 'dot';
814
822
  /**
815
823
  * Icon to display (for rounded, pill, icon shapes)
816
824
  */
@@ -835,7 +843,9 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
835
843
  stroke?: boolean;
836
844
  /**
837
845
  * Force a specific theme's color tokens
838
- * Useful when component needs to use Light theme tokens regardless of current theme
846
+ * Useful when component needs to use Light theme tokens regardless of current theme.
847
+ * Web only: on iOS/Android wrap the badge in `.phxTheme(.dark)` /
848
+ * `PhxTheme(PhxColorScheme.Dark) { }`, which themes any subtree.
839
849
  */
840
850
  forceTheme?: 'light' | 'dark';
841
851
  }
@@ -1086,6 +1096,16 @@ interface ChipProps extends React.HTMLAttributes<HTMLDivElement> {
1086
1096
  }
1087
1097
  declare const Chip: React.ForwardRefExoticComponent<ChipProps & React.RefAttributes<HTMLDivElement>>;
1088
1098
 
1099
+ /**
1100
+ * How a bar paints itself against content scrolling beneath it.
1101
+ * - `flat`: nothing beneath it, primary surface.
1102
+ * - `merged`: raised surface without its own shadow or divider, because a bar below carries them.
1103
+ * - `elevated`: raised surface with divider and shadow, the bottom edge of a pinned stack.
1104
+ *
1105
+ * The raised surface is the elevator surface, or the primary one inside a non-tonal StickyStack.
1106
+ */
1107
+ type BarSurface = 'flat' | 'merged' | 'elevated';
1108
+
1089
1109
  interface ChipBarProps extends React.HTMLAttributes<HTMLDivElement> {
1090
1110
  /**
1091
1111
  * Element to show on the left, typically a filter Chip or IconButton
@@ -1113,6 +1133,11 @@ interface ChipBarProps extends React.HTMLAttributes<HTMLDivElement> {
1113
1133
  * Optional externally controlled stuck state
1114
1134
  */
1115
1135
  stuck?: boolean;
1136
+ /**
1137
+ * Surface against content scrolled beneath the bar. Inherited from an enclosing
1138
+ * StickyStackItem; when set, it replaces the stuck state `sticky` detects.
1139
+ */
1140
+ surface?: BarSurface;
1116
1141
  /**
1117
1142
  * Whether the ChipBar has horizontal padding (16px default), or custom value
1118
1143
  */
package/dist/index.d.ts CHANGED
@@ -690,6 +690,11 @@ interface InputFormatOptions {
690
690
  maxDigits?: number;
691
691
  /** Allow decimal input for currency. Default: true */
692
692
  allowDecimal?: boolean;
693
+ /**
694
+ * Calling code for `phone` when it is shown outside the value (a country
695
+ * picker, say). A `leadingText` such as `+84` is picked up on its own.
696
+ */
697
+ countryCode?: string;
693
698
  }
694
699
  interface TextFieldDropdownOption {
695
700
  label: string;
@@ -807,10 +812,13 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
807
812
  * - pill: Fully rounded (capsule) - DEFAULT
808
813
  * - icon: 24px circle holding an icon, or a one- or two-character label
809
814
  * (a step number) when no icon is given
810
- * - text: Pill shape with text only
811
- * - dot: Small dot status indicator (8px)
815
+ * - number: Compact 16px capsule for a count (Figma `number`, native `.number`)
816
+ * - text: Web-only shorthand that picks for the content: `number` for a count
817
+ * ("3", "99+") or a single character, `pill` without an icon otherwise
818
+ * - dot: Small dot status indicator (8px). Always the solid colour: `variant`
819
+ * does not change a dot (a subtle dot is too faint to read)
812
820
  */
813
- shape?: 'rounded' | 'pill' | 'icon' | 'text' | 'dot';
821
+ shape?: 'rounded' | 'pill' | 'icon' | 'number' | 'text' | 'dot';
814
822
  /**
815
823
  * Icon to display (for rounded, pill, icon shapes)
816
824
  */
@@ -835,7 +843,9 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
835
843
  stroke?: boolean;
836
844
  /**
837
845
  * Force a specific theme's color tokens
838
- * Useful when component needs to use Light theme tokens regardless of current theme
846
+ * Useful when component needs to use Light theme tokens regardless of current theme.
847
+ * Web only: on iOS/Android wrap the badge in `.phxTheme(.dark)` /
848
+ * `PhxTheme(PhxColorScheme.Dark) { }`, which themes any subtree.
839
849
  */
840
850
  forceTheme?: 'light' | 'dark';
841
851
  }
@@ -1086,6 +1096,16 @@ interface ChipProps extends React.HTMLAttributes<HTMLDivElement> {
1086
1096
  }
1087
1097
  declare const Chip: React.ForwardRefExoticComponent<ChipProps & React.RefAttributes<HTMLDivElement>>;
1088
1098
 
1099
+ /**
1100
+ * How a bar paints itself against content scrolling beneath it.
1101
+ * - `flat`: nothing beneath it, primary surface.
1102
+ * - `merged`: raised surface without its own shadow or divider, because a bar below carries them.
1103
+ * - `elevated`: raised surface with divider and shadow, the bottom edge of a pinned stack.
1104
+ *
1105
+ * The raised surface is the elevator surface, or the primary one inside a non-tonal StickyStack.
1106
+ */
1107
+ type BarSurface = 'flat' | 'merged' | 'elevated';
1108
+
1089
1109
  interface ChipBarProps extends React.HTMLAttributes<HTMLDivElement> {
1090
1110
  /**
1091
1111
  * Element to show on the left, typically a filter Chip or IconButton
@@ -1113,6 +1133,11 @@ interface ChipBarProps extends React.HTMLAttributes<HTMLDivElement> {
1113
1133
  * Optional externally controlled stuck state
1114
1134
  */
1115
1135
  stuck?: boolean;
1136
+ /**
1137
+ * Surface against content scrolled beneath the bar. Inherited from an enclosing
1138
+ * StickyStackItem; when set, it replaces the stuck state `sticky` detects.
1139
+ */
1140
+ surface?: BarSurface;
1116
1141
  /**
1117
1142
  * Whether the ChipBar has horizontal padding (16px default), or custom value
1118
1143
  */