@newhighsco/chipset 6.25.5 → 6.26.1

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.25.5",
4
+ "version": "6.26.1",
5
5
  "author": "New High Score",
6
6
  "license": "ISC",
7
7
  "repository": {
@@ -42,48 +42,48 @@
42
42
  "react-device-detect": "2.2.3"
43
43
  },
44
44
  "devDependencies": {
45
- "@babel/core": "7.28.5",
46
- "@babel/preset-env": "7.28.5",
45
+ "@babel/core": "7.28.6",
46
+ "@babel/preset-env": "7.28.6",
47
47
  "@babel/preset-react": "7.28.5",
48
- "@commitlint/cli": "20.1.0",
48
+ "@commitlint/cli": "20.3.1",
49
49
  "@fullhuman/postcss-purgecss": "7.0.2",
50
50
  "@newhighsco/browserslist-config": "2.0.0",
51
51
  "@newhighsco/commitlint-config": "1.1.46",
52
52
  "@newhighsco/editor-config": "1.2.0",
53
- "@newhighsco/eslint-config": "6.0.0",
54
- "@newhighsco/postcss-config": "4.0.7",
53
+ "@newhighsco/eslint-config": "6.0.7",
54
+ "@newhighsco/postcss-config": "4.0.11",
55
55
  "@newhighsco/prettier-config": "2.3.2",
56
- "@newhighsco/release-config": "1.4.19",
57
- "@newhighsco/storybook-preset": "9.0.0",
58
- "@newhighsco/stylelint-config": "4.0.18",
56
+ "@newhighsco/release-config": "1.4.20",
57
+ "@newhighsco/storybook-preset": "9.0.8",
58
+ "@newhighsco/stylelint-config": "4.0.19",
59
59
  "@newhighsco/svgr-config": "1.0.0",
60
60
  "@omlet/cli": "2.0.0",
61
- "@storybook/react-webpack5": "10.0.8",
61
+ "@storybook/react-webpack5": "10.1.11",
62
62
  "@testing-library/dom": "10.4.1",
63
63
  "@testing-library/jest-dom": "6.9.1",
64
- "@testing-library/react": "16.3.0",
64
+ "@testing-library/react": "16.3.1",
65
65
  "babel-loader": "10.0.0",
66
- "chromatic": "13.3.4",
66
+ "chromatic": "13.3.5",
67
67
  "concurrently": "9.2.1",
68
- "eslint": "9.39.1",
68
+ "eslint": "9.39.2",
69
69
  "husky": "9.1.7",
70
70
  "identity-obj-proxy": "3.0.0",
71
71
  "jest": "30.2.0",
72
72
  "jest-environment-jsdom": "30.2.0",
73
73
  "jest-junit": "16.0.0",
74
74
  "postcss": "8.5.6",
75
- "prettier": "3.6.2",
76
- "react": "19.2.0",
77
- "react-dom": "19.2.0",
78
- "sass-true": "10.0.0",
75
+ "prettier": "3.8.0",
76
+ "react": "19.2.3",
77
+ "react-dom": "19.2.3",
78
+ "sass-true": "10.1.0",
79
79
  "semantic-release": "25.0.2",
80
- "storybook": "10.0.8",
81
- "stylelint": "16.26.0",
82
- "webpack": "5.103.0"
80
+ "storybook": "10.1.11",
81
+ "stylelint": "17.0.0",
82
+ "webpack": "5.104.1"
83
83
  },
84
84
  "peerDependencies": {
85
- "react": "19.2.0",
86
- "react-dom": "19.2.0"
85
+ "react": "19.2.3",
86
+ "react-dom": "19.2.3"
87
87
  },
88
88
  "browserslist": [
89
89
  "extends @newhighsco/browserslist-config"
@@ -0,0 +1,122 @@
1
+ import { any, array, bool, func, node, oneOf, shape, string } from 'prop-types'
2
+ import React, { useId } from 'react'
3
+
4
+ import { useToggle } from '../../hooks'
5
+ import { classNames } from '../../utils'
6
+ import Button from '../Button'
7
+ import Icon from '../Icon'
8
+ import List from '../List'
9
+ import SmartLink from '../SmartLink'
10
+ import { ReactComponent as ArrowDownSvg } from './images/arrow-down.svg'
11
+ import { ReactComponent as ArrowUpSvg } from './images/arrow-up.svg'
12
+ import { ReactComponent as CloseSvg } from './images/close.svg'
13
+ import { ReactComponent as MenuSvg } from './images/menu.svg'
14
+
15
+ const ICONS = { true: <CloseSvg />, false: <MenuSvg /> }
16
+ const LABELS = { false: 'Show', true: 'Hide' }
17
+
18
+ const Menubar = ({
19
+ title,
20
+ role = 'menubar',
21
+ links = [],
22
+ inline,
23
+ renderLink = props => <Button {...props} />,
24
+ toggle,
25
+ onToggle = () => {},
26
+ theme
27
+ }) => {
28
+ const [visible, setVisibility] = useToggle(!toggle)
29
+ const id = useId()
30
+
31
+ if (!links.length) return null
32
+
33
+ const icons = toggle?.icons || ICONS
34
+
35
+ const toggleVisibility = () => {
36
+ setVisibility()
37
+ onToggle({ visible })
38
+ }
39
+
40
+ return (
41
+ <>
42
+ {toggle && (
43
+ <Button
44
+ active={visible}
45
+ aria-controls={id}
46
+ aria-expanded={visible}
47
+ onClick={toggleVisibility}
48
+ theme={{ root: theme?.toggle, active: theme?.toggleActive }}
49
+ >
50
+ {toggle.children}
51
+ <Icon
52
+ theme={{ root: theme?.toggleIcon }}
53
+ alt={`${LABELS[visible]} ${title}`}
54
+ >
55
+ {icons[visible]}
56
+ </Icon>
57
+ </Button>
58
+ )}
59
+ <List
60
+ id={id}
61
+ role={role}
62
+ unstyled
63
+ inline={inline}
64
+ hidden={!visible}
65
+ theme={{ root: theme?.list, inline: theme?.inline }}
66
+ >
67
+ {links.map(({ links = [], ...rest }, index) => {
68
+ const props = { ...rest, className: theme?.link }
69
+ const hasLinks = !!links.length
70
+
71
+ return (
72
+ <li
73
+ key={index}
74
+ role="menuitem"
75
+ className={classNames(theme?.item, hasLinks && theme?.itemToggle)}
76
+ >
77
+ {!hasLinks ? (
78
+ renderLink(props, index)
79
+ ) : (
80
+ <Menubar
81
+ title="Sub-navigation"
82
+ role="menu"
83
+ links={links}
84
+ toggle={{
85
+ icons: { true: <ArrowUpSvg />, false: <ArrowDownSvg /> },
86
+ ...props
87
+ }}
88
+ theme={{ ...theme, toggle: theme?.link }}
89
+ />
90
+ )}
91
+ </li>
92
+ )
93
+ })}
94
+ </List>
95
+ </>
96
+ )
97
+ }
98
+
99
+ Menubar.displayName = 'Menubar'
100
+ Menubar.propTypes = {
101
+ title: string,
102
+ role: string,
103
+ links: array,
104
+ inline: bool,
105
+ renderLink: func,
106
+ toggle: oneOf([
107
+ bool,
108
+ shape({ icons: { true: any, false: any }, children: node })
109
+ ]),
110
+ onToggle: func,
111
+ theme: shape({
112
+ list: string,
113
+ item: string,
114
+ itemToggle: string,
115
+ link: string,
116
+ toggle: string,
117
+ toggleActive: string,
118
+ toggleIcon: string
119
+ })
120
+ }
121
+
122
+ export default Menubar
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 24 24"><path d="M7 10l5 5 5-5H7z"/></svg>
@@ -0,0 +1 @@
1
+ <svg viewBox="0 0 24 24"><path d="M7 14l5-5 5 5H7z"/></svg>
@@ -0,0 +1 @@
1
+ export { default } from './Menubar'
@@ -1,99 +1,51 @@
1
- import { array, bool, func, shape, string } from 'prop-types'
2
- import React from 'react'
1
+ import { shape, string } from 'prop-types'
2
+ import React, { useId } from 'react'
3
3
 
4
- import { useIds, useToggle } from '../../hooks'
5
4
  import { classNames } from '../../utils'
6
- import Button from '../Button'
7
- import Icon from '../Icon'
8
- import List from '../List'
5
+ import Menubar from '../Menubar'
9
6
  import SmartLink from '../SmartLink'
10
7
  import VisuallyHidden from '../VisuallyHidden'
11
- import { ReactComponent as CloseSvg } from './images/close.svg'
12
- import { ReactComponent as MenuSvg } from './images/menu.svg'
13
8
 
14
9
  const Navigation = ({
15
10
  title = 'Navigation',
16
11
  links = [],
17
12
  inline,
18
- renderLink,
13
+ renderLink = props => <SmartLink {...props} />,
19
14
  toggle,
20
15
  onToggle = () => {},
21
16
  theme,
22
17
  className
23
18
  }) => {
24
- const [visible, setVisibility] = useToggle(!toggle)
25
- const [titleId, menuId] = useIds(['title', 'menu'])
19
+ const id = useId()
26
20
 
27
21
  if (!links.length) return null
28
22
 
29
- const toggleVisibility = () => {
30
- setVisibility()
31
- onToggle({ visible })
32
- }
33
-
34
23
  return (
35
24
  <nav
36
- aria-labelledby={titleId}
25
+ aria-labelledby={id}
37
26
  role="navigation"
38
27
  className={classNames(theme?.root, className)}
39
28
  >
40
- <VisuallyHidden as="h2" id={titleId}>
29
+ <VisuallyHidden as="h2" id={id}>
41
30
  {title}
42
31
  </VisuallyHidden>
43
- {toggle && (
44
- <Button
45
- active={visible}
46
- aria-controls={menuId}
47
- aria-expanded={visible}
48
- onClick={toggleVisibility}
49
- theme={{ root: theme?.toggle, active: theme?.toggleActive }}
50
- >
51
- <Icon
52
- theme={{ root: theme?.toggleIcon }}
53
- alt={`${!visible ? 'Show' : 'Hide'} ${title}`}
54
- >
55
- {!visible ? <MenuSvg /> : <CloseSvg />}
56
- </Icon>
57
- </Button>
58
- )}
59
- <List
60
- id={menuId}
61
- role="menubar"
62
- unstyled
32
+ <Menubar
33
+ title={title}
34
+ links={links}
63
35
  inline={inline}
64
- hidden={!visible}
65
- theme={{ root: theme?.list, inline: theme?.inline }}
66
- >
67
- {links.map((link, index) => {
68
- const props = { ...link, className: theme?.link }
69
-
70
- return (
71
- <li key={index} role="menuitem" className={theme?.item}>
72
- {renderLink ? renderLink(props, index) : <SmartLink {...props} />}
73
- </li>
74
- )
75
- })}
76
- </List>
36
+ renderLink={renderLink}
37
+ toggle={toggle}
38
+ onToggle={onToggle}
39
+ theme={theme}
40
+ />
77
41
  </nav>
78
42
  )
79
43
  }
80
44
 
81
45
  Navigation.displayName = 'Navigation'
82
46
  Navigation.propTypes = {
83
- title: string,
84
- links: array,
85
- inline: bool,
86
- renderLink: func,
87
- toggle: bool,
88
- onToggle: func,
89
- theme: shape({
90
- root: string,
91
- item: string,
92
- link: string,
93
- toggle: string,
94
- toggleActive: string,
95
- toggleIcon: string
96
- }),
47
+ ...Menubar.propTypes,
48
+ theme: shape({ root: string, ...Menubar.propTypes.theme }),
97
49
  className: string
98
50
  }
99
51
 
@@ -1,3 +1,17 @@
1
1
  .list[hidden] {
2
2
  display: none;
3
3
  }
4
+
5
+ .itemToggle {
6
+ position: relative;
7
+
8
+ .inline & .list {
9
+ position: absolute;
10
+ z-index: 1;
11
+ }
12
+ }
13
+
14
+ .link {
15
+ display: block;
16
+ width: 100%;
17
+ }