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.
- package/CHANGELOG.md +6 -0
- package/dist/definitions/index.d.ts +2 -0
- package/dist/definitions/index.d.ts.map +1 -1
- package/dist/definitions/ui/inputs/Select.d.ts +4 -0
- package/dist/definitions/ui/inputs/Select.d.ts.map +1 -0
- package/dist/definitions/ui/inputs/Select.shared.d.ts +30 -0
- package/dist/definitions/ui/inputs/Select.shared.d.ts.map +1 -0
- package/dist/definitions/ui/inputs/Select.stories.d.ts +23 -0
- package/dist/definitions/ui/inputs/Select.stories.d.ts.map +1 -0
- package/dist/definitions/ui/inputs/Select.web.d.ts +4 -0
- package/dist/definitions/ui/inputs/Select.web.d.ts.map +1 -0
- package/dist/index-browser.es.js +186 -1
- package/dist/index-browser.es.js.map +1 -1
- package/dist/index-node22.cjs +220 -0
- package/dist/index-node22.cjs.map +1 -1
- package/dist/index-node22.mjs +221 -2
- package/dist/index-node22.mjs.map +1 -1
- package/dist/index-react-native.cjs.js +220 -0
- package/dist/index-react-native.cjs.js.map +1 -1
- package/dist/index-react-native.es.js +221 -2
- package/dist/index-react-native.es.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/ui/inputs/Select.shared.tsx +104 -0
- package/src/ui/inputs/Select.stories.tsx +135 -0
- package/src/ui/inputs/Select.tsx +191 -0
- package/src/ui/inputs/Select.web.tsx +159 -0
package/dist/index-node22.cjs
CHANGED
|
@@ -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;
|