@fvc/chip 2.0.0-next-207ecd1bb62ad0a0f4fdfdf14ce2db83e5078a81
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/CHANGELOG.md +55 -0
- package/README.md +180 -0
- package/dist/lib/chip/src/Chip.d.ts +9 -0
- package/dist/lib/chip/src/index.d.ts +2 -0
- package/dist/lib/chip/src/types/Chip.types.d.ts +7 -0
- package/dist/lib/chip/src/types/index.d.ts +1 -0
- package/dist/lib/index.js +6 -0
- package/package.json +46 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# @fvc/chip
|
|
2
|
+
|
|
3
|
+
## 2.0.0-next-207ecd1bb62ad0a0f4fdfdf14ce2db83e5078a81
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- f8551e4: Add `@fvc/chip` component package
|
|
8
|
+
|
|
9
|
+
### What
|
|
10
|
+
|
|
11
|
+
Initial release of the `@fvc/chip` package — a compact label / badge component
|
|
12
|
+
built on top of Ant Design's `Tag`. Chips are used to represent discrete values,
|
|
13
|
+
filter criteria, or removable selections inside forms and data-display surfaces.
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
- **Two sizes** via the `size` prop: `"m"` (default) and `"s"`.
|
|
17
|
+
- **Closable / dismissible** — set `closable` and handle removal via `onClose`.
|
|
18
|
+
The component is consumer-controlled: it does not auto-unmount on close.
|
|
19
|
+
- **Disabled state** — `disabled` blocks all interactions and hides the close
|
|
20
|
+
button.
|
|
21
|
+
- **Keyboard accessible** — when `onClick` is provided the chip responds to
|
|
22
|
+
`Enter` and `Space`, meeting WCAG interactive-element expectations.
|
|
23
|
+
|
|
24
|
+
### Usage
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { Chip } from '@fvc/chip';
|
|
28
|
+
|
|
29
|
+
// Basic
|
|
30
|
+
<Chip>Label</Chip>
|
|
31
|
+
|
|
32
|
+
// Small, closable
|
|
33
|
+
<Chip size="s" closable onClose={() => removeTag(id)}>
|
|
34
|
+
Removable
|
|
35
|
+
</Chip>
|
|
36
|
+
|
|
37
|
+
// Disabled
|
|
38
|
+
<Chip disabled>Read-only</Chip>
|
|
39
|
+
|
|
40
|
+
// Interactive
|
|
41
|
+
<Chip onClick={() => toggleFilter(id)}>Clickable</Chip>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Install
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install @fvc/chip
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Peer dependencies: `react ^18.0.0`, `antd ^5.0.0`.
|
|
51
|
+
|
|
52
|
+
### Patch Changes
|
|
53
|
+
|
|
54
|
+
- Updated dependencies
|
|
55
|
+
- @fvc/icons@1.1.6-next-207ecd1bb62ad0a0f4fdfdf14ce2db83e5078a81
|
package/README.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# @fvc/chip
|
|
2
|
+
|
|
3
|
+
`@fvc/chip` provides FE-VIS styled chip primitives on top of Ant Design. It wraps the antd `Tag` component, replaces the class prefix with `fvc-chip`, and delivers the Figma-exact design-system appearance: two sizes, an optional close action, and a disabled state.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @fvc/chip
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Peer Dependencies
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bun add react antd
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Import
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { Chip } from '@fvc/chip';
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { Chip } from '@fvc/chip';
|
|
27
|
+
|
|
28
|
+
export function FilterBar() {
|
|
29
|
+
return <Chip size="medium">Active</Chip>;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Common Usage
|
|
34
|
+
|
|
35
|
+
### Sizes
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
<Chip size="medium">Medium</Chip>
|
|
39
|
+
<Chip size="small">Small</Chip>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Closable
|
|
43
|
+
|
|
44
|
+
Set `closable` to render a close icon. Use `onClose` to react to the close action.
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
const [visible, setVisible] = useState(true);
|
|
48
|
+
|
|
49
|
+
{visible && (
|
|
50
|
+
<Chip closable onClose={() => setVisible(false)}>
|
|
51
|
+
Filter
|
|
52
|
+
</Chip>
|
|
53
|
+
)}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Disabled
|
|
57
|
+
|
|
58
|
+
A disabled chip ignores clicks and hides the close icon.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
<Chip disabled>Disabled</Chip>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Leading Icon
|
|
65
|
+
|
|
66
|
+
Use the `icon` prop to render a React node before the label text.
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
<Chip icon={<SomeIcon width={16} height={16} />}>With icon</Chip>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Forwarding Refs
|
|
73
|
+
|
|
74
|
+
The component forwards its ref to the underlying `<span>` element.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
const ref = useRef<HTMLSpanElement>(null);
|
|
78
|
+
<Chip ref={ref}>Label</Chip>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Props
|
|
82
|
+
|
|
83
|
+
`Chip` accepts all Ant Design `TagProps` except `color`, `bordered`, and `prefixCls`, plus the additions below.
|
|
84
|
+
|
|
85
|
+
| Prop | Type | Default | Description |
|
|
86
|
+
| ----------- | --------------------------- | ---------- | ----------------------------------------------------------------------- |
|
|
87
|
+
| `size` | `'medium' \| 'small'` | `'medium'` | Visual size of the chip. |
|
|
88
|
+
| `disabled` | `boolean` | `false` | Disables interaction and dims the chip. |
|
|
89
|
+
| `closable` | `boolean` | — | Renders a close icon. Inherited from antd `TagProps`. |
|
|
90
|
+
| `onClose` | `(e: MouseEvent) => void` | — | Called when the close icon is clicked. Inherited from antd `TagProps`. |
|
|
91
|
+
| `icon` | `ReactNode` | — | Icon rendered before the label text. Inherited from antd `TagProps`. |
|
|
92
|
+
| `className` | `string` | — | Additional class names merged onto the root element. |
|
|
93
|
+
| `testId` | `string` | — | Maps to `data-testid` on the root element. |
|
|
94
|
+
|
|
95
|
+
## CSS Classes
|
|
96
|
+
|
|
97
|
+
| Class | Applied when |
|
|
98
|
+
| ---------------------- | ----------------------------------------------------------------- |
|
|
99
|
+
| `.fvc-chip` | Always — the root `<span>` element. |
|
|
100
|
+
| `.fvc-chip-borderless` | Always — chip is always rendered without a border. |
|
|
101
|
+
| `.fvc-chip-medium` | When `size="medium"` (default). |
|
|
102
|
+
| `.fvc-chip-small` | When `size="small"`. |
|
|
103
|
+
| `.fvc-chip-disabled` | When `disabled={true}`. |
|
|
104
|
+
| `.fvc-chip-close-icon` | The close icon wrapper rendered by antd when `closable={true}`. |
|
|
105
|
+
|
|
106
|
+
### Example override
|
|
107
|
+
|
|
108
|
+
```scss
|
|
109
|
+
.my-filter-bar .fvc-chip-close-icon {
|
|
110
|
+
width: 20px;
|
|
111
|
+
height: 20px;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## CSS Custom Properties
|
|
118
|
+
|
|
119
|
+
Override these variables in your global stylesheet. All variables are declared on `:root` in `src/styles/variables.scss`.
|
|
120
|
+
|
|
121
|
+
### Typography
|
|
122
|
+
|
|
123
|
+
| Variable | Default |
|
|
124
|
+
| -------------------- | ---------------------- |
|
|
125
|
+
| `--chip-font-family` | `'Roboto', sans-serif` |
|
|
126
|
+
| `--chip-fz` | `14px` |
|
|
127
|
+
| `--chip-fw` | `400` |
|
|
128
|
+
| `--chip-lh` | `16px` |
|
|
129
|
+
|
|
130
|
+
### Layout
|
|
131
|
+
|
|
132
|
+
| Variable | Default |
|
|
133
|
+
| ----------------------- | ------- |
|
|
134
|
+
| `--chip-px` | `10px` |
|
|
135
|
+
| `--chip-radius` | `16px` |
|
|
136
|
+
| `--chip-gap` | `4px` |
|
|
137
|
+
| `--chip-close-icon-size`| `16px` |
|
|
138
|
+
|
|
139
|
+
### Sizes
|
|
140
|
+
|
|
141
|
+
| Variable | Default |
|
|
142
|
+
| ------------------------ | ------- |
|
|
143
|
+
| `--chip-medium-size-py` | `8px` |
|
|
144
|
+
| `--chip-small-size-py` | `4px` |
|
|
145
|
+
|
|
146
|
+
### Colours
|
|
147
|
+
|
|
148
|
+
| Variable | Default |
|
|
149
|
+
| ------------------------ | ------------------------------------------- |
|
|
150
|
+
| `--chip-bg` | `var(--gray-150)` |
|
|
151
|
+
| `--chip-fg` | `var(--body-text-color-1000)` |
|
|
152
|
+
| `--chip-close-icon-fg` | `var(--gray-450)` |
|
|
153
|
+
| `--chip-close-icon-hover-fg` | `var(--link-icon-color-500)` |
|
|
154
|
+
| `--chip-disabled-fg` | `var(--blue-gray-600)` |
|
|
155
|
+
| `--chip-disabled-bg` | `var(--gray-150)` |
|
|
156
|
+
| `--chip-focus-ring-color`| `var(--blue-400)` |
|
|
157
|
+
|
|
158
|
+
### Global override example
|
|
159
|
+
|
|
160
|
+
```scss
|
|
161
|
+
// globals.scss
|
|
162
|
+
:root {
|
|
163
|
+
--chip-font-family: 'Inter', sans-serif;
|
|
164
|
+
--chip-bg: var(--neutral-200);
|
|
165
|
+
--chip-fg: var(--neutral-900);
|
|
166
|
+
--chip-radius: 4px;
|
|
167
|
+
--chip-focus-ring-color: var(--brand-500);
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Development
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
bun run lint
|
|
177
|
+
bun run type-check
|
|
178
|
+
bun run test
|
|
179
|
+
bun run build
|
|
180
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type TagProps } from 'antd';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import './styles/Chip.scss';
|
|
4
|
+
export declare const getClosableConfig: (disabled: boolean, closable: TagProps["closable"]) => TagProps["closable"];
|
|
5
|
+
export declare const Chip: React.ForwardRefExoticComponent<Omit<TagProps, "color" | "bordered" | "prefixCls"> & {
|
|
6
|
+
size?: import("./types").ChipSize;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
testId?: string;
|
|
9
|
+
} & React.RefAttributes<HTMLSpanElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { ChipProps, ChipSize } from './Chip.types';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{Tag as e}from"antd";import n,{forwardRef as i,useMemo as r}from"react";import{Icon as c}from"@fvc/icons";function o(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}"function"==typeof SuppressedError&&SuppressedError;var t,p={exports:{}};
|
|
2
|
+
/*!
|
|
3
|
+
Copyright (c) 2018 Jed Watson.
|
|
4
|
+
Licensed under the MIT License (MIT), see
|
|
5
|
+
http://jedwatson.github.io/classnames
|
|
6
|
+
*/var s,a=o((t||(t=1,s=p,function(){var e={}.hasOwnProperty;function n(){for(var e="",n=0;n<arguments.length;n++){var c=arguments[n];c&&(e=r(e,i(c)))}return e}function i(i){if("string"==typeof i||"number"==typeof i)return i;if("object"!=typeof i)return"";if(Array.isArray(i))return n.apply(null,i);if(i.toString!==Object.prototype.toString&&!i.toString.toString().includes("[native code]"))return i.toString();var c="";for(var o in i)e.call(i,o)&&i[o]&&(c=r(c,o));return c}function r(e,n){return n?e?e+" "+n:e+n:e}s.exports?(n.default=n,s.exports=n):window.classNames=n}()),p.exports));!function(e,n){void 0===n&&(n={});var i=n.insertAt;if("undefined"!=typeof document){var r=document.head||document.getElementsByTagName("head")[0],c=document.createElement("style");c.type="text/css","top"===i&&r.firstChild?r.insertBefore(c,r.firstChild):r.appendChild(c),c.styleSheet?c.styleSheet.cssText=e:c.appendChild(document.createTextNode(e))}}("@charset \"UTF-8\";\n:root {\n /* Chip – typography */\n --chip-font-family: 'Roboto', sans-serif;\n --chip-fz: 14px;\n --chip-fw: 400;\n --chip-lh: 16px;\n /* Chip – layout */\n --chip-px: 10px;\n --chip-radius: 16px;\n --chip-gap: 4px;\n --chip-close-icon-size: 16px;\n /* Chip – size: m */\n --chip-medium-size-py: 8px;\n /* Chip – size: s */\n --chip-small-size-py: 4px;\n /* Chip – colours */\n --chip-bg: var(--gray-150);\n --chip-fg: var(--body-text-color-1000);\n --chip-close-icon-fg: var(--gray-450);\n --chip-close-icon-hover-fg: var(--link-icon-color-500);\n --chip-disabled-fg: var(--blue-gray-600);\n --chip-disabled-bg: var(--gray-150);\n /* Chip – focus ring */\n --chip-focus-ring-color: var(--blue-400);\n}\n.fvc-chip.fvc-chip-borderless {\n display: inline-flex;\n align-items: center;\n gap: var(--chip-gap);\n padding: var(--chip-medium-size-py) var(--chip-px);\n background-color: var(--chip-bg);\n color: var(--chip-fg);\n border: none;\n border-radius: var(--chip-radius);\n font-family: var(--chip-font-family);\n font-size: var(--chip-fz);\n font-weight: var(--chip-fw);\n line-height: var(--chip-lh);\n cursor: default;\n margin: 0;\n box-shadow: none;\n}\n.fvc-chip.fvc-chip-borderless:focus-visible {\n outline: 2px solid var(--chip-focus-ring-color);\n outline-offset: 1px;\n}\n.fvc-chip.fvc-chip-borderless:focus:not(:focus-visible) {\n outline: none;\n}\n.fvc-chip.fvc-chip-borderless.fvc-chip-small {\n padding: var(--chip-small-size-py) var(--chip-px);\n}\n.fvc-chip.fvc-chip-borderless.fvc-chip-disabled {\n color: var(--chip-disabled-fg);\n background-color: var(--chip-disabled-bg);\n cursor: not-allowed;\n}\n.fvc-chip.fvc-chip .fvc-chip-close-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--chip-close-icon-size);\n height: var(--chip-close-icon-size);\n margin-inline-start: 0;\n color: var(--chip-close-icon-fg);\n cursor: pointer;\n line-height: 1;\n}\n.fvc-chip.fvc-chip .fvc-chip-close-icon svg {\n width: 100%;\n height: 100%;\n}\n.fvc-chip.fvc-chip.fvc-chip-borderless:hover .fvc-chip-close-icon {\n color: var(--chip-close-icon-hover-fg);\n}");const l="fvc-chip",h=({onClick:e,className:i})=>n.createElement("span",{role:"img","aria-label":"Close",className:i,onClick:e},n.createElement(c.Close,{color:"currentColor",width:"100%",height:"100%"})),f=i((i,c)=>{var{size:o="medium",disabled:t=!1,closable:p,className:s,testId:f}=i,d=function(e,n){var i={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&n.indexOf(r)<0&&(i[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var c=0;for(r=Object.getOwnPropertySymbols(e);c<r.length;c++)n.indexOf(r[c])<0&&Object.prototype.propertyIsEnumerable.call(e,r[c])&&(i[r[c]]=e[r[c]])}return i}(i,["size","disabled","closable","className","testId"]);const v=r(()=>((e,i)=>{if(e||!i)return!1;const r="object"==typeof i?i:{};return Object.assign({closeIcon:n.createElement(h,null)},r)})(t,p),[t,p]),u=a(s,`${l}-${o}`,{[`${l}-disabled`]:t});return n.createElement(e,Object.assign({ref:c,prefixCls:l,bordered:!1,"data-testid":f},d,{closable:v,className:u}))});f.displayName="Chip";export{f as Chip};
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fvc/chip",
|
|
3
|
+
"version": "2.0.0-next-207ecd1bb62ad0a0f4fdfdf14ce2db83e5078a81",
|
|
4
|
+
"main": "./dist/lib/index.js",
|
|
5
|
+
"types": "./dist/lib/chip/src/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist/lib/index.js",
|
|
8
|
+
"dist/lib/chip",
|
|
9
|
+
"package.json",
|
|
10
|
+
"CHANGELOG.md",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./dist/lib/index.js",
|
|
16
|
+
"types": "./dist/lib/chip/src/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./types": {
|
|
19
|
+
"types": "./dist/lib/chip/src/types/index.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "rollup -c ./rollup.config.mjs",
|
|
24
|
+
"clean": "rm -rf dist && rm -rf .rollup.cache && rm -rf .turbo",
|
|
25
|
+
"lint": "eslint --config ../../eslint.config.js \"src/**/*.{ts,tsx}\"",
|
|
26
|
+
"lint:fix": "eslint --config ../../eslint.config.js \"src/**/*.{ts,tsx}\" --fix",
|
|
27
|
+
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
28
|
+
"type-check": "tsc --noEmit",
|
|
29
|
+
"test": "bun test --preload ../../tests/happydom.ts --preload ../../tests/testing-library.tsx"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"react",
|
|
33
|
+
"react-component",
|
|
34
|
+
"fvc",
|
|
35
|
+
"fe-vis-core",
|
|
36
|
+
"ui",
|
|
37
|
+
"chip",
|
|
38
|
+
"design-system",
|
|
39
|
+
"antd"
|
|
40
|
+
],
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@fvc/icons": "1.1.6-next-207ecd1bb62ad0a0f4fdfdf14ce2db83e5078a81",
|
|
43
|
+
"antd": "^5.0.0",
|
|
44
|
+
"react": "^18.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|