@a-type/ui 5.0.7 → 5.0.9
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/css/main.css +8 -8
- package/dist/esm/components/button/Button.js +1 -1
- package/dist/esm/components/button/Button.js.map +1 -1
- package/dist/esm/components/button/classes.js +2 -2
- package/dist/esm/components/button/classes.js.map +1 -1
- package/dist/esm/components/camera/Camera.js +1 -1
- package/dist/esm/components/camera/Camera.js.map +1 -1
- package/dist/esm/components/card/Card.js +3 -3
- package/dist/esm/components/card/Card.js.map +1 -1
- package/dist/esm/components/checkbox/Checkbox.js +2 -2
- package/dist/esm/components/checkbox/Checkbox.js.map +1 -1
- package/dist/esm/components/datePicker/Calendar.js +1 -1
- package/dist/esm/components/datePicker/Calendar.js.map +1 -1
- package/dist/esm/components/datePicker/DateRangePicker.js +1 -1
- package/dist/esm/components/datePicker/DateRangePicker.js.map +1 -1
- package/dist/esm/components/editableText/EditableText.js +1 -1
- package/dist/esm/components/editableText/EditableText.js.map +1 -1
- package/dist/esm/components/horizontalList/HorizontalList.js +2 -2
- package/dist/esm/components/horizontalList/HorizontalList.js.map +1 -1
- package/dist/esm/components/input/Input.js +1 -1
- package/dist/esm/components/input/Input.js.map +1 -1
- package/dist/esm/components/lightbox/Lightbox.js +1 -1
- package/dist/esm/components/lightbox/Lightbox.js.map +1 -1
- package/dist/esm/components/navBar/NavBar.js +5 -5
- package/dist/esm/components/navBar/NavBar.js.map +1 -1
- package/dist/esm/components/note/Note.js +1 -1
- package/dist/esm/components/note/Note.js.map +1 -1
- package/dist/esm/components/primitives/menus.js +1 -1
- package/dist/esm/components/primitives/menus.js.map +1 -1
- package/dist/esm/components/progress/Progress.js +5 -5
- package/dist/esm/components/progress/Progress.js.map +1 -1
- package/dist/esm/components/provider/Provider.d.ts +2 -1
- package/dist/esm/components/provider/Provider.js +5 -3
- package/dist/esm/components/provider/Provider.js.map +1 -1
- package/dist/esm/components/provider/TweakPane.d.ts +1 -0
- package/dist/esm/components/provider/TweakPane.js +36 -0
- package/dist/esm/components/provider/TweakPane.js.map +1 -0
- package/dist/esm/components/scrollArea/ScrollArea.js +5 -5
- package/dist/esm/components/scrollArea/ScrollArea.js.map +1 -1
- package/dist/esm/components/slider/Slider.d.ts +1 -0
- package/dist/esm/components/slider/Slider.js +9 -4
- package/dist/esm/components/slider/Slider.js.map +1 -1
- package/dist/esm/components/slider/Slider.stories.d.ts +1 -0
- package/dist/esm/components/switch/Switch.js +2 -2
- package/dist/esm/components/switch/Switch.js.map +1 -1
- package/dist/esm/components/tabs/tabs.js +1 -1
- package/dist/esm/components/tabs/tabs.js.map +1 -1
- package/dist/esm/components/toggleGroup/toggleGroup.js +1 -1
- package/dist/esm/components/toggleGroup/toggleGroup.js.map +1 -1
- package/dist/esm/components/viewport/Viewport.js +1 -1
- package/dist/esm/components/viewport/Viewport.js.map +1 -1
- package/dist/esm/hooks/useVisualViewportOffset.d.ts +2 -2
- package/dist/esm/hooks/useVisualViewportOffset.js +22 -10
- package/dist/esm/hooks/useVisualViewportOffset.js.map +1 -1
- package/dist/esm/keyboard.stories.js +3 -3
- package/dist/esm/keyboard.stories.js.map +1 -1
- package/dist/esm/themes.stories.js +2 -2
- package/dist/esm/themes.stories.js.map +1 -1
- package/dist/esm/uno/logic/properties.d.ts +6 -0
- package/dist/esm/uno/logic/properties.js +6 -0
- package/dist/esm/uno/logic/properties.js.map +1 -1
- package/dist/esm/uno/preflights/index.d.ts +2 -1
- package/dist/esm/uno/preflights/index.js +1 -1
- package/dist/esm/uno/preflights/index.js.map +1 -1
- package/dist/esm/uno/preflights/keyboard.d.ts +4 -1
- package/dist/esm/uno/preflights/keyboard.js +3 -3
- package/dist/esm/uno/preflights/keyboard.js.map +1 -1
- package/dist/esm/uno/preflights/user.d.ts +2 -1
- package/dist/esm/uno/preflights/user.js +8 -1
- package/dist/esm/uno/preflights/user.js.map +1 -1
- package/dist/esm/uno/rules/focus.d.ts +3 -0
- package/dist/esm/uno/rules/focus.js +43 -0
- package/dist/esm/uno/rules/focus.js.map +1 -0
- package/dist/esm/uno/rules/index.d.ts +1 -1
- package/dist/esm/uno/rules/index.js +2 -0
- package/dist/esm/uno/rules/index.js.map +1 -1
- package/dist/esm/uno/theme/colors.d.ts +1 -1
- package/dist/esm/uno/theme/colors.js +3 -3
- package/dist/esm/uno/theme/colors.js.map +1 -1
- package/package.json +1 -1
- package/src/__screenshots__/themes.snapshots.tsx/snapshot-chromium-win32.png +0 -0
- package/src/components/button/Button.tsx +1 -1
- package/src/components/button/classes.tsx +3 -4
- package/src/components/camera/Camera.tsx +5 -5
- package/src/components/card/Card.tsx +6 -6
- package/src/components/checkbox/Checkbox.tsx +2 -2
- package/src/components/datePicker/Calendar.tsx +2 -2
- package/src/components/datePicker/DateRangePicker.tsx +3 -3
- package/src/components/editableText/EditableText.tsx +2 -1
- package/src/components/horizontalList/HorizontalList.tsx +2 -1
- package/src/components/input/Input.tsx +2 -2
- package/src/components/lightbox/Lightbox.tsx +1 -1
- package/src/components/navBar/NavBar.tsx +101 -101
- package/src/components/note/Note.tsx +3 -3
- package/src/components/primitives/menus.tsx +1 -1
- package/src/components/progress/Progress.tsx +101 -101
- package/src/components/provider/Provider.tsx +10 -1
- package/src/components/provider/TweakPane.tsx +139 -0
- package/src/components/scrollArea/ScrollArea.tsx +15 -15
- package/src/components/slider/Slider.tsx +103 -97
- package/src/components/switch/Switch.tsx +38 -38
- package/src/components/tabs/tabs.tsx +2 -1
- package/src/components/toggleGroup/toggleGroup.tsx +1 -1
- package/src/components/viewport/Viewport.tsx +1 -1
- package/src/hooks/useVisualViewportOffset.ts +22 -14
- package/src/keyboard.stories.tsx +21 -10
- package/src/themes.stories.tsx +2 -0
- package/src/uno/logic/properties.ts +6 -0
- package/src/uno/preflights/index.ts +4 -3
- package/src/uno/preflights/keyboard.ts +15 -8
- package/src/uno/preflights/user.ts +13 -0
- package/src/uno/rules/focus.ts +46 -0
- package/src/uno/rules/index.ts +2 -0
- package/src/uno/theme/colors.ts +7 -3
|
@@ -11,27 +11,27 @@ export type * from '@base-ui/react/scroll-area';
|
|
|
11
11
|
|
|
12
12
|
export const ScrollAreaRoot = withClassName(
|
|
13
13
|
BaseScrollArea.Root,
|
|
14
|
-
'layer-components:(min-
|
|
14
|
+
'layer-components:(box-border min-h-0 min-w-0 flex flex-col)',
|
|
15
15
|
);
|
|
16
16
|
|
|
17
17
|
export const ScrollAreaViewport = withClassName(
|
|
18
18
|
BaseScrollArea.Viewport,
|
|
19
|
-
'layer-components:(h-full
|
|
20
|
-
'layer-components:
|
|
19
|
+
'layer-components:(h-full min-h-0 outline-none)',
|
|
20
|
+
'layer-components:foc',
|
|
21
21
|
);
|
|
22
22
|
|
|
23
23
|
export const ScrollAreaVerticalFades = withClassName(
|
|
24
24
|
'div',
|
|
25
|
-
'layer-components:(
|
|
26
|
-
'layer-components:before:(
|
|
27
|
-
'layer-components:after:(
|
|
25
|
+
'layer-components:([--scroll-area-overflow-y-end:inherit] [--scroll-area-overflow-y-start:inherit] pointer-events-none absolute inset-0)',
|
|
26
|
+
'layer-components:before:([--scroll-area-overflow-y-start:inherit] absolute left-0 top-0 block h-[min(40px,var(--scroll-area-overflow-y-start,40px))] w-full bg-gradient-from-bg bg-gradient-to-transparent bg-gradient-to-b transition-height content-empty)',
|
|
27
|
+
'layer-components:after:([--scroll-area-overflow-y-end:inherit] absolute bottom-0 left-0 block h-[min(40px,var(--scroll-area-overflow-y-end,40px))] w-full bg-gradient-from-bg bg-gradient-to-transparent bg-gradient-to-t transition-height content-empty)',
|
|
28
28
|
);
|
|
29
29
|
|
|
30
30
|
export const ScrollAreaHorizontalFades = withClassName(
|
|
31
31
|
'div',
|
|
32
|
-
'layer-components:(
|
|
33
|
-
'layer-components:before:(
|
|
34
|
-
'layer-components:after:(
|
|
32
|
+
'layer-components:([--scroll-area-overflow-x-end:inherit] [--scroll-area-overflow-x-start:inherit] pointer-events-none absolute inset-0)',
|
|
33
|
+
'layer-components:before:([--scroll-area-overflow-x-start:inherit] absolute left-0 top-0 block h-full w-[min(40px,var(--scroll-area-overflow-x-start,40px))] bg-gradient-from-bg bg-gradient-to-transparent bg-gradient-to-r transition-width content-empty)',
|
|
34
|
+
'layer-components:after:([--scroll-area-overflow-x-end:inherit] absolute right-0 top-0 block h-full w-[min(40px,var(--scroll-area-overflow-x-end,40px))] bg-gradient-from-bg bg-gradient-to-transparent bg-gradient-to-l transition-width content-empty)',
|
|
35
35
|
);
|
|
36
36
|
|
|
37
37
|
export const ScrollAreaViewportFades = () => (
|
|
@@ -76,14 +76,14 @@ ComposedScrollbar.displayName = 'ScrollAreaScrollbar';
|
|
|
76
76
|
|
|
77
77
|
export const ScrollAreaScrollbar = withClassName(
|
|
78
78
|
ComposedScrollbar,
|
|
79
|
-
'layer-components:(
|
|
80
|
-
'layer-components:(
|
|
81
|
-
'layer-components:data-[hovering]:(
|
|
79
|
+
'layer-components:(pointer-events-none relative m-xxs flex touch-none select-none rounded-full opacity-0)',
|
|
80
|
+
'layer-components:(transition-[opacity,height,width] bg-fg/5)',
|
|
81
|
+
'layer-components:data-[hovering]:(pointer-events-auto opacity-100)',
|
|
82
82
|
'layer-components:data-[scrolling]:(duration-0)',
|
|
83
|
-
'layer-components:before:(content-empty
|
|
83
|
+
'layer-components:before:(absolute content-empty)',
|
|
84
84
|
|
|
85
|
-
'layer-components:data-[orientation=vertical]:(w-0.25rem justify-center before:
|
|
86
|
-
'layer-components:data-[orientation=horizontal]:(h-0.25rem items-center before:
|
|
85
|
+
'layer-components:data-[orientation=vertical]:(w-0.25rem justify-center before:h-full before:w-1.25rem hover:w-0.5rem)',
|
|
86
|
+
'layer-components:data-[orientation=horizontal]:(h-0.25rem items-center before:h-1.25rem before:w-full hover:h-0.5rem)',
|
|
87
87
|
);
|
|
88
88
|
|
|
89
89
|
export const ScrollAreaCorner = withClassName(
|
|
@@ -1,97 +1,103 @@
|
|
|
1
|
-
import { Slider as BaseSlider, SliderRootProps } from '@base-ui/react/slider';
|
|
2
|
-
import clsx from 'clsx';
|
|
3
|
-
import { Ref } from 'react';
|
|
4
|
-
import { withClassName } from '../../hooks.js';
|
|
5
|
-
import { PaletteName } from '../../uno/index.js';
|
|
6
|
-
|
|
7
|
-
export const SliderRoot = withClassName(
|
|
8
|
-
BaseSlider.Root,
|
|
9
|
-
'layer-components:w-full',
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
export const SliderControl = withClassName(
|
|
13
|
-
BaseSlider.Control,
|
|
14
|
-
'layer-components:(relative
|
|
15
|
-
'layer-variants:[&[data-orientation=vertical]]:(
|
|
16
|
-
);
|
|
17
|
-
export const SliderTrack = withClassName(
|
|
18
|
-
BaseSlider.Track,
|
|
19
|
-
'layer-components:(
|
|
20
|
-
'layer-variants:[&[data-orientation=vertical]]:(w-7px
|
|
21
|
-
);
|
|
22
|
-
export const SliderRange = withClassName(
|
|
23
|
-
BaseSlider.Indicator,
|
|
24
|
-
'layer-components:(
|
|
25
|
-
'layer-variants:[&[data-orientation=vertical]]:(bg-main)',
|
|
26
|
-
);
|
|
27
|
-
export const SliderThumb = withClassName(
|
|
28
|
-
BaseSlider.Thumb,
|
|
29
|
-
'layer-components:(
|
|
30
|
-
'layer-components:hover:(shadow-md)',
|
|
31
|
-
'layer-components:active:(shadow-lg ring-4 ring-
|
|
32
|
-
'layer-components:focus-visible:(shadow-lg
|
|
33
|
-
'
|
|
34
|
-
'layer-components:
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
*
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
1
|
+
import { Slider as BaseSlider, SliderRootProps } from '@base-ui/react/slider';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { Ref } from 'react';
|
|
4
|
+
import { withClassName } from '../../hooks.js';
|
|
5
|
+
import { PaletteName } from '../../uno/index.js';
|
|
6
|
+
|
|
7
|
+
export const SliderRoot = withClassName(
|
|
8
|
+
BaseSlider.Root,
|
|
9
|
+
'layer-components:w-full',
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export const SliderControl = withClassName(
|
|
13
|
+
BaseSlider.Control,
|
|
14
|
+
'layer-components:(relative h-30px w-full flex translate-z-0 touch-none select-none items-center)',
|
|
15
|
+
'layer-variants:[&[data-orientation=vertical]]:(h-full w-30px flex-col)',
|
|
16
|
+
);
|
|
17
|
+
export const SliderTrack = withClassName(
|
|
18
|
+
BaseSlider.Track,
|
|
19
|
+
'layer-components:(relative h-7px grow select-none rounded-lg ring-1 transition-colors bg-transparent ring-black)',
|
|
20
|
+
'layer-variants:[&[data-orientation=vertical]]:(h-full w-7px flex-1)',
|
|
21
|
+
);
|
|
22
|
+
export const SliderRange = withClassName(
|
|
23
|
+
BaseSlider.Indicator,
|
|
24
|
+
'layer-components:(rounded-lg transition-colors bg-main)',
|
|
25
|
+
'layer-variants:[&[data-orientation=vertical]]:(bg-main)',
|
|
26
|
+
);
|
|
27
|
+
export const SliderThumb = withClassName(
|
|
28
|
+
BaseSlider.Thumb,
|
|
29
|
+
'layer-components:(h-5 w-5 flex cursor-pointer touch-none items-center justify-center rounded-lg leading-none shadow-sm ring-2 transition-color bg-white ring-black)',
|
|
30
|
+
'layer-components:hover:(shadow-md)',
|
|
31
|
+
'layer-components:active:(shadow-lg ring-4 ring-opacity-50 bg-main-light ring-main-dark)',
|
|
32
|
+
'layer-components:focus-visible:(shadow-lg bg-main-light)',
|
|
33
|
+
'foc-lg',
|
|
34
|
+
'layer-components:focus:(outline-none)',
|
|
35
|
+
'layer-components:disabled:(opacity-50)',
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export const SliderBase = ({
|
|
39
|
+
children,
|
|
40
|
+
color,
|
|
41
|
+
className,
|
|
42
|
+
...props
|
|
43
|
+
}: SliderProps) => {
|
|
44
|
+
return (
|
|
45
|
+
<SliderRoot
|
|
46
|
+
{...props}
|
|
47
|
+
className={clsx(color && `palette-${color}`, className)}
|
|
48
|
+
>
|
|
49
|
+
<SliderControl>{children}</SliderControl>
|
|
50
|
+
</SliderRoot>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A pre-configured Slider UI component. Meant to compose
|
|
56
|
+
* under Slider.Root when you want to use Slider.Value, too
|
|
57
|
+
*/
|
|
58
|
+
export const SliderUi = ({
|
|
59
|
+
label,
|
|
60
|
+
className,
|
|
61
|
+
}: {
|
|
62
|
+
label?: string;
|
|
63
|
+
className?: string;
|
|
64
|
+
}) => (
|
|
65
|
+
<Slider.Control className={className}>
|
|
66
|
+
<SliderTrack>
|
|
67
|
+
<SliderRange />
|
|
68
|
+
<SliderThumb aria-label={label} />
|
|
69
|
+
</SliderTrack>
|
|
70
|
+
</Slider.Control>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
export interface SliderProps extends SliderRootProps {
|
|
74
|
+
color?: PaletteName;
|
|
75
|
+
ref?: Ref<HTMLDivElement>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const Slider = Object.assign(
|
|
79
|
+
function Slider(props: SliderProps) {
|
|
80
|
+
return (
|
|
81
|
+
<SliderRoot {...props}>
|
|
82
|
+
<SliderUi />
|
|
83
|
+
</SliderRoot>
|
|
84
|
+
);
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
Root: SliderRoot,
|
|
88
|
+
Base: SliderBase,
|
|
89
|
+
Control: SliderControl,
|
|
90
|
+
Track: SliderTrack,
|
|
91
|
+
/** @deprecated - use Indicator */
|
|
92
|
+
Range: SliderRange,
|
|
93
|
+
Indicator: SliderRange,
|
|
94
|
+
Thumb: SliderThumb,
|
|
95
|
+
Value: BaseSlider.Value,
|
|
96
|
+
Ui: SliderUi,
|
|
97
|
+
|
|
98
|
+
getSingle: (v: number | readonly number[]) => {
|
|
99
|
+
if (Array.isArray(v)) return v[0];
|
|
100
|
+
return v;
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
);
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import { Switch as BaseSwitch, SwitchRootProps } from '@base-ui/react/switch';
|
|
2
|
-
import { withClassName } from '../../hooks/withClassName.js';
|
|
3
|
-
|
|
4
|
-
const SwitchRoot = withClassName(
|
|
5
|
-
BaseSwitch.Root,
|
|
6
|
-
'layer-components:(unset
|
|
7
|
-
'layer-components:data-[checked]:bg-main',
|
|
8
|
-
'layer-components:hover:[&:not(:disabled)]:(bg-lighten-2 ring-
|
|
9
|
-
'layer-components:active:[&:not(:disabled)]:(bg-darken-1
|
|
10
|
-
'layer-components:focus:outline-none',
|
|
11
|
-
'layer-components:
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
const SwitchThumb = withClassName(
|
|
15
|
-
BaseSwitch.Thumb,
|
|
16
|
-
'layer-components:(block aspect-1 h-full
|
|
17
|
-
'layer-components:data-[checked]:(translate-x-1rem)',
|
|
18
|
-
'layer-components:data-[checked]:before:(
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
export const Switch = Object.assign(
|
|
22
|
-
function Switch({
|
|
23
|
-
ref,
|
|
24
|
-
...props
|
|
25
|
-
}: SwitchRootProps & {
|
|
26
|
-
ref?: React.Ref<HTMLButtonElement>;
|
|
27
|
-
}) {
|
|
28
|
-
return (
|
|
29
|
-
<SwitchRoot {...props} ref={ref}>
|
|
30
|
-
<SwitchThumb />
|
|
31
|
-
</SwitchRoot>
|
|
32
|
-
);
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
Root: SwitchRoot,
|
|
36
|
-
Thumb: SwitchThumb,
|
|
37
|
-
},
|
|
38
|
-
);
|
|
1
|
+
import { Switch as BaseSwitch, SwitchRootProps } from '@base-ui/react/switch';
|
|
2
|
+
import { withClassName } from '../../hooks/withClassName.js';
|
|
3
|
+
|
|
4
|
+
const SwitchRoot = withClassName(
|
|
5
|
+
BaseSwitch.Root,
|
|
6
|
+
'layer-components:(unset relative h-25px w-42px flex flex-shrink-0 cursor-pointer appearance-none border-default rounded-lg p-3px shadow-sm shadow-inset transition-all bg-gray-light)',
|
|
7
|
+
'layer-components:data-[checked]:bg-main',
|
|
8
|
+
'layer-components:hover:[&:not(:disabled)]:(ring-2 bg-lighten-2 ring-bg)',
|
|
9
|
+
'layer-components:active:[&:not(:disabled)]:(ring-4 bg-darken-1)',
|
|
10
|
+
'layer-components:focus:outline-none',
|
|
11
|
+
'layer-components:foc',
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const SwitchThumb = withClassName(
|
|
15
|
+
BaseSwitch.Thumb,
|
|
16
|
+
'layer-components:(block aspect-1 h-full border-default rounded-lg shadow-sm transition-transform will-change-transform bg-white)',
|
|
17
|
+
'layer-components:data-[checked]:(translate-x-1rem)',
|
|
18
|
+
'layer-components:data-[checked]:before:(absolute left-0 top-0 h-full w-full flex items-center justify-center text-xs text-main-ink content-["✓"])',
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export const Switch = Object.assign(
|
|
22
|
+
function Switch({
|
|
23
|
+
ref,
|
|
24
|
+
...props
|
|
25
|
+
}: SwitchRootProps & {
|
|
26
|
+
ref?: React.Ref<HTMLButtonElement>;
|
|
27
|
+
}) {
|
|
28
|
+
return (
|
|
29
|
+
<SwitchRoot {...props} ref={ref}>
|
|
30
|
+
<SwitchThumb />
|
|
31
|
+
</SwitchRoot>
|
|
32
|
+
);
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
Root: SwitchRoot,
|
|
36
|
+
Thumb: SwitchThumb,
|
|
37
|
+
},
|
|
38
|
+
);
|
|
@@ -24,7 +24,8 @@ export const TabsTrigger = withClassName(
|
|
|
24
24
|
'layer-components:(min-h-touch min-w-100px flex-shrink-0)',
|
|
25
25
|
'layer-components:(border rounded-lg bg-transparent border-transparent)',
|
|
26
26
|
'layer-components:hover:[&[data-state=inactive]]:(ring-4 bg-gray-light bg-darken-1 ring-bg)',
|
|
27
|
-
'layer-components:focus-visible:(
|
|
27
|
+
'layer-components:focus-visible:(border bg-darken-1 border-black)',
|
|
28
|
+
'foc',
|
|
28
29
|
'data-[active]:(cursor-default)',
|
|
29
30
|
);
|
|
30
31
|
|
|
@@ -14,7 +14,7 @@ export const ToggleGroupItem = withClassName(
|
|
|
14
14
|
'layer-components:(flex cursor-pointer items-center justify-center border-1 rounded-lg border-solid px-md py-sm text-nowrap transition-all color-black bg-gray/30 border-transparent)',
|
|
15
15
|
'layer-components:hover:(ring-2 bg-lighten-2 border-main-ink/20 ring-bg)',
|
|
16
16
|
'layer-components:active:(ring-4 bg-darken-1 border-main-ink/30)',
|
|
17
|
-
'layer-components:
|
|
17
|
+
'layer-components:foc',
|
|
18
18
|
'layer-components:data-[pressed]:(border-default shadow-sm bg-main hover:border-default)',
|
|
19
19
|
);
|
|
20
20
|
|
|
@@ -181,14 +181,18 @@ function useReactToViewportChanges(
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
export interface VirtualKeyboardFocusOptions {
|
|
184
|
-
|
|
184
|
+
shouldScrollIntoView?: (el: Element) => boolean;
|
|
185
|
+
}
|
|
186
|
+
function defaultShouldScrollIntoView(el: Element) {
|
|
187
|
+
if (['input', 'textarea', 'select'].includes(el.tagName.toLowerCase()))
|
|
188
|
+
return true;
|
|
189
|
+
if (el.hasAttribute('contenteditable')) return true;
|
|
190
|
+
return false;
|
|
185
191
|
}
|
|
186
192
|
export function useVirtualKeyboardFocusBehavior({
|
|
187
|
-
|
|
193
|
+
shouldScrollIntoView = defaultShouldScrollIntoView,
|
|
188
194
|
}: VirtualKeyboardFocusOptions = {}) {
|
|
189
|
-
const
|
|
190
|
-
.map((type) => type.toLowerCase())
|
|
191
|
-
.join(',');
|
|
195
|
+
const stableShouldScroll = useStableCallback(shouldScrollIntoView);
|
|
192
196
|
useEffect(() => {
|
|
193
197
|
if (typeof navigator === 'undefined' || typeof window === 'undefined') {
|
|
194
198
|
return;
|
|
@@ -204,16 +208,20 @@ export function useVirtualKeyboardFocusBehavior({
|
|
|
204
208
|
|
|
205
209
|
const virtualKeyboard = navigator.virtualKeyboard as any;
|
|
206
210
|
|
|
207
|
-
const matchElements = stableFocusElementTypes.split(',');
|
|
208
|
-
|
|
209
211
|
function update() {
|
|
210
|
-
|
|
212
|
+
const open = virtualKeyboard.boundingRect.height > 0;
|
|
213
|
+
if (open) {
|
|
214
|
+
console.log('keyboard opened');
|
|
215
|
+
}
|
|
211
216
|
const activeElement = document.activeElement;
|
|
212
|
-
if (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
+
if (activeElement && stableShouldScroll(activeElement)) {
|
|
218
|
+
setTimeout(() => {
|
|
219
|
+
console.log('scroll focused element');
|
|
220
|
+
activeElement.scrollIntoView({
|
|
221
|
+
behavior: 'instant',
|
|
222
|
+
block: 'start',
|
|
223
|
+
});
|
|
224
|
+
}, 10);
|
|
217
225
|
}
|
|
218
226
|
}
|
|
219
227
|
|
|
@@ -221,5 +229,5 @@ export function useVirtualKeyboardFocusBehavior({
|
|
|
221
229
|
return () => {
|
|
222
230
|
virtualKeyboard.removeEventListener('geometrychange', update);
|
|
223
231
|
};
|
|
224
|
-
}, [
|
|
232
|
+
}, [stableShouldScroll]);
|
|
225
233
|
}
|
package/src/keyboard.stories.tsx
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Input,
|
|
4
|
+
PageContent,
|
|
5
|
+
PageNowPlaying,
|
|
6
|
+
PageRoot,
|
|
7
|
+
TextArea,
|
|
8
|
+
} from './components/index.js';
|
|
3
9
|
import { useVirtualKeyboardBehavior } from './hooks/useVirtualKeyboardBehavior.js';
|
|
4
10
|
|
|
5
11
|
const meta = {
|
|
@@ -19,16 +25,21 @@ export const Default: Story = {
|
|
|
19
25
|
render(args) {
|
|
20
26
|
useVirtualKeyboardBehavior('overlay');
|
|
21
27
|
return (
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
<div className="
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
<PageRoot id="root">
|
|
29
|
+
<PageContent>
|
|
30
|
+
<div className="h-screen flex flex-col">
|
|
31
|
+
<div className="flex flex-grow flex-col items-center justify-center p-lg">
|
|
32
|
+
Focus the inputs below to see how the virtual keyboard behavior
|
|
33
|
+
works.
|
|
34
|
+
</div>
|
|
35
|
+
<Input className="w-full" />
|
|
36
|
+
<TextArea className="w-full" />
|
|
27
37
|
</div>
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
<PageNowPlaying keepAboveKeyboard>
|
|
39
|
+
<Input placeholder="now playing" />
|
|
40
|
+
</PageNowPlaying>
|
|
41
|
+
</PageContent>
|
|
42
|
+
</PageRoot>
|
|
32
43
|
);
|
|
33
44
|
},
|
|
34
45
|
};
|
package/src/themes.stories.tsx
CHANGED
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
Progress,
|
|
36
36
|
Provider,
|
|
37
37
|
Select,
|
|
38
|
+
Slider,
|
|
38
39
|
TextSkeleton,
|
|
39
40
|
ToggleGroup,
|
|
40
41
|
Tooltip,
|
|
@@ -242,6 +243,7 @@ export function DemoUI({ className }: { className?: string }) {
|
|
|
242
243
|
onChange={() => {}}
|
|
243
244
|
/>
|
|
244
245
|
<Progress value={50} className="m-auto" />
|
|
246
|
+
<Slider defaultValue={50} min={0} max={100} />
|
|
245
247
|
<Box surface color="primary" p gap d="col">
|
|
246
248
|
<H1>Primary surface</H1>
|
|
247
249
|
<H2>Primary surface</H2>
|
|
@@ -17,6 +17,7 @@ export const PROPS = {
|
|
|
17
17
|
SERIF: '--u-font-serif',
|
|
18
18
|
TITLE: '--u-font-title',
|
|
19
19
|
},
|
|
20
|
+
FOCUS_COLOR: '--u-focus-color',
|
|
20
21
|
},
|
|
21
22
|
|
|
22
23
|
PALETTE: {
|
|
@@ -134,5 +135,10 @@ export const PROPS = {
|
|
|
134
135
|
SHADOW_COLOR: '--un-shadow-color',
|
|
135
136
|
SHADOW_OPACITY: '--un-shadow-opacity',
|
|
136
137
|
SHADOW: '--un-shadow',
|
|
138
|
+
RING_WIDTH: '--un-ring-width',
|
|
139
|
+
RING_STYLE: '--un-ring-style',
|
|
140
|
+
RING_OFFSET_SHADOW: '--un-ring-offset-shadow',
|
|
141
|
+
RING_SHADOW: '--un-ring-shadow',
|
|
142
|
+
RING_INSET: '--un-ring-inset',
|
|
137
143
|
},
|
|
138
144
|
};
|
|
@@ -3,7 +3,7 @@ import { basePreflight } from './base.js';
|
|
|
3
3
|
import { colorPreflight, ColorPreflightOptions } from './colors.js';
|
|
4
4
|
import { fontsPreflight, FontsPreflightOptions } from './fonts.js';
|
|
5
5
|
import { globalPreflight, GlobalsPreflightConfig } from './globals.js';
|
|
6
|
-
import { keyboardPreflight } from './keyboard.js';
|
|
6
|
+
import { keyboardPreflight, KeyboardPreflightOptions } from './keyboard.js';
|
|
7
7
|
import { layerPreflight } from './layers.js';
|
|
8
8
|
import { modePreflight } from './mode.js';
|
|
9
9
|
import { propertiesPreflight } from './properties.js';
|
|
@@ -12,7 +12,8 @@ import { userPreflight, UserPreflightOptions } from './user.js';
|
|
|
12
12
|
export type PreflightConfig = FontsPreflightOptions &
|
|
13
13
|
GlobalsPreflightConfig &
|
|
14
14
|
UserPreflightOptions &
|
|
15
|
-
ColorPreflightOptions
|
|
15
|
+
ColorPreflightOptions &
|
|
16
|
+
KeyboardPreflightOptions;
|
|
16
17
|
|
|
17
18
|
export const preflights = (config: PreflightConfig): Preflight<any>[] => [
|
|
18
19
|
layerPreflight,
|
|
@@ -23,5 +24,5 @@ export const preflights = (config: PreflightConfig): Preflight<any>[] => [
|
|
|
23
24
|
fontsPreflight(config),
|
|
24
25
|
propertiesPreflight,
|
|
25
26
|
userPreflight(config),
|
|
26
|
-
keyboardPreflight,
|
|
27
|
+
keyboardPreflight(config),
|
|
27
28
|
];
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { preflight } from './_util.js';
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
export interface KeyboardPreflightOptions {
|
|
4
|
+
rootSelector?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const keyboardPreflight = ({
|
|
8
|
+
rootSelector = '#root,#main',
|
|
9
|
+
}: KeyboardPreflightOptions) =>
|
|
10
|
+
preflight({
|
|
11
|
+
getCSS: () =>
|
|
12
|
+
// add space to bottom of body equal to virtual keyboard inset so that
|
|
13
|
+
// content is not hidden behind the keyboard
|
|
14
|
+
`
|
|
15
|
+
${rootSelector} {
|
|
16
|
+
transform: translateY(calc(-1 * env(keyboard-inset-height,0px)));
|
|
10
17
|
}
|
|
11
18
|
`,
|
|
12
|
-
});
|
|
19
|
+
});
|
|
@@ -18,6 +18,7 @@ export interface UserPreflightOptions {
|
|
|
18
18
|
cornerScale?: number;
|
|
19
19
|
shadowSpread?: number;
|
|
20
20
|
fontSize?: number;
|
|
21
|
+
focusColor?: 'black' | 'primary' | 'accent' | 'gray';
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export const userPreflight = ({
|
|
@@ -30,6 +31,7 @@ export const userPreflight = ({
|
|
|
30
31
|
shadowSpread = 1,
|
|
31
32
|
namedHues,
|
|
32
33
|
fontSize = 16,
|
|
34
|
+
focusColor = 'accent',
|
|
33
35
|
}: UserPreflightOptions) =>
|
|
34
36
|
preflight({
|
|
35
37
|
getCSS: () => {
|
|
@@ -44,6 +46,7 @@ export const userPreflight = ({
|
|
|
44
46
|
|
|
45
47
|
${PROPS.USER.COLOR.PRIMARY_HUE}: ${primaryHue};
|
|
46
48
|
${PROPS.USER.COLOR.ACCENT_HUE}: ${accentHue};
|
|
49
|
+
${PROPS.USER.FOCUS_COLOR}: var(${focusColors[focusColor]});
|
|
47
50
|
${
|
|
48
51
|
namedHues
|
|
49
52
|
? Object.entries(namedHues)
|
|
@@ -65,3 +68,13 @@ export const userPreflight = ({
|
|
|
65
68
|
`;
|
|
66
69
|
},
|
|
67
70
|
});
|
|
71
|
+
|
|
72
|
+
const focusColors: Record<
|
|
73
|
+
NonNullable<UserPreflightOptions['focusColor']>,
|
|
74
|
+
string
|
|
75
|
+
> = {
|
|
76
|
+
black: PROPS.MODE.BLACK,
|
|
77
|
+
primary: PROPS.PALETTE.NAMED_SHADES('primary').DARK,
|
|
78
|
+
accent: PROPS.PALETTE.NAMED_SHADES('accent').MID,
|
|
79
|
+
gray: PROPS.PALETTE.GRAY_SHADES.DARK,
|
|
80
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Theme } from '@unocss/preset-mini';
|
|
2
|
+
import { Rule } from 'unocss';
|
|
3
|
+
import { PROPS } from '../logic/properties.js';
|
|
4
|
+
|
|
5
|
+
export const focusRules: Rule<Theme>[] = [
|
|
6
|
+
[
|
|
7
|
+
/^foc(?:-effect)?(-lg)?$/,
|
|
8
|
+
function* ([, size], { symbols }) {
|
|
9
|
+
yield {
|
|
10
|
+
[symbols.selector]: (selector) =>
|
|
11
|
+
`${selector}:focus-visible:not([data-focus-clicked]), ${selector}[data-focus-visible]`,
|
|
12
|
+
[PROPS.BUILT_IN.RING_COLOR]: `var(${PROPS.USER.FOCUS_COLOR})`,
|
|
13
|
+
[PROPS.BUILT_IN.RING_WIDTH]: size === '-lg' ? '4px' : '2px',
|
|
14
|
+
[PROPS.BUILT_IN.RING_STYLE]: 'solid',
|
|
15
|
+
[PROPS.BUILT_IN
|
|
16
|
+
.RING_SHADOW]: `var(${PROPS.BUILT_IN.RING_INSET}) 0 0 0 var(${PROPS.BUILT_IN.RING_WIDTH}) var(${PROPS.BUILT_IN.RING_COLOR})`,
|
|
17
|
+
outline: 'none',
|
|
18
|
+
'box-shadow': `var(${PROPS.BUILT_IN.RING_OFFSET_SHADOW}), var(${PROPS.BUILT_IN.RING_SHADOW}), var(${PROPS.BUILT_IN.SHADOW})`,
|
|
19
|
+
};
|
|
20
|
+
yield {
|
|
21
|
+
[symbols.selector]: (selector) => `${selector}:focus`,
|
|
22
|
+
outline: 'none',
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
[
|
|
27
|
+
/^foc-contained(-lg)?$/,
|
|
28
|
+
function* ([, size], { symbols }) {
|
|
29
|
+
yield {
|
|
30
|
+
[symbols.selector]: (selector) =>
|
|
31
|
+
`${selector}:has(:focus-visible:not([data-focus-clicked])), ${selector}:has([data-focus-visible])`,
|
|
32
|
+
[PROPS.BUILT_IN.RING_COLOR]: `var(${PROPS.USER.FOCUS_COLOR})`,
|
|
33
|
+
[PROPS.BUILT_IN.RING_WIDTH]: size === '-lg' ? '4px' : '2px',
|
|
34
|
+
[PROPS.BUILT_IN.RING_STYLE]: 'solid',
|
|
35
|
+
[PROPS.BUILT_IN
|
|
36
|
+
.RING_SHADOW]: `0 0 0 var(${PROPS.BUILT_IN.RING_WIDTH}) var(${PROPS.BUILT_IN.RING_COLOR})`,
|
|
37
|
+
outline: 'none',
|
|
38
|
+
'box-shadow': `var(${PROPS.BUILT_IN.RING_OFFSET_SHADOW}), var(${PROPS.BUILT_IN.RING_SHADOW})`,
|
|
39
|
+
};
|
|
40
|
+
yield {
|
|
41
|
+
[symbols.selector]: (selector) => `${selector}>*:focus`,
|
|
42
|
+
outline: 'none',
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
];
|