@musecat/uikit 0.2.0 → 0.2.1

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.
Files changed (29) hide show
  1. package/README.md +24 -2
  2. package/index.ts +65 -46
  3. package/package.json +1 -1
  4. package/packages/Components/Card/Card.default.tsx +4 -2
  5. package/packages/Components/Card/Card.foldable.tsx +4 -2
  6. package/packages/Components/Card/Card.tsx +1 -1
  7. package/packages/Components/CodeBox/CodeBox.tsx +1 -0
  8. package/packages/Components/ContextMenu/ContextMenu.tsx +1 -0
  9. package/packages/Components/ContributionGraph/ContributionGraph.tsx +12 -3
  10. package/packages/Components/DatePicker/DatePicker.tsx +38 -17
  11. package/packages/Components/Icon/Icon.group.tsx +1 -1
  12. package/packages/Components/Pagination/Pagination.tsx +1 -0
  13. package/packages/Components/Select/Select.trigger.tsx +1 -1
  14. package/packages/Components/Select/hooks/useSelectNavigation.ts +3 -6
  15. package/packages/Components/Select/select.control.tsx +9 -18
  16. package/packages/Components/Title/Title.tsx +1 -1
  17. package/packages/Frameworks/Dialog/Dialog.tsx +1 -0
  18. package/packages/Frameworks/Dialog/hooks/useSheetDrag.ts +2 -0
  19. package/packages/Frameworks/Dialog/hooks/useSheetGeometry.ts +3 -1
  20. package/packages/Frameworks/Dialog/hooks/useSheetProgressive.ts +1 -1
  21. package/packages/Frameworks/Dialog/renderers/renderSheet.tsx +4 -4
  22. package/packages/Frameworks/Pressable/Pressable.tsx +2 -2
  23. package/packages/Frameworks/Pressable/Pressable.types.ts +10 -1
  24. package/packages/Frameworks/Toaster/Toaster.boot.tsx +3 -3
  25. package/packages/Frameworks/Toaster/Toaster.types.ts +2 -0
  26. package/packages/Frameworks/View/ImageView/Dialog/ImageDialog.footer.tsx +4 -0
  27. package/packages/Frameworks/View/ImageView/Image.tsx +37 -21
  28. package/packages/Frameworks/View/ImageView/Image.utils.ts +1 -1
  29. package/packages/Frameworks/_shared/Padding.types.ts +1 -3
package/README.md CHANGED
@@ -5,7 +5,29 @@ A Next.js 16 + React 19 + TypeScript UI Design component library.
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @musecat/uikit
8
+ npm install @musecat/uikit @musecat/functionkit
9
+ ```
10
+
11
+ This package ships **raw TypeScript + SCSS source** (no prebuilt bundle), so your app must transpile it.
12
+
13
+ ### Next.js setup
14
+
15
+ Add the packages to `transpilePackages` in `next.config.ts`:
16
+
17
+ ```ts
18
+ import type { NextConfig } from "next";
19
+
20
+ const nextConfig: NextConfig = {
21
+ transpilePackages: ["@musecat/uikit", "@musecat/functionkit"],
22
+ };
23
+
24
+ export default nextConfig;
25
+ ```
26
+
27
+ Install the Sass compiler so the bundled `*.module.scss` styles are compiled:
28
+
29
+ ```bash
30
+ npm install -D sass
9
31
  ```
10
32
 
11
33
  ## Usage
@@ -50,7 +72,7 @@ This package includes `.agents/references/` directory with detailed documentatio
50
72
  - [es-hangul](https://es-hangul.toss.im/)
51
73
  - [MapLibre GL JS](https://maplibre.org/)
52
74
 
53
- Built with [tsup](https://tsup.egoist.dev/) and [TypeScript](https://www.typescriptlang.org/).
75
+ Published as raw TypeScript + SCSS source and built with [TypeScript](https://www.typescriptlang.org/).
54
76
 
55
77
  ## License
56
78
 
package/index.ts CHANGED
@@ -1,48 +1,4 @@
1
- /// <reference path="./global.d.ts" />
2
1
  // Frameworks
3
- export { default as View } from "./packages/Frameworks/View/View";
4
- export { default as Pressable } from "./packages/Frameworks/Pressable/Pressable";
5
- export { default as ImageView } from "./packages/Frameworks/View/ImageView/Image";
6
- export { default as HScrollView } from "./packages/Frameworks/View/HScrollView/HScrollView";
7
- export { default as DNDView } from "./packages/Frameworks/View/DNDView/DNDView";
8
- export { default as Dialog, useDialog } from "./packages/Frameworks/Dialog/Dialog";
9
- export { dialog, DialogStore } from "./packages/Frameworks/Dialog/Dialog.store";
10
- export type { DialogInstance } from "./packages/Frameworks/Dialog/Dialog.store";
11
- export { default as DialogBootstrap } from "./packages/Frameworks/Dialog/Dialog.boot";
12
- export { default as ToasterBootstrap, toast } from "./packages/Frameworks/Toaster/Toaster.boot";
13
- export type { ToasterBootstrapProps } from "./packages/Frameworks/Toaster/Toaster.types";
14
- export { default as Squircle } from "./packages/Frameworks/Squircle/Squircle";
15
- export { default as EdgeEffect } from "./packages/Frameworks/EdgeEffect/EdgeEffect";
16
- export { motionTransitions, motionPresets } from "./packages/Frameworks/Motion/Motion.presets";
17
- export { default as StopParentInteraction } from "./packages/Frameworks/_shared/StopParentInteraction";
18
- export { useScrollLock } from "./packages/Frameworks/_shared/bodyScrollLock";
19
- export { useControllableState } from "./packages/Frameworks/_shared/useControllableState";
20
- export { Size, SizePX } from "./packages/Frameworks/_shared/sizing";
21
- export { normalizeUIKitImageSrc, normalizeBrandIconClass, normalizeLang } from "./packages/Frameworks/_shared/normalize";
22
- export { LAYER_Z_INDEX } from "./packages/Frameworks/_shared/layer.constants";
23
- export { default as DialogHeader } from "./packages/Frameworks/Dialog/contents/Dialog.header";
24
- export { default as DialogFooter } from "./packages/Frameworks/Dialog/contents/Dialog.footer";
25
-
26
- // Theme
27
- export {
28
- Shadow,
29
- Border,
30
- BackgroundBlur,
31
- resolveThemeClasses,
32
- resolveThemeHasBorder,
33
- type ThemePreset,
34
- type ThemePaint,
35
- type ThemeBackgroundPaint,
36
- type ThemeBorderPaint,
37
- type ThemeBorderWidth,
38
- type ThemeShadow,
39
- type ShadowScale,
40
- type ThemeSystemProps,
41
- type BorderProps,
42
- type BackgroundBlurValue,
43
- } from "./packages/Frameworks/Theme/Theme.types";
44
- export { Radius } from "./packages/Frameworks/Theme/Radius.types";
45
- export type { RadiusProps, RadiusValue, RadiusScale } from "./packages/Frameworks/Theme/Radius.types";
46
2
 
47
3
  // Components
48
4
  export { default as Box } from "./packages/Components/Box/Box";
@@ -60,7 +16,11 @@ export { default as Header } from "./packages/Components/Header/Header";
60
16
  export { default as Icon } from "./packages/Components/Icon/Icon";
61
17
  export { default as Input } from "./packages/Components/Input/Input";
62
18
  export { default as Label } from "./packages/Components/Label/Label";
63
- export { default as Layout, LayoutGrid, LayoutSection } from "./packages/Components/Layout/Layout";
19
+ export {
20
+ default as Layout,
21
+ LayoutGrid,
22
+ LayoutSection,
23
+ } from "./packages/Components/Layout/Layout";
64
24
  export { default as MapOSM } from "./packages/Components/Maps/OSM/MapOSM";
65
25
  export { default as Nav } from "./packages/Components/Nav/Nav";
66
26
  export { default as Pagination } from "./packages/Components/Pagination/Pagination";
@@ -72,8 +32,67 @@ export { default as Select } from "./packages/Components/Select/Select";
72
32
  export { default as Skeleton } from "./packages/Components/Skeleton/Skeleton";
73
33
  export { default as Spinner } from "./packages/Components/Spinner/Spinner";
74
34
  export { default as Text } from "./packages/Components/Text/Text";
75
- export { default as TimePicker } from "./packages/Components/TimePicker/TimePicker";
76
35
  export { default as Timeline } from "./packages/Components/Timeline/Timeline";
36
+ export { default as TimePicker } from "./packages/Components/TimePicker/TimePicker";
77
37
  export { default as Title } from "./packages/Components/Title/Title";
78
38
  export { default as Toggle } from "./packages/Components/Toggle/Toggle";
79
39
  export { default as Tooltip } from "./packages/Components/Tooltip/Tooltip";
40
+ export { useScrollLock } from "./packages/Frameworks/_shared/bodyScrollLock";
41
+ export { LAYER_Z_INDEX } from "./packages/Frameworks/_shared/layer.constants";
42
+ export {
43
+ normalizeBrandIconClass,
44
+ normalizeLang,
45
+ normalizeUIKitImageSrc,
46
+ } from "./packages/Frameworks/_shared/normalize";
47
+ export { default as StopParentInteraction } from "./packages/Frameworks/_shared/StopParentInteraction";
48
+ export { Size, SizePX } from "./packages/Frameworks/_shared/sizing";
49
+ export { useControllableState } from "./packages/Frameworks/_shared/useControllableState";
50
+ export { default as DialogFooter } from "./packages/Frameworks/Dialog/contents/Dialog.footer";
51
+ export { default as DialogHeader } from "./packages/Frameworks/Dialog/contents/Dialog.header";
52
+ export {
53
+ default as Dialog,
54
+ useDialog,
55
+ } from "./packages/Frameworks/Dialog/Dialog";
56
+ export { default as DialogBootstrap } from "./packages/Frameworks/Dialog/Dialog.boot";
57
+ export type { DialogInstance } from "./packages/Frameworks/Dialog/Dialog.store";
58
+ export { DialogStore, dialog } from "./packages/Frameworks/Dialog/Dialog.store";
59
+ export { default as EdgeEffect } from "./packages/Frameworks/EdgeEffect/EdgeEffect";
60
+ export {
61
+ motionPresets,
62
+ motionTransitions,
63
+ } from "./packages/Frameworks/Motion/Motion.presets";
64
+ export { default as Pressable } from "./packages/Frameworks/Pressable/Pressable";
65
+ export { default as Squircle } from "./packages/Frameworks/Squircle/Squircle";
66
+ export type {
67
+ RadiusProps,
68
+ RadiusScale,
69
+ RadiusValue,
70
+ } from "./packages/Frameworks/Theme/Radius.types";
71
+ export { Radius } from "./packages/Frameworks/Theme/Radius.types";
72
+ // Theme
73
+ export {
74
+ BackgroundBlur,
75
+ type BackgroundBlurValue,
76
+ Border,
77
+ type BorderProps,
78
+ resolveThemeClasses,
79
+ resolveThemeHasBorder,
80
+ Shadow,
81
+ type ShadowScale,
82
+ type ThemeBackgroundPaint,
83
+ type ThemeBorderPaint,
84
+ type ThemeBorderWidth,
85
+ type ThemePaint,
86
+ type ThemePreset,
87
+ type ThemeShadow,
88
+ type ThemeSystemProps,
89
+ } from "./packages/Frameworks/Theme/Theme.types";
90
+ export {
91
+ default as ToasterBootstrap,
92
+ toast,
93
+ } from "./packages/Frameworks/Toaster/Toaster.boot";
94
+ export type { ToasterBootstrapProps } from "./packages/Frameworks/Toaster/Toaster.types";
95
+ export { default as DNDView } from "./packages/Frameworks/View/DNDView/DNDView";
96
+ export { default as HScrollView } from "./packages/Frameworks/View/HScrollView/HScrollView";
97
+ export { default as ImageView } from "./packages/Frameworks/View/ImageView/Image";
98
+ export { default as View } from "./packages/Frameworks/View/View";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@musecat/uikit",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "High-performance Next.js React UI component library with Squircle shapes, theme tokens, and gesture-driven overlays",
@@ -2,11 +2,13 @@ import clsx from "clsx";
2
2
  import { useInBoxContent } from "../Box/Box";
3
3
  import styles from "./Card.module.scss";
4
4
  import type { CardDefaultProps } from "./Card.types";
5
- import { buildRenderKeys } from "./Card.utils";
5
+ import {
6
+ buildRenderKeys,
7
+ normalizeCardIcon,
8
+ } from "./Card.utils";
6
9
  import Icon from "../Icon/Icon";
7
10
  import Pill from "../Pill/Pill";
8
11
  import Text from "../Text/Text";
9
- import { normalizeCardIcon } from "./Card.utils";
10
12
  import StopParentInteraction from "../../Frameworks/_shared/StopParentInteraction";
11
13
  import Pressable from "../../Frameworks/Pressable/Pressable";
12
14
  import View from "../../Frameworks/View/View";
@@ -7,11 +7,13 @@ import { useInBoxContent } from "../Box/Box";
7
7
  import styles from "./Card.module.scss";
8
8
  import type { CardFoldableProps } from "./Card.types";
9
9
  import { resolveState } from "./Card.types";
10
- import { buildRenderKeys } from "./Card.utils";
10
+ import {
11
+ buildRenderKeys,
12
+ normalizeCardIcon,
13
+ } from "./Card.utils";
11
14
  import Icon from "../Icon/Icon";
12
15
  import Pill from "../Pill/Pill";
13
16
  import Text from "../Text/Text";
14
- import { normalizeCardIcon } from "./Card.utils";
15
17
  import StopParentInteraction from "../../Frameworks/_shared/StopParentInteraction";
16
18
  import {
17
19
  getComputedPixelValue,
@@ -1,6 +1,6 @@
1
- import type { CardProps } from "./Card.types";
2
1
  import CardDefault from "./Card.default";
3
2
  import CardFoldable from "./Card.foldable";
3
+ import type { CardProps } from "./Card.types";
4
4
 
5
5
  export default function Card(props: CardProps) {
6
6
  if (props.accordion) return <CardFoldable {...props} />;
@@ -83,6 +83,7 @@ export default function CodeBox({
83
83
  <code
84
84
  className={`${styles.Code} language-${lang}`}
85
85
  data-color-mode={dataTheme}
86
+ // biome-ignore lint/security/noDangerouslySetInnerHtml: needed for syntax highlighting
86
87
  dangerouslySetInnerHTML={{ __html: html }}
87
88
  />
88
89
  </pre>
@@ -357,6 +357,7 @@ export default function ContextMenu(props: ContextMenuProps): ReactElement {
357
357
  ) : (
358
358
  contents.map((item, index) => (
359
359
  <ContextMenuOption
360
+ // biome-ignore lint/suspicious/noArrayIndexKey: items have stable order
360
361
  key={`${item.value}-${index}`}
361
362
  item={item}
362
363
  index={index}
@@ -6,7 +6,6 @@ import {
6
6
  getUtcWeekdayIndex,
7
7
  parseUtcDateInput,
8
8
  } from "@musecat/functionkit";
9
- import clsx from "clsx";
10
9
  import {
11
10
  type PointerEvent as ReactPointerEvent,
12
11
  useMemo,
@@ -95,7 +94,13 @@ function GraphCell({
95
94
  className={styles.Cell}
96
95
  data-level={level}
97
96
  data-in-range={inRange ? "true" : "false"}
98
- title={buildCellTitle({ date, total_count, changelog_count, flag_count, legacy_ticket_count })}
97
+ title={buildCellTitle({
98
+ date,
99
+ total_count,
100
+ changelog_count,
101
+ flag_count,
102
+ legacy_ticket_count,
103
+ })}
99
104
  style={{
100
105
  gridColumn: `${weekIndex + 1}`,
101
106
  gridRow: `${dayIndex + 1}`,
@@ -387,7 +392,11 @@ export default function ContributionGraph({
387
392
  style={{ position: "relative", marginLeft: "3.6rem" }}
388
393
  >
389
394
  {graphData.months.map((m) => (
390
- <MonthLabel key={`${m.title}-${m.colIndex}`} title={m.title} colIndex={m.colIndex} />
395
+ <MonthLabel
396
+ key={`${m.title}-${m.colIndex}`}
397
+ title={m.title}
398
+ colIndex={m.colIndex}
399
+ />
391
400
  ))}
392
401
  </View>
393
402
 
@@ -9,9 +9,9 @@ import {
9
9
  } from "react";
10
10
  import { normalizeLocale } from "../../../i18n/shared";
11
11
  import { Calendar } from "./DatePicker.calendar";
12
- import DatePickerCore from "./DatePicker.core";
13
- import { useCalendar } from "./hooks/useCalendar";
14
- import { useSelection } from "./hooks/useSelection";
12
+ import DatePickerCore, {
13
+ type DatePickerCoreRef,
14
+ } from "./DatePicker.core";
15
15
  import styles from "./DatePicker.module.scss";
16
16
  import type { DatePickerProps } from "./DatePicker.types";
17
17
  import {
@@ -19,10 +19,14 @@ import {
19
19
  parseDate,
20
20
  toYMD,
21
21
  } from "./DatePicker.utils";
22
+ import { useCalendar } from "./hooks/useCalendar";
23
+ import { useSelection } from "./hooks/useSelection";
22
24
  import Icon from "../Icon/Icon";
23
25
  import Label from "../Label/Label";
24
26
  import Text from "../Text/Text";
25
- import TimePickerCore from "../TimePicker/TimePicker.core";
27
+ import TimePickerCore, {
28
+ type TimePickerCoreRef,
29
+ } from "../TimePicker/TimePicker.core";
26
30
  import Dialog from "../../Frameworks/Dialog/Dialog";
27
31
  import View from "../../Frameworks/View/View";
28
32
 
@@ -333,9 +337,18 @@ export default function DatePicker({
333
337
  isValidDate(ey, em, ed) &&
334
338
  (!showTime || (eh !== null && emin !== null));
335
339
 
336
- if (isStartValid && isEndValid) {
337
- let start = new Date(sy!, sm! - 1, sd!, sh ?? 0, smin ?? 0);
338
- let end = new Date(ey!, em! - 1, ed!, eh ?? 0, emin ?? 0);
340
+ if (
341
+ isStartValid &&
342
+ isEndValid &&
343
+ sy !== null &&
344
+ sm !== null &&
345
+ sd !== null &&
346
+ ey !== null &&
347
+ em !== null &&
348
+ ed !== null
349
+ ) {
350
+ let start = new Date(sy, sm - 1, sd, sh ?? 0, smin ?? 0);
351
+ let end = new Date(ey, em - 1, ed, eh ?? 0, emin ?? 0);
339
352
  if (isBefore(end, start)) {
340
353
  [start, end] = [end, start];
341
354
  }
@@ -344,8 +357,16 @@ export default function DatePicker({
344
357
  setRangeEnd(end);
345
358
  }
346
359
  onRangeChange?.(toYMD(start, showTime), toYMD(end, showTime));
347
- } else if (isStartValid && ey === null && em === null && ed === null) {
348
- const start = new Date(sy!, sm! - 1, sd!, sh ?? 0, smin ?? 0);
360
+ } else if (
361
+ isStartValid &&
362
+ sy !== null &&
363
+ sm !== null &&
364
+ sd !== null &&
365
+ ey === null &&
366
+ em === null &&
367
+ ed === null
368
+ ) {
369
+ const start = new Date(sy, sm - 1, sd, sh ?? 0, smin ?? 0);
349
370
  if (!isControlled) {
350
371
  setRangeStart(start);
351
372
  setRangeEnd(null);
@@ -357,7 +378,7 @@ export default function DatePicker({
357
378
  );
358
379
 
359
380
  const handleDateChange = useCallback(
360
- (seg: any, val: number | null) => {
381
+ (seg: string, val: number | null) => {
361
382
  const setter = (() => {
362
383
  switch (seg) {
363
384
  case "year":
@@ -382,7 +403,7 @@ export default function DatePicker({
382
403
  return null;
383
404
  }
384
405
  })();
385
- if (setter) setter(val as any);
406
+ if (setter) setter(val);
386
407
 
387
408
  if (mode === "single") {
388
409
  emitSingle(
@@ -507,12 +528,12 @@ export default function DatePicker({
507
528
  ],
508
529
  );
509
530
 
510
- const singleDateRef = useRef<any>(null);
511
- const singleTimeRef = useRef<any>(null);
512
- const startDateRef = useRef<any>(null);
513
- const startTimeRef = useRef<any>(null);
514
- const endDateRef = useRef<any>(null);
515
- const endTimeRef = useRef<any>(null);
531
+ const singleDateRef = useRef<DatePickerCoreRef | null>(null);
532
+ const singleTimeRef = useRef<TimePickerCoreRef | null>(null);
533
+ const startDateRef = useRef<DatePickerCoreRef | null>(null);
534
+ const startTimeRef = useRef<TimePickerCoreRef | null>(null);
535
+ const endDateRef = useRef<DatePickerCoreRef | null>(null);
536
+ const endTimeRef = useRef<TimePickerCoreRef | null>(null);
516
537
 
517
538
  useEffect(() => {
518
539
  if (!isControlled) return;
@@ -1,6 +1,6 @@
1
1
  import { Children } from "react";
2
- import type { IconGroupProps } from "./Icon.group.types";
3
2
  import Icon from "./Icon";
3
+ import type { IconGroupProps } from "./Icon.group.types";
4
4
  import type { IconProps } from "./Icon.types";
5
5
  import {
6
6
  Size,
@@ -138,6 +138,7 @@ export default function Pagination({
138
138
  }
139
139
 
140
140
  return (
141
+ // biome-ignore lint/a11y/useSemanticElements: nav[role="group"] is correct for pagination
141
142
  <nav
142
143
  aria-label={resolvedNavigationLabel}
143
144
  data-color-mode={dataTheme}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import type { KeyboardEvent, ReactElement } from "react";
3
- import Pressable from "../../Frameworks/Pressable/Pressable";
4
3
  import Text from "../Text/Text";
4
+ import Pressable from "../../Frameworks/Pressable/Pressable";
5
5
  import View from "../../Frameworks/View/View";
6
6
 
7
7
  interface SelectTriggerProps {
@@ -322,10 +322,7 @@ export function useSelectNavigation(
322
322
  );
323
323
 
324
324
  const handleControlKeyDown = useCallback(
325
- (
326
- e: KeyboardEvent<Element>,
327
- allowSpaceSelection: boolean,
328
- ) => {
325
+ (e: KeyboardEvent<Element>, allowSpaceSelection: boolean) => {
329
326
  if (e.key === "Tab") {
330
327
  setOpen(false);
331
328
  return;
@@ -436,7 +433,7 @@ export function useSelectNavigation(
436
433
  const handleTriggerClick = useCallback(() => {
437
434
  if (Date.now() < suppressClickUntilRef.current) return;
438
435
  toggleOpenFromTrigger();
439
- }, [toggleOpenFromTrigger]);
436
+ }, [toggleOpenFromTrigger, suppressClickUntilRef.current]);
440
437
  const handleTriggerPointerUp = useCallback(
441
438
  (e: ReactPointerEvent<HTMLButtonElement>) => {
442
439
  if (e.pointerType !== "touch") return;
@@ -444,7 +441,7 @@ export function useSelectNavigation(
444
441
  suppressClickUntilRef.current = Date.now() + 400;
445
442
  toggleOpenFromTrigger();
446
443
  },
447
- [toggleOpenFromTrigger],
444
+ [toggleOpenFromTrigger, suppressClickUntilRef],
448
445
  );
449
446
 
450
447
  return {
@@ -5,12 +5,11 @@ import type {
5
5
  MouseEvent as ReactMouseEvent,
6
6
  } from "react";
7
7
  import Pill from "../Pill/Pill";
8
- import SelectTrigger from "./Select.trigger";
9
8
  import type { SelectNavigation } from "./hooks/useSelectNavigation";
10
9
  import type { SelectState } from "./hooks/useSelectState";
10
+ import SelectTrigger from "./Select.trigger";
11
11
  import type { SelectValue } from "./Select.types";
12
12
  import { filterOptionsByQuery } from "./Select.utils";
13
- import Text from "../Text/Text";
14
13
  import View from "../../Frameworks/View/View";
15
14
 
16
15
  interface SelectControlProps {
@@ -54,19 +53,10 @@ export default function SelectControl({
54
53
  visibleOptions,
55
54
  } = state;
56
55
 
57
- const {
58
- placeholder,
59
- title,
60
- disabled,
61
- readOnly,
62
- required,
63
- } = props;
56
+ const { placeholder, title, disabled, readOnly, required } = props;
64
57
 
65
- const {
66
- handleControlKeyDown,
67
- handleTriggerClick,
68
- handleTriggerPointerUp,
69
- } = navigation;
58
+ const { handleControlKeyDown, handleTriggerClick, handleTriggerPointerUp } =
59
+ navigation;
70
60
 
71
61
  const selectedPills =
72
62
  isMultiple && selectedOptions.length > 0 ? (
@@ -159,9 +149,7 @@ export default function SelectControl({
159
149
  }
160
150
  value={isMultiple ? query : inputValue}
161
151
  placeholder={
162
- isMultiple && selectedOptions.length > 0
163
- ? undefined
164
- : placeholderText
152
+ isMultiple && selectedOptions.length > 0 ? undefined : placeholderText
165
153
  }
166
154
  className="Subheadline"
167
155
  onFocus={() => {
@@ -186,7 +174,10 @@ export default function SelectControl({
186
174
  const nextQuery = e.target.value;
187
175
  setOpenSource("keyboard");
188
176
  if (!isMultiple) {
189
- if (selectedValues.length > 0 && nextQuery !== selectedOptionLabel) {
177
+ if (
178
+ selectedValues.length > 0 &&
179
+ nextQuery !== selectedOptionLabel
180
+ ) {
190
181
  setSelectedValues([]);
191
182
  emitNativeChange("" as SelectValue<boolean>);
192
183
  }
@@ -1,6 +1,6 @@
1
1
  import clsx from "clsx";
2
- import IconGroup from "../Icon/Icon.group";
3
2
  import { IconInner } from "../Icon/Icon";
3
+ import IconGroup from "../Icon/Icon.group";
4
4
  import Pill from "../Pill/Pill";
5
5
  import Text from "../Text/Text";
6
6
  import type {
@@ -84,6 +84,7 @@ export default function Dialog(props: DialogProps) {
84
84
  open,
85
85
  closeDialog: close,
86
86
  }),
87
+ // biome-ignore lint/correctness/useExhaustiveDependencies: close is intentionally a stable reference
87
88
  [id, resolvedMode, open, close],
88
89
  );
89
90
 
@@ -76,6 +76,8 @@ export function useSheetDrag({
76
76
  onSnapIndexChange,
77
77
  onDragStateChange,
78
78
  }: UseSheetDragInput): DragHandlers {
79
+ void maxPx;
80
+ void getGapHiddenY;
79
81
  const _dragControls = useDragControls();
80
82
  const contentDraggingRef = useRef(false);
81
83
  const contentPointerActiveRef = useRef(false);
@@ -145,7 +145,9 @@ export function useSheetGeometry({
145
145
  const _snapPointsStr = JSON.stringify(config?.snapPoints);
146
146
  const normalizedSnapPoints = useMemo(
147
147
  () =>
148
- config?.snapPoints?.length ? normalizeSnapPoints(config.snapPoints) : [1],
148
+ config?.snapPoints?.length
149
+ ? normalizeSnapPoints(config?.snapPoints)
150
+ : [1],
149
151
  [config?.snapPoints?.length, config?.snapPoints],
150
152
  );
151
153
 
@@ -45,7 +45,7 @@ export function useSheetProgressive({
45
45
  hasExplicitSnapPoints,
46
46
  }: UseSheetProgressiveInput): UseSheetProgressiveOutput {
47
47
  const firstSnap = normalizedSnapPoints[0];
48
- const lastSnap = normalizedSnapPoints.at(-1)!;
48
+ const lastSnap = normalizedSnapPoints.at(-1) ?? 0;
49
49
  const hasProgression =
50
50
  hasExplicitSnapPoints && normalizedSnapPoints.length > 1 && !isFreeDrag;
51
51
 
@@ -28,8 +28,10 @@ import {
28
28
  useEscapeClose,
29
29
  } from "../Dialog.utils";
30
30
  import { useSheetDrag } from "../hooks/useSheetDrag";
31
- import { resolveInitialSnapIndex } from "../hooks/useSheetGeometry";
32
- import { useSheetGeometry } from "../hooks/useSheetGeometry";
31
+ import {
32
+ resolveInitialSnapIndex,
33
+ useSheetGeometry,
34
+ } from "../hooks/useSheetGeometry";
33
35
  import { useSheetProgressive } from "../hooks/useSheetProgressive";
34
36
  import { motionTransitions } from "../../Motion/Motion.presets";
35
37
  import Pressable from "../../Pressable/Pressable";
@@ -567,5 +569,3 @@ export default function RenderSheet({
567
569
  if (!mounted) return null;
568
570
  return <DialogPortal>{sheetNode}</DialogPortal>;
569
571
  }
570
-
571
-
@@ -505,8 +505,8 @@ const Pressable = forwardRef<HTMLElement, PressableProps>((props, ref) => {
505
505
  themeInteractive,
506
506
  selected: resolvedControlSelected,
507
507
  disabled,
508
- readOnly,
509
- isInteractive: true,
508
+ readOnly,
509
+ isInteractive: true,
510
510
  }),
511
511
  Border(border),
512
512
  className,
@@ -11,7 +11,16 @@ import type {
11
11
  export interface PressableProps
12
12
  extends Omit<
13
13
  React.HTMLAttributes<HTMLElement>,
14
- "title" | "onClick" | "onChange" | "value" | "checked" | "type" | "disabled" | "tabIndex" | "popover" | "color"
14
+ | "title"
15
+ | "onClick"
16
+ | "onChange"
17
+ | "value"
18
+ | "checked"
19
+ | "type"
20
+ | "disabled"
21
+ | "tabIndex"
22
+ | "popover"
23
+ | "color"
15
24
  >,
16
25
  ThemeSystemProps,
17
26
  BorderProps,
@@ -1,14 +1,14 @@
1
1
  "use client";
2
2
 
3
+ import clsx from "clsx";
4
+ import { Toaster, toast } from "sonner";
3
5
  import Icon from "../../Components/Icon/Icon";
4
6
  import type { IconProps } from "../../Components/Icon/Icon.types";
5
7
  import styles from "./Toaster.module.scss";
6
8
  import type { ToasterBootstrapProps } from "./Toaster.types";
7
- import clsx from "clsx";
8
- import { Toaster, toast } from "sonner";
9
9
 
10
- export { toast };
11
10
  export type { ToasterBootstrapProps };
11
+ export { toast };
12
12
 
13
13
  const getToastIcon = (color: IconProps["color"]) => (
14
14
  <Icon icon="iCircle" iconFill size={10} color={color} />
@@ -1,6 +1,8 @@
1
1
  import type { ToasterProps } from "sonner";
2
2
  import type { IconProps } from "../../Components/Icon/Icon.types";
3
3
 
4
+ export type { ToasterProps };
5
+
4
6
  export interface ToasterBootstrapProps extends ToasterProps {
5
7
  "data-color-mode"?: string;
6
8
  theme?: ToasterProps["theme"];
@@ -32,6 +32,10 @@ export function DialogImageFooter({
32
32
  canScrollPrev,
33
33
  canScrollNext,
34
34
  }: DialogImageFooterProps) {
35
+ void scrollPrev;
36
+ void scrollNext;
37
+ void canScrollPrev;
38
+ void canScrollNext;
35
39
  if (!dialog.footer) return null;
36
40
 
37
41
  const selectedItem = items[selectedIndex];
@@ -2,6 +2,7 @@
2
2
 
3
3
  import NextImage from "next/image";
4
4
  import { useCallback, useMemo, useState } from "react";
5
+ import type { UIKitSizeValue } from "../../_shared/sizing";
5
6
  import Dialog from "../../Dialog/Dialog";
6
7
  import Pressable from "../../Pressable/Pressable";
7
8
  import HScrollView from "../HScrollView/HScrollView";
@@ -10,9 +11,11 @@ import {
10
11
  ImageLeftControl,
11
12
  ImageRightControl,
12
13
  } from "./Image.controls";
13
- import type { ImageOverlay, ImageProps } from "./Image.types";
14
- import type { RadiusValue } from "../../Theme/Radius.types";
15
- import type { UIKitSizeValue } from "../../_shared/sizing";
14
+ import type {
15
+ ImageItem,
16
+ ImageOverlay,
17
+ ImageProps,
18
+ } from "./Image.types";
16
19
  import {
17
20
  resolveAtIndex,
18
21
  resolveBlurDataURL,
@@ -25,10 +28,25 @@ import View from "../View";
25
28
  const DEFAULT_GROUP_WIDTH = "auto";
26
29
  const DEFAULT_GROUP_HEIGHT = "29rem";
27
30
 
28
- const PRESSABLE_STYLE: React.CSSProperties = { position: "relative", overflow: "hidden" };
29
- const OVERLAY_STYLE: React.CSSProperties = { position: "absolute", inset: 0, pointerEvents: "none" };
30
- const IMG_STYLE: React.CSSProperties = { height: "100%", objectFit: "cover", objectPosition: "center", display: "block" };
31
- const NEXT_IMG_STYLE: React.CSSProperties = { objectFit: "cover", objectPosition: "center" };
31
+ const PRESSABLE_STYLE: React.CSSProperties = {
32
+ position: "relative",
33
+ overflow: "hidden",
34
+ };
35
+ const OVERLAY_STYLE: React.CSSProperties = {
36
+ position: "absolute",
37
+ inset: 0,
38
+ pointerEvents: "none",
39
+ };
40
+ const IMG_STYLE: React.CSSProperties = {
41
+ height: "100%",
42
+ objectFit: "cover",
43
+ objectPosition: "center",
44
+ display: "block",
45
+ };
46
+ const NEXT_IMG_STYLE: React.CSSProperties = {
47
+ objectFit: "cover",
48
+ objectPosition: "center",
49
+ };
32
50
 
33
51
  function ImageGroupItem({
34
52
  item,
@@ -43,11 +61,17 @@ function ImageGroupItem({
43
61
  priority,
44
62
  openDialog,
45
63
  }: {
46
- item: { id: number; src: string; alt: string; srcDialog?: string; blurDataURL?: string };
64
+ item: {
65
+ id: number;
66
+ src: string;
67
+ alt: string;
68
+ srcDialog?: string;
69
+ blurDataURL?: string;
70
+ };
47
71
  index: number;
48
72
  dialog?: ImageProps["dialog"];
49
73
  className?: string;
50
- radius?: RadiusValue;
74
+ radius?: import("../../Theme/Radius.types").RadiusValue;
51
75
  width?: UIKitSizeValue | UIKitSizeValue[];
52
76
  height?: UIKitSizeValue | UIKitSizeValue[];
53
77
  overlay?: ImageOverlay;
@@ -90,11 +114,7 @@ function ImageGroupItem({
90
114
  style={NEXT_IMG_STYLE}
91
115
  />
92
116
  )}
93
- {resolvedOverlay && (
94
- <View style={OVERLAY_STYLE}>
95
- {resolvedOverlay}
96
- </View>
97
- )}
117
+ {resolvedOverlay && <View style={OVERLAY_STYLE}>{resolvedOverlay}</View>}
98
118
  </Pressable>
99
119
  );
100
120
  }
@@ -165,9 +185,7 @@ export default function Image({
165
185
  className={
166
186
  typeof control === "object" ? control.groupClassName : undefined
167
187
  }
168
- style={
169
- typeof control === "object" ? control.groupStyle : undefined
170
- }
188
+ style={typeof control === "object" ? control.groupStyle : undefined}
171
189
  >
172
190
  {renderLeft && (
173
191
  <ImageLeftControl
@@ -193,7 +211,7 @@ export default function Image({
193
211
  if (items.length === 0) return null;
194
212
 
195
213
  if (items.length === 1) {
196
- const item = items[0]!;
214
+ const item = items[0] as ImageItem;
197
215
  const resolvedWidth = resolveAtIndex(width, 0);
198
216
  const resolvedHeight = resolveAtIndex(height, 0);
199
217
  const resolvedOverlay = resolveOverlay(overlay, 0);
@@ -310,9 +328,7 @@ export default function Image({
310
328
 
311
329
  {}
312
330
  {resolvedOverlay && (
313
- <View style={OVERLAY_STYLE}>
314
- {resolvedOverlay}
315
- </View>
331
+ <View style={OVERLAY_STYLE}>{resolvedOverlay}</View>
316
332
  )}
317
333
  </View>
318
334
  );
@@ -75,5 +75,5 @@ export function resolveBlurDataURL(item: ImageItem, index: number): string {
75
75
  String(item.id)
76
76
  .split("")
77
77
  .reduce((acc, char) => acc + char.charCodeAt(0), 0) + index;
78
- return FALLBACK_BLURS[hash % FALLBACK_BLURS.length]!;
78
+ return FALLBACK_BLURS[hash % FALLBACK_BLURS.length] ?? "";
79
79
  }
@@ -23,9 +23,7 @@ export interface PaddingProps {
23
23
  paddingVertical?: UIKitSizeValue;
24
24
  }
25
25
 
26
- function PaddingValue(
27
- padding?: PaddingValue,
28
- ): string | number | undefined {
26
+ function PaddingValue(padding?: PaddingValue): string | number | undefined {
29
27
  if (padding === undefined || padding === null) {
30
28
  return undefined;
31
29
  }