@ecohouse/ui 0.1.36 → 0.1.38
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/README.md +2 -0
- package/dist/index.cjs +945 -416
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -2
- package/dist/index.d.ts +75 -2
- package/dist/index.js +870 -346
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.stories.tsx +47 -0
- package/src/components/Accordion/Accordion.tsx +165 -0
- package/src/components/Accordion/index.ts +2 -0
- package/src/components/AutocompleteInput/AutocompleteInput.stories.tsx +80 -0
- package/src/components/AutocompleteInput/AutocompleteInput.tsx +313 -0
- package/src/components/AutocompleteInput/index.ts +2 -0
- package/src/components/Counter/Counter.tsx +61 -26
- package/src/components/QuantityInput/QuantityInput.stories.tsx +45 -0
- package/src/components/QuantityInput/QuantityInput.tsx +153 -0
- package/src/components/QuantityInput/index.ts +2 -0
- package/src/components/index.ts +9 -0
- package/src/icons/ArrowLeft/ArrowLeftIcon.test.ts +10 -0
- package/src/icons/ArrowLeft/ArrowLeftIcon.tsx +21 -0
- package/src/icons/ArrowLeft/ArrowLeftIcon.web.tsx +26 -0
- package/src/icons/ArrowLeft/arrowLeftPath.ts +3 -0
- package/src/icons/ArrowLeft/index.ts +1 -0
- package/src/icons/CurrentLocation/CurrentLocationIcon.test.ts +10 -0
- package/src/icons/CurrentLocation/CurrentLocationIcon.tsx +25 -0
- package/src/icons/CurrentLocation/CurrentLocationIcon.web.tsx +30 -0
- package/src/icons/CurrentLocation/currentLocationPath.ts +3 -0
- package/src/icons/CurrentLocation/index.ts +1 -0
- package/src/icons/index.ts +2 -0
- package/src/icons/registry.ts +6 -0
- package/src/index.ts +9 -0
- package/src/theme/colors.test.ts +1 -0
- package/src/theme/colors.ts +1 -0
|
@@ -23,6 +23,8 @@ export interface CounterProps extends Omit<ViewProps, "style" | "children"> {
|
|
|
23
23
|
max?: number;
|
|
24
24
|
step?: number;
|
|
25
25
|
disabled?: boolean;
|
|
26
|
+
/** Places the value before both controls for use inside input-like fields. */
|
|
27
|
+
layout?: "controls-around" | "value-first";
|
|
26
28
|
style?: StyleProp<ViewStyle>;
|
|
27
29
|
className?: string;
|
|
28
30
|
hitSlop?: PressableProps["hitSlop"];
|
|
@@ -51,6 +53,7 @@ export const Counter = forwardRef<ComponentRef<typeof View>, CounterProps>(funct
|
|
|
51
53
|
max,
|
|
52
54
|
step = 1,
|
|
53
55
|
disabled = false,
|
|
56
|
+
layout = "controls-around",
|
|
54
57
|
style,
|
|
55
58
|
className,
|
|
56
59
|
hitSlop,
|
|
@@ -78,33 +81,57 @@ export const Counter = forwardRef<ComponentRef<typeof View>, CounterProps>(funct
|
|
|
78
81
|
onValueChange?.(next);
|
|
79
82
|
};
|
|
80
83
|
|
|
81
|
-
|
|
82
|
-
<
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
84
|
+
const decrement = (
|
|
85
|
+
<Pressable
|
|
86
|
+
disabled={decrementDisabled}
|
|
87
|
+
hitSlop={hitSlop}
|
|
88
|
+
onPress={() => updateValue(resolvedValue - step)}
|
|
89
|
+
accessibilityRole="button"
|
|
90
|
+
accessibilityLabel="Decrease value"
|
|
91
|
+
accessibilityState={{ disabled: decrementDisabled }}
|
|
92
|
+
style={[styles.button, webBlurStyle, decrementDisabled && styles.buttonDisabled]}
|
|
93
|
+
>
|
|
94
|
+
<MinusIcon />
|
|
95
|
+
</Pressable>
|
|
96
|
+
);
|
|
97
|
+
const increment = (
|
|
98
|
+
<Pressable
|
|
99
|
+
disabled={incrementDisabled}
|
|
100
|
+
hitSlop={hitSlop}
|
|
101
|
+
onPress={() => updateValue(resolvedValue + step)}
|
|
102
|
+
accessibilityRole="button"
|
|
103
|
+
accessibilityLabel="Increase value"
|
|
104
|
+
accessibilityState={{ disabled: incrementDisabled }}
|
|
105
|
+
style={[styles.button, webBlurStyle, incrementDisabled && styles.buttonDisabled]}
|
|
106
|
+
>
|
|
107
|
+
<PlusIcon />
|
|
108
|
+
</Pressable>
|
|
109
|
+
);
|
|
110
|
+
const valueNode = (
|
|
111
|
+
<Text style={[styles.value, layout === "value-first" && styles.leadingValue]}>
|
|
112
|
+
{resolvedValue}
|
|
113
|
+
</Text>
|
|
114
|
+
);
|
|
96
115
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
116
|
+
return (
|
|
117
|
+
<View
|
|
118
|
+
{...rest}
|
|
119
|
+
ref={setContainerRef}
|
|
120
|
+
style={[styles.base, layout === "value-first" && styles.valueFirst, style]}
|
|
121
|
+
>
|
|
122
|
+
{layout === "value-first" ? (
|
|
123
|
+
<>
|
|
124
|
+
{valueNode}
|
|
125
|
+
{decrement}
|
|
126
|
+
{increment}
|
|
127
|
+
</>
|
|
128
|
+
) : (
|
|
129
|
+
<>
|
|
130
|
+
{decrement}
|
|
131
|
+
{valueNode}
|
|
132
|
+
{increment}
|
|
133
|
+
</>
|
|
134
|
+
)}
|
|
108
135
|
</View>
|
|
109
136
|
);
|
|
110
137
|
});
|
|
@@ -116,6 +143,11 @@ const styles = StyleSheet.create({
|
|
|
116
143
|
alignSelf: "flex-start",
|
|
117
144
|
gap: 17,
|
|
118
145
|
},
|
|
146
|
+
valueFirst: {
|
|
147
|
+
alignSelf: "stretch",
|
|
148
|
+
flex: 1,
|
|
149
|
+
gap: 6,
|
|
150
|
+
},
|
|
119
151
|
button: {
|
|
120
152
|
width: BUTTON_SIZE,
|
|
121
153
|
height: BUTTON_SIZE,
|
|
@@ -132,4 +164,7 @@ const styles = StyleSheet.create({
|
|
|
132
164
|
...counterTypography,
|
|
133
165
|
color: colors.white,
|
|
134
166
|
},
|
|
167
|
+
leadingValue: {
|
|
168
|
+
flex: 1,
|
|
169
|
+
},
|
|
135
170
|
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
3
|
+
import { GuestsIcon } from "../../icons";
|
|
4
|
+
import { QuantityInput } from "./QuantityInput";
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: "Components/QuantityInput",
|
|
8
|
+
component: QuantityInput,
|
|
9
|
+
args: {
|
|
10
|
+
label: "Maximum guests",
|
|
11
|
+
icon: GuestsIcon,
|
|
12
|
+
defaultValue: 1,
|
|
13
|
+
min: 1,
|
|
14
|
+
},
|
|
15
|
+
parameters: {
|
|
16
|
+
backgrounds: { default: "black" },
|
|
17
|
+
},
|
|
18
|
+
} satisfies Meta<typeof QuantityInput>;
|
|
19
|
+
|
|
20
|
+
export default meta;
|
|
21
|
+
type Story = StoryObj<typeof meta>;
|
|
22
|
+
|
|
23
|
+
export const Default: Story = {};
|
|
24
|
+
|
|
25
|
+
export const WithError: Story = {
|
|
26
|
+
args: { error: true, hint: "Choose at least one guest" },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function ControlledQuantityInput() {
|
|
30
|
+
const [value, setValue] = useState(1);
|
|
31
|
+
return (
|
|
32
|
+
<QuantityInput
|
|
33
|
+
icon={GuestsIcon}
|
|
34
|
+
label="Maximum guests"
|
|
35
|
+
max={20}
|
|
36
|
+
min={1}
|
|
37
|
+
onValueChange={setValue}
|
|
38
|
+
value={value}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const Controlled: Story = {
|
|
44
|
+
render: () => <ControlledQuantityInput />,
|
|
45
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { forwardRef, useMemo, useRef, type ComponentRef } from "react";
|
|
2
|
+
import {
|
|
3
|
+
StyleSheet,
|
|
4
|
+
Text,
|
|
5
|
+
View,
|
|
6
|
+
type StyleProp,
|
|
7
|
+
type ViewProps,
|
|
8
|
+
type ViewStyle,
|
|
9
|
+
} from "react-native";
|
|
10
|
+
import type { IconComponent, IconProps } from "../../icons";
|
|
11
|
+
import { colors, fonts } from "../../theme";
|
|
12
|
+
import { mergeRefs } from "../../utils/mergeRefs";
|
|
13
|
+
import { useApplyWebClassName } from "../../utils/useApplyWebClassName";
|
|
14
|
+
import { Counter } from "../Counter";
|
|
15
|
+
|
|
16
|
+
export interface QuantityInputProps extends Omit<ViewProps, "style" | "children"> {
|
|
17
|
+
label: string;
|
|
18
|
+
icon: IconComponent;
|
|
19
|
+
iconProps?: Omit<IconProps, "size">;
|
|
20
|
+
iconSize?: number;
|
|
21
|
+
value?: number;
|
|
22
|
+
defaultValue?: number;
|
|
23
|
+
onValueChange?: (value: number) => void;
|
|
24
|
+
min?: number;
|
|
25
|
+
max?: number;
|
|
26
|
+
step?: number;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
error?: boolean;
|
|
29
|
+
hint?: string;
|
|
30
|
+
showHint?: boolean;
|
|
31
|
+
style?: StyleProp<ViewStyle>;
|
|
32
|
+
className?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Input-like labeled quantity control with an icon and increment/decrement actions. */
|
|
36
|
+
export const QuantityInput = forwardRef<ComponentRef<typeof View>, QuantityInputProps>(
|
|
37
|
+
function QuantityInput(
|
|
38
|
+
{
|
|
39
|
+
label,
|
|
40
|
+
icon: Icon,
|
|
41
|
+
iconProps,
|
|
42
|
+
iconSize = 20,
|
|
43
|
+
value,
|
|
44
|
+
defaultValue,
|
|
45
|
+
onValueChange,
|
|
46
|
+
min = 1,
|
|
47
|
+
max,
|
|
48
|
+
step = 1,
|
|
49
|
+
disabled = false,
|
|
50
|
+
error = false,
|
|
51
|
+
hint,
|
|
52
|
+
showHint = true,
|
|
53
|
+
style,
|
|
54
|
+
className,
|
|
55
|
+
accessibilityLabel,
|
|
56
|
+
...rest
|
|
57
|
+
},
|
|
58
|
+
forwardedRef,
|
|
59
|
+
) {
|
|
60
|
+
const rootRef = useRef<ComponentRef<typeof View>>(null);
|
|
61
|
+
const setRootRef = useMemo(() => mergeRefs(rootRef, forwardedRef), [forwardedRef]);
|
|
62
|
+
|
|
63
|
+
useApplyWebClassName(rootRef, className?.trim() || undefined);
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<View
|
|
67
|
+
{...rest}
|
|
68
|
+
ref={setRootRef}
|
|
69
|
+
accessibilityLabel={accessibilityLabel ?? label}
|
|
70
|
+
accessibilityState={{ disabled }}
|
|
71
|
+
style={[styles.root, disabled && styles.disabled, style]}
|
|
72
|
+
>
|
|
73
|
+
<Text style={[styles.label, error && styles.errorText]}>{label}</Text>
|
|
74
|
+
<View style={[styles.field, error && styles.errorField]}>
|
|
75
|
+
<View style={styles.iconSlot}>
|
|
76
|
+
<Icon
|
|
77
|
+
{...iconProps}
|
|
78
|
+
color={iconProps?.color ?? (error ? colors.red : colors.grey150)}
|
|
79
|
+
size={iconSize}
|
|
80
|
+
/>
|
|
81
|
+
</View>
|
|
82
|
+
<Counter
|
|
83
|
+
defaultValue={defaultValue}
|
|
84
|
+
disabled={disabled}
|
|
85
|
+
layout="value-first"
|
|
86
|
+
max={max}
|
|
87
|
+
min={min}
|
|
88
|
+
onValueChange={onValueChange}
|
|
89
|
+
step={step}
|
|
90
|
+
value={value}
|
|
91
|
+
/>
|
|
92
|
+
</View>
|
|
93
|
+
{showHint && hint ? (
|
|
94
|
+
<Text style={[styles.hint, error && styles.errorText]}>{hint}</Text>
|
|
95
|
+
) : null}
|
|
96
|
+
</View>
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const styles = StyleSheet.create({
|
|
102
|
+
root: {
|
|
103
|
+
alignSelf: "stretch",
|
|
104
|
+
flexDirection: "column",
|
|
105
|
+
gap: 8,
|
|
106
|
+
minWidth: 0,
|
|
107
|
+
},
|
|
108
|
+
label: {
|
|
109
|
+
color: colors.white,
|
|
110
|
+
fontFamily: fonts.sans,
|
|
111
|
+
fontSize: 12,
|
|
112
|
+
fontWeight: "500",
|
|
113
|
+
letterSpacing: -0.24,
|
|
114
|
+
lineHeight: 12,
|
|
115
|
+
},
|
|
116
|
+
field: {
|
|
117
|
+
alignItems: "center",
|
|
118
|
+
alignSelf: "stretch",
|
|
119
|
+
backgroundColor: colors.grey700,
|
|
120
|
+
borderColor: colors.grey700,
|
|
121
|
+
borderRadius: 60,
|
|
122
|
+
borderWidth: 1,
|
|
123
|
+
flexDirection: "row",
|
|
124
|
+
gap: 10,
|
|
125
|
+
height: 44,
|
|
126
|
+
paddingLeft: 16,
|
|
127
|
+
paddingRight: 6,
|
|
128
|
+
paddingVertical: 5,
|
|
129
|
+
},
|
|
130
|
+
iconSlot: {
|
|
131
|
+
alignItems: "center",
|
|
132
|
+
flexShrink: 0,
|
|
133
|
+
height: 20,
|
|
134
|
+
justifyContent: "center",
|
|
135
|
+
width: 20,
|
|
136
|
+
},
|
|
137
|
+
hint: {
|
|
138
|
+
color: colors.grey100,
|
|
139
|
+
fontFamily: fonts.sans,
|
|
140
|
+
fontSize: 12,
|
|
141
|
+
fontWeight: "400",
|
|
142
|
+
lineHeight: 12,
|
|
143
|
+
},
|
|
144
|
+
errorField: {
|
|
145
|
+
borderColor: colors.redMuted,
|
|
146
|
+
},
|
|
147
|
+
errorText: {
|
|
148
|
+
color: colors.red,
|
|
149
|
+
},
|
|
150
|
+
disabled: {
|
|
151
|
+
opacity: 0.6,
|
|
152
|
+
},
|
|
153
|
+
});
|
package/src/components/index.ts
CHANGED
|
@@ -28,12 +28,18 @@ export type { ContactInfoCardProps } from "./ContactInfoCard";
|
|
|
28
28
|
export { AccordionItem } from "./AccordionItem";
|
|
29
29
|
export type { AccordionItemProps } from "./AccordionItem";
|
|
30
30
|
|
|
31
|
+
export { Accordion } from "./Accordion";
|
|
32
|
+
export type { AccordionProps } from "./Accordion";
|
|
33
|
+
|
|
31
34
|
export { StepList } from "./StepList";
|
|
32
35
|
export type { StepListProps } from "./StepList";
|
|
33
36
|
|
|
34
37
|
export { Counter } from "./Counter";
|
|
35
38
|
export type { CounterProps } from "./Counter";
|
|
36
39
|
|
|
40
|
+
export { QuantityInput } from "./QuantityInput";
|
|
41
|
+
export type { QuantityInputProps } from "./QuantityInput";
|
|
42
|
+
|
|
37
43
|
export { SegmentedToggle } from "./SegmentedToggle";
|
|
38
44
|
export type { SegmentedToggleOption, SegmentedToggleProps } from "./SegmentedToggle";
|
|
39
45
|
|
|
@@ -74,6 +80,9 @@ export type { ModalProps } from "./Modal";
|
|
|
74
80
|
export { Input } from "./Input";
|
|
75
81
|
export type { InputIcon, InputProps, InputSize } from "./Input";
|
|
76
82
|
|
|
83
|
+
export { AutocompleteInput } from "./AutocompleteInput";
|
|
84
|
+
export type { AutocompleteInputProps, AutocompleteOption } from "./AutocompleteInput";
|
|
85
|
+
|
|
77
86
|
export { VerificationCodeInput } from "./VerificationCodeInput";
|
|
78
87
|
export type {
|
|
79
88
|
VerificationCodeInputHandle,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { ARROW_LEFT_PATH } from "./arrowLeftPath";
|
|
3
|
+
|
|
4
|
+
describe("ArrowLeftIcon", () => {
|
|
5
|
+
it("uses the approved 24px path", () => {
|
|
6
|
+
expect(ARROW_LEFT_PATH).toBe(
|
|
7
|
+
"M10.1972 6.59961L4.80078 11.9994L10.1972 17.3996M4.80078 11.9965H19.202",
|
|
8
|
+
);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Svg, { Path } from "react-native-svg";
|
|
2
|
+
import { colors } from "../../theme";
|
|
3
|
+
import type { IconProps } from "../types";
|
|
4
|
+
import { ARROW_LEFT_PATH } from "./arrowLeftPath";
|
|
5
|
+
|
|
6
|
+
export { ARROW_LEFT_PATH } from "./arrowLeftPath";
|
|
7
|
+
|
|
8
|
+
/** Native — react-native-svg (peer dependency). */
|
|
9
|
+
export function ArrowLeftIcon({ size = 24, color = colors.white, strokeWidth = 1.35 }: IconProps) {
|
|
10
|
+
return (
|
|
11
|
+
<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
|
|
12
|
+
<Path
|
|
13
|
+
d={ARROW_LEFT_PATH}
|
|
14
|
+
stroke={color}
|
|
15
|
+
strokeWidth={strokeWidth}
|
|
16
|
+
strokeLinecap="round"
|
|
17
|
+
strokeLinejoin="round"
|
|
18
|
+
/>
|
|
19
|
+
</Svg>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { colors } from "../../theme";
|
|
2
|
+
import type { IconProps } from "../types";
|
|
3
|
+
import { ARROW_LEFT_PATH } from "./arrowLeftPath";
|
|
4
|
+
|
|
5
|
+
export function ArrowLeftIcon({ size = 24, color = colors.white, strokeWidth = 1.35 }: IconProps) {
|
|
6
|
+
return (
|
|
7
|
+
<svg
|
|
8
|
+
aria-hidden
|
|
9
|
+
fill="none"
|
|
10
|
+
height={size}
|
|
11
|
+
viewBox="0 0 24 24"
|
|
12
|
+
width={size}
|
|
13
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
14
|
+
>
|
|
15
|
+
<path
|
|
16
|
+
d={ARROW_LEFT_PATH}
|
|
17
|
+
stroke={color}
|
|
18
|
+
strokeLinecap="round"
|
|
19
|
+
strokeLinejoin="round"
|
|
20
|
+
strokeWidth={strokeWidth}
|
|
21
|
+
/>
|
|
22
|
+
</svg>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { ARROW_LEFT_PATH } from "./arrowLeftPath";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ArrowLeftIcon, ARROW_LEFT_PATH } from "./ArrowLeftIcon";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { CURRENT_LOCATION_PATH } from "./currentLocationPath";
|
|
3
|
+
|
|
4
|
+
describe("CurrentLocationIcon", () => {
|
|
5
|
+
it("uses the approved 19px path", () => {
|
|
6
|
+
expect(CURRENT_LOCATION_PATH).toBe(
|
|
7
|
+
"M17.4167 9.08333H14.0833M4.08333 9.08333H0.75M9.08333 4.08333V0.75M9.08333 17.4167V14.0833M15.75 9.08333C15.75 12.7652 12.7652 15.75 9.08333 15.75C5.40144 15.75 2.41667 12.7652 2.41667 9.08333C2.41667 5.40144 5.40144 2.41667 9.08333 2.41667C12.7652 2.41667 15.75 5.40144 15.75 9.08333ZM11.5833 9.08333C11.5833 10.464 10.464 11.5833 9.08333 11.5833C7.70262 11.5833 6.58333 10.464 6.58333 9.08333C6.58333 7.70262 7.70262 6.58333 9.08333 6.58333C10.464 6.58333 11.5833 7.70262 11.5833 9.08333Z",
|
|
8
|
+
);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import Svg, { Path } from "react-native-svg";
|
|
2
|
+
import { colors } from "../../theme";
|
|
3
|
+
import type { IconProps } from "../types";
|
|
4
|
+
import { CURRENT_LOCATION_PATH } from "./currentLocationPath";
|
|
5
|
+
|
|
6
|
+
export { CURRENT_LOCATION_PATH } from "./currentLocationPath";
|
|
7
|
+
|
|
8
|
+
/** Native — react-native-svg (peer dependency). */
|
|
9
|
+
export function CurrentLocationIcon({
|
|
10
|
+
size = 19,
|
|
11
|
+
color = colors.primary,
|
|
12
|
+
strokeWidth = 1.5,
|
|
13
|
+
}: IconProps) {
|
|
14
|
+
return (
|
|
15
|
+
<Svg width={size} height={size} viewBox="0 0 19 19" fill="none">
|
|
16
|
+
<Path
|
|
17
|
+
d={CURRENT_LOCATION_PATH}
|
|
18
|
+
stroke={color}
|
|
19
|
+
strokeWidth={strokeWidth}
|
|
20
|
+
strokeLinecap="round"
|
|
21
|
+
strokeLinejoin="round"
|
|
22
|
+
/>
|
|
23
|
+
</Svg>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { colors } from "../../theme";
|
|
2
|
+
import type { IconProps } from "../types";
|
|
3
|
+
import { CURRENT_LOCATION_PATH } from "./currentLocationPath";
|
|
4
|
+
|
|
5
|
+
export function CurrentLocationIcon({
|
|
6
|
+
size = 19,
|
|
7
|
+
color = colors.primary,
|
|
8
|
+
strokeWidth = 1.5,
|
|
9
|
+
}: IconProps) {
|
|
10
|
+
return (
|
|
11
|
+
<svg
|
|
12
|
+
aria-hidden
|
|
13
|
+
fill="none"
|
|
14
|
+
height={size}
|
|
15
|
+
viewBox="0 0 19 19"
|
|
16
|
+
width={size}
|
|
17
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
18
|
+
>
|
|
19
|
+
<path
|
|
20
|
+
d={CURRENT_LOCATION_PATH}
|
|
21
|
+
stroke={color}
|
|
22
|
+
strokeLinecap="round"
|
|
23
|
+
strokeLinejoin="round"
|
|
24
|
+
strokeWidth={strokeWidth}
|
|
25
|
+
/>
|
|
26
|
+
</svg>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { CURRENT_LOCATION_PATH } from "./currentLocationPath";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Current-location crosshair path — 19×19 viewBox. */
|
|
2
|
+
export const CURRENT_LOCATION_PATH =
|
|
3
|
+
"M17.4167 9.08333H14.0833M4.08333 9.08333H0.75M9.08333 4.08333V0.75M9.08333 17.4167V14.0833M15.75 9.08333C15.75 12.7652 12.7652 15.75 9.08333 15.75C5.40144 15.75 2.41667 12.7652 2.41667 9.08333C2.41667 5.40144 5.40144 2.41667 9.08333 2.41667C12.7652 2.41667 15.75 5.40144 15.75 9.08333ZM11.5833 9.08333C11.5833 10.464 10.464 11.5833 9.08333 11.5833C7.70262 11.5833 6.58333 10.464 6.58333 9.08333C6.58333 7.70262 7.70262 6.58333 9.08333 6.58333C10.464 6.58333 11.5833 7.70262 11.5833 9.08333Z";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CurrentLocationIcon, CURRENT_LOCATION_PATH } from "./CurrentLocationIcon";
|
package/src/icons/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { AmenityIcon } from "./Amenity";
|
|
|
9
9
|
export type { AmenityIconProps, AmenityName } from "./Amenity";
|
|
10
10
|
export { AlertTriangleIcon } from "./AlertTriangle";
|
|
11
11
|
export { AppleIcon } from "./Store";
|
|
12
|
+
export { ArrowLeftIcon } from "./ArrowLeft";
|
|
12
13
|
export { ArrowRightIcon } from "./ArrowRight";
|
|
13
14
|
export { BagIcon } from "./Bag";
|
|
14
15
|
export { BanIcon } from "./Ban";
|
|
@@ -24,6 +25,7 @@ export { ChevronDownIcon } from "./ChevronDown";
|
|
|
24
25
|
export { ChevronLeftIcon } from "./ChevronLeft";
|
|
25
26
|
export { ClockIcon } from "./Clock";
|
|
26
27
|
export { CloseIcon } from "./Close";
|
|
28
|
+
export { CurrentLocationIcon } from "./CurrentLocation";
|
|
27
29
|
export { EditIcon } from "./Edit";
|
|
28
30
|
export {
|
|
29
31
|
BathroomsIcon,
|
package/src/icons/registry.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ArrowRightIcon } from "./ArrowRight";
|
|
2
|
+
import { ArrowLeftIcon } from "./ArrowLeft";
|
|
2
3
|
import { AlertTriangleIcon } from "./AlertTriangle";
|
|
3
4
|
import { AppleIcon, GooglePlayIcon } from "./Store";
|
|
4
5
|
import { BagIcon } from "./Bag";
|
|
@@ -15,6 +16,7 @@ import { ChevronDownIcon } from "./ChevronDown";
|
|
|
15
16
|
import { ChevronLeftIcon } from "./ChevronLeft";
|
|
16
17
|
import { ClockIcon } from "./Clock";
|
|
17
18
|
import { CloseIcon } from "./Close";
|
|
19
|
+
import { CurrentLocationIcon } from "./CurrentLocation";
|
|
18
20
|
import { EditIcon } from "./Edit";
|
|
19
21
|
import {
|
|
20
22
|
BathroomsIcon,
|
|
@@ -85,6 +87,7 @@ export const icons = {
|
|
|
85
87
|
alertTriangle: AlertTriangleIcon,
|
|
86
88
|
areaExpand: AreaExpandIcon,
|
|
87
89
|
apple: AppleIcon,
|
|
90
|
+
arrowLeft: ArrowLeftIcon,
|
|
88
91
|
arrowRight: ArrowRightIcon,
|
|
89
92
|
bag: BagIcon,
|
|
90
93
|
ban: BanIcon,
|
|
@@ -101,6 +104,7 @@ export const icons = {
|
|
|
101
104
|
chevronLeft: ChevronLeftIcon,
|
|
102
105
|
clock: ClockIcon,
|
|
103
106
|
close: CloseIcon,
|
|
107
|
+
currentLocation: CurrentLocationIcon,
|
|
104
108
|
edit: EditIcon,
|
|
105
109
|
clockFilled: ClockFilledIcon,
|
|
106
110
|
copy: CopyIcon,
|
|
@@ -172,9 +176,11 @@ export const iconNames = Object.keys(icons) as IconName[];
|
|
|
172
176
|
|
|
173
177
|
export const iconGroups = {
|
|
174
178
|
navigation: [
|
|
179
|
+
"arrowLeft",
|
|
175
180
|
"arrowRight",
|
|
176
181
|
"chevronDown",
|
|
177
182
|
"chevronLeft",
|
|
183
|
+
"currentLocation",
|
|
178
184
|
"home",
|
|
179
185
|
"listView",
|
|
180
186
|
"locationPin",
|
package/src/index.ts
CHANGED
|
@@ -9,8 +9,10 @@ export {
|
|
|
9
9
|
InfoTile,
|
|
10
10
|
ContactInfoCard,
|
|
11
11
|
AccordionItem,
|
|
12
|
+
Accordion,
|
|
12
13
|
StepList,
|
|
13
14
|
Counter,
|
|
15
|
+
QuantityInput,
|
|
14
16
|
SegmentedToggle,
|
|
15
17
|
Sidebar,
|
|
16
18
|
LanguageSwitcher,
|
|
@@ -22,6 +24,7 @@ export {
|
|
|
22
24
|
FloatingActionButton,
|
|
23
25
|
Modal,
|
|
24
26
|
Input,
|
|
27
|
+
AutocompleteInput,
|
|
25
28
|
VerificationCodeInput,
|
|
26
29
|
Select,
|
|
27
30
|
Textarea,
|
|
@@ -45,8 +48,10 @@ export type {
|
|
|
45
48
|
InfoTileProps,
|
|
46
49
|
ContactInfoCardProps,
|
|
47
50
|
AccordionItemProps,
|
|
51
|
+
AccordionProps,
|
|
48
52
|
StepListProps,
|
|
49
53
|
CounterProps,
|
|
54
|
+
QuantityInputProps,
|
|
50
55
|
SegmentedToggleOption,
|
|
51
56
|
SegmentedToggleProps,
|
|
52
57
|
SidebarProps,
|
|
@@ -71,6 +76,8 @@ export type {
|
|
|
71
76
|
InputIcon,
|
|
72
77
|
InputProps,
|
|
73
78
|
InputSize,
|
|
79
|
+
AutocompleteInputProps,
|
|
80
|
+
AutocompleteOption,
|
|
74
81
|
VerificationCodeInputHandle,
|
|
75
82
|
VerificationCodeInputProps,
|
|
76
83
|
SelectIcon,
|
|
@@ -119,6 +126,7 @@ export {
|
|
|
119
126
|
iconGroups,
|
|
120
127
|
iconGroupNames,
|
|
121
128
|
getIconsByGroup,
|
|
129
|
+
ArrowLeftIcon,
|
|
122
130
|
ArrowRightIcon,
|
|
123
131
|
BagIcon,
|
|
124
132
|
BanIcon,
|
|
@@ -134,6 +142,7 @@ export {
|
|
|
134
142
|
ChevronLeftIcon,
|
|
135
143
|
ClockIcon,
|
|
136
144
|
CloseIcon,
|
|
145
|
+
CurrentLocationIcon,
|
|
137
146
|
EditIcon,
|
|
138
147
|
BathroomsIcon,
|
|
139
148
|
BedroomsIcon,
|
package/src/theme/colors.test.ts
CHANGED
|
@@ -16,6 +16,7 @@ describe("design tokens", () => {
|
|
|
16
16
|
expect(colors.whiteAlpha86).toBe("#FFFFFFDB");
|
|
17
17
|
expect(colors.whiteAlpha40).toBe("#FFFFFF66");
|
|
18
18
|
expect(colors.whiteAlpha20).toBe("#FFFFFF33");
|
|
19
|
+
expect(colors.whiteAlpha1).toBe("#FFFFFF03");
|
|
19
20
|
expect(colors.whiteAlpha6).toBe("#FFFFFF0F");
|
|
20
21
|
expect(colors.whiteAlpha10).toBe("#FFFFFF1A");
|
|
21
22
|
expect(colors.whiteAlpha5).toBe("#FFFFFF0D");
|
package/src/theme/colors.ts
CHANGED