@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 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,2 @@
1
+ export { Chip } from './Chip';
2
+ export type { ChipProps, ChipSize } from './types';
@@ -0,0 +1,7 @@
1
+ import type { TagProps } from 'antd';
2
+ export type ChipSize = 'medium' | 'small';
3
+ export type ChipProps = Omit<TagProps, 'color' | 'bordered' | 'prefixCls'> & {
4
+ size?: ChipSize;
5
+ disabled?: boolean;
6
+ testId?: string;
7
+ };
@@ -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
+ }