@4alldigital/foundation-ui--core 3.12.2 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4alldigital/foundation-ui--core",
3
- "version": "3.12.2",
3
+ "version": "3.13.0",
4
4
  "description": "Foundation UI Core Component Library (source distribution)",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -38,5 +38,5 @@
38
38
  "devDependencies": {
39
39
  "@types/he": "^1.2.3"
40
40
  },
41
- "gitHead": "3d674cdb288d74e5021fcf47bdf674c44355b7af"
41
+ "gitHead": "2394d061bf5fa814a00ffb74c334a001dbbc9bf4"
42
42
  }
@@ -124,6 +124,8 @@ export const AddressForm = React.forwardRef<HTMLDivElement, AddressFormProps>(
124
124
  {/* Full Name */}
125
125
  <TextInput
126
126
  id="shipping-name"
127
+ name="name"
128
+ autoComplete="shipping name"
127
129
  placeholder="Full Name"
128
130
  value={address.name || ''}
129
131
  onChange={(e) => handleChange('name', e.target.value)}
@@ -136,6 +138,8 @@ export const AddressForm = React.forwardRef<HTMLDivElement, AddressFormProps>(
136
138
  {/* Address Line 1 */}
137
139
  <TextInput
138
140
  id="shipping-line1"
141
+ name="address-line1"
142
+ autoComplete="shipping address-line1"
139
143
  placeholder="Street Address"
140
144
  value={address.line1 || ''}
141
145
  onChange={(e) => handleChange('line1', e.target.value)}
@@ -148,6 +152,8 @@ export const AddressForm = React.forwardRef<HTMLDivElement, AddressFormProps>(
148
152
  {/* Address Line 2 */}
149
153
  <TextInput
150
154
  id="shipping-line2"
155
+ name="address-line2"
156
+ autoComplete="shipping address-line2"
151
157
  placeholder="Apartment, suite, etc. (optional)"
152
158
  value={address.line2 || ''}
153
159
  onChange={(e) => handleChange('line2', e.target.value)}
@@ -158,6 +164,8 @@ export const AddressForm = React.forwardRef<HTMLDivElement, AddressFormProps>(
158
164
  <div className="grid gap-4 sm:grid-cols-2">
159
165
  <TextInput
160
166
  id="shipping-city"
167
+ name="address-level2"
168
+ autoComplete="shipping address-level2"
161
169
  placeholder="City"
162
170
  value={address.city || ''}
163
171
  onChange={(e) => handleChange('city', e.target.value)}
@@ -169,6 +177,8 @@ export const AddressForm = React.forwardRef<HTMLDivElement, AddressFormProps>(
169
177
 
170
178
  <TextInput
171
179
  id="shipping-state"
180
+ name="address-level1"
181
+ autoComplete="shipping address-level1"
172
182
  placeholder="State / County / Province"
173
183
  value={address.state || ''}
174
184
  onChange={(e) => handleChange('state', e.target.value)}
@@ -183,6 +193,8 @@ export const AddressForm = React.forwardRef<HTMLDivElement, AddressFormProps>(
183
193
  <div className="grid gap-4 sm:grid-cols-2">
184
194
  <TextInput
185
195
  id="shipping-postal-code"
196
+ name="postal-code"
197
+ autoComplete="shipping postal-code"
186
198
  placeholder="Postal / ZIP Code"
187
199
  value={address.postal_code || ''}
188
200
  onChange={(e) => handleChange('postal_code', e.target.value)}
@@ -194,6 +206,8 @@ export const AddressForm = React.forwardRef<HTMLDivElement, AddressFormProps>(
194
206
 
195
207
  <FormSelect
196
208
  id="shipping-country"
209
+ name="country"
210
+ autoComplete="shipping country"
197
211
  placeholder="Country"
198
212
  value={address.country || ''}
199
213
  onChange={(e) => handleChange('country', e.target.value)}
@@ -208,7 +222,9 @@ export const AddressForm = React.forwardRef<HTMLDivElement, AddressFormProps>(
208
222
  {/* Phone */}
209
223
  <TextInput
210
224
  id="shipping-phone"
225
+ name="phone"
211
226
  type={InputType.TEL}
227
+ autoComplete="shipping tel"
212
228
  placeholder="Phone Number (optional)"
213
229
  value={address.phone || ''}
214
230
  onChange={(e) => handleChange('phone', e.target.value)}
@@ -4,17 +4,16 @@ import { useCallback, useEffect, useState } from 'react';
4
4
  import { clsx as cx } from 'clsx';
5
5
  import { Props } from './Header.types';
6
6
  import { useAppContext } from '../../context/App';
7
+ import { useThemeContext } from '../../context/Theme';
7
8
  import Logo from '../Logo';
8
9
  import Button from '../Button';
9
10
  import Menu from '../Menu';
10
11
  import { BTN_VARIANTS } from '../Button/Button.types';
11
- // import Copy from '../Copy';
12
12
  import Link from '../Link';
13
13
  import { useLanguage } from '../../hooks';
14
14
  import Container from '../Container';
15
15
  import { twMerge } from 'tailwind-merge';
16
16
  import Cart from '../Cart';
17
- // import Avatar from '../Avatar';
18
17
 
19
18
  const Header = ({
20
19
  testID,
@@ -28,6 +27,7 @@ const Header = ({
28
27
  }: Props) => {
29
28
  const context = useAppContext();
30
29
  const T = useLanguage();
30
+ const theme = useThemeContext();
31
31
 
32
32
  const [mobileMenuClass, mobileMenuIcon] = useState('hidden');
33
33
  const [showDropdown, setShowDropdown] = useState(false);
@@ -94,6 +94,13 @@ const Header = ({
94
94
  </div>
95
95
  {/* <!-- tablet/desktop --> */}
96
96
  <div className="hidden md:flex items-center justify-center gap-2">
97
+ {theme?.toggleTheme && (
98
+ <Button
99
+ onClick={theme.toggleTheme}
100
+ icon={theme.isDarkTheme ? 'mdi:weather-sunny' : 'mdi:weather-night'}
101
+ ariaLabel={theme.isDarkTheme ? 'Switch to light mode' : 'Switch to dark mode'}
102
+ />
103
+ )}
97
104
  {!context?.app?.isAuthenticated && context?.app?.loginCallback && (
98
105
  <div className="w-32 flex justify-end">
99
106
  <Button rounded onClick={context?.app?.loginCallback}>{T.UI.LOGIN}</Button>
@@ -158,6 +165,15 @@ const Header = ({
158
165
  <Menu links={context.header.profile} separators />
159
166
  )}
160
167
  </div>
168
+ {theme?.toggleTheme && (
169
+ <div className="md:hidden flex justify-center">
170
+ <Button
171
+ onClick={theme.toggleTheme}
172
+ icon={theme.isDarkTheme ? 'mdi:weather-sunny' : 'mdi:weather-night'}
173
+ ariaLabel={theme.isDarkTheme ? 'Switch to light mode' : 'Switch to dark mode'}
174
+ />
175
+ </div>
176
+ )}
161
177
  {context?.app?.isAuthenticated && (
162
178
  <div className="md:hidden flex justify-center">
163
179
  <Button rounded onClick={context?.app?.logoutCallback}>{T.UI.LOGOUT}</Button>
@@ -7,7 +7,20 @@ import Heading from '../Heading';
7
7
  import { HEADING_TAGS } from '../Heading/Heading.types';
8
8
  import { twMerge } from 'tailwind-merge';
9
9
 
10
+ function useCurrentPathname(): string | null {
11
+ try {
12
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
13
+ const { usePathname } = require('next/navigation');
14
+ // eslint-disable-next-line react-hooks/rules-of-hooks
15
+ return usePathname();
16
+ } catch {
17
+ return null;
18
+ }
19
+ }
20
+
10
21
  const Menu = ({ testID, title, links, inline = true, separators = false, className }: Props) => {
22
+ const pathname = useCurrentPathname();
23
+
11
24
  return (
12
25
  <div data-testid={testID || '"Menu"'} className={twMerge(cx('flex flex-col gap-2', className))}>
13
26
  {title && (
@@ -18,13 +31,17 @@ const Menu = ({ testID, title, links, inline = true, separators = false, classNa
18
31
  <div className={cx('flex gap-0 items-center md:items-start', { 'flex-col md:flex-row ': inline }, { 'flex-col ': !inline })}>
19
32
  {links?.map((link, index) => {
20
33
  const key = `${link.id}--${index}`;
34
+ const isActive = pathname ? pathname === link.url || (link.url !== '/' && pathname.startsWith(link.url)) : false;
21
35
  return (
22
36
  <div key={key} className='flex gap-0'>
23
37
  <div className="relative py-2">
24
- <Link href={link.url} className="flex gap-1 transition-opacity hover:opacity-70">
38
+ <Link href={link.url} className={cx("flex gap-1 transition-opacity hover:opacity-70", isActive && "opacity-100 font-bold")}>
25
39
  {link.icon && <Icon name={link.icon} />}
26
40
  {link.title && <div>{link.title}</div>}
27
41
  </Link>
42
+ {isActive && (
43
+ <div className="absolute bottom-0 left-0 right-0 h-0.5 bg-current rounded-full" />
44
+ )}
28
45
  </div>
29
46
  {separators && index + 1 < links.length && (
30
47
  <div className="h-full hidden md:flex self-center px-2">
@@ -17,7 +17,7 @@ function SearchBox({
17
17
  resetTrigger = () => {},
18
18
  }: Props) {
19
19
  return (
20
- <div className={cx('m-0 md:px-48', className)}>
20
+ <div className={cx('m-0 w-full', className)}>
21
21
  <form onSubmit={e => onSubmit(e)} className="flex items-center">
22
22
  <div className="flex-1 bg-body-bg/80 dark:bg-body-bg-dark/80 rounded">
23
23
  <TextInput
@@ -7,4 +7,5 @@ export interface Props {
7
7
  placeholder?: string;
8
8
  allowReset?: boolean;
9
9
  resetTrigger?: (data?: any, options?: any) => void;
10
+ shouldClearFilters?: boolean;
10
11
  }