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.
@@ -1,12 +1,13 @@
1
1
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
2
2
  import { VariableContextProvider, styled as styled$1 } from 'nativewind';
3
3
  import { createContext, useContext, forwardRef, Children, cloneElement, Fragment, useRef, useState, useEffect, isValidElement, useCallback } from 'react';
4
- import { useColorScheme, View as View$1, Text as Text$1, ScrollView as ScrollView$1, FlatList as FlatList$1, SectionList as SectionList$1, Pressable, Platform, TextInput, Switch as Switch$1, useWindowDimensions, Linking } from 'react-native';
4
+ import { useColorScheme, View as View$1, Text as Text$1, ScrollView as ScrollView$1, FlatList as FlatList$1, SectionList as SectionList$1, Pressable, Platform, TextInput, Switch as Switch$1, useWindowDimensions, Modal, Linking } from 'react-native';
5
5
  import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
6
6
  export { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
7
7
  import { extendTailwindMerge, twMerge as twMerge$1 } from 'tailwind-merge';
8
8
  import { tv } from 'tailwind-variants';
9
9
  import { CheckRegularIcon } from 'alouette-icons/phosphor-icons/CheckRegularIcon';
10
+ import { CaretDownRegularIcon } from 'alouette-icons/phosphor-icons/CaretDownRegularIcon';
10
11
  import { InfoRegularIcon } from 'alouette-icons/phosphor-icons/InfoRegularIcon';
11
12
  import { WarningRegularIcon } from 'alouette-icons/phosphor-icons/WarningRegularIcon';
12
13
  import { XRegularIcon } from 'alouette-icons/phosphor-icons/XRegularIcon';
@@ -1728,6 +1729,224 @@ function Switch({ accent, ...rest }) {
1728
1729
  return /* @__PURE__ */ jsx(AccentScope, { accent, children: /* @__PURE__ */ jsx(SwitchInner, { ...rest }) });
1729
1730
  }
1730
1731
 
1732
+ function useControllableValue(controlled, defaultValue, onValueChange) {
1733
+ const [internal, setInternal] = useState(defaultValue);
1734
+ const value = controlled ?? internal;
1735
+ const setValue = useCallback(
1736
+ (next) => {
1737
+ if (controlled === void 0) {
1738
+ setInternal(next);
1739
+ }
1740
+ if (next !== value) {
1741
+ onValueChange?.(next);
1742
+ }
1743
+ },
1744
+ [controlled, onValueChange, value]
1745
+ );
1746
+ return [value, setValue];
1747
+ }
1748
+ const selectTriggerBaseClassName = [
1749
+ "flex-row items-center justify-between gap-xs",
1750
+ "rounded-md border px-m py-xs min-h-[44px]",
1751
+ "transition-[border-color,outline-color,background-color] duration-200 ease-in"
1752
+ ].join(" ");
1753
+ const triggerLabelVariants = tv({
1754
+ base: "flex-1 text-base",
1755
+ variants: {
1756
+ // Mirrors InputText: sharp value, form-placeholder, form-disabled-text.
1757
+ state: {
1758
+ value: "text-sharp",
1759
+ placeholder: "text-form-placeholder",
1760
+ disabled: "text-form-disabled-text"
1761
+ }
1762
+ },
1763
+ defaultVariants: { state: "value" }
1764
+ });
1765
+ function SelectTriggerContent({
1766
+ label,
1767
+ placeholder,
1768
+ disabled
1769
+ }) {
1770
+ const state = (() => {
1771
+ if (label === void 0) return "placeholder";
1772
+ if (disabled) return "disabled";
1773
+ return "value";
1774
+ })();
1775
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1776
+ /* @__PURE__ */ jsx(Text, { numberOfLines: 1, className: triggerLabelVariants({ state }), children: label ?? placeholder ?? "" }),
1777
+ /* @__PURE__ */ jsx(
1778
+ Icon,
1779
+ {
1780
+ icon: /* @__PURE__ */ jsx(CaretDownRegularIcon, {}),
1781
+ size: 18,
1782
+ className: disabled ? "text-form-disabled-text" : "text-muted"
1783
+ }
1784
+ )
1785
+ ] });
1786
+ }
1787
+
1788
+ const triggerVariants = tv(
1789
+ {
1790
+ base: selectTriggerBaseClassName,
1791
+ variants: {
1792
+ // bg lives in each branch (not the shared base) so the disabled bg never
1793
+ // competes with bg-highlight at equal specificity.
1794
+ disabled: {
1795
+ true: "bg-disabled-interactive-muted border-interactive-outlined-disabled",
1796
+ false: [
1797
+ "bg-highlight",
1798
+ "border-interactive-outlined-pressable",
1799
+ "hover:border-interactive-outlined-hover",
1800
+ "focus:border-interactive-outlined-focus",
1801
+ "active:border-interactive-outlined-active"
1802
+ ].join(" ")
1803
+ }
1804
+ },
1805
+ defaultVariants: { disabled: false }
1806
+ },
1807
+ { twMerge: false }
1808
+ );
1809
+ const optionVariants = tv(
1810
+ {
1811
+ base: [
1812
+ "flex-row items-center justify-between gap-xxs rounded-xs px-m py-m my-xxs",
1813
+ "hover:bg-interactive-contained-hover focus:bg-interactive-contained-focus active:bg-interactive-contained-active"
1814
+ ].join(" "),
1815
+ variants: {
1816
+ selected: {
1817
+ true: "bg-interactive-contained-active",
1818
+ false: "bg-interactive-contained-pressable"
1819
+ },
1820
+ disabled: {
1821
+ true: "opacity-50",
1822
+ false: ""
1823
+ }
1824
+ },
1825
+ defaultVariants: { selected: false, disabled: false }
1826
+ },
1827
+ { twMerge: false }
1828
+ );
1829
+ function SelectOptionRow({
1830
+ option,
1831
+ selected,
1832
+ onSelect
1833
+ }) {
1834
+ return /* @__PURE__ */ jsxs(
1835
+ Pressable,
1836
+ {
1837
+ role: "option",
1838
+ "aria-selected": selected,
1839
+ "aria-disabled": option.disabled === true,
1840
+ disabled: option.disabled,
1841
+ className: optionVariants({ selected, disabled: option.disabled }),
1842
+ onPress: () => {
1843
+ onSelect(option.value);
1844
+ },
1845
+ children: [
1846
+ /* @__PURE__ */ jsx(Text, { numberOfLines: 1, className: "flex-1 text-base text-on-accent", children: option.label }),
1847
+ selected ? /* @__PURE__ */ jsx(
1848
+ Icon,
1849
+ {
1850
+ icon: /* @__PURE__ */ jsx(CheckRegularIcon, {}),
1851
+ size: 18,
1852
+ className: "text-on-accent"
1853
+ }
1854
+ ) : null
1855
+ ]
1856
+ }
1857
+ );
1858
+ }
1859
+ function SelectInner({
1860
+ options,
1861
+ value,
1862
+ defaultValue,
1863
+ onValueChange,
1864
+ placeholder,
1865
+ disabled,
1866
+ testID,
1867
+ "aria-label": ariaLabel,
1868
+ "aria-labelledby": ariaLabelledby
1869
+ }) {
1870
+ const [current, setValue] = useControllableValue(
1871
+ value,
1872
+ defaultValue,
1873
+ onValueChange
1874
+ );
1875
+ const [open, setOpen] = useState(false);
1876
+ const { height: windowHeight } = useWindowDimensions();
1877
+ const selected = options.find((option) => option.value === current);
1878
+ const onSelect = (next) => {
1879
+ setValue(next);
1880
+ setOpen(false);
1881
+ };
1882
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1883
+ /* @__PURE__ */ jsx(
1884
+ InteractiveBox,
1885
+ {
1886
+ withFocusVisibleOutline: true,
1887
+ role: "combobox",
1888
+ "aria-expanded": open,
1889
+ "aria-disabled": disabled === true,
1890
+ disabled,
1891
+ testID,
1892
+ "aria-label": ariaLabel,
1893
+ "aria-labelledby": ariaLabelledby,
1894
+ className: triggerVariants({ disabled }),
1895
+ onPress: () => {
1896
+ setOpen(true);
1897
+ },
1898
+ children: /* @__PURE__ */ jsx(
1899
+ SelectTriggerContent,
1900
+ {
1901
+ label: selected?.label,
1902
+ placeholder,
1903
+ disabled
1904
+ }
1905
+ )
1906
+ }
1907
+ ),
1908
+ /* @__PURE__ */ jsx(
1909
+ Modal,
1910
+ {
1911
+ transparent: true,
1912
+ visible: open,
1913
+ animationType: "fade",
1914
+ onRequestClose: () => {
1915
+ setOpen(false);
1916
+ },
1917
+ children: /* @__PURE__ */ jsx(
1918
+ Pressable,
1919
+ {
1920
+ className: "flex-1 justify-center bg-translucent px-xl",
1921
+ onPress: () => {
1922
+ setOpen(false);
1923
+ },
1924
+ children: /* @__PURE__ */ jsx(Pressable, { className: "w-full", "aria-label": ariaLabel, children: /* @__PURE__ */ jsx(Surface, { variant: "highlight", shadow: "l", size: "sm", className: "py-xs", children: /* @__PURE__ */ jsx(
1925
+ ScrollView,
1926
+ {
1927
+ style: { maxHeight: windowHeight * 0.7 },
1928
+ showsVerticalScrollIndicator: false,
1929
+ children: options.map((option) => /* @__PURE__ */ jsx(
1930
+ SelectOptionRow,
1931
+ {
1932
+ option,
1933
+ selected: option.value === current,
1934
+ onSelect
1935
+ },
1936
+ option.value
1937
+ ))
1938
+ }
1939
+ ) }) })
1940
+ }
1941
+ )
1942
+ }
1943
+ )
1944
+ ] });
1945
+ }
1946
+ function Select({ accent, ...rest }) {
1947
+ return /* @__PURE__ */ jsx(AccentScope, { accent, children: /* @__PURE__ */ jsx(SelectInner, { ...rest }) });
1948
+ }
1949
+
1731
1950
  const badgeVariants = tv(
1732
1951
  {
1733
1952
  slots: {
@@ -2055,5 +2274,5 @@ function ExternalLink({
2055
2274
  return /* @__PURE__ */ jsx(C, { ...props, onPress: handlePress });
2056
2275
  }
2057
2276
 
2058
- export { AccentScope, AlouetteDecorator, AlouetteProvider, Badge, Box, BreakpointNameEnum, Breakpoints, Button, ConfirmationMessage, ExternalLink, ExternalLinkButton, FlatList, GradientBackground, GradientScrollView, HStack, Icon, IconButton, InfoMessage, InputText, InteractiveBox, InternalLinkButton, Message, Paragraph, PresenceList, PresenceOne, PressableBox, PressableListItem, SafeAreaBox, ScopedTheme, ScrollView, SectionList, Separator, Stack, Story, StoryContainer, StoryDecorator, StoryGrid, StoryTitle, Surface, Switch, SwitchBreakpointsUsingDisplayNone, SwitchBreakpointsUsingNull, Text, TextArea, VStack, View, WarningMessage, animationDurationsMs, styled, themeVariables, useCurrentBreakpointName, useCurrentBreakpointNameFiltered, useCurrentMode, useCurrentTheme, useThemeToken };
2277
+ export { AccentScope, AlouetteDecorator, AlouetteProvider, Badge, Box, BreakpointNameEnum, Breakpoints, Button, ConfirmationMessage, ExternalLink, ExternalLinkButton, FlatList, GradientBackground, GradientScrollView, HStack, Icon, IconButton, InfoMessage, InputText, InteractiveBox, InternalLinkButton, Message, Paragraph, PresenceList, PresenceOne, PressableBox, PressableListItem, SafeAreaBox, ScopedTheme, ScrollView, SectionList, Select, Separator, Stack, Story, StoryContainer, StoryDecorator, StoryGrid, StoryTitle, Surface, Switch, SwitchBreakpointsUsingDisplayNone, SwitchBreakpointsUsingNull, Text, TextArea, VStack, View, WarningMessage, animationDurationsMs, styled, themeVariables, useCurrentBreakpointName, useCurrentBreakpointNameFiltered, useCurrentMode, useCurrentTheme, useThemeToken };
2059
2278
  //# sourceMappingURL=index-react-native.es.js.map