diff --git a/.changeset/brave-eagles-teach.md b/.changeset/brave-eagles-teach.md new file mode 100644 index 0000000000..3124b95815 --- /dev/null +++ b/.changeset/brave-eagles-teach.md @@ -0,0 +1,24 @@ +--- +'braid-design-system': major +--- + +--- +updated: + - Stack +--- + +**Stack:** Consumers need to render `li` elements + +When setting `component` to `ul` or `ol` on a `Stack`, consumers need to ensure they render children as `li` elements. +Previously Braid owned an intermediate HTML element, ensuring it was an `li` when required. +Moving to CSS gap means child elements are no longer being wrapped, requiring consumers to update their child elements to the correct HTML element, e.g. `li`. + +**MIGRATION GUIDE:** +```diff + +- Item 1 ++ Item 1 +- Item 2 ++ Item 2 + +``` diff --git a/.changeset/brown-socks-talk.md b/.changeset/brown-socks-talk.md new file mode 100644 index 0000000000..39868f301c --- /dev/null +++ b/.changeset/brown-socks-talk.md @@ -0,0 +1,23 @@ +--- +'braid-design-system': major +--- + +--- +updated: + - Autosuggest +--- + +**Autosuggest:** Remove deprecated message syntax from `suggestions` prop + +Remove the deprecated message syntax from the `suggestions` prop in favour of the `noSuggestionsMessage` prop. + +### MIGRATION GUIDE: + +```diff + +``` diff --git a/.changeset/curvy-countries-grab.md b/.changeset/curvy-countries-grab.md new file mode 100644 index 0000000000..29c84eb86f --- /dev/null +++ b/.changeset/curvy-countries-grab.md @@ -0,0 +1,22 @@ +--- +'braid-design-system': major +--- + +--- +updated: + - Text + - Heading +--- + +**Text, Heading:** Remove deprecated `truncate` prop + +Remove the deprecated `truncate` prop in favour of the `maxLines` prop which accepts a number of lines to truncate the text to. + +### MIGRATION GUIDE: + +```diff + +``` diff --git a/.changeset/empty-numbers-live.md b/.changeset/empty-numbers-live.md new file mode 100644 index 0000000000..536af0a098 --- /dev/null +++ b/.changeset/empty-numbers-live.md @@ -0,0 +1,101 @@ +--- +'braid-design-system': major +--- + +--- +updated: + - Stack + - Tiles +--- + +**Stack, Tiles:** Remove `divider` support + +As part of migrating our layout components to leverage flex gap, the `Stack` & `Tiles` components no longer iterate over their children, making `dividers` no longer feasible to implement centrally. + +While we could have exposed an API to apply this behaviour conditionally, there are edge cases that cannot be handled correctly without consumer-side rendering logic, such as when child components render nothing or a hidden element. + +### MIGRATION GUIDE: +For `Stack`s with static children you can manually interleave `Divider` components: +```diff +- ++ + ++ + ++ + + +``` + +Or for conditionally rendering children you can return a [React Fragment], including the `Divider` and child: +```diff +- ++ + + {condition ? ( +- ++ <> ++ ++ ++ + ) : null} + +``` + +For `Stack`s with iterable children you can return a [React Fragment] and conditionally render the `Divider` component as the first child, before each item (except the first): +```diff +- ++ + {items.map((item, index) => ( +- {item} ++ ++ {index > 0 ? : null} ++ {item} ++ + ))} + +``` + +For `Tiles` the `dividers` prop was only applied when showing a single column. + +For this you can conditionally render the `Divider` in a `Stack` with the same spacing as specified on the `Tiles` instance, and hide it on breakpoints showing more than one column. + +Here is an example of this with static children: + +```diff +- ++ + {item} ++ ++ ++ ++ + {item} ++ ++ ++ ++ ++ + {item} ++ + +``` + +Here is an example of this with iterable children: + +```diff +- ++ + {items.map((item, index) => ( +- {item} ++ ++ {index > 0 ? ( ++ ++ ++ ++ ) : null} + {item} ++ + ))} + +``` diff --git a/.changeset/fresh-pots-bathe.md b/.changeset/fresh-pots-bathe.md new file mode 100644 index 0000000000..cfd7ea92bf --- /dev/null +++ b/.changeset/fresh-pots-bathe.md @@ -0,0 +1,26 @@ +--- +'braid-design-system': major +--- + +--- +updated: + - Button + - ButtonLink +--- + +**Button, ButtonLink:** Remove deprecated `bleedY` prop + +Remove the deprecated `bleedY` prop from the `Button` and `ButtonLink` components. +Consumers should use the `bleed` prop instead, which bleeds based on the selected `variant`. + +### MIGRATION GUIDE: + +```diff + +``` diff --git a/.changeset/large-turkeys-wait.md b/.changeset/large-turkeys-wait.md new file mode 100644 index 0000000000..5821189fae --- /dev/null +++ b/.changeset/large-turkeys-wait.md @@ -0,0 +1,22 @@ +--- +'braid-design-system': major +--- + +--- +updated: + - ButtonIcon +--- + +**ButtonIcon:** Remove deprecated `secondary` tone + +Remove the deprecated `secondary` tone from `ButtonIcon` in favour of providing the `tone` directly to the `Icon` itself. + +### MIGRATION GUIDE: + +```diff + } ++ icon={} + /> +``` diff --git a/.changeset/pink-carrots-switch.md b/.changeset/pink-carrots-switch.md new file mode 100644 index 0000000000..167ecbf16e --- /dev/null +++ b/.changeset/pink-carrots-switch.md @@ -0,0 +1,17 @@ +--- +'braid-design-system': major +--- + +--- +updated: + - useBreakpoint +--- + +**useBreakpoint:** Remove deprecated Hook + +This Hook has been deprecated since [v30.1.0] in favour of `useResponsiveValue`, to prevent consumers from inadvertently coupling themselves to the current set of breakpoints, making it risky for us to introduce new breakpoints. + +See the [migration guide] for more information. + +[v30.1.0]: https://seek-oss.github.io/braid-design-system/components/useBreakpoint/releases/#v30.1.0 +[migration guide]: https://seek-oss.github.io/braid-design-system/components/useBreakpoint/releases/#v30.1.0 diff --git a/.changeset/plenty-dancers-serve.md b/.changeset/plenty-dancers-serve.md new file mode 100644 index 0000000000..3baff7db3a --- /dev/null +++ b/.changeset/plenty-dancers-serve.md @@ -0,0 +1,22 @@ +--- +'braid-design-system': major +--- + +--- +updated: + - Rating +--- + +**Rating:** Remove deprecated `showTextRating` prop + +Remove the deprecated `showTextRating` prop in favour of `variant="starsOnly"`. + +### MIGRATION GUIDE: + +```diff + +``` diff --git a/.changeset/tasty-weeks-search.md b/.changeset/tasty-weeks-search.md new file mode 100644 index 0000000000..8d7816ada8 --- /dev/null +++ b/.changeset/tasty-weeks-search.md @@ -0,0 +1,13 @@ +--- +'braid-design-system': minor +--- + +--- +updated: + - Stack +--- + +**Stack:** Widen `component` support + +With `Stack` no longer adding intermediary elements, the `component` prop can now accept a wider range of elements. +Valid options are kept to a white list of elements relevant to `Stack` that do not require other HTML attributes, keeping in mind that props are not blindly spread in Braid. diff --git a/.changeset/three-squids-explode.md b/.changeset/three-squids-explode.md new file mode 100644 index 0000000000..2355d9393b --- /dev/null +++ b/.changeset/three-squids-explode.md @@ -0,0 +1,12 @@ +--- +'braid-design-system': major +--- + +--- +updated: + - Spread +--- + +**Spread:** Narrow `component` options to valid layout elements + +Not all HTML elements make sense to be a layout container, e.g. `input`, so scoping the `component` prop to only surface relevant element types. diff --git a/.changeset/tough-kangaroos-sell.md b/.changeset/tough-kangaroos-sell.md new file mode 100644 index 0000000000..d249145148 --- /dev/null +++ b/.changeset/tough-kangaroos-sell.md @@ -0,0 +1,24 @@ +--- +'braid-design-system': minor +--- + +--- +new: + - Box + - atoms +--- + +**Box, atoms:** Add responsive `gap` support + +Add the `gap` property to the available styling atoms, inclusive of responsive spacing values. + +**EXAMPLE USAGE:** +```jsx + +``` + +```jsx +import { atoms } from 'braid-design-system/css'; + +atoms({ gap: 'small' }); +``` diff --git a/.changeset/tricky-penguins-search.md b/.changeset/tricky-penguins-search.md new file mode 100644 index 0000000000..69b7ee1541 --- /dev/null +++ b/.changeset/tricky-penguins-search.md @@ -0,0 +1,17 @@ +--- +'braid-design-system': major +--- + +--- +updated: + - Stack +--- + +Migrate to CSS `gap` internally. + +With the browser support policy now enabling adoption of CSS [gap], Braid’s layout components are now able to lean into the platform directly for its declarative, parent-driven approach to white space management. + +Previously to enable gap-like behaviour, layout components iterated over their children wrapping them in container elements that applied padding. +The trade off of this technique was increased number of DOM elements and the introduction of unwanted space if the child element was hidden or returned `null`, requiring developers to hoist logic to the parent component. + +[gap]: https://developer.mozilla.org/en-US/docs/Web/CSS/gap diff --git a/packages/braid-design-system/src/lib/components/Accordion/Accordion.tsx b/packages/braid-design-system/src/lib/components/Accordion/Accordion.tsx index 6e5c4d18a6..f1ff900cd9 100644 --- a/packages/braid-design-system/src/lib/components/Accordion/Accordion.tsx +++ b/packages/braid-design-system/src/lib/components/Accordion/Accordion.tsx @@ -1,5 +1,5 @@ import assert from 'assert'; -import React, { useMemo } from 'react'; +import React, { Children, useMemo } from 'react'; import type { ReactNodeNoStrings } from '../private/ReactNodeNoStrings'; import { type RequiredResponsiveValue, @@ -8,7 +8,6 @@ import { import buildDataAttributes, { type DataAttributeMap, } from '../private/buildDataAttributes'; -import { Box } from '../Box/Box'; import { Stack } from '../Stack/Stack'; import { Divider } from '../Divider/Divider'; import { @@ -16,6 +15,7 @@ import { AccordionContext, validTones, } from './AccordionContext'; +import flattenChildren from '../../utils/flattenChildren'; export const validSpaceValues = ['medium', 'large', 'xlarge'] as const; @@ -81,21 +81,29 @@ export const Accordion = ({ return ( - {!dividers ? ( - - {children} - - ) : ( - - - - - {children} - - - - - )} + + {!dividers ? ( + children + ) : ( + <> + + {Children.map(flattenChildren(children), (child, index) => ( + <> + {index > 0 ? ( + + ) : null} + {child} + + ))} + + + )} + ); }; diff --git a/packages/braid-design-system/src/lib/components/Autosuggest/Autosuggest.test.tsx b/packages/braid-design-system/src/lib/components/Autosuggest/Autosuggest.test.tsx index 6c1099e997..05de11feb5 100644 --- a/packages/braid-design-system/src/lib/components/Autosuggest/Autosuggest.test.tsx +++ b/packages/braid-design-system/src/lib/components/Autosuggest/Autosuggest.test.tsx @@ -894,42 +894,6 @@ describe('Autosuggest', () => { expect(getAnnouncements()).toBeNull(); }); - it('should support legacy no results messages via `suggestions`', async () => { - // Hide deprecation warning from test log - jest.spyOn(console, 'warn').mockImplementation(() => {}); - - const TestCase = () => ( - - {}} - hideSuggestionsOnSelection={false} - suggestions={{ message: 'Legacy no suggestions message' }} - /> - - ); - - const { getByRole, queryByRole } = render(); - expect(queryByRole('listitem')).not.toBeInTheDocument(); - expect(getAnnouncements()).toBeNull(); - - const input = getByRole('combobox'); - await userEvent.click(input); - expect(queryByRole('listitem')).toHaveTextContent( - 'Legacy no suggestions message', - ); - expect(getAnnouncements()).toBe('Legacy no suggestions message'); - - fireEvent.blur(input); - expect(queryByRole('listitem')).not.toBeInTheDocument(); - expect(getAnnouncements()).toBeNull(); - - // Restore console warnings - jest.spyOn(console, 'warn').mockRestore(); - }); - it('should not show `noSuggestionsMessage` when suggestions are provided', async () => { const TestCase = () => ( diff --git a/packages/braid-design-system/src/lib/components/Autosuggest/Autosuggest.tsx b/packages/braid-design-system/src/lib/components/Autosuggest/Autosuggest.tsx index 093de4a36d..4cea86a6bf 100644 --- a/packages/braid-design-system/src/lib/components/Autosuggest/Autosuggest.tsx +++ b/packages/braid-design-system/src/lib/components/Autosuggest/Autosuggest.tsx @@ -271,12 +271,6 @@ const noop = () => { const fallbackValue = { text: '' }; const fallbackSuggestions: Suggestion[] = []; -/** @deprecated Use `noSuggestionsMessage` prop instead */ -interface LegacyMessageSuggestion { - /** @deprecated Use `noSuggestionsMessage` prop instead */ - message: string; -} - type HighlightOptions = 'matching' | 'remaining'; export type AutosuggestBaseProps = Omit< @@ -286,10 +280,7 @@ export type AutosuggestBaseProps = Omit< value: AutosuggestValue; suggestions: | Suggestions - | LegacyMessageSuggestion - | (( - value: AutosuggestValue, - ) => Suggestions | LegacyMessageSuggestion); + | ((value: AutosuggestValue) => Suggestions); noSuggestionsMessage?: string | { title: string; description: string }; onChange: (value: AutosuggestValue) => void; clearLabel?: string; @@ -311,33 +302,10 @@ export type AutosuggestProps = AutosuggestBaseProps & function normaliseNoSuggestionMessage( noSuggestionsMessage: AutosuggestBaseProps['noSuggestionsMessage'], - suggestionProp: AutosuggestBaseProps['suggestions'], ): { title?: string; description: string } | undefined { - if (noSuggestionsMessage) { - return typeof noSuggestionsMessage === 'string' - ? { description: noSuggestionsMessage } - : noSuggestionsMessage; - } - - if ('message' in suggestionProp) { - const message = suggestionProp.message; - if (process.env.NODE_ENV !== 'production') { - // eslint-disable-next-line no-console - console.warn( - dedent` - Passing \`message\` to \`suggestions\` is deprecated and will be removed in a future version. Use "noSuggestionsMessage" instead. See the documentation for usage: https://seek-oss.github.io/braid-design-system/components/Autosuggest#messaging-when-no-suggestions-are-available - - `, - 'color: red', - 'color: green', - 'color: inherit', - ); - } - return { description: message }; - } + return typeof noSuggestionsMessage === 'string' + ? { description: noSuggestionsMessage } + : noSuggestionsMessage; } export function highlightSuggestions( @@ -387,7 +355,6 @@ export const Autosuggest = forwardRef(function ( : []; const noSuggestionsMessage = normaliseNoSuggestionMessage( noSuggestionsMessageProp, - suggestionsPropValue, ); const hasItems = suggestions.length > 0 || Boolean(noSuggestionsMessage); diff --git a/packages/braid-design-system/src/lib/components/Button/Button.screenshots.tsx b/packages/braid-design-system/src/lib/components/Button/Button.screenshots.tsx index 206d7eab7a..0cdc2c340d 100644 --- a/packages/braid-design-system/src/lib/components/Button/Button.screenshots.tsx +++ b/packages/braid-design-system/src/lib/components/Button/Button.screenshots.tsx @@ -175,22 +175,6 @@ export const screenshots: ComponentScreenshot = { ), }, - { - label: 'With legacy bleedY (transparent)', - background: 'surface', - Example: () => ( - - - Heading - - - - - - ), - }, { label: 'With full bleed (transparent)', background: 'surface', diff --git a/packages/braid-design-system/src/lib/components/Button/Button.tsx b/packages/braid-design-system/src/lib/components/Button/Button.tsx index 6e61e4b762..6c496afb05 100644 --- a/packages/braid-design-system/src/lib/components/Button/Button.tsx +++ b/packages/braid-design-system/src/lib/components/Button/Button.tsx @@ -1,5 +1,4 @@ import assert from 'assert'; -import dedent from 'dedent'; import React, { type ReactNode, type AllHTMLAttributes, @@ -42,8 +41,6 @@ export interface ButtonStyleProps { size?: ButtonSize; tone?: ButtonTone; variant?: ButtonVariant; - /** @deprecated Use `bleed` prop instead https://seek-oss.github.io/braid-design-system/components/Button#bleed */ - bleedY?: boolean; bleed?: boolean; loading?: boolean; } @@ -491,7 +488,6 @@ export const Button = forwardRef( tone, icon, iconPosition, - bleedY, bleed, variant, loading, @@ -509,68 +505,48 @@ export const Button = forwardRef( ...restProps }, ref, - ) => { - if (process.env.NODE_ENV !== 'production') { - if (typeof bleedY !== 'undefined') { - // eslint-disable-next-line no-console - console.warn( - dedent` - The "bleedY" prop has been deprecated and will be removed in a future version. Use "bleed" instead. -