@windstream/react-shared-components 0.2.48 → 0.2.49
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/contentful/index.esm.js +1 -1
- package/dist/contentful/index.esm.js.map +1 -1
- package/dist/contentful/index.js +1 -1
- package/dist/contentful/index.js.map +1 -1
- package/dist/core.d.ts +48 -6
- package/dist/index.d.ts +48 -6
- package/dist/index.esm.js +6 -6
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/components/brand-button/index.tsx +2 -2
- package/src/components/precisely-address-autocomplete/PreciselyAddressAutocomplete.stories.tsx +69 -0
- package/src/components/precisely-address-autocomplete/index.test.tsx +159 -0
- package/src/components/precisely-address-autocomplete/index.tsx +219 -0
- package/src/components/precisely-address-autocomplete/types.ts +54 -0
- package/src/contentful/blocks/cards/floating-image-card/index.tsx +4 -3
- package/src/contentful/blocks/cards/simple-card/index.tsx +2 -1
- package/src/index.ts +8 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
|
|
3
|
+
import { AddressAutocomplete } from "./index";
|
|
4
|
+
|
|
5
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
6
|
+
|
|
7
|
+
const suggestions = [
|
|
8
|
+
{
|
|
9
|
+
address: {
|
|
10
|
+
addressLine1: "123 Dale Springs",
|
|
11
|
+
addressLine2: "Apt B",
|
|
12
|
+
city: "Binsport",
|
|
13
|
+
state: "NC",
|
|
14
|
+
postalCode: "17032",
|
|
15
|
+
providerId: "candidate-1",
|
|
16
|
+
},
|
|
17
|
+
mainText: "123 Dale Springs",
|
|
18
|
+
placeId: "place-1",
|
|
19
|
+
provider: "precisely",
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
describe("AddressAutocomplete", () => {
|
|
24
|
+
it("requests suggestions and displays results at the minimum query length", () => {
|
|
25
|
+
const onChange = jest.fn();
|
|
26
|
+
render(
|
|
27
|
+
<AddressAutocomplete suggestions={suggestions} onChange={onChange} />
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const input = screen.getByRole("combobox");
|
|
31
|
+
fireEvent.change(input, { target: { value: "12" } });
|
|
32
|
+
expect(
|
|
33
|
+
screen.queryByTestId("address-autocomplete-suggestions")
|
|
34
|
+
).not.toBeInTheDocument();
|
|
35
|
+
|
|
36
|
+
fireEvent.change(input, { target: { value: "123" } });
|
|
37
|
+
expect(onChange).toHaveBeenLastCalledWith("123");
|
|
38
|
+
expect(
|
|
39
|
+
screen.getByTestId("address-autocomplete-suggestions")
|
|
40
|
+
).toBeInTheDocument();
|
|
41
|
+
expect(screen.getByTestId("address-autocomplete-suggestions")).toHaveClass(
|
|
42
|
+
"max-h-[220px]",
|
|
43
|
+
"overflow-y-auto",
|
|
44
|
+
"p-0",
|
|
45
|
+
"border",
|
|
46
|
+
"border-input-border",
|
|
47
|
+
"bg-bg-surface",
|
|
48
|
+
"shadow-dark-drop"
|
|
49
|
+
);
|
|
50
|
+
expect(
|
|
51
|
+
screen.getByRole("button", { name: /123 Dale Springs/i })
|
|
52
|
+
).toHaveClass("px-4");
|
|
53
|
+
expect(screen.getByRole("combobox").parentElement).toHaveClass("pl-4");
|
|
54
|
+
expect(screen.getAllByText("location_on")[0]).toHaveClass(
|
|
55
|
+
"text-icon-brand"
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("uses the input pin color for each suggestion pin", () => {
|
|
60
|
+
render(
|
|
61
|
+
<AddressAutocomplete
|
|
62
|
+
defaultValue="123"
|
|
63
|
+
suggestions={suggestions}
|
|
64
|
+
prefixIconClassName="text-input-icon-placeholder"
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
fireEvent.focus(screen.getByRole("combobox"));
|
|
69
|
+
const pins = screen.getAllByText("location_on");
|
|
70
|
+
expect(pins).toHaveLength(2);
|
|
71
|
+
pins.forEach(pin => {
|
|
72
|
+
expect(pin).toHaveClass("text-input-icon-placeholder");
|
|
73
|
+
expect(pin).toHaveClass(
|
|
74
|
+
"inline-flex",
|
|
75
|
+
"items-center",
|
|
76
|
+
"justify-center",
|
|
77
|
+
"leading-none"
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("returns the selected provider address without requesting again", () => {
|
|
83
|
+
const onChange = jest.fn();
|
|
84
|
+
const onSelectAddress = jest.fn();
|
|
85
|
+
render(
|
|
86
|
+
<AddressAutocomplete
|
|
87
|
+
defaultValue="123"
|
|
88
|
+
suggestions={suggestions}
|
|
89
|
+
onChange={onChange}
|
|
90
|
+
onSelectAddress={onSelectAddress}
|
|
91
|
+
/>
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
fireEvent.focus(screen.getByRole("combobox"));
|
|
95
|
+
fireEvent.click(screen.getByRole("button", { name: /123 Dale Springs/i }));
|
|
96
|
+
|
|
97
|
+
expect(onSelectAddress).toHaveBeenCalledWith({
|
|
98
|
+
address: "123 Dale Springs, Apt B, Binsport, NC, 17032",
|
|
99
|
+
unit: "Apt B",
|
|
100
|
+
addressToSend: suggestions[0].address,
|
|
101
|
+
placeId: "place-1",
|
|
102
|
+
});
|
|
103
|
+
expect(onChange).not.toHaveBeenCalled();
|
|
104
|
+
expect(screen.getByRole("combobox")).toHaveValue(
|
|
105
|
+
"123 Dale Springs, Apt B, Binsport, NC, 17032"
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("clears the selected address when the input is emptied", () => {
|
|
110
|
+
const onSelectAddress = jest.fn();
|
|
111
|
+
render(
|
|
112
|
+
<AddressAutocomplete
|
|
113
|
+
defaultValue="123"
|
|
114
|
+
onSelectAddress={onSelectAddress}
|
|
115
|
+
/>
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
fireEvent.change(screen.getByRole("combobox"), {
|
|
119
|
+
target: { value: "" },
|
|
120
|
+
});
|
|
121
|
+
expect(onSelectAddress).toHaveBeenCalledWith();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("focuses and reports load when its provider becomes ready", () => {
|
|
125
|
+
const onLoadProvider = jest.fn();
|
|
126
|
+
const { rerender } = render(
|
|
127
|
+
<AddressAutocomplete isReady={false} onLoadProvider={onLoadProvider} />
|
|
128
|
+
);
|
|
129
|
+
const input = screen.getByRole("combobox");
|
|
130
|
+
|
|
131
|
+
expect(input).toBeDisabled();
|
|
132
|
+
expect(onLoadProvider).not.toHaveBeenCalled();
|
|
133
|
+
|
|
134
|
+
rerender(
|
|
135
|
+
<AddressAutocomplete isReady={true} onLoadProvider={onLoadProvider} />
|
|
136
|
+
);
|
|
137
|
+
expect(input).toHaveFocus();
|
|
138
|
+
expect(onLoadProvider).toHaveBeenCalledTimes(1);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("dismisses suggestions after an outside click", () => {
|
|
142
|
+
render(
|
|
143
|
+
<div>
|
|
144
|
+
<AddressAutocomplete defaultValue="123" suggestions={suggestions} />
|
|
145
|
+
<button type="button">Outside</button>
|
|
146
|
+
</div>
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
fireEvent.focus(screen.getByRole("combobox"));
|
|
150
|
+
expect(
|
|
151
|
+
screen.getByTestId("address-autocomplete-suggestions")
|
|
152
|
+
).toBeInTheDocument();
|
|
153
|
+
|
|
154
|
+
fireEvent.click(screen.getByRole("button", { name: "Outside" }));
|
|
155
|
+
expect(
|
|
156
|
+
screen.queryByTestId("address-autocomplete-suggestions")
|
|
157
|
+
).not.toBeInTheDocument();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useId, useRef, useState } from "react";
|
|
4
|
+
import type {
|
|
5
|
+
AddressAutocompleteAddress,
|
|
6
|
+
AddressAutocompleteProps,
|
|
7
|
+
AddressAutocompleteSuggestion,
|
|
8
|
+
} from "./types";
|
|
9
|
+
|
|
10
|
+
import { Input } from "@shared/components/input";
|
|
11
|
+
import { MaterialIcon } from "@shared/components/material-icon";
|
|
12
|
+
import { useOutsideClick } from "@shared/hooks/use-outside-click";
|
|
13
|
+
import { cx } from "@shared/utils";
|
|
14
|
+
|
|
15
|
+
const formatSuggestion = <TAddress extends AddressAutocompleteAddress>(
|
|
16
|
+
suggestion: AddressAutocompleteSuggestion<TAddress>
|
|
17
|
+
) => {
|
|
18
|
+
const { address, mainText, postalCode: suggestionPostalCode } = suggestion;
|
|
19
|
+
if (!address) {
|
|
20
|
+
return { primaryText: mainText, secondaryText: "", value: mainText };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const primaryText = [address.addressLine1, address.addressLine2]
|
|
24
|
+
.filter(Boolean)
|
|
25
|
+
.join(", ");
|
|
26
|
+
const secondaryText = [
|
|
27
|
+
address.city,
|
|
28
|
+
address.state,
|
|
29
|
+
address.postalCode || suggestionPostalCode,
|
|
30
|
+
]
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.join(", ");
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
primaryText: primaryText || mainText,
|
|
36
|
+
secondaryText,
|
|
37
|
+
value: [primaryText, secondaryText].filter(Boolean).join(", ") || mainText,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const AddressAutocomplete = <
|
|
42
|
+
TAddress extends AddressAutocompleteAddress = AddressAutocompleteAddress,
|
|
43
|
+
>({
|
|
44
|
+
className,
|
|
45
|
+
containerClassName,
|
|
46
|
+
defaultValue = "",
|
|
47
|
+
errorText,
|
|
48
|
+
fixedPositionedSuggestions = false,
|
|
49
|
+
focusOnLoad = true,
|
|
50
|
+
hasError,
|
|
51
|
+
inputContainerClassName,
|
|
52
|
+
isIframe = false,
|
|
53
|
+
isLoading = false,
|
|
54
|
+
isReady = true,
|
|
55
|
+
mapPinIcon = true,
|
|
56
|
+
minQueryLength = 3,
|
|
57
|
+
onChange,
|
|
58
|
+
onFocus,
|
|
59
|
+
onLoadProvider,
|
|
60
|
+
onSelectAddress,
|
|
61
|
+
onSuggestionsChange,
|
|
62
|
+
optionsContainerClassName,
|
|
63
|
+
prefixIconClassName = "text-icon-brand",
|
|
64
|
+
suggestions = [],
|
|
65
|
+
value: controlledValue,
|
|
66
|
+
...inputProps
|
|
67
|
+
}: AddressAutocompleteProps<TAddress>) => {
|
|
68
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
69
|
+
const rootRef = useRef<HTMLDivElement>(null);
|
|
70
|
+
const suggestionsId = useId();
|
|
71
|
+
const [value, setValue] = useState(controlledValue ?? defaultValue);
|
|
72
|
+
const [showSuggestions, setShowSuggestions] = useState(false);
|
|
73
|
+
const pinIconClassName = cx(
|
|
74
|
+
"inline-flex items-center justify-center leading-none",
|
|
75
|
+
prefixIconClassName
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (controlledValue !== undefined) setValue(controlledValue);
|
|
80
|
+
}, [controlledValue]);
|
|
81
|
+
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (isReady && focusOnLoad) inputRef.current?.focus();
|
|
84
|
+
}, [focusOnLoad, isReady]);
|
|
85
|
+
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (isReady) onLoadProvider?.();
|
|
88
|
+
}, [isReady, onLoadProvider]);
|
|
89
|
+
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
onSuggestionsChange?.(suggestions);
|
|
92
|
+
}, [onSuggestionsChange, suggestions]);
|
|
93
|
+
|
|
94
|
+
useOutsideClick(rootRef, () => setShowSuggestions(false));
|
|
95
|
+
|
|
96
|
+
const selectSuggestion = useCallback(
|
|
97
|
+
(suggestion: AddressAutocompleteSuggestion<TAddress>) => {
|
|
98
|
+
if (!suggestion.address) return;
|
|
99
|
+
|
|
100
|
+
const formatted = formatSuggestion(suggestion);
|
|
101
|
+
setValue(formatted.value);
|
|
102
|
+
setShowSuggestions(false);
|
|
103
|
+
onSelectAddress?.({
|
|
104
|
+
address: formatted.value,
|
|
105
|
+
unit: suggestion.address.addressLine2 || "",
|
|
106
|
+
addressToSend: suggestion.address,
|
|
107
|
+
placeId: suggestion.placeId || "",
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
[onSelectAddress]
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const hasSuggestions =
|
|
114
|
+
showSuggestions &&
|
|
115
|
+
value.length >= minQueryLength &&
|
|
116
|
+
!isLoading &&
|
|
117
|
+
suggestions.length > 0;
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<div
|
|
121
|
+
ref={rootRef}
|
|
122
|
+
className={cx("relative min-w-[300px] text-text", containerClassName)}
|
|
123
|
+
>
|
|
124
|
+
<Input
|
|
125
|
+
{...inputProps}
|
|
126
|
+
ref={inputRef}
|
|
127
|
+
size="medium"
|
|
128
|
+
value={value}
|
|
129
|
+
className={cx(
|
|
130
|
+
"mx-auto w-full bg-transparent pl-2 placeholder:text-input-text-placeholder",
|
|
131
|
+
"body2",
|
|
132
|
+
className
|
|
133
|
+
)}
|
|
134
|
+
containerClassName={cx("pl-4", inputContainerClassName)}
|
|
135
|
+
loading={!isReady}
|
|
136
|
+
onChange={event => {
|
|
137
|
+
const nextValue = event.target.value;
|
|
138
|
+
setValue(nextValue);
|
|
139
|
+
setShowSuggestions(nextValue.length >= minQueryLength);
|
|
140
|
+
if (!nextValue) onSelectAddress?.();
|
|
141
|
+
onChange?.(nextValue);
|
|
142
|
+
}}
|
|
143
|
+
onFocus={event => {
|
|
144
|
+
setShowSuggestions(true);
|
|
145
|
+
onFocus?.(event);
|
|
146
|
+
}}
|
|
147
|
+
autoComplete="off"
|
|
148
|
+
role="combobox"
|
|
149
|
+
aria-autocomplete="list"
|
|
150
|
+
aria-controls={suggestionsId}
|
|
151
|
+
aria-expanded={hasSuggestions}
|
|
152
|
+
data-cy="address-autocomplete-input"
|
|
153
|
+
data-testid="address-autocomplete-input"
|
|
154
|
+
prefixIconName={mapPinIcon ? "location_on" : undefined}
|
|
155
|
+
prefixIconFill={true}
|
|
156
|
+
prefixIconClassName={pinIconClassName}
|
|
157
|
+
errorText={errorText}
|
|
158
|
+
state={errorText || hasError ? "error" : inputProps.state}
|
|
159
|
+
hasError={hasError}
|
|
160
|
+
/>
|
|
161
|
+
|
|
162
|
+
{hasSuggestions && (
|
|
163
|
+
<ul
|
|
164
|
+
id={suggestionsId}
|
|
165
|
+
role="listbox"
|
|
166
|
+
data-cy="address-autocomplete-suggestions"
|
|
167
|
+
data-testid="address-autocomplete-suggestions"
|
|
168
|
+
className={cx(
|
|
169
|
+
"shadow-dark-drop absolute top-full z-20 m-0 mt-1 w-full list-none overflow-y-auto overscroll-contain rounded-lg border border-input-border bg-bg-surface p-0",
|
|
170
|
+
isIframe ? "max-h-[117px]" : "max-h-[220px]",
|
|
171
|
+
fixedPositionedSuggestions &&
|
|
172
|
+
(isIframe
|
|
173
|
+
? "fixed z-50 max-h-[117px]"
|
|
174
|
+
: "fixed z-50 max-h-[220px]"),
|
|
175
|
+
optionsContainerClassName
|
|
176
|
+
)}
|
|
177
|
+
>
|
|
178
|
+
{suggestions.map((suggestion, index) => {
|
|
179
|
+
const { primaryText, secondaryText } = formatSuggestion(suggestion);
|
|
180
|
+
return (
|
|
181
|
+
<li
|
|
182
|
+
role="option"
|
|
183
|
+
aria-selected="false"
|
|
184
|
+
key={suggestion.placeId || `${suggestion.mainText}-${index}`}
|
|
185
|
+
>
|
|
186
|
+
<button
|
|
187
|
+
type="button"
|
|
188
|
+
className="flex w-full items-center px-4 py-4 text-left hover:bg-bg-surface-secondary"
|
|
189
|
+
onClick={() => selectSuggestion(suggestion)}
|
|
190
|
+
>
|
|
191
|
+
<MaterialIcon
|
|
192
|
+
fill={1}
|
|
193
|
+
name="location_on"
|
|
194
|
+
size={24}
|
|
195
|
+
weight="200"
|
|
196
|
+
className={cx("mr-4 min-w-[24px]", pinIconClassName)}
|
|
197
|
+
/>
|
|
198
|
+
<span>
|
|
199
|
+
<span>{primaryText}</span>
|
|
200
|
+
{secondaryText && (
|
|
201
|
+
<small className="ml-1">{secondaryText}</small>
|
|
202
|
+
)}
|
|
203
|
+
</span>
|
|
204
|
+
</button>
|
|
205
|
+
</li>
|
|
206
|
+
);
|
|
207
|
+
})}
|
|
208
|
+
</ul>
|
|
209
|
+
)}
|
|
210
|
+
</div>
|
|
211
|
+
);
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export type {
|
|
215
|
+
AddressAutocompleteAddress,
|
|
216
|
+
AddressAutocompleteProps,
|
|
217
|
+
AddressAutocompleteResult,
|
|
218
|
+
AddressAutocompleteSuggestion,
|
|
219
|
+
} from "./types";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { InputFieldProps } from "@shared/components/input";
|
|
2
|
+
|
|
3
|
+
export type AddressAutocompleteAddress = {
|
|
4
|
+
addressLine1?: string;
|
|
5
|
+
addressLine2?: string | null;
|
|
6
|
+
city?: string;
|
|
7
|
+
state?: string;
|
|
8
|
+
postalCode?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type AddressAutocompleteSuggestion<
|
|
12
|
+
TAddress extends AddressAutocompleteAddress = AddressAutocompleteAddress,
|
|
13
|
+
> = {
|
|
14
|
+
address?: TAddress;
|
|
15
|
+
mainText: string;
|
|
16
|
+
placeId?: string;
|
|
17
|
+
postalCode?: string;
|
|
18
|
+
provider?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type AddressAutocompleteResult<
|
|
22
|
+
TAddress extends AddressAutocompleteAddress = AddressAutocompleteAddress,
|
|
23
|
+
> = {
|
|
24
|
+
address: string;
|
|
25
|
+
unit: string;
|
|
26
|
+
addressToSend: TAddress;
|
|
27
|
+
placeId: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type AddressAutocompleteProps<
|
|
31
|
+
TAddress extends AddressAutocompleteAddress = AddressAutocompleteAddress,
|
|
32
|
+
> = Omit<
|
|
33
|
+
InputFieldProps,
|
|
34
|
+
"defaultValue" | "loading" | "onChange" | "size" | "value"
|
|
35
|
+
> & {
|
|
36
|
+
value?: string;
|
|
37
|
+
defaultValue?: string;
|
|
38
|
+
suggestions?: AddressAutocompleteSuggestion<TAddress>[];
|
|
39
|
+
isLoading?: boolean;
|
|
40
|
+
isReady?: boolean;
|
|
41
|
+
focusOnLoad?: boolean;
|
|
42
|
+
minQueryLength?: number;
|
|
43
|
+
mapPinIcon?: boolean;
|
|
44
|
+
fixedPositionedSuggestions?: boolean;
|
|
45
|
+
isIframe?: boolean;
|
|
46
|
+
inputContainerClassName?: string;
|
|
47
|
+
optionsContainerClassName?: string;
|
|
48
|
+
onChange?: (value: string) => void;
|
|
49
|
+
onSelectAddress?: (result?: AddressAutocompleteResult<TAddress>) => void;
|
|
50
|
+
onSuggestionsChange?: (
|
|
51
|
+
suggestions: AddressAutocompleteSuggestion<TAddress>[]
|
|
52
|
+
) => void;
|
|
53
|
+
onLoadProvider?: () => void;
|
|
54
|
+
};
|
|
@@ -7,10 +7,11 @@ import { NextImage } from "@shared/components/next-image";
|
|
|
7
7
|
import { Text } from "@shared/components/text";
|
|
8
8
|
import { cx } from "@shared/utils";
|
|
9
9
|
|
|
10
|
+
// Block (full-width) on mobile so the button fills the card; flex alignment only on desktop.
|
|
10
11
|
const alignmentClasses: Record<string, string> = {
|
|
11
|
-
left: "
|
|
12
|
-
right: "
|
|
13
|
-
center: "
|
|
12
|
+
left: "w-full lg:flex lg:justify-start",
|
|
13
|
+
right: "w-full lg:flex lg:justify-end",
|
|
14
|
+
center: "w-full lg:flex lg:justify-center",
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
export const FloatingImageCard: React.FC<FloatingImageCardProps> = ({
|
|
@@ -331,7 +331,8 @@ export const SimpleCard: React.FC<SimpleCardProps> = ({
|
|
|
331
331
|
fullWidth={true}
|
|
332
332
|
buttonClassName={cx(
|
|
333
333
|
card.cta.buttonClassName,
|
|
334
|
-
|
|
334
|
+
// Narrower padding so long labels still fit the fixed width.
|
|
335
|
+
isCtaOnly && "w-[342px] max-w-full px-4 lg:w-[342px]"
|
|
335
336
|
)}
|
|
336
337
|
/>
|
|
337
338
|
</div>
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,14 @@ export type { ButtonProps } from "./components/button";
|
|
|
8
8
|
export { Input, InputField, Input as TextInput } from "./components/input";
|
|
9
9
|
export type { InputProps, InputFieldProps } from "./components/input";
|
|
10
10
|
|
|
11
|
+
export { AddressAutocomplete } from "./components/precisely-address-autocomplete";
|
|
12
|
+
export type {
|
|
13
|
+
AddressAutocompleteAddress,
|
|
14
|
+
AddressAutocompleteProps,
|
|
15
|
+
AddressAutocompleteResult,
|
|
16
|
+
AddressAutocompleteSuggestion,
|
|
17
|
+
} from "./components/precisely-address-autocomplete";
|
|
18
|
+
|
|
11
19
|
export { Image } from "./components/image";
|
|
12
20
|
export type { ImageProps, ImageComponentProps } from "./components/image";
|
|
13
21
|
|