alouette 19.2.0 → 19.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.
@@ -10,6 +10,7 @@ const reactNativeSafeAreaContext = require('react-native-safe-area-context');
10
10
  const tailwindMerge = require('tailwind-merge');
11
11
  const tailwindVariants = require('tailwind-variants');
12
12
  const CheckRegularIcon = require('alouette-icons/phosphor-icons/CheckRegularIcon');
13
+ const CaretDownRegularIcon = require('alouette-icons/phosphor-icons/CaretDownRegularIcon');
13
14
  const InfoRegularIcon = require('alouette-icons/phosphor-icons/InfoRegularIcon');
14
15
  const WarningRegularIcon = require('alouette-icons/phosphor-icons/WarningRegularIcon');
15
16
  const XRegularIcon = require('alouette-icons/phosphor-icons/XRegularIcon');
@@ -1743,6 +1744,224 @@ function Switch({ accent, ...rest }) {
1743
1744
  return /* @__PURE__ */ jsxRuntime.jsx(AccentScope, { accent, children: /* @__PURE__ */ jsxRuntime.jsx(SwitchInner, { ...rest }) });
1744
1745
  }
1745
1746
 
1747
+ function useControllableValue(controlled, defaultValue, onValueChange) {
1748
+ const [internal, setInternal] = react.useState(defaultValue);
1749
+ const value = controlled ?? internal;
1750
+ const setValue = react.useCallback(
1751
+ (next) => {
1752
+ if (controlled === void 0) {
1753
+ setInternal(next);
1754
+ }
1755
+ if (next !== value) {
1756
+ onValueChange?.(next);
1757
+ }
1758
+ },
1759
+ [controlled, onValueChange, value]
1760
+ );
1761
+ return [value, setValue];
1762
+ }
1763
+ const selectTriggerBaseClassName = [
1764
+ "flex-row items-center justify-between gap-xs",
1765
+ "rounded-md border px-m py-xs min-h-[44px]",
1766
+ "transition-[border-color,outline-color,background-color] duration-200 ease-in"
1767
+ ].join(" ");
1768
+ const triggerLabelVariants = tailwindVariants.tv({
1769
+ base: "flex-1 text-base",
1770
+ variants: {
1771
+ // Mirrors InputText: sharp value, form-placeholder, form-disabled-text.
1772
+ state: {
1773
+ value: "text-sharp",
1774
+ placeholder: "text-form-placeholder",
1775
+ disabled: "text-form-disabled-text"
1776
+ }
1777
+ },
1778
+ defaultVariants: { state: "value" }
1779
+ });
1780
+ function SelectTriggerContent({
1781
+ label,
1782
+ placeholder,
1783
+ disabled
1784
+ }) {
1785
+ const state = (() => {
1786
+ if (label === void 0) return "placeholder";
1787
+ if (disabled) return "disabled";
1788
+ return "value";
1789
+ })();
1790
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1791
+ /* @__PURE__ */ jsxRuntime.jsx(Text, { numberOfLines: 1, className: triggerLabelVariants({ state }), children: label ?? placeholder ?? "" }),
1792
+ /* @__PURE__ */ jsxRuntime.jsx(
1793
+ Icon,
1794
+ {
1795
+ icon: /* @__PURE__ */ jsxRuntime.jsx(CaretDownRegularIcon.CaretDownRegularIcon, {}),
1796
+ size: 18,
1797
+ className: disabled ? "text-form-disabled-text" : "text-muted"
1798
+ }
1799
+ )
1800
+ ] });
1801
+ }
1802
+
1803
+ const triggerVariants = tailwindVariants.tv(
1804
+ {
1805
+ base: selectTriggerBaseClassName,
1806
+ variants: {
1807
+ // bg lives in each branch (not the shared base) so the disabled bg never
1808
+ // competes with bg-highlight at equal specificity.
1809
+ disabled: {
1810
+ true: "bg-disabled-interactive-muted border-interactive-outlined-disabled",
1811
+ false: [
1812
+ "bg-highlight",
1813
+ "border-interactive-outlined-pressable",
1814
+ "hover:border-interactive-outlined-hover",
1815
+ "focus:border-interactive-outlined-focus",
1816
+ "active:border-interactive-outlined-active"
1817
+ ].join(" ")
1818
+ }
1819
+ },
1820
+ defaultVariants: { disabled: false }
1821
+ },
1822
+ { twMerge: false }
1823
+ );
1824
+ const optionVariants = tailwindVariants.tv(
1825
+ {
1826
+ base: [
1827
+ "flex-row items-center justify-between gap-xxs rounded-xs px-m py-m my-xxs",
1828
+ "hover:bg-interactive-contained-hover focus:bg-interactive-contained-focus active:bg-interactive-contained-active"
1829
+ ].join(" "),
1830
+ variants: {
1831
+ selected: {
1832
+ true: "bg-interactive-contained-active",
1833
+ false: "bg-interactive-contained-pressable"
1834
+ },
1835
+ disabled: {
1836
+ true: "opacity-50",
1837
+ false: ""
1838
+ }
1839
+ },
1840
+ defaultVariants: { selected: false, disabled: false }
1841
+ },
1842
+ { twMerge: false }
1843
+ );
1844
+ function SelectOptionRow({
1845
+ option,
1846
+ selected,
1847
+ onSelect
1848
+ }) {
1849
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1850
+ reactNative.Pressable,
1851
+ {
1852
+ role: "option",
1853
+ "aria-selected": selected,
1854
+ "aria-disabled": option.disabled === true,
1855
+ disabled: option.disabled,
1856
+ className: optionVariants({ selected, disabled: option.disabled }),
1857
+ onPress: () => {
1858
+ onSelect(option.value);
1859
+ },
1860
+ children: [
1861
+ /* @__PURE__ */ jsxRuntime.jsx(Text, { numberOfLines: 1, className: "flex-1 text-base text-on-accent", children: option.label }),
1862
+ selected ? /* @__PURE__ */ jsxRuntime.jsx(
1863
+ Icon,
1864
+ {
1865
+ icon: /* @__PURE__ */ jsxRuntime.jsx(CheckRegularIcon.CheckRegularIcon, {}),
1866
+ size: 18,
1867
+ className: "text-on-accent"
1868
+ }
1869
+ ) : null
1870
+ ]
1871
+ }
1872
+ );
1873
+ }
1874
+ function SelectInner({
1875
+ options,
1876
+ value,
1877
+ defaultValue,
1878
+ onValueChange,
1879
+ placeholder,
1880
+ disabled,
1881
+ testID,
1882
+ "aria-label": ariaLabel,
1883
+ "aria-labelledby": ariaLabelledby
1884
+ }) {
1885
+ const [current, setValue] = useControllableValue(
1886
+ value,
1887
+ defaultValue,
1888
+ onValueChange
1889
+ );
1890
+ const [open, setOpen] = react.useState(false);
1891
+ const { height: windowHeight } = reactNative.useWindowDimensions();
1892
+ const selected = options.find((option) => option.value === current);
1893
+ const onSelect = (next) => {
1894
+ setValue(next);
1895
+ setOpen(false);
1896
+ };
1897
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1898
+ /* @__PURE__ */ jsxRuntime.jsx(
1899
+ InteractiveBox,
1900
+ {
1901
+ withFocusVisibleOutline: true,
1902
+ role: "combobox",
1903
+ "aria-expanded": open,
1904
+ "aria-disabled": disabled === true,
1905
+ disabled,
1906
+ testID,
1907
+ "aria-label": ariaLabel,
1908
+ "aria-labelledby": ariaLabelledby,
1909
+ className: triggerVariants({ disabled }),
1910
+ onPress: () => {
1911
+ setOpen(true);
1912
+ },
1913
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1914
+ SelectTriggerContent,
1915
+ {
1916
+ label: selected?.label,
1917
+ placeholder,
1918
+ disabled
1919
+ }
1920
+ )
1921
+ }
1922
+ ),
1923
+ /* @__PURE__ */ jsxRuntime.jsx(
1924
+ reactNative.Modal,
1925
+ {
1926
+ transparent: true,
1927
+ visible: open,
1928
+ animationType: "fade",
1929
+ onRequestClose: () => {
1930
+ setOpen(false);
1931
+ },
1932
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1933
+ reactNative.Pressable,
1934
+ {
1935
+ className: "flex-1 justify-center bg-translucent px-xl",
1936
+ onPress: () => {
1937
+ setOpen(false);
1938
+ },
1939
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { className: "w-full", "aria-label": ariaLabel, children: /* @__PURE__ */ jsxRuntime.jsx(Surface, { variant: "highlight", shadow: "l", size: "sm", className: "py-xs", children: /* @__PURE__ */ jsxRuntime.jsx(
1940
+ ScrollView,
1941
+ {
1942
+ style: { maxHeight: windowHeight * 0.7 },
1943
+ showsVerticalScrollIndicator: false,
1944
+ children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
1945
+ SelectOptionRow,
1946
+ {
1947
+ option,
1948
+ selected: option.value === current,
1949
+ onSelect
1950
+ },
1951
+ option.value
1952
+ ))
1953
+ }
1954
+ ) }) })
1955
+ }
1956
+ )
1957
+ }
1958
+ )
1959
+ ] });
1960
+ }
1961
+ function Select({ accent, ...rest }) {
1962
+ return /* @__PURE__ */ jsxRuntime.jsx(AccentScope, { accent, children: /* @__PURE__ */ jsxRuntime.jsx(SelectInner, { ...rest }) });
1963
+ }
1964
+
1746
1965
  const badgeVariants = tailwindVariants.tv(
1747
1966
  {
1748
1967
  slots: {
@@ -2103,6 +2322,7 @@ exports.SafeAreaBox = SafeAreaBox;
2103
2322
  exports.ScopedTheme = ScopedTheme;
2104
2323
  exports.ScrollView = ScrollView;
2105
2324
  exports.SectionList = SectionList;
2325
+ exports.Select = Select;
2106
2326
  exports.Separator = Separator;
2107
2327
  exports.Stack = Stack;
2108
2328
  exports.Story = Story;