@newhighsco/chipset 6.17.6 → 6.19.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,7 +1,7 @@
1
1
  {
2
2
  "name": "@newhighsco/chipset",
3
3
  "description": "Shareable, theme-able component library by New High Score",
4
- "version": "6.17.6",
4
+ "version": "6.19.0",
5
5
  "author": "New High Score",
6
6
  "license": "ISC",
7
7
  "repository": {
@@ -28,6 +28,7 @@
28
28
  "test": "jest --runInBand",
29
29
  "test:list": "jest --listTests",
30
30
  "snapshot": "chromatic --storybook-build-dir build --auto-accept-changes main --exit-once-uploaded --only-changed",
31
+ "analyze": "omlet analyze",
31
32
  "lint": "concurrently yarn:lint:*",
32
33
  "lint:js": "eslint --cache --ignore-path .gitignore .",
33
34
  "lint:css": "stylelint --cache --ignore-path .gitignore '**/*.?(s)css'",
@@ -41,27 +42,28 @@
41
42
  "react-device-detect": "2.2.3"
42
43
  },
43
44
  "devDependencies": {
44
- "@babel/core": "7.28.0",
45
- "@babel/preset-env": "7.28.0",
45
+ "@babel/core": "7.28.3",
46
+ "@babel/preset-env": "7.28.3",
46
47
  "@babel/preset-react": "7.27.1",
47
48
  "@commitlint/cli": "19.8.1",
48
49
  "@fullhuman/postcss-purgecss": "7.0.2",
49
50
  "@newhighsco/browserslist-config": "2.0.0",
50
51
  "@newhighsco/commitlint-config": "1.1.46",
51
52
  "@newhighsco/editor-config": "1.2.0",
52
- "@newhighsco/eslint-config": "4.1.40",
53
- "@newhighsco/postcss-config": "3.5.339",
53
+ "@newhighsco/eslint-config": "4.1.44",
54
+ "@newhighsco/postcss-config": "3.5.343",
54
55
  "@newhighsco/prettier-config": "2.1.32",
55
- "@newhighsco/release-config": "1.4.6",
56
- "@newhighsco/storybook-preset": "7.0.145",
56
+ "@newhighsco/release-config": "1.4.7",
57
+ "@newhighsco/storybook-preset": "7.1.1",
57
58
  "@newhighsco/stylelint-config": "4.0.17",
59
+ "@omlet/cli": "2.0.0",
58
60
  "@storybook/react-webpack5": "8.6.14",
59
- "@testing-library/dom": "10.4.0",
60
- "@testing-library/jest-dom": "6.6.3",
61
+ "@testing-library/dom": "10.4.1",
62
+ "@testing-library/jest-dom": "6.7.0",
61
63
  "@testing-library/react": "16.3.0",
62
64
  "babel-loader": "10.0.0",
63
- "chromatic": "13.1.2",
64
- "concurrently": "9.2.0",
65
+ "chromatic": "13.1.3",
66
+ "concurrently": "9.2.1",
65
67
  "eslint": "8.57.1",
66
68
  "husky": "9.1.7",
67
69
  "identity-obj-proxy": "3.0.0",
@@ -70,17 +72,17 @@
70
72
  "jest-junit": "16.0.0",
71
73
  "postcss": "8.5.6",
72
74
  "prettier": "3.6.2",
73
- "react": "19.1.0",
74
- "react-dom": "19.1.0",
75
+ "react": "19.1.1",
76
+ "react-dom": "19.1.1",
75
77
  "sass-true": "9.0.0",
76
78
  "semantic-release": "24.2.7",
77
79
  "storybook": "8.6.14",
78
- "stylelint": "16.22.0",
79
- "webpack": "5.100.2"
80
+ "stylelint": "16.23.1",
81
+ "webpack": "5.101.3"
80
82
  },
81
83
  "peerDependencies": {
82
- "react": "19.1.0",
83
- "react-dom": "19.1.0"
84
+ "react": "19.1.1",
85
+ "react-dom": "19.1.1"
84
86
  },
85
87
  "browserslist": [
86
88
  "extends @newhighsco/browserslist-config"
@@ -95,6 +97,14 @@
95
97
  "@newhighsco/eslint-config"
96
98
  ]
97
99
  },
100
+ "omlet": {
101
+ "exports": {
102
+ ".": "src/index.js"
103
+ },
104
+ "ignore": [
105
+ "example/**"
106
+ ]
107
+ },
98
108
  "prettier": "@newhighsco/prettier-config",
99
109
  "release": {
100
110
  "extends": "@newhighsco/release-config",
@@ -1,7 +1,7 @@
1
- import classNames from 'classnames'
2
1
  import { node, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
5
  import Element from '../Element'
6
6
  import styles from './Backdrop.module.scss'
7
7
 
@@ -1,7 +1,7 @@
1
- import classNames from 'classnames'
2
1
  import { bool, func, node, object, oneOfType, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
5
  import SmartLink from '../SmartLink'
6
6
 
7
7
  const Button = ({ active, children, theme, className, setRef, ...rest }) => {
@@ -1,7 +1,8 @@
1
- import classNames from 'classnames'
2
1
  import { node, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
+
5
6
  const ButtonGroup = ({ children, theme, className }) => {
6
7
  if (!children) return null
7
8
 
@@ -1,4 +1,3 @@
1
- import classNames from 'classnames'
2
1
  import {
3
2
  func,
4
3
  node,
@@ -10,6 +9,7 @@ import {
10
9
  } from 'prop-types'
11
10
  import React from 'react'
12
11
 
12
+ import { classNames } from '../../utils'
13
13
  import CardHeading from './CardHeading'
14
14
  import CardImage from './CardImage'
15
15
 
@@ -1,7 +1,7 @@
1
- import classNames from 'classnames'
2
1
  import { bool, node, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
5
  import Element from '../Element'
6
6
 
7
7
  /**
@@ -1,6 +1,7 @@
1
1
  import { oneOf, shape, string } from 'prop-types'
2
2
  import React from 'react'
3
3
 
4
+ import { classNames } from '../../utils'
4
5
  import Icon from '../Icon'
5
6
  import SmartLink from '../SmartLink'
6
7
  import { ReactComponent as LogoSvg } from './images/logo.svg'
@@ -13,8 +14,8 @@ const href = 'http://newhighsco.re'
13
14
  /**
14
15
  * The `CreditLockup` provides a link to the New High Score website
15
16
  */
16
- const CreditLockup = ({ theme, ...rest }) => (
17
- <span className={theme?.root} {...rest}>
17
+ const CreditLockup = ({ theme, className, ...rest }) => (
18
+ <span className={classNames(theme?.root, className)} {...rest}>
18
19
  <SmartLink
19
20
  className={theme?.link}
20
21
  href={href}
@@ -38,7 +39,8 @@ CreditLockup.displayName = 'CreditLockup'
38
39
  CreditLockup.propTypes = {
39
40
  align: oneOf(['left', 'right', 'center']),
40
41
  dir: oneOf(['ltr', 'rtl']),
41
- theme: shape({ root: string, link: string, logo: string, text: string })
42
+ theme: shape({ root: string, link: string, logo: string, text: string }),
43
+ className: string
42
44
  }
43
45
 
44
46
  export default CreditLockup
@@ -1,7 +1,8 @@
1
- import classNames from 'classnames'
2
1
  import { bool, node, oneOf, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
+
5
6
  /**
6
7
  * `Grid` provides a simple `inline-block` based responsive grid
7
8
  */
@@ -1,7 +1,8 @@
1
- import classNames from 'classnames'
2
1
  import { arrayOf, node, oneOf, oneOfType, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
+
5
6
  const GridItem = ({ sizes, children, theme, className, ...rest }) => {
6
7
  if (!children) return null
7
8
 
@@ -1,7 +1,7 @@
1
- import classNames from 'classnames'
2
1
  import { node, number, oneOfType, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
5
  import VisuallyHidden from '../VisuallyHidden'
6
6
 
7
7
  /**
@@ -8,13 +8,9 @@ import styles from './Landmark.module.scss'
8
8
  * Use `Landmark` to create visually hidden anchors
9
9
  */
10
10
  const Landmark = ({ children, ...rest }) => (
11
- <>
12
- {/* eslint-disable jsx-a11y/anchor-is-valid */}
13
- <a className={styles.root} {...rest}>
14
- <VisuallyHidden>{children}</VisuallyHidden>
15
- </a>
16
- {/* eslint-enable jsx-a11y/anchor-is-valid */}
17
- </>
11
+ <a className={styles.root} {...rest}>
12
+ <VisuallyHidden>{children}</VisuallyHidden>
13
+ </a>
18
14
  )
19
15
 
20
16
  Landmark.propTypes = {
@@ -1,7 +1,7 @@
1
- import classNames from 'classnames'
2
1
  import { bool, node, oneOf, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
5
  import Element from '../Element'
6
6
 
7
7
  const List = ({
@@ -1,7 +1,7 @@
1
- import classNames from 'classnames'
2
1
  import { bool, shape, string } from 'prop-types'
3
2
  import React, { useEffect, useState } from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
5
  import Grid from '../Grid'
6
6
  import ResponsiveMedia from '../ResponsiveMedia'
7
7
  import VisuallyHidden from '../VisuallyHidden'
@@ -1,8 +1,8 @@
1
- import classNames from 'classnames'
2
1
  import { array, bool, func, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
5
- import { useToggle } from '../../hooks'
4
+ import { useIds, useToggle } from '../../hooks'
5
+ import { classNames } from '../../utils'
6
6
  import Button from '../Button'
7
7
  import Icon from '../Icon'
8
8
  import List from '../List'
@@ -22,6 +22,7 @@ const Navigation = ({
22
22
  className
23
23
  }) => {
24
24
  const [visible, setVisibility] = useToggle(!toggle)
25
+ const [titleId, menuId] = useIds(['title', 'menu'])
25
26
 
26
27
  if (!links.length) return null
27
28
 
@@ -31,11 +32,18 @@ const Navigation = ({
31
32
  }
32
33
 
33
34
  return (
34
- <nav role="navigation" className={classNames(theme?.root, className)}>
35
- <VisuallyHidden as="h2">{title}</VisuallyHidden>
35
+ <nav
36
+ aria-labelledby={titleId}
37
+ role="navigation"
38
+ className={classNames(theme?.root, className)}
39
+ >
40
+ <VisuallyHidden as="h2" id={titleId}>
41
+ {title}
42
+ </VisuallyHidden>
36
43
  {toggle && (
37
44
  <Button
38
45
  active={visible}
46
+ aria-controls={menuId}
39
47
  aria-expanded={visible}
40
48
  onClick={toggleVisibility}
41
49
  theme={{ root: theme?.toggle, active: theme?.toggleActive }}
@@ -49,6 +57,7 @@ const Navigation = ({
49
57
  </Button>
50
58
  )}
51
59
  <List
60
+ id={menuId}
52
61
  role="menubar"
53
62
  unstyled
54
63
  inline={inline}
@@ -1,7 +1,8 @@
1
- import classNames from 'classnames'
2
1
  import { node, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
+
5
6
  const Prose = ({ html, children, theme, className, ...rest }) => {
6
7
  if (!html && !children) return null
7
8
 
@@ -1,7 +1,7 @@
1
- import classNames from 'classnames'
2
1
  import { node, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
4
+ import { classNames } from '../../utils'
5
5
  import Element from '../Element'
6
6
 
7
7
  /**
@@ -1,6 +1,7 @@
1
1
  import { bool, func, node, object, oneOf, oneOfType, string } from 'prop-types'
2
2
  import React from 'react'
3
3
 
4
+ import { useLink } from '../../providers'
4
5
  import { absoluteUrl } from '../../utils'
5
6
 
6
7
  /**
@@ -16,8 +17,24 @@ const SmartLink = ({
16
17
  className,
17
18
  ...rest
18
19
  }) => {
20
+ const renderLink = useLink()
21
+
19
22
  if (!children) return null
20
23
 
24
+ if (!href) {
25
+ return (
26
+ <button
27
+ ref={setRef}
28
+ className={className}
29
+ disabled={disabled}
30
+ type={type}
31
+ {...rest}
32
+ >
33
+ {children}
34
+ </button>
35
+ )
36
+ }
37
+
21
38
  if (disabled) {
22
39
  const { role = 'link' } = rest
23
40
 
@@ -29,14 +46,6 @@ const SmartLink = ({
29
46
  )
30
47
  }
31
48
 
32
- if (!href) {
33
- return (
34
- <button ref={setRef} className={className} type={type} {...rest}>
35
- {children}
36
- </button>
37
- )
38
- }
39
-
40
49
  if (absoluteUrl(href)) {
41
50
  return (
42
51
  <a
@@ -52,11 +61,7 @@ const SmartLink = ({
52
61
  )
53
62
  }
54
63
 
55
- return (
56
- <a ref={setRef} className={className} href={href} {...rest}>
57
- {children}
58
- </a>
59
- )
64
+ return renderLink({ ref: setRef, className, href, children, ...rest })
60
65
  }
61
66
 
62
67
  SmartLink.displayName = 'SmartLink'
@@ -1,8 +1,8 @@
1
- import classNames from 'classnames'
2
1
  import { bool, node, oneOf, shape, string } from 'prop-types'
3
2
  import React from 'react'
4
3
 
5
4
  import { useToggle } from '../../hooks'
5
+ import { classNames } from '../../utils'
6
6
  import SmartLink from '../SmartLink'
7
7
 
8
8
  /**
@@ -1,4 +1,4 @@
1
- import { Meta, Title, Unstyled } from '@storybook/blocks'
1
+ import { Meta, Title } from '@storybook/blocks'
2
2
 
3
3
  import { ReactComponent as LogoSvg } from '../../.storybook/static/logo.svg'
4
4
  import { CreditLockup, Image, SmartLink } from '../../src'
@@ -27,7 +27,5 @@ Shareable, theme-able component library
27
27
  ---
28
28
 
29
29
  <p>
30
- <Unstyled>
31
- <CreditLockup />
32
- </Unstyled>
30
+ <CreditLockup className="sb-unstyled" />
33
31
  </p>
@@ -1 +1,2 @@
1
+ export { useIds } from './use-ids'
1
2
  export { useToggle } from './use-toggle'
@@ -0,0 +1,7 @@
1
+ import { useId } from 'react'
2
+
3
+ export const useIds = (elements = []) => {
4
+ const id = useId()
5
+
6
+ return elements.map(element => [id, element].join('-'))
7
+ }
@@ -0,0 +1,28 @@
1
+ import { func, node } from 'prop-types'
2
+ import React, { createContext, useContext } from 'react'
3
+
4
+ // eslint-disable-next-line jsx-a11y/anchor-has-content
5
+ const LinkContext = createContext(props => <a {...props} />)
6
+
7
+ export const useLink = () => {
8
+ const renderLink = useContext(LinkContext)
9
+
10
+ if (!renderLink) {
11
+ throw new Error("<LinkProvider /> missing 'renderLink'")
12
+ }
13
+
14
+ return renderLink
15
+ }
16
+
17
+ const LinkProvider = ({ children, renderLink }) => {
18
+ return (
19
+ <LinkContext.Provider value={renderLink}>{children}</LinkContext.Provider>
20
+ )
21
+ }
22
+
23
+ LinkProvider.propTypes = {
24
+ children: node,
25
+ renderLink: func
26
+ }
27
+
28
+ export default LinkProvider
@@ -1 +1,2 @@
1
+ export { default, useLink } from './LinkProvider'
1
2
  export { ThemeProvider, withTheme } from './ThemeProvider'
@@ -0,0 +1,6 @@
1
+ import classnames from 'classnames/dedupe'
2
+
3
+ export const classNames = (...args) =>
4
+ classnames(...args)
5
+ .replace(undefined, '')
6
+ .trim()
@@ -1 +1,2 @@
1
1
  export { absoluteUrl } from './absolute-url'
2
+ export { classNames } from './class-names'