@satellatickets/ui 0.2.1 → 0.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/native/index.d.ts +1 -1
- package/dist/native/index.js +1 -1
- package/dist/web/index.d.ts +7 -5
- package/dist/web/index.js +247 -38
- package/dist/web/styles.css +82 -8
- package/package.json +4 -4
package/dist/native/index.d.ts
CHANGED
|
@@ -189,7 +189,7 @@ interface SelectNativeProps extends SelectProps$1 {
|
|
|
189
189
|
//#endregion
|
|
190
190
|
//#region src/select/Select.native.d.ts
|
|
191
191
|
/**
|
|
192
|
-
* Un disparador con aspecto de `Input` que abre una lista modal (ADR-
|
|
192
|
+
* Un disparador con aspecto de `Input` que abre una lista modal (ADR-042). React
|
|
193
193
|
* Native no trae ningún selector, y así `Select` no añade dependencias.
|
|
194
194
|
*/
|
|
195
195
|
export declare function Select({ options, value, defaultValue, onValueChange, placeholder, size, disabled, invalid, required, accessibilityLabel, style, testID, ref }: SelectNativeProps): import("react").JSX.Element;
|
package/dist/native/index.js
CHANGED
|
@@ -1536,7 +1536,7 @@ const styles$6 = StyleSheet.create({
|
|
|
1536
1536
|
}
|
|
1537
1537
|
});
|
|
1538
1538
|
/**
|
|
1539
|
-
* Un disparador con aspecto de `Input` que abre una lista modal (ADR-
|
|
1539
|
+
* Un disparador con aspecto de `Input` que abre una lista modal (ADR-042). React
|
|
1540
1540
|
* Native no trae ningún selector, y así `Select` no añade dependencias.
|
|
1541
1541
|
*/
|
|
1542
1542
|
function Select({ options, value, defaultValue, onValueChange, placeholder, size = "md", disabled, invalid, required, accessibilityLabel, style, testID, ref }) {
|
package/dist/web/index.d.ts
CHANGED
|
@@ -182,20 +182,22 @@ export declare function Modal(props: ModalWebProps): import("react").JSX.Element
|
|
|
182
182
|
//#region src/select/Select.types.d.ts
|
|
183
183
|
/** Extensión solo web del contrato (ADR-009): atributos de formulario y escape hatches. */
|
|
184
184
|
interface SelectWebProps extends SelectProps$1 {
|
|
185
|
-
/** `id` del
|
|
185
|
+
/** `id` del botón que abre la lista. Dentro de un `FormField` no hace falta: lo pone él. */
|
|
186
186
|
id?: string | undefined;
|
|
187
187
|
/** Nombre con el que viaja en un `<form>`. */
|
|
188
188
|
name?: string | undefined;
|
|
189
|
-
/** Se aplican a la caja del campo, no al
|
|
189
|
+
/** Se aplican a la caja del campo, no al botón. */
|
|
190
190
|
className?: string | undefined;
|
|
191
191
|
style?: CSSProperties | undefined;
|
|
192
|
-
|
|
192
|
+
/** El botón que abre la lista (ADR-042). */
|
|
193
|
+
ref?: Ref<HTMLButtonElement> | undefined;
|
|
193
194
|
}
|
|
194
195
|
//#endregion
|
|
195
196
|
//#region src/select/Select.web.d.ts
|
|
196
197
|
/**
|
|
197
|
-
* Un
|
|
198
|
-
*
|
|
198
|
+
* Un botón que abre una lista propia (ADR-042). El foco no sale del botón: la opción
|
|
199
|
+
* resaltada se comunica con `aria-activedescendant`, y la lista se pinta en la capa
|
|
200
|
+
* superior del navegador, por encima de todo y sin que la recorte ningún contenedor.
|
|
199
201
|
*/
|
|
200
202
|
export declare function Select({ options, value, defaultValue, onValueChange, placeholder, size, disabled, invalid, required, accessibilityLabel, id, name, className, style, testID, ref }: SelectWebProps): import("react").JSX.Element;
|
|
201
203
|
//#endregion
|
package/dist/web/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { FormFieldContext, ToastContext, UIContext, buttonIconSize, createFormFieldValue, createToastStore, createUIContextValue, firstEnabledTab, getTabInDirection, iconButtonIconSize, iconSizePx, inputIconSize, isFeedbackTone, textVariantStyles, useBrand, useButton, useColorScheme, useControllableState, useFormFieldControl, useLink, useTheme, useToast } from "@satellatickets/core";
|
|
2
|
+
import { FormFieldContext, ToastContext, UIContext, buttonIconSize, createFormFieldValue, createToastStore, createUIContextValue, findOptionByText, firstEnabledTab, getOptionInDirection, getTabInDirection, iconButtonIconSize, iconSizePx, inputIconSize, isFeedbackTone, textVariantStyles, useBrand, useButton, useColorScheme, useControllableState, useFormFieldControl, useLink, useTheme, useToast } from "@satellatickets/core";
|
|
3
3
|
import { cssVariables } from "@satellatickets/tokens";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { useContext, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
5
|
+
import { useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
6
6
|
//#region src/_internal/cx.ts
|
|
7
7
|
/** Une clases CSS ignorando valores falsos. */
|
|
8
8
|
function cx(...parts) {
|
|
@@ -1085,13 +1085,19 @@ function Modal(props) {
|
|
|
1085
1085
|
//#endregion
|
|
1086
1086
|
//#region src/select/Select.module.css
|
|
1087
1087
|
var Select_module_default = {
|
|
1088
|
+
"active": "sui-active-Rxx4wG",
|
|
1088
1089
|
"chevron": "sui-chevron-Rxx4wG",
|
|
1090
|
+
"disabled": "sui-disabled-Rxx4wG",
|
|
1091
|
+
"focused": "sui-focused-Rxx4wG",
|
|
1092
|
+
"label": "sui-label-Rxx4wG",
|
|
1089
1093
|
"lg": "sui-lg-Rxx4wG",
|
|
1094
|
+
"list": "sui-list-Rxx4wG",
|
|
1090
1095
|
"md": "sui-md-Rxx4wG",
|
|
1096
|
+
"option": "sui-option-Rxx4wG",
|
|
1091
1097
|
"placeholder": "sui-placeholder-Rxx4wG",
|
|
1092
1098
|
"root": "sui-root-Rxx4wG",
|
|
1093
|
-
"
|
|
1094
|
-
"
|
|
1099
|
+
"sm": "sui-sm-Rxx4wG",
|
|
1100
|
+
"trigger": "sui-trigger-Rxx4wG"
|
|
1095
1101
|
};
|
|
1096
1102
|
//#endregion
|
|
1097
1103
|
//#region src/select/Select.web.tsx
|
|
@@ -1100,57 +1106,260 @@ const sizeClass = {
|
|
|
1100
1106
|
md: Select_module_default.md,
|
|
1101
1107
|
lg: Select_module_default.lg
|
|
1102
1108
|
};
|
|
1109
|
+
const keyDirection$1 = {
|
|
1110
|
+
ArrowDown: "next",
|
|
1111
|
+
ArrowUp: "previous",
|
|
1112
|
+
Home: "first",
|
|
1113
|
+
End: "last",
|
|
1114
|
+
PageDown: "nextPage",
|
|
1115
|
+
PageUp: "previousPage"
|
|
1116
|
+
};
|
|
1117
|
+
/** Pasado este tiempo sin escribir, la siguiente letra empieza una búsqueda nueva. */
|
|
1118
|
+
const SEARCH_TIMEOUT_MS = 500;
|
|
1119
|
+
/** Lo escrito para buscar una opción y el momento de la última letra. */
|
|
1120
|
+
const NO_SEARCH = {
|
|
1121
|
+
text: "",
|
|
1122
|
+
at: Number.NEGATIVE_INFINITY
|
|
1123
|
+
};
|
|
1103
1124
|
/**
|
|
1104
|
-
* Un
|
|
1105
|
-
*
|
|
1125
|
+
* Un botón que abre una lista propia (ADR-042). El foco no sale del botón: la opción
|
|
1126
|
+
* resaltada se comunica con `aria-activedescendant`, y la lista se pinta en la capa
|
|
1127
|
+
* superior del navegador, por encima de todo y sin que la recorte ningún contenedor.
|
|
1106
1128
|
*/
|
|
1107
1129
|
function Select({ options, value, defaultValue, onValueChange, placeholder, size = "md", disabled, invalid, required, accessibilityLabel, id, name, className, style, testID, ref }) {
|
|
1108
1130
|
const control = useFormFieldControl({
|
|
1109
1131
|
id,
|
|
1110
1132
|
invalid,
|
|
1111
1133
|
disabled,
|
|
1112
|
-
required
|
|
1134
|
+
required,
|
|
1135
|
+
accessibilityLabel
|
|
1113
1136
|
});
|
|
1114
1137
|
const [current, setCurrent] = useControllableState({
|
|
1115
1138
|
value,
|
|
1116
1139
|
defaultValue: defaultValue ?? "",
|
|
1117
1140
|
onChange: onValueChange
|
|
1118
1141
|
});
|
|
1142
|
+
const [opened, setOpened] = useState(false);
|
|
1143
|
+
const [active, setActive] = useState();
|
|
1144
|
+
const baseId = useId();
|
|
1145
|
+
const root = useRef(null);
|
|
1146
|
+
const list = useRef(null);
|
|
1147
|
+
const search = useRef(NO_SEARCH);
|
|
1148
|
+
const pointer = useRef(void 0);
|
|
1149
|
+
if (opened && control.disabled) setOpened(false);
|
|
1150
|
+
const open = opened && !control.disabled;
|
|
1151
|
+
const selected = options.find((option) => option.value === current);
|
|
1152
|
+
const activeIndex = open ? options.findIndex((option) => option.value === active?.value) : -1;
|
|
1153
|
+
const listId = `${baseId}-list`;
|
|
1154
|
+
const activeId = activeIndex === -1 ? void 0 : `${baseId}-option-${activeIndex}`;
|
|
1155
|
+
/** Abre la lista con una opción resaltada: la indicada o, si no, la elegida. */
|
|
1156
|
+
function show(keyboard, highlighted = selected?.disabled === true ? void 0 : selected) {
|
|
1157
|
+
setActive(highlighted === void 0 ? void 0 : {
|
|
1158
|
+
value: highlighted.value,
|
|
1159
|
+
keyboard
|
|
1160
|
+
});
|
|
1161
|
+
setOpened(true);
|
|
1162
|
+
if (keyboard) pointer.current = void 0;
|
|
1163
|
+
}
|
|
1164
|
+
function choose(next) {
|
|
1165
|
+
setCurrent(next);
|
|
1166
|
+
setOpened(false);
|
|
1167
|
+
}
|
|
1168
|
+
useLayoutEffect(() => {
|
|
1169
|
+
const anchor = root.current;
|
|
1170
|
+
const popup = list.current;
|
|
1171
|
+
if (!open || anchor === null || popup === null) return;
|
|
1172
|
+
let above = false;
|
|
1173
|
+
const place = () => {
|
|
1174
|
+
const { top, bottom, left, width } = anchor.getBoundingClientRect();
|
|
1175
|
+
const viewport = document.documentElement.clientHeight;
|
|
1176
|
+
popup.dataset.side = above ? "top" : "bottom";
|
|
1177
|
+
popup.style.setProperty("--select-list-left", `${left}px`);
|
|
1178
|
+
popup.style.setProperty("--select-list-width", `${width}px`);
|
|
1179
|
+
popup.style.setProperty("--select-list-offset", `${above ? viewport - top : bottom}px`);
|
|
1180
|
+
popup.style.setProperty("--select-list-space", `${above ? top : viewport - bottom}px`);
|
|
1181
|
+
};
|
|
1182
|
+
const { top, bottom, width } = anchor.getBoundingClientRect();
|
|
1183
|
+
popup.style.setProperty("--select-list-width", `${width}px`);
|
|
1184
|
+
if (typeof popup.showPopover === "function" && !popup.matches(":popover-open")) popup.showPopover();
|
|
1185
|
+
const wanted = popup.offsetHeight + parseFloat(getComputedStyle(popup).marginTop) * 2;
|
|
1186
|
+
const below = document.documentElement.clientHeight - bottom;
|
|
1187
|
+
above = below < wanted && top > below;
|
|
1188
|
+
place();
|
|
1189
|
+
const chosen = popup.querySelector("[aria-selected=\"true\"]");
|
|
1190
|
+
if (chosen !== null) popup.scrollTop = chosen.offsetTop - (popup.clientHeight - chosen.offsetHeight) / 2;
|
|
1191
|
+
const handlePointerDown = (event) => {
|
|
1192
|
+
if (event.target instanceof Node && !anchor.contains(event.target)) setOpened(false);
|
|
1193
|
+
};
|
|
1194
|
+
const handleScroll = (event) => {
|
|
1195
|
+
if (event.target instanceof Node && popup.contains(event.target)) return;
|
|
1196
|
+
place();
|
|
1197
|
+
};
|
|
1198
|
+
document.addEventListener("pointerdown", handlePointerDown, true);
|
|
1199
|
+
window.addEventListener("scroll", handleScroll, true);
|
|
1200
|
+
window.addEventListener("resize", place);
|
|
1201
|
+
return () => {
|
|
1202
|
+
document.removeEventListener("pointerdown", handlePointerDown, true);
|
|
1203
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
1204
|
+
window.removeEventListener("resize", place);
|
|
1205
|
+
};
|
|
1206
|
+
}, [open]);
|
|
1207
|
+
useLayoutEffect(() => {
|
|
1208
|
+
if (activeId !== void 0) document.getElementById(activeId)?.scrollIntoView({ block: "nearest" });
|
|
1209
|
+
}, [activeId]);
|
|
1210
|
+
function handleClick(event) {
|
|
1211
|
+
event.currentTarget.focus();
|
|
1212
|
+
pointer.current = {
|
|
1213
|
+
x: event.clientX,
|
|
1214
|
+
y: event.clientY
|
|
1215
|
+
};
|
|
1216
|
+
if (open) setOpened(false);
|
|
1217
|
+
else show(false);
|
|
1218
|
+
}
|
|
1219
|
+
function handlePointerMove(event, option) {
|
|
1220
|
+
if (event.pointerType === "touch") return;
|
|
1221
|
+
const last = pointer.current;
|
|
1222
|
+
pointer.current = {
|
|
1223
|
+
x: event.clientX,
|
|
1224
|
+
y: event.clientY
|
|
1225
|
+
};
|
|
1226
|
+
if (last === void 0 || last.x === event.clientX && last.y === event.clientY) return;
|
|
1227
|
+
if (option.disabled === true) return;
|
|
1228
|
+
if (active?.value !== option.value || active.keyboard) setActive({
|
|
1229
|
+
value: option.value,
|
|
1230
|
+
keyboard: false
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
function handleKeyDown(event) {
|
|
1234
|
+
const { key } = event;
|
|
1235
|
+
if (event.ctrlKey || event.metaKey) return;
|
|
1236
|
+
const searching = event.timeStamp - search.current.at < SEARCH_TIMEOUT_MS;
|
|
1237
|
+
if (key.length === 1 && !event.altKey && (key !== " " || searching)) {
|
|
1238
|
+
event.preventDefault();
|
|
1239
|
+
const text = searching ? search.current.text + key : key;
|
|
1240
|
+
search.current = {
|
|
1241
|
+
text,
|
|
1242
|
+
at: event.timeStamp
|
|
1243
|
+
};
|
|
1244
|
+
const match = findOptionByText(options, text, open ? active?.value : selected?.value);
|
|
1245
|
+
const option = options.find((candidate) => candidate.value === match);
|
|
1246
|
+
if (!open) show(true, option);
|
|
1247
|
+
else if (option !== void 0) setActive({
|
|
1248
|
+
value: option.value,
|
|
1249
|
+
keyboard: true
|
|
1250
|
+
});
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
const direction = keyDirection$1[key];
|
|
1254
|
+
const confirms = key === "Enter" || key === " ";
|
|
1255
|
+
if (direction === void 0 && !confirms && key !== "Escape" && key !== "Tab") return;
|
|
1256
|
+
search.current = NO_SEARCH;
|
|
1257
|
+
if (key === "Escape") {
|
|
1258
|
+
if (!open) return;
|
|
1259
|
+
event.preventDefault();
|
|
1260
|
+
event.stopPropagation();
|
|
1261
|
+
setOpened(false);
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
1264
|
+
if (key === "Tab") {
|
|
1265
|
+
if (open && active !== void 0) choose(active.value);
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
event.preventDefault();
|
|
1269
|
+
if (!open) {
|
|
1270
|
+
const value = direction === "first" || direction === "last" ? getOptionInDirection(options, void 0, direction) : void 0;
|
|
1271
|
+
show(true, options.find((option) => option.value === value));
|
|
1272
|
+
return;
|
|
1273
|
+
}
|
|
1274
|
+
if (confirms || event.altKey && key === "ArrowUp") {
|
|
1275
|
+
if (active === void 0) setOpened(false);
|
|
1276
|
+
else choose(active.value);
|
|
1277
|
+
return;
|
|
1278
|
+
}
|
|
1279
|
+
if (direction === void 0 || event.altKey) return;
|
|
1280
|
+
const next = getOptionInDirection(options, active?.value, direction);
|
|
1281
|
+
setActive(next === void 0 ? void 0 : {
|
|
1282
|
+
value: next,
|
|
1283
|
+
keyboard: true
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1119
1286
|
return /* @__PURE__ */ jsxs("div", {
|
|
1287
|
+
ref: root,
|
|
1120
1288
|
className: cx(field_module_default.field, Select_module_default.root, sizeClass[size], control.invalid && field_module_default.invalid, control.disabled && field_module_default.disabled, className),
|
|
1121
1289
|
style,
|
|
1122
|
-
children: [
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1290
|
+
children: [
|
|
1291
|
+
/* @__PURE__ */ jsx("button", {
|
|
1292
|
+
ref,
|
|
1293
|
+
type: "button",
|
|
1294
|
+
role: "combobox",
|
|
1295
|
+
id: control.id,
|
|
1296
|
+
className: cx(field_module_default.control, Select_module_default.trigger, selected === void 0 && Select_module_default.placeholder),
|
|
1297
|
+
disabled: control.disabled,
|
|
1298
|
+
"aria-haspopup": "listbox",
|
|
1299
|
+
"aria-expanded": open,
|
|
1300
|
+
"aria-controls": open ? listId : void 0,
|
|
1301
|
+
"aria-activedescendant": activeId,
|
|
1302
|
+
"aria-label": accessibilityLabel,
|
|
1303
|
+
"aria-describedby": control.describedBy,
|
|
1304
|
+
"aria-invalid": control.invalid ? true : void 0,
|
|
1305
|
+
"aria-required": control.required ? true : void 0,
|
|
1306
|
+
"data-testid": testID,
|
|
1307
|
+
onClick: handleClick,
|
|
1308
|
+
onKeyDown: handleKeyDown,
|
|
1309
|
+
onKeyUp: (event) => {
|
|
1310
|
+
if (event.key === " ") event.preventDefault();
|
|
1311
|
+
},
|
|
1312
|
+
onBlur: () => setOpened(false),
|
|
1313
|
+
children: selected?.label ?? placeholder ?? ""
|
|
1314
|
+
}),
|
|
1315
|
+
/* @__PURE__ */ jsx("span", {
|
|
1316
|
+
className: Select_module_default.chevron,
|
|
1317
|
+
"aria-hidden": "true",
|
|
1318
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
1319
|
+
name: "chevron-down",
|
|
1320
|
+
size: inputIconSize[size],
|
|
1321
|
+
color: control.disabled ? "disabled" : "muted"
|
|
1322
|
+
})
|
|
1323
|
+
}),
|
|
1324
|
+
open ? /* @__PURE__ */ jsx("div", {
|
|
1325
|
+
ref: list,
|
|
1326
|
+
popover: "manual",
|
|
1327
|
+
role: "listbox",
|
|
1328
|
+
id: listId,
|
|
1329
|
+
tabIndex: -1,
|
|
1330
|
+
"aria-label": control.accessibilityLabel,
|
|
1331
|
+
className: Select_module_default.list,
|
|
1332
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
1333
|
+
children: options.map((option, index) => {
|
|
1334
|
+
const isSelected = option.value === current;
|
|
1335
|
+
const isDisabled = option.disabled === true;
|
|
1336
|
+
const isActive = index === activeIndex;
|
|
1337
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1338
|
+
id: `${baseId}-option-${index}`,
|
|
1339
|
+
role: "option",
|
|
1340
|
+
"aria-selected": isSelected,
|
|
1341
|
+
"aria-disabled": isDisabled ? true : void 0,
|
|
1342
|
+
className: cx(Select_module_default.option, isActive && (active?.keyboard === true ? Select_module_default.focused : Select_module_default.active), isDisabled && Select_module_default.disabled),
|
|
1343
|
+
onClick: isDisabled ? void 0 : () => choose(option.value),
|
|
1344
|
+
onPointerMove: (event) => handlePointerMove(event, option),
|
|
1345
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1346
|
+
className: Select_module_default.label,
|
|
1347
|
+
children: option.label
|
|
1348
|
+
}), isSelected ? /* @__PURE__ */ jsx(Icon, {
|
|
1349
|
+
name: "check",
|
|
1350
|
+
size: inputIconSize[size],
|
|
1351
|
+
color: "link"
|
|
1352
|
+
}) : null]
|
|
1353
|
+
}, option.value);
|
|
1354
|
+
})
|
|
1355
|
+
}) : null,
|
|
1356
|
+
name === void 0 ? null : /* @__PURE__ */ jsx("input", {
|
|
1357
|
+
type: "hidden",
|
|
1358
|
+
name,
|
|
1359
|
+
value: current,
|
|
1360
|
+
disabled: control.disabled
|
|
1152
1361
|
})
|
|
1153
|
-
|
|
1362
|
+
]
|
|
1154
1363
|
});
|
|
1155
1364
|
}
|
|
1156
1365
|
//#endregion
|
package/dist/web/styles.css
CHANGED
|
@@ -784,27 +784,26 @@
|
|
|
784
784
|
--select-icon: var(--space-5);
|
|
785
785
|
}
|
|
786
786
|
|
|
787
|
-
.sui-
|
|
787
|
+
.sui-trigger-Rxx4wG {
|
|
788
788
|
min-height: calc(var(--select-height) - var(--border-width-thin) * 2);
|
|
789
789
|
padding: var(--space-0) calc(var(--select-padding-x) + var(--select-icon) + var(--space-2))
|
|
790
790
|
var(--space-0) var(--select-padding-x);
|
|
791
791
|
border-radius: inherit;
|
|
792
|
+
text-align: start;
|
|
792
793
|
text-overflow: ellipsis;
|
|
794
|
+
white-space: nowrap;
|
|
793
795
|
cursor: inherit;
|
|
796
|
+
-webkit-tap-highlight-color: transparent;
|
|
794
797
|
align-self: stretch;
|
|
798
|
+
overflow: hidden;
|
|
795
799
|
}
|
|
796
800
|
|
|
797
801
|
.sui-placeholder-Rxx4wG {
|
|
798
802
|
color: var(--color-text-muted);
|
|
799
803
|
}
|
|
800
804
|
|
|
801
|
-
.sui-
|
|
802
|
-
|
|
803
|
-
color: var(--color-text-primary);
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
.sui-select-Rxx4wG option:disabled {
|
|
807
|
-
color: var(--color-text-disabled);
|
|
805
|
+
.sui-placeholder-Rxx4wG:disabled {
|
|
806
|
+
color: inherit;
|
|
808
807
|
}
|
|
809
808
|
|
|
810
809
|
.sui-chevron-Rxx4wG {
|
|
@@ -812,10 +811,85 @@
|
|
|
812
811
|
right: var(--select-padding-x);
|
|
813
812
|
bottom: var(--space-0);
|
|
814
813
|
pointer-events: none;
|
|
814
|
+
transition: transform var(--duration-fast);
|
|
815
815
|
align-items: center;
|
|
816
816
|
display: flex;
|
|
817
817
|
position: absolute;
|
|
818
818
|
}
|
|
819
|
+
|
|
820
|
+
.sui-trigger-Rxx4wG[aria-expanded="true"] + .sui-chevron-Rxx4wG {
|
|
821
|
+
transform: rotate(180deg);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
.sui-list-Rxx4wG {
|
|
825
|
+
inset: auto;
|
|
826
|
+
top: var(--select-list-offset);
|
|
827
|
+
left: var(--select-list-left);
|
|
828
|
+
z-index: var(--z-index-dropdown);
|
|
829
|
+
box-sizing: border-box;
|
|
830
|
+
width: max-content;
|
|
831
|
+
min-width: var(--select-list-width);
|
|
832
|
+
max-width: calc(100vw - var(--select-list-left, 0px) - var(--space-2));
|
|
833
|
+
max-height: min(calc(var(--size-control-md) * 7),
|
|
834
|
+
calc(var(--select-list-space, 100vh) - var(--space-1) * 2));
|
|
835
|
+
margin: var(--space-1) var(--space-0);
|
|
836
|
+
padding: var(--space-1);
|
|
837
|
+
overscroll-behavior: contain;
|
|
838
|
+
scroll-padding-block: var(--space-1);
|
|
839
|
+
scrollbar-color: var(--color-border-strong) transparent;
|
|
840
|
+
scrollbar-width: thin;
|
|
841
|
+
border: var(--border-width-thin) solid var(--color-border-default);
|
|
842
|
+
border-radius: var(--radius-md);
|
|
843
|
+
background-color: var(--color-bg-elevated);
|
|
844
|
+
box-shadow: var(--shadow-md);
|
|
845
|
+
color: var(--color-text-primary);
|
|
846
|
+
cursor: default;
|
|
847
|
+
position: fixed;
|
|
848
|
+
overflow-y: auto;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
.sui-list-Rxx4wG[data-side="top"] {
|
|
852
|
+
top: auto;
|
|
853
|
+
bottom: var(--select-list-offset);
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
.sui-option-Rxx4wG {
|
|
857
|
+
align-items: center;
|
|
858
|
+
gap: var(--space-2);
|
|
859
|
+
box-sizing: border-box;
|
|
860
|
+
min-height: var(--select-height);
|
|
861
|
+
padding: var(--space-2) calc(var(--select-padding-x) - var(--space-1));
|
|
862
|
+
border-radius: var(--radius-sm);
|
|
863
|
+
cursor: pointer;
|
|
864
|
+
-webkit-tap-highlight-color: transparent;
|
|
865
|
+
display: flex;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
.sui-label-Rxx4wG {
|
|
869
|
+
overflow-wrap: anywhere;
|
|
870
|
+
flex: auto;
|
|
871
|
+
min-width: 0;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
.sui-active-Rxx4wG, .sui-option-Rxx4wG:active:not(.sui-disabled-Rxx4wG) {
|
|
875
|
+
background-color: var(--color-bg-muted);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
.sui-focused-Rxx4wG {
|
|
879
|
+
outline: var(--border-width-thick) solid var(--color-border-focus);
|
|
880
|
+
outline-offset: calc(var(--border-width-thick) * -1);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
.sui-disabled-Rxx4wG {
|
|
884
|
+
color: var(--color-text-disabled);
|
|
885
|
+
cursor: not-allowed;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
@media (prefers-reduced-motion: reduce) {
|
|
889
|
+
.sui-chevron-Rxx4wG {
|
|
890
|
+
transition: none;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
819
893
|
.sui-root-KsqoQq {
|
|
820
894
|
--skeleton-width: initial;
|
|
821
895
|
--skeleton-height: initial;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@satellatickets/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Componentes de satella-ui con una sola API para React (web) y React Native",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@satellatickets/core": "0.
|
|
57
|
+
"@satellatickets/core": "0.3.0",
|
|
58
58
|
"@satellatickets/tokens": "0.1.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"tsdown": "^0.23.0",
|
|
81
81
|
"typescript": "^5.9.3",
|
|
82
82
|
"@satellatickets/eslint-config": "0.0.0",
|
|
83
|
-
"@satellatickets/
|
|
84
|
-
"@satellatickets/
|
|
83
|
+
"@satellatickets/tsconfig": "0.0.0",
|
|
84
|
+
"@satellatickets/icons": "0.0.0"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"build": "tsdown",
|