@photonix/basic 3.1.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,15 @@
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
+ }
5987
+ .brand {
5988
+ --badge-color: var(--surface-brand-primary);
5989
+ --badge-on-color: var(--text-neutral-primary-inverse);
5990
+ --badge-bg-subtle: var(--surface-brand-subtle);
5991
+ --badge-text-subtle: var(--text-brand-primary);
5992
+ }
5992
5993
  .gray {
5993
5994
  --badge-color: var(--surface-neutral-on-surface);
5994
5995
  --badge-on-color: var(--text-neutral-secondary);
@@ -6187,7 +6188,7 @@
6187
6188
  .primary:active:not(:disabled)::after {
6188
6189
  background-color: var(--surface-state-inverse-press);
6189
6190
  }
6190
- .primary:disabled {
6191
+ .primary:disabled:not(.buttonLoading) {
6191
6192
  background-color: var(--surface-state-disabled);
6192
6193
  color: var(--text-state-disabled);
6193
6194
  }
@@ -6196,7 +6197,7 @@
6196
6197
  border: var(--border-sm) solid var(--border-neutral-tertiary);
6197
6198
  color: var(--text-neutral-primary);
6198
6199
  }
6199
- .secondary:disabled {
6200
+ .secondary:disabled:not(.buttonLoading) {
6200
6201
  background-color: transparent;
6201
6202
  border-color: var(--border-state-disabled);
6202
6203
  color: var(--text-state-disabled);
@@ -6218,7 +6219,7 @@
6218
6219
  background-color: transparent;
6219
6220
  color: var(--text-neutral-primary);
6220
6221
  }
6221
- .tertiary:disabled {
6222
+ .tertiary:disabled:not(.buttonLoading) {
6222
6223
  background-color: transparent;
6223
6224
  color: var(--text-state-disabled);
6224
6225
  }
@@ -6237,7 +6238,7 @@
6237
6238
  var(--gradient-special-2-end) 100%);
6238
6239
  color: var(--text-neutral-on-dark-fixed);
6239
6240
  }
6240
- .brand:disabled {
6241
+ .brand:disabled:not(.buttonLoading) {
6241
6242
  background: var(--surface-state-disabled);
6242
6243
  color: var(--text-state-disabled);
6243
6244
  }
@@ -6279,7 +6280,7 @@
6279
6280
  .tertiary .buttonIcon {
6280
6281
  color: var(--foreground-neutral-primary);
6281
6282
  }
6282
- .button:disabled .buttonIcon {
6283
+ .button:disabled:not(.buttonLoading) .buttonIcon {
6283
6284
  color: var(--foreground-state-disabled);
6284
6285
  }
6285
6286
  .large .buttonContent,
@@ -6662,8 +6663,11 @@
6662
6663
  gap: var(--space-xs);
6663
6664
  vertical-align: middle;
6664
6665
  }
6665
- .checkboxContainer .checkboxRoot {
6666
- margin: calc((var(--dimensions-20) - var(--dimensions-40)) / 2);
6666
+ .checkboxContainer .checkboxRoot.medium {
6667
+ margin: calc((var(--dimensions-24) - var(--dimensions-40)) / 2);
6668
+ }
6669
+ .checkboxContainer .checkboxRoot.small {
6670
+ margin: calc((var(--dimensions-20) - var(--dimensions-32)) / 2);
6667
6671
  }
6668
6672
  .checkboxContainer.disabled {
6669
6673
  cursor: not-allowed;
@@ -6759,7 +6763,7 @@
6759
6763
  position: relative;
6760
6764
  z-index: var(--z-local-below);
6761
6765
  }
6762
- .small {
6766
+ .radioRoot.small {
6763
6767
  block-size: var(--dimensions-32);
6764
6768
  inline-size: var(--dimensions-32);
6765
6769
  }
@@ -6767,7 +6771,7 @@
6767
6771
  block-size: var(--dimensions-20);
6768
6772
  inline-size: var(--dimensions-20);
6769
6773
  }
6770
- .medium {
6774
+ .radioRoot.medium {
6771
6775
  block-size: var(--dimensions-40);
6772
6776
  inline-size: var(--dimensions-40);
6773
6777
  }
@@ -6784,8 +6788,11 @@
6784
6788
  min-inline-size: max-content;
6785
6789
  vertical-align: middle;
6786
6790
  }
6787
- .radioContainer .radioRoot {
6788
- margin: calc((var(--dimensions-20) - var(--dimensions-40)) / 2);
6791
+ .radioContainer .radioRoot.medium {
6792
+ margin: calc((var(--dimensions-24) - var(--dimensions-40)) / 2);
6793
+ }
6794
+ .radioContainer .radioRoot.small {
6795
+ margin: calc((var(--dimensions-20) - var(--dimensions-32)) / 2);
6789
6796
  }
6790
6797
  .radioContainer.disabled {
6791
6798
  cursor: not-allowed;
@@ -8666,6 +8673,87 @@
8666
8673
  color: var(--foreground-state-disabled);
8667
8674
  }
8668
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
+
8669
8757
  /* ../ultimate/src/components/chip-bar/ChipBar.module.css */
8670
8758
  .chipBarRoot {
8671
8759
  align-items: center;
@@ -8695,6 +8783,14 @@
8695
8783
  background-color: var(--surface-neutral-elevator);
8696
8784
  box-shadow: inset 0 calc(-1 * var(--border-sm)) 0 0 var(--border-neutral-tertiary), var(--shadow-down-sm);
8697
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
+ }
8698
8794
  .chipBarLeading {
8699
8795
  align-items: center;
8700
8796
  display: flex;
@@ -8881,10 +8977,19 @@
8881
8977
  .chipBarStuck .chipBarNavButton {
8882
8978
  background: var(--surface-neutral-elevator);
8883
8979
  }
8980
+ .chipBarMerged .chipBarNavButton,
8981
+ .chipBarRaised .chipBarNavButton {
8982
+ background: var(--sticky-stack-raised-surface, var(--surface-neutral-elevator));
8983
+ transition-duration: 0s;
8984
+ }
8884
8985
  @media (hover: hover) and (pointer: fine) {
8885
8986
  .chipBarStuck .chipBarNavButton {
8886
8987
  background: var(--surface-neutral-elevator);
8887
8988
  }
8989
+ .chipBarMerged .chipBarNavButton,
8990
+ .chipBarRaised .chipBarNavButton {
8991
+ background: var(--sticky-stack-raised-surface, var(--surface-neutral-elevator));
8992
+ }
8888
8993
  }
8889
8994
 
8890
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;
@@ -800,16 +805,20 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
800
805
  /**
801
806
  * Color theme of the badge
802
807
  */
803
- color?: 'gray' | 'black' | 'white' | 'red' | 'orange' | 'yellow' | 'green' | 'mint' | 'teal' | 'cyan' | 'blue' | 'indigo' | 'purple' | 'pink' | 'brown';
808
+ color?: 'brand' | 'gray' | 'black' | 'white' | 'red' | 'orange' | 'yellow' | 'green' | 'mint' | 'teal' | 'cyan' | 'blue' | 'indigo' | 'purple' | 'pink' | 'brown';
804
809
  /**
805
810
  * Shape of the badge
806
811
  * - rounded: Small border radius (6px)
807
812
  * - pill: Fully rounded (capsule) - DEFAULT
808
- * - icon: Circle shape with icon only
809
- * - text: Pill shape with text only
810
- * - dot: Small dot status indicator (8px)
813
+ * - icon: 24px circle holding an icon, or a one- or two-character label
814
+ * (a step number) when no icon is given
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)
811
820
  */
812
- shape?: 'rounded' | 'pill' | 'icon' | 'text' | 'dot';
821
+ shape?: 'rounded' | 'pill' | 'icon' | 'number' | 'text' | 'dot';
813
822
  /**
814
823
  * Icon to display (for rounded, pill, icon shapes)
815
824
  */
@@ -820,7 +829,7 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
820
829
  */
821
830
  trailingIcon?: React.ReactNode;
822
831
  /**
823
- * Text label (for rounded, pill, text shapes)
832
+ * Text label (for rounded, pill, text shapes; icon shape when no icon)
824
833
  */
825
834
  label?: string;
826
835
  /**
@@ -834,7 +843,9 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
834
843
  stroke?: boolean;
835
844
  /**
836
845
  * Force a specific theme's color tokens
837
- * 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.
838
849
  */
839
850
  forceTheme?: 'light' | 'dark';
840
851
  }
@@ -1085,6 +1096,16 @@ interface ChipProps extends React.HTMLAttributes<HTMLDivElement> {
1085
1096
  }
1086
1097
  declare const Chip: React.ForwardRefExoticComponent<ChipProps & React.RefAttributes<HTMLDivElement>>;
1087
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
+
1088
1109
  interface ChipBarProps extends React.HTMLAttributes<HTMLDivElement> {
1089
1110
  /**
1090
1111
  * Element to show on the left, typically a filter Chip or IconButton
@@ -1112,6 +1133,11 @@ interface ChipBarProps extends React.HTMLAttributes<HTMLDivElement> {
1112
1133
  * Optional externally controlled stuck state
1113
1134
  */
1114
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;
1115
1141
  /**
1116
1142
  * Whether the ChipBar has horizontal padding (16px default), or custom value
1117
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;
@@ -800,16 +805,20 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
800
805
  /**
801
806
  * Color theme of the badge
802
807
  */
803
- color?: 'gray' | 'black' | 'white' | 'red' | 'orange' | 'yellow' | 'green' | 'mint' | 'teal' | 'cyan' | 'blue' | 'indigo' | 'purple' | 'pink' | 'brown';
808
+ color?: 'brand' | 'gray' | 'black' | 'white' | 'red' | 'orange' | 'yellow' | 'green' | 'mint' | 'teal' | 'cyan' | 'blue' | 'indigo' | 'purple' | 'pink' | 'brown';
804
809
  /**
805
810
  * Shape of the badge
806
811
  * - rounded: Small border radius (6px)
807
812
  * - pill: Fully rounded (capsule) - DEFAULT
808
- * - icon: Circle shape with icon only
809
- * - text: Pill shape with text only
810
- * - dot: Small dot status indicator (8px)
813
+ * - icon: 24px circle holding an icon, or a one- or two-character label
814
+ * (a step number) when no icon is given
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)
811
820
  */
812
- shape?: 'rounded' | 'pill' | 'icon' | 'text' | 'dot';
821
+ shape?: 'rounded' | 'pill' | 'icon' | 'number' | 'text' | 'dot';
813
822
  /**
814
823
  * Icon to display (for rounded, pill, icon shapes)
815
824
  */
@@ -820,7 +829,7 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
820
829
  */
821
830
  trailingIcon?: React.ReactNode;
822
831
  /**
823
- * Text label (for rounded, pill, text shapes)
832
+ * Text label (for rounded, pill, text shapes; icon shape when no icon)
824
833
  */
825
834
  label?: string;
826
835
  /**
@@ -834,7 +843,9 @@ interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
834
843
  stroke?: boolean;
835
844
  /**
836
845
  * Force a specific theme's color tokens
837
- * 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.
838
849
  */
839
850
  forceTheme?: 'light' | 'dark';
840
851
  }
@@ -1085,6 +1096,16 @@ interface ChipProps extends React.HTMLAttributes<HTMLDivElement> {
1085
1096
  }
1086
1097
  declare const Chip: React.ForwardRefExoticComponent<ChipProps & React.RefAttributes<HTMLDivElement>>;
1087
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
+
1088
1109
  interface ChipBarProps extends React.HTMLAttributes<HTMLDivElement> {
1089
1110
  /**
1090
1111
  * Element to show on the left, typically a filter Chip or IconButton
@@ -1112,6 +1133,11 @@ interface ChipBarProps extends React.HTMLAttributes<HTMLDivElement> {
1112
1133
  * Optional externally controlled stuck state
1113
1134
  */
1114
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;
1115
1141
  /**
1116
1142
  * Whether the ChipBar has horizontal padding (16px default), or custom value
1117
1143
  */