willba-component-library 0.3.11 → 0.3.13

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 (43) hide show
  1. package/README.md +6 -18
  2. package/lib/assets/IconsSvg.d.ts +1 -2
  3. package/lib/components/Button/Button.d.ts +6 -6
  4. package/lib/components/FilterBar/FilterBar.d.ts +1 -1
  5. package/lib/components/FilterBar/FilterBarTypes.d.ts +1 -1
  6. package/lib/components/FilterBar/components/buttons/select-button/SelectButton.d.ts +1 -2
  7. package/lib/components/FilterBar/components/buttons/tab-button/TabButton.d.ts +1 -2
  8. package/lib/components/FilterBar/components/cards/image-card/ImageCard.d.ts +1 -2
  9. package/lib/components/FilterBar/components/categories/Categories.d.ts +1 -2
  10. package/lib/components/FilterBar/components/common/FilterSectionHeader.d.ts +2 -2
  11. package/lib/components/FilterBar/components/dates/Dates.d.ts +4 -4
  12. package/lib/components/FilterBar/components/divider/Divider.d.ts +1 -2
  13. package/lib/components/FilterBar/components/guests/Guests.d.ts +1 -2
  14. package/lib/components/FilterBar/components/locations/Locations.d.ts +1 -2
  15. package/lib/components/FilterCalendar/FilterCalendar.d.ts +1 -2
  16. package/lib/components/FilterCalendar/components/Footer.d.ts +1 -2
  17. package/lib/core/components/buttons/close-button/CloseButton.d.ts +1 -2
  18. package/lib/core/components/buttons/submit-button/SubmitButton.d.ts +2 -2
  19. package/lib/core/components/calendar/Calendar.d.ts +1 -2
  20. package/lib/index.d.ts +9 -9
  21. package/lib/index.esm.js +204 -290
  22. package/lib/index.esm.js.map +1 -1
  23. package/lib/index.js +291 -377
  24. package/lib/index.js.map +1 -1
  25. package/lib/index.umd.js +293 -380
  26. package/lib/index.umd.js.map +1 -1
  27. package/package.json +1 -1
  28. package/rollup.config.mjs +1 -1
  29. package/src/components/Button/Button.stories.tsx +16 -16
  30. package/src/components/Button/Button.tsx +15 -15
  31. package/src/components/FilterBar/FilterBar.tsx +1 -1
  32. package/src/components/FilterBar/FilterBarTypes.ts +1 -1
  33. package/src/components/FilterBar/components/buttons/select-button/SelectButton.tsx +12 -1
  34. package/src/components/FilterBar/components/common/FilterSectionHeader.tsx +1 -0
  35. package/src/components/FilterBar/components/dates/Dates.tsx +3 -4
  36. package/src/components/FilterBar/components/guests/Guests.tsx +10 -1
  37. package/src/components/FilterBar/utils/calculateDropdownPosition.tsx +0 -10
  38. package/src/components/FilterCalendar/FilterCalendar.stories.tsx +1 -1
  39. package/src/core/components/buttons/submit-button/SubmitButton.tsx +2 -1
  40. package/src/core/components/calendar/Calendar.tsx +6 -3
  41. package/stories/Button.tsx +16 -11
  42. package/stories/Header.tsx +28 -14
  43. package/stories/Page.tsx +39 -21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "willba-component-library",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
4
4
  "description": "A custom UI component library",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.esm.js",
package/rollup.config.mjs CHANGED
@@ -46,7 +46,7 @@ export default [
46
46
  resolve(),
47
47
  commonjs(),
48
48
  typescript({
49
- jsx: 'react',
49
+ jsx: 'react-jsx',
50
50
  }),
51
51
  postcss({
52
52
  extensions: ['.css'],
@@ -1,34 +1,34 @@
1
- import React from "react";
2
- import type { Meta, StoryObj } from "@storybook/react";
3
- import Button from "./Button";
1
+ import React from 'react'
2
+ import type { Meta, StoryObj } from '@storybook/react'
3
+ import Button from './Button'
4
4
 
5
5
  // Default metadata of the story https://storybook.js.org/docs/react/api/csf#default-export
6
6
  const meta: Meta<typeof Button> = {
7
- title: "Components/Button",
7
+ title: 'Components/Button',
8
8
  component: Button,
9
9
  argTypes: {
10
- textColor: { control: "color" },
11
- onClick: { action: "clicked" },
10
+ textColor: { control: 'color' },
11
+ onClick: { action: 'clicked' },
12
12
  },
13
- };
13
+ }
14
14
 
15
- export default meta;
15
+ export default meta
16
16
 
17
17
  // The story type for the component https://storybook.js.org/docs/react/api/csf#named-story-exports
18
- type Story = StoryObj<typeof Button>;
18
+ type Story = StoryObj<typeof Button>
19
19
 
20
20
  export const Primary: Story = {
21
21
  args: {
22
- label: "Primary 😃",
23
- size: "large",
24
- type: "primary",
22
+ label: 'Primary 😃',
23
+ size: 'large',
24
+ type: 'primary',
25
25
  },
26
- };
26
+ }
27
27
 
28
28
  export const Secondary: Story = {
29
29
  args: {
30
30
  ...Primary.args,
31
- type: "secondary",
32
- label: "Secondary 😇",
31
+ type: 'secondary',
32
+ label: 'Secondary 😇',
33
33
  },
34
- };
34
+ }
@@ -1,47 +1,47 @@
1
- import React, { useState } from "react";
2
- import classNames from "classnames";
3
- import "./button.css";
1
+ import React, { useState, MouseEvent } from 'react'
2
+ import classNames from 'classnames'
3
+ import './button.css'
4
4
 
5
5
  export interface ButtonProps {
6
6
  /**
7
7
  * Is this the principal call to action on the page?
8
8
  */
9
- type?: "primary" | "secondary";
9
+ type?: 'primary' | 'secondary'
10
10
  /**
11
11
  * What background color to use
12
12
  */
13
- textColor?: string;
13
+ textColor?: string
14
14
  /**
15
15
  * How large should the button be?
16
16
  */
17
- size?: "small" | "medium" | "large";
17
+ size?: 'small' | 'medium' | 'large'
18
18
  /**
19
19
  * Button contents
20
20
  */
21
- label: string;
21
+ label: string
22
22
  /**
23
23
  * Optional click handler
24
24
  */
25
- onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
25
+ onClick?: (event: MouseEvent<HTMLButtonElement>) => void
26
26
  }
27
27
 
28
28
  /**
29
29
  * Primary UI component for user interaction
30
30
  */
31
31
  const Button = ({
32
- type = "primary",
32
+ type = 'primary',
33
33
  textColor,
34
- size = "medium",
34
+ size = 'medium',
35
35
  onClick,
36
36
  label,
37
37
  }: ButtonProps) => {
38
- const [theState, setTheState] = useState(4);
38
+ const [theState, setTheState] = useState(4)
39
39
 
40
40
  return (
41
41
  <button
42
42
  type="button"
43
43
  className={classNames(
44
- "storybook-button",
44
+ 'storybook-button',
45
45
  `storybook-button--${size}`,
46
46
  `storybook-button--${type}`
47
47
  )}
@@ -50,7 +50,7 @@ const Button = ({
50
50
  >
51
51
  {`${label} ${theState}`}
52
52
  </button>
53
- );
54
- };
53
+ )
54
+ }
55
55
 
56
- export default Button;
56
+ export default Button
@@ -1,4 +1,4 @@
1
- import {
1
+ import React, {
2
2
  CSSProperties,
3
3
  MutableRefObject,
4
4
  useEffect,
@@ -66,6 +66,6 @@ export type Locations = {
66
66
  export type Location = {
67
67
  id: number
68
68
  label: string
69
- description?: string
69
+ description?: string | null
70
70
  imageUrl?: string | null
71
71
  }
@@ -13,7 +13,18 @@ type Props = {
13
13
  }
14
14
 
15
15
  export const SelectButton = forwardRef<HTMLButtonElement, Props>(
16
- ({ active, label, onClick, description, disabled, ariaExpanded, ariaControls }, ref) => {
16
+ (
17
+ {
18
+ active,
19
+ label,
20
+ onClick,
21
+ description,
22
+ disabled,
23
+ ariaExpanded,
24
+ ariaControls,
25
+ },
26
+ ref
27
+ ) => {
17
28
  return (
18
29
  <button
19
30
  ref={ref}
@@ -1,4 +1,5 @@
1
1
  import React, { ReactNode } from 'react'
2
+
2
3
  import './FilterSectionHeader.css'
3
4
 
4
5
  type Props = {
@@ -1,16 +1,15 @@
1
- import React from 'react'
1
+ import React, { RefObject, forwardRef } from 'react'
2
2
 
3
3
  import { DateRange } from 'react-day-picker'
4
4
  import { Calendar } from '../../../../core/components'
5
5
  import { DisableCalendarDates } from '../../../../core/components/calendar/CalendarTypes'
6
6
  import { CloseButton } from '../buttons'
7
7
  import { FilterSectionHeader } from '../common/FilterSectionHeader'
8
- import { forwardRef } from 'react'
9
8
 
10
9
  import './Dates.css'
11
10
 
12
11
  type Props = {
13
- ref: React.RefObject<HTMLDivElement>
12
+ ref: RefObject<HTMLDivElement>
14
13
  onClose?: () => void
15
14
  autoFocus?: boolean
16
15
  calendarRange: DateRange | undefined
@@ -18,7 +17,7 @@ type Props = {
18
17
  disableCalendarDates?: DisableCalendarDates
19
18
  selectedPath?: string
20
19
  language?: string
21
- filtersRef?: React.RefObject<HTMLDivElement>
20
+ filtersRef?: RefObject<HTMLDivElement>
22
21
  }
23
22
 
24
23
  export const Dates = forwardRef<HTMLDivElement, Props>(
@@ -18,7 +18,16 @@ type Props = {
18
18
  }
19
19
 
20
20
  export const Guests = forwardRef<HTMLDivElement, Props>(
21
- ({ ageCategories, updateGuestsCount, ageCategoryCounts, autoFocus, onClose }: Props, ref) => {
21
+ (
22
+ {
23
+ ageCategories,
24
+ updateGuestsCount,
25
+ ageCategoryCounts,
26
+ autoFocus,
27
+ onClose,
28
+ }: Props,
29
+ ref
30
+ ) => {
22
31
  const { t } = useTranslation('filterBar')
23
32
  const containerRef = useAutoFocus<HTMLDivElement>(autoFocus)
24
33
 
@@ -18,8 +18,6 @@ export const calculateDropdownPosition = ({
18
18
  guestsButtonRef,
19
19
  isMobile,
20
20
  }: CalculateDropdownPositionParams): CSSProperties => {
21
- // On mobile, don't apply any positioning - let CSS handle it naturally
22
- // Dropdowns will start from leftmost point with position: relative
23
21
  if (isMobile) {
24
22
  return {}
25
23
  }
@@ -31,7 +29,6 @@ export const calculateDropdownPosition = ({
31
29
 
32
30
  switch (filterSection) {
33
31
  case FilterSections.LOCATIONS:
34
- // Locations: Start from beginning, hug content
35
32
  if (locationsButtonRef.current) {
36
33
  const buttonRect = locationsButtonRef.current.getBoundingClientRect()
37
34
  const relativeLeft = buttonRect.left - containerRect.left
@@ -44,8 +41,6 @@ export const calculateDropdownPosition = ({
44
41
  break
45
42
 
46
43
  case FilterSections.CALENDAR:
47
- // Calendar: Two months side-by-side, needs ~650-700px
48
- // Start from dates button, but push left if not enough space
49
44
  if (datesButtonRef.current) {
50
45
  const buttonRect = datesButtonRef.current.getBoundingClientRect()
51
46
  const relativeLeft = buttonRect.left - containerRect.left
@@ -53,7 +48,6 @@ export const calculateDropdownPosition = ({
53
48
  const calendarMinWidth = 650
54
49
 
55
50
  if (availableWidth < calendarMinWidth) {
56
- // Not enough space, align to the right edge
57
51
  return {
58
52
  left: 'auto',
59
53
  right: containerLeft,
@@ -61,7 +55,6 @@ export const calculateDropdownPosition = ({
61
55
  maxWidth: `${containerRect.width}px`,
62
56
  }
63
57
  } else {
64
- // Enough space, start from dates button
65
58
  return {
66
59
  left: relativeLeft,
67
60
  right: 'auto',
@@ -72,7 +65,6 @@ export const calculateDropdownPosition = ({
72
65
  break
73
66
 
74
67
  case FilterSections.GUESTS:
75
- // Guests: Start from guests button, push left if not enough space
76
68
  if (guestsButtonRef.current) {
77
69
  const buttonRect = guestsButtonRef.current.getBoundingClientRect()
78
70
  const relativeLeft = buttonRect.left - containerRect.left
@@ -80,7 +72,6 @@ export const calculateDropdownPosition = ({
80
72
  const dropdownMinWidth = 350
81
73
 
82
74
  if (availableWidth < dropdownMinWidth) {
83
- // Not enough space, align to the right
84
75
  return {
85
76
  left: 'auto',
86
77
  right: containerLeft,
@@ -88,7 +79,6 @@ export const calculateDropdownPosition = ({
88
79
  maxWidth: `${containerRect.width}px`,
89
80
  }
90
81
  } else {
91
- // Enough space, start from button
92
82
  return {
93
83
  left: relativeLeft,
94
84
  right: 'auto',
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react'
1
+ import { useState } from 'react'
2
2
  import type { Meta, StoryObj } from '@storybook/react'
3
3
 
4
4
  import FilterCalendar from './FilterCalendar'
@@ -1,5 +1,6 @@
1
+ import React from 'react'
1
2
  import { FaSpinner } from 'react-icons/fa'
2
- import React, { ReactNode } from 'react'
3
+ import { ReactNode } from 'react'
3
4
 
4
5
  import './SubmitButton.css'
5
6
 
@@ -147,8 +147,8 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
147
147
  const base = disabledDatesByPage.length
148
148
  ? disabledDatesByPage
149
149
  : disabledDates?.length
150
- ? disabledDates
151
- : newDisableCalendarDates?.disabledDates || []
150
+ ? disabledDates
151
+ : newDisableCalendarDates?.disabledDates || []
152
152
 
153
153
  const disabled = disabledDatesByPage.length
154
154
  ? base
@@ -162,7 +162,10 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
162
162
 
163
163
  return (
164
164
  <div className="will-filter-bar-calendar" ref={ref}>
165
- <div className="will-calendar-filter-container" ref={calendarContainerRef}>
165
+ <div
166
+ className="will-calendar-filter-container"
167
+ ref={calendarContainerRef}
168
+ >
166
169
  <DayPicker
167
170
  key={updateCalendarDefaultMonth}
168
171
  id="will-calendar"
@@ -1,27 +1,28 @@
1
- import React from 'react';
2
- import './button.css';
1
+ import React from 'react'
2
+
3
+ import './button.css'
3
4
 
4
5
  interface ButtonProps {
5
6
  /**
6
7
  * Is this the principal call to action on the page?
7
8
  */
8
- primary?: boolean;
9
+ primary?: boolean
9
10
  /**
10
11
  * What background color to use
11
12
  */
12
- backgroundColor?: string;
13
+ backgroundColor?: string
13
14
  /**
14
15
  * How large should the button be?
15
16
  */
16
- size?: 'small' | 'medium' | 'large';
17
+ size?: 'small' | 'medium' | 'large'
17
18
  /**
18
19
  * Button contents
19
20
  */
20
- label: string;
21
+ label: string
21
22
  /**
22
23
  * Optional click handler
23
24
  */
24
- onClick?: () => void;
25
+ onClick?: () => void
25
26
  }
26
27
 
27
28
  /**
@@ -34,15 +35,19 @@ export const Button = ({
34
35
  label,
35
36
  ...props
36
37
  }: ButtonProps) => {
37
- const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
38
+ const mode = primary
39
+ ? 'storybook-button--primary'
40
+ : 'storybook-button--secondary'
38
41
  return (
39
42
  <button
40
43
  type="button"
41
- className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
44
+ className={['storybook-button', `storybook-button--${size}`, mode].join(
45
+ ' '
46
+ )}
42
47
  style={{ backgroundColor }}
43
48
  {...props}
44
49
  >
45
50
  {label}
46
51
  </button>
47
- );
48
- };
52
+ )
53
+ }
@@ -1,24 +1,33 @@
1
- import React from 'react';
2
-
3
- import { Button } from './Button';
4
- import './header.css';
1
+ import React from 'react'
2
+ import { Button } from './Button'
3
+ import './header.css'
5
4
 
6
5
  type User = {
7
- name: string;
8
- };
6
+ name: string
7
+ }
9
8
 
10
9
  interface HeaderProps {
11
- user?: User;
12
- onLogin: () => void;
13
- onLogout: () => void;
14
- onCreateAccount: () => void;
10
+ user?: User
11
+ onLogin: () => void
12
+ onLogout: () => void
13
+ onCreateAccount: () => void
15
14
  }
16
15
 
17
- export const Header = ({ user, onLogin, onLogout, onCreateAccount }: HeaderProps) => (
16
+ export const Header = ({
17
+ user,
18
+ onLogin,
19
+ onLogout,
20
+ onCreateAccount,
21
+ }: HeaderProps) => (
18
22
  <header>
19
23
  <div className="storybook-header">
20
24
  <div>
21
- <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
25
+ <svg
26
+ width="32"
27
+ height="32"
28
+ viewBox="0 0 32 32"
29
+ xmlns="http://www.w3.org/2000/svg"
30
+ >
22
31
  <g fill="none" fillRule="evenodd">
23
32
  <path
24
33
  d="M10 0h12a10 10 0 0110 10v12a10 10 0 01-10 10H10A10 10 0 010 22V10A10 10 0 0110 0z"
@@ -47,10 +56,15 @@ export const Header = ({ user, onLogin, onLogout, onCreateAccount }: HeaderProps
47
56
  ) : (
48
57
  <>
49
58
  <Button size="small" onClick={onLogin} label="Log in" />
50
- <Button primary size="small" onClick={onCreateAccount} label="Sign up" />
59
+ <Button
60
+ primary
61
+ size="small"
62
+ onClick={onCreateAccount}
63
+ label="Sign up"
64
+ />
51
65
  </>
52
66
  )}
53
67
  </div>
54
68
  </div>
55
69
  </header>
56
- );
70
+ )
package/stories/Page.tsx CHANGED
@@ -1,14 +1,14 @@
1
- import React from 'react';
1
+ import React, { FC, useState } from 'react'
2
2
 
3
- import { Header } from './Header';
4
- import './page.css';
3
+ import { Header } from './Header'
4
+ import './page.css'
5
5
 
6
6
  type User = {
7
- name: string;
8
- };
7
+ name: string
8
+ }
9
9
 
10
- export const Page: React.FC = () => {
11
- const [user, setUser] = React.useState<User>();
10
+ export const Page: FC = () => {
11
+ const [user, setUser] = useState<User>()
12
12
 
13
13
  return (
14
14
  <article>
@@ -23,40 +23,58 @@ export const Page: React.FC = () => {
23
23
  <h2>Pages in Storybook</h2>
24
24
  <p>
25
25
  We recommend building UIs with a{' '}
26
- <a href="https://componentdriven.org" target="_blank" rel="noopener noreferrer">
26
+ <a
27
+ href="https://componentdriven.org"
28
+ target="_blank"
29
+ rel="noopener noreferrer"
30
+ >
27
31
  <strong>component-driven</strong>
28
32
  </a>{' '}
29
33
  process starting with atomic components and ending with pages.
30
34
  </p>
31
35
  <p>
32
- Render pages with mock data. This makes it easy to build and review page states without
33
- needing to navigate to them in your app. Here are some handy patterns for managing page
34
- data in Storybook:
36
+ Render pages with mock data. This makes it easy to build and review
37
+ page states without needing to navigate to them in your app. Here are
38
+ some handy patterns for managing page data in Storybook:
35
39
  </p>
36
40
  <ul>
37
41
  <li>
38
- Use a higher-level connected component. Storybook helps you compose such data from the
39
- "args" of child component stories
42
+ Use a higher-level connected component. Storybook helps you compose
43
+ such data from the "args" of child component stories
40
44
  </li>
41
45
  <li>
42
- Assemble data in the page component from your services. You can mock these services out
43
- using Storybook.
46
+ Assemble data in the page component from your services. You can mock
47
+ these services out using Storybook.
44
48
  </li>
45
49
  </ul>
46
50
  <p>
47
51
  Get a guided tutorial on component-driven development at{' '}
48
- <a href="https://storybook.js.org/tutorials/" target="_blank" rel="noopener noreferrer">
52
+ <a
53
+ href="https://storybook.js.org/tutorials/"
54
+ target="_blank"
55
+ rel="noopener noreferrer"
56
+ >
49
57
  Storybook tutorials
50
58
  </a>
51
59
  . Read more in the{' '}
52
- <a href="https://storybook.js.org/docs" target="_blank" rel="noopener noreferrer">
60
+ <a
61
+ href="https://storybook.js.org/docs"
62
+ target="_blank"
63
+ rel="noopener noreferrer"
64
+ >
53
65
  docs
54
66
  </a>
55
67
  .
56
68
  </p>
57
69
  <div className="tip-wrapper">
58
- <span className="tip">Tip</span> Adjust the width of the canvas with the{' '}
59
- <svg width="10" height="10" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
70
+ <span className="tip">Tip</span> Adjust the width of the canvas with
71
+ the{' '}
72
+ <svg
73
+ width="10"
74
+ height="10"
75
+ viewBox="0 0 12 12"
76
+ xmlns="http://www.w3.org/2000/svg"
77
+ >
60
78
  <g fill="none" fillRule="evenodd">
61
79
  <path
62
80
  d="M1.5 5.2h4.8c.3 0 .5.2.5.4v5.1c-.1.2-.3.3-.4.3H1.4a.5.5 0 01-.5-.4V5.7c0-.3.2-.5.5-.5zm0-2.1h6.9c.3 0 .5.2.5.4v7a.5.5 0 01-1 0V4H1.5a.5.5 0 010-1zm0-2.1h9c.3 0 .5.2.5.4v9.1a.5.5 0 01-1 0V2H1.5a.5.5 0 010-1zm4.3 5.2H2V10h3.8V6.2z"
@@ -69,5 +87,5 @@ export const Page: React.FC = () => {
69
87
  </div>
70
88
  </section>
71
89
  </article>
72
- );
73
- };
90
+ )
91
+ }