@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.
@@ -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-038). React
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;
@@ -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-038). React
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 }) {
@@ -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 `<select>`. Dentro de un `FormField` no hace falta: lo pone él. */
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 `<select>`. */
189
+ /** Se aplican a la caja del campo, no al botón. */
190
190
  className?: string | undefined;
191
191
  style?: CSSProperties | undefined;
192
- ref?: Ref<HTMLSelectElement> | undefined;
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 `<select>` real (ADR-038): el teclado, los lectores de pantalla y el selector del
198
- * sistema en móvil son los del navegador.
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
- "select": "sui-select-Rxx4wG",
1094
- "sm": "sui-sm-Rxx4wG"
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 `<select>` real (ADR-038): el teclado, los lectores de pantalla y el selector del
1105
- * sistema en móvil son los del navegador.
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: [/* @__PURE__ */ jsxs("select", {
1123
- ref,
1124
- id: control.id,
1125
- className: cx(field_module_default.control, Select_module_default.select, current === "" && Select_module_default.placeholder),
1126
- name,
1127
- value: current,
1128
- onChange: (event) => setCurrent(event.target.value),
1129
- disabled: control.disabled,
1130
- "aria-label": accessibilityLabel,
1131
- "aria-describedby": control.describedBy,
1132
- "aria-invalid": control.invalid ? true : void 0,
1133
- "aria-required": control.required ? true : void 0,
1134
- "data-testid": testID,
1135
- children: [/* @__PURE__ */ jsx("option", {
1136
- value: "",
1137
- disabled: true,
1138
- hidden: true,
1139
- children: placeholder ?? ""
1140
- }), options.map((option) => /* @__PURE__ */ jsx("option", {
1141
- value: option.value,
1142
- disabled: option.disabled,
1143
- children: option.label
1144
- }, option.value))]
1145
- }), /* @__PURE__ */ jsx("span", {
1146
- className: Select_module_default.chevron,
1147
- "aria-hidden": "true",
1148
- children: /* @__PURE__ */ jsx(Icon, {
1149
- name: "chevron-down",
1150
- size: inputIconSize[size],
1151
- color: control.disabled ? "disabled" : "muted"
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
@@ -784,27 +784,26 @@
784
784
  --select-icon: var(--space-5);
785
785
  }
786
786
 
787
- .sui-select-Rxx4wG {
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-select-Rxx4wG option {
802
- background-color: var(--color-bg-surface);
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.2.1",
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.2.1",
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/icons": "0.0.0",
84
- "@satellatickets/tsconfig": "0.0.0"
83
+ "@satellatickets/tsconfig": "0.0.0",
84
+ "@satellatickets/icons": "0.0.0"
85
85
  },
86
86
  "scripts": {
87
87
  "build": "tsdown",